*第2回目 CocoaでOpenGL [#jbc78006]
 第1回目CocoaでOpenGLで作ったプログラムにいろいろ追加してみます。
***タイマを使ってフレームレートを一定化 [#ac77233c]
 NSTimer *timer;
 timer = [ NSTimer scheduledTimerWithTimeInterval:0.016
 			target:self
 			selector: @selector(update:)
 			userInfo:nil
 			repeats:YES ];
 これでタイマを起動できます。16ミリ秒にすることによって大体60コマ/秒を目指します。(精度未確認)
 scheduledTimerWithTimeInterval:0.016 = タイマ間隔は0.016秒(16ミリ秒)
 selector: @selector(update:) = タイマ割り込みが掛かったらupdate関数を呼び出す
 repeats:YES = 何度も繰り返す
#author("2018-06-18T16:16:41+09:00","default:kuran","kuran")

***OpenGLでのレンダリング部分をC++化 [#j5d238e1]
 OpenGLの制御部分をrender.hppおよびrender.cppに書きます。
 Objective-CからCやC++の関数はそのまま呼び出すことができます。
 ただし.mファイルからはC++の関数はそのまま呼び出せないため
 extern "C"を書く必要があります。CからC++の関数を呼び出す方法と同じです。
 .mmファイルからはC++の関数はそのまま呼び出すことができます。

**プログラム変更 [#s39eac65]
***MyOpenGLView.h [#xd5bde97]
 #import <Cocoa/Cocoa.h>
 
 @interface MyOpenGLView : NSOpenGLView
 {
 	NSTimer *timer;
 }
 @end

 NSTimerを追加します。
***MyOpenGLView.m [#l6321948]
 #import "MyOpenGLView.h"
 #import "render.hpp"
 
 @implementation MyOpenGLView
 
 - (id) initWithFrame : (NSRect) frameRect {
 
 	self = [ super initWithFrame : frameRect
                      pixelFormat : [ NSOpenGLView defaultPixelFormat ] ];
 
 	[ [ self openGLContext ] makeCurrentContext ];
 
 	timer = [ NSTimer scheduledTimerWithTimeInterval:0.016
 				target:self
 				selector: @selector(update:)
 				userInfo:nil
 				repeats:YES ];
 
 	Render_Initialize();
 	return( self );
 }
 
 - (void) drawRect : (NSRect) rect {
 
 	Render_Draw();
 	[ [ self openGLContext ] flushBuffer ];
 }
 
 - (void) update : (NSTimer *) timer {
 	Render_Update();
 	[ self display ];
 }
 
 @end

 scheduledTimerWithTimeIntervalでタイマの設定をしています。
 また元々OpenGLの関数があった所でRender_の付いた関数を呼び出しています。
**プログラム追加 [#h6967916]
***render.hpp [#p23e03f1]
 #ifndef RENDER_HPP
 #define RENDER_HPP
 
 #ifdef __cplusplus
 extern "C"
 {
 #endif
 
 void Render_Initialize(void);
 void Render_Draw(void);
 void Render_Update(void);
 
 #ifdef __cplusplus
 }
 #endif
 
 #endif

 Render_Initialize、Render_Draw、Render_Updateの3つの関数を定義しています。
 exrern "C"を書くことによって.mファイルからC++の関数を呼び出すことができるようになります。
 .mmファイルから呼び出す場合はextern "C"は必要はありません。
***render.cpp [#gec448a0]
 #include <math.h>
 #include <OpenGL/OpenGL.h>
 #include <OpenGL/gl.h>
 #include <OpenGL/glu.h>
 #include "render.hpp"
 
 static float radian = 0.0f;
 
 void Render_Initialize(void)
 {
 	glDisable(GL_CULL_FACE);
 	glPolygonMode(GL_FRONT, GL_FILL);
 	glPolygonMode(GL_BACK, GL_LINE);
 	Render_Update();
 }
 
 void Render_Draw(void)
 {
 	float x;
 	float y;
 	x = sinf( radian ) * 0.5f;
 	y = cosf( radian ) * 0.5f;
 
 	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
 	glClear(GL_COLOR_BUFFER_BIT);
 
 	glBegin(GL_TRIANGLES);
 	glColor3d(1.0f, 1.0f, 1.0f);
 	glVertex3f(0.0f + x, 0.5f + y, 0.0f);
 	glVertex3f(-0.5f + x, -0.5f + y, 0.0f);
 	glVertex3f(0.5f + x, -0.5f + y, 0.0f);
 	glEnd();
 	glFlush();
 }
 
 void Render_Update(void)
 {
 	radian += 3.14159f * 2.0f / 60.0f;
 	if( radian > 3.14159f * 2.0f )
 	{
 		radian = 0.0f;
 	}
 }

 Render_Initialize、Render_Draw、Render_UpdateがそれぞれOpenGLでのレンダリングの初期化、描画、更新になります。
 Render_Updateは一度呼ばれるとアニメーションを1コマ進めます。

 render.hppとrender.cppを以下の手順で登録します。
#ref(cocoa_opengl2_1.png,,,100%)
 グループとファイルのOther sourcesを右クリックして「追加」-「既存のファイル」を選びます。
#ref(cocoa_opengl2_2.png,,,100%)
 render.hpp、render.cppを選んで「追加」ボタンを押します。
#ref(cocoa_opengl2_3.png,,,100%)
 何も変更せずに「追加」ボタンを押します。
 もしWindowsなどで打ち込んだファイルを追加する場合はエンコーディングをShift-JISにすると良いかもしれません。
**実行結果 [#s3bc8fa7]
#ref(cocoa_opengl2_4.png,,,100%)
 三角形がウィンドウ内をぐるぐる回れば成功です。

[[前に戻る>プログラミング]]


トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS