*第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%) 三角形がウィンドウ内をぐるぐる回れば成功です。 [[前に戻る>プログラミング]]