前回予告した通り、今回は「OpenTK、再び」シリーズの最終回として、DLLに入れた
基本図形(プリミティブ)6種のサンプル(注)のお披露目
をします。
注:前々回紹介したGLControl_BaseとGameWindow_Baseの内、後者を利用して作りました。コンパイルには
(1)前回紹介したOpenTK_Primitives.csをMSCompAssの"Option"で「ライブラリー」をターゲットにしてコンパイルしてDLL(OpenTK_Primitives.dll)を作り、
(2)今回のサンプルプログラムではプログラム本文で"using OpenTK_Primitives;"とし、
(3)今回のサンプルプログラムではそのライブラリー(OpenTK_Primitives.dll)をMSCompAssの"Option"で参照します。
1.立(直)方体(Cube)と(正)三角錐(Triangular)
先ずはGLUTでも使った立方体と正三角錐から。OpenTK_Primitives名前空間で定義されたOTKPrimsクラスのインスタンスを生成します。(以下すべて同じ為、以下省略。)
OTKPrims pv = new OTKPrims(); //otkPrimitivesクラスインスタンス
インスタンス"pv”のメソッドとしてプリミティブの描画を行うOnRenderFrameのコードは以下の通り。
//ウィンドウ描画が更新された場合に実行される
protected override void OnRenderFrame(FrameEventArgs e)
{
base.OnRenderFrame(e);
if(drawStop)
return; //描画停止
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.MatrixMode(MatrixMode.Modelview); //モデルビューモードを選択
//視点を設定して原点(0, 0, 0)を見る
Vector3 eye = new Vector3(0.0f, 0.0f, 5.0f);
Matrix4 modelview = Matrix4.LookAt(eye, Vector3.Zero, Vector3.UnitY); //gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0);
GL.LoadMatrix(ref modelview); //現在の変換マトリックスに設定
//以下に描画処理を行う
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.PushMatrix();
{
GL.Translate(1.0, 0.0, 0.0);
GL.Rotate(RotateX, 1, 0, 0);
GL.Rotate(RotateY, 0, 1, 0);
GL.Rotate(RotateZ, 0, 0, 1);
GL.Material(MaterialFace.Front, MaterialParameter.Ambient, Color4.Red);
pv.Cube(SorW);
}
GL.PopMatrix();
GL.PushMatrix();
{
GL.Translate(-1.0, 0.0, 0.0);
GL.Rotate(RotateX, 1, 0, 0);
GL.Rotate(RotateY, 0, 1, 0);
GL.Rotate(RotateZ, 0, 0, 1);
GL.Material(MaterialFace.Front, MaterialParameter.Ambient, Color4.Blue);
pv.Triangular(SorW);
}
GL.PopMatrix();
RotateX += 1.5f;
RotateY += 5.0f;
RotateZ += 1.0f;
this.SwapBuffers();
}
するとこうなります。(ソリッドとワイアー)
2.球(Sphere)とt円環(Torus)
次は球と円環。描画を行うOnRenderFrameのコードは以下の通り。
//ウィンドウ描画が更新された場合に実行される
protected override void OnRenderFrame(FrameEventArgs e)
{
base.OnRenderFrame(e);
if(drawStop)
return; //描画停止
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.MatrixMode(MatrixMode.Modelview); //モデルビューモードを選択
//視点を設定して原点(0, 0, 0)を見る
Vector3 eye = new Vector3(0.0f, 0.0f, 5.0f);
Matrix4 modelview = Matrix4.LookAt(eye, Vector3.Zero, Vector3.UnitY); //gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0);
GL.LoadMatrix(ref modelview); //現在の変換マトリックスに設定
//以下に描画処理を行う
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.PushMatrix();
{
GL.Rotate(RotateX, 1, 0, 0);
GL.Rotate(RotateY, 0, 1, 0);
GL.Rotate(RotateZ, 0, 0, 1);
pv.Sphere(SorW);
pv.Torus(SorW);
}
GL.PopMatrix();
RotateX += 1.5f;
RotateY += 5.0f;
RotateZ += 1.0f;
this.SwapBuffers();
}
するとこうなります。(ソリッドとワイアー)
![](https://stat.ameba.jp/user_images/20240612/06/ysama2021/cf/24/j/o0642051215450455777.jpg?caw=800)
3.円柱(Pipe)と円錐(Cone)
次は円柱と円錐。描画を行うOnRenderFrameのコードは以下の通り。
//ウィンドウ描画が更新された場合に実行される
protected override void OnRenderFrame(FrameEventArgs e)
{
base.OnRenderFrame(e);
if(drawStop)
return; //描画停止
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.MatrixMode(MatrixMode.Modelview); //モデルビューモードを選択
//視点を設定して原点(0, 0, 0)を見る
Vector3 eye = new Vector3(0.0f, 0.0f, 5.0f);
Matrix4 modelview = Matrix4.LookAt(eye, Vector3.Zero, Vector3.UnitY); //gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0);
GL.LoadMatrix(ref modelview); //現在の変換マトリックスに設定
//以下に描画処理を行う
GL.PushMatrix();
{
GL.Rotate(RotateX, 1, 0, 0);
GL.Rotate(RotateY, 0, 1, 0);
GL.Rotate(RotateZ, 0, 0, 1);
GL.Material(MaterialFace.Front, MaterialParameter.Ambient, Color4.Red);
pv.Pipe(SorW, 0.35, 1.5);
GL.PushMatrix();
GL.Rotate(90, 0, 0, 1);
GL.Material(MaterialFace.Front, MaterialParameter.Ambient, Color4.Cyan);
pv.Cone(SorW, 0.5, 2);
GL.PopMatrix();
}
GL.PopMatrix();
RotateX += 1.5f;
RotateY += 5.0f;
RotateZ += 1.0f;
this.SwapBuffers();
}
するとこうなります。(ソリッドとワイアー)
4.おまけ(惑星軌道)
最後に(既に「におわせ画像」でご存じと思いますが)、
球を使って太陽、地球、月の自公転の様子(勿論縮尺等は正確ではありませんよ)っぽくしたGLUTのサンプルがあったので、OpenTKに移植してみました。描画を行うOnRenderFrameのコードは以下の通り。(なお、"Theta_"はクラスフィールドとして予め宣言しておきます。)
//ウィンドウ描画が更新された場合に実行される
protected override void OnRenderFrame(FrameEventArgs e)
{
base.OnRenderFrame(e);
if(drawStop)
return; //描画停止
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.MatrixMode(MatrixMode.Modelview); //モデルビューモードを選択
//視点を設定して原点(0, 0, 0)を見る
Vector3 eye = new Vector3(0.0f, 0.0f, 5.0f);
Matrix4 modelview = Matrix4.LookAt(eye, Vector3.Zero, Vector3.UnitY); //gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0);
GL.LoadMatrix(ref modelview); //現在の変換マトリックスに設定
//以下に描画処理を行う
//鏡面光成分のセット
//float[] material_specular = new float[4] {0.2f, 0.2f, 0.2f, 1.0f}; //鏡面光成分
GL.Material(MaterialFace.Front, MaterialParameter.Specular, Color4.White);
GL.Material(MaterialFace.Front, MaterialParameter.Shininess, 32.0f);
GL.Material(MaterialFace.Front, MaterialParameter.Diffuse, Color4.OrangeRed);
pv.Sphere(SorW,20.0); //太陽
GL.PushMatrix();
{
GL.Rotate(Theta_Sun, 0.0f, 0.0f, 1.0f); //z軸周りにTheta_Sun度回転
GL.Translate(60.0f, 0.0f, 0.0f); //x軸に60平行移動
GL.Rotate(Theta_Earth, 0.0f, 0.0f, 1.0f);//z軸周りにTheta_Earth度回転
GL.Material(MaterialFace.Front, MaterialParameter.Diffuse, Color4.SeaGreen);
pv.Sphere(SorW, 10.0); //地球
GL.Rotate(Theta_Moon, 0.0f, 0.0f, 1.0f);//z軸周りにTheta_Moon度回転
GL.Translate(20.0f, 0.0f, 0.0f); //x軸に20平行移動
GL.Material(MaterialFace.Front, MaterialParameter.Diffuse, Color4.Yellow);
pv.Sphere(SorW, 5.0); //月
}
GL.PopMatrix();
Theta_Sun += 2.0f;
Theta_Earth -= 10.0f;
Theta_Moon += 6.0f;
//ダブルバッファー
this.SwapBuffers();
}
するとこうなります。(ソリッドとワイアー)
今年四月末に「次ネタ」として思いつき、五月から始めた【OpenGL】シリーズですが、ほぼ1か月半かかり、OpenTK導入、GLUT及びWindows SDK、GLUT及びBCCSkeltonを経て、再度OpenTKで無事締めることが出来ました。懸案であったOpenGLの学習(と言っても「初めの一歩」程度ですが)も何とかでき、Windows SDK、(久々の)BCCCSkelton、そして現代的なC#による夫々の、そしてそれなりの成果物も残すことが出来ました。
ということで、本シリーズは一応ここで仮締め
ということに致します。皆さま、ご清聴ありがとうございました。