blog

OpenGLの場合 - 正方形を描画し、その動きをキーボードで制御する。

OpenGLを使って正方形を描き、キーボードの上下左右キーで正方形の上下左右の動きを制御します。その効果は次のようになります:開発におけるメイン関数に似ていて、アプリプログラムの入口であり、OpenG...

Jul 1, 2020 · 5 min. read
シェア

I. 例と関連する機能の説明

OpenGLを使って正方形を描き、キーボードの上下左右キーで正方形の上下左右の動きをコントロールします。この場合、いくつかの関数が必要になります:

  • int main(int argc,char *argv[]) メイン関数:開発におけるメイン関数と同様、APPプログラムの入り口であり、OpenGLではプログラムの出口です。OpenGLは手続き型プログラミングに向いています。そのため、OpenGLを使ったグラフィック/イメージ処理はチェーンの形をしていることがわかります。OpenGLに基づくイメージ処理フレームワークもチェーンプログラミングです。
  • void changeSize(int w ,int h):changeSize関数: glutReshaperFuncを介してリシェイパーとして登録されるカスタム関数.この関数はスクリーンサイズが変更された時やウィンドウが初めて作成された時にウィンドウやポートのサイズを変更するために呼び出されます.
  • void RenderScene(void) RenderScene関数: glutDisplayFunc(関数名)を介してディスプレイレンダリング関数として登録されるカスタム関数.この関数は画面が変化した時や開発者がレンダリングを開始した時に呼び出され、data->rendering処理を実装するために使用されます。
  • void setupRC(void) setupRC関数:レンダリングに必要なグラフィックの頂点データ/色データ、その他のデータ準備を設定するカスタム関数で、初期設定関数と解釈できます。
  • void setupRC(void) SpecialKey関数:キーボードの上下左右キーのレスポンスを受け取り、そのキーに応じた再描画APIの計算とトリガーを行うカスタム関数です。

次に、ケース全体のフローチャートを見てください:

次に、コード上の

main()`

プログラム立ち上げの入口で、プログラムの主な準備作業が行われます:

  1. OpenGLの初期化、カレント作業ディレクトリの設定、GLUTライブラリの初期化など;
  2. ウィンドウサイズとタイトル表示に関する設定
  3. 各種リスナーコールバック関数の登録
  4. setupRC()を呼び出してglutMainLoopをオンにします(iOSのRunLoopに似ています)。
int main(int argc,char *argv[])
{
 //MAC OS Xのカレント・ワーキング・ディレクトリを設定する。
 gltSetWorkingDirectory(argv[0]);
 //GLUTライブラリーを初期化する。この関数は単なる凡例コマンド・パラメーターで、glutライブラリーを初期化する。
 glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL);
 
 //GLUTウィンドウ・サイズ、ウィンドウ・タイトル
 glutInitWindowSize();
 glutCreateWindow("Triangle");
 //リシェイプ関数を登録して、ウィンドウ・サイズが変更されたら、changeSize()コールバックをトリガーする。
 glutReshapeFunc(changeSize);
 //表示関数を登録する;changeSizeがトリガーされると、あるいはglutPostRedisplay()がトリガーされる。
 //RenderScene() 
 glutDisplayFunc(RenderScene);
 //キーボードがクリックされたときにトリガーされる特別な関数を登録する;
 glutSpecialFunc(SpecialKeys);
 GLenum status = glewInit();
 if (GLEW_OK != status) {
 printf("GLEW Error:%s
",glewGetErrorString(status));
 return 1;
 }
 //レンダリング環境のセットアップ
 setupRC();
 glutMainLoop();
 return 0;
}

setupRC()` :

setupRCは主にいくつかの初期化操作を行います。これはiOSでUIViewを初期化する際のUI開発設定として理解できます。

  1. ウィンドウの背景色の設定
  2. シェーダーを保存するshaderManagerを初期化します。
  3. グラフ頂点データの設定
  4. GLBatch三角バッチクラスを使ってシェーダにデータを渡す setupRCは、main関数内で呼び出すことによってのみ手動でトリガできます。
void setupRC()
{
 //クリア画面の色を設定する
 glClearColor(0.98f, 0.40f, 0.7f, 1);
 //カラーリング・マネージャーを初期化する
 shaderManager.InitializeStockShaders();
 //GLに修正_TRIANGLE_FAN ,4 
 //実際には、後のレンダリングで使われる方法でデータを構築している。
 //ここでは、コンテナ・クラスであるGLBatchバッチ・クラスを使っている。
 //どのようなデータを読み込むか
 triangleBatch.Begin(GL_TRIANGLE_FAN, 4);
 //データとは
 triangleBatch.CopyVertexData3f(vVerts);
 // 
 triangleBatch.End();
}

changeSize()`

changeSizeでは主に2つのことが行われます:

  1. OpenGLビューポートの設定
  2. OpenGLの投影スタイルなどを設定します。changeSizeトリガーには大きく分けて、手動トリガーとコールバックトリガーの2種類があります。
void changeSize(int w ,int h) {
/*
 x,y パラメータはウィンドウ内のビューの左下隅の座標を表し、幅と高さはピクセルで表され、通常x,yは0である。
 */
 glViewport(0, 0, w, h);
}

RenderScene()`

RenderSceneは、主に画面にレンダリングされるものを扱います。

  1. キャッシュのクリア
  2. メモリーカラリストの使用
  3. 図面.

RenderSceneのトリガーには主に2つの方法があります:自動システムトリガーとコールバックトリガー(glutPostRedisplayの再描画を呼び出す)です。

void RenderScene(void)
{
 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
 //色を設定する{R,G,B,A}
 GLfloat vRed[] = {1.0f,0.0f,0.0f,0.0f};
 //4x4 
 M3DMatrix44f mTransfromMatrix;
 // 
 m3dTranslationMatrix44(mTransfromMatrix, xPos, yPos, 0.0f);
 //マトリックスの結果を描画用の固定シェーダーに提出する。
 shaderManager.UseStockShader(GLT_SHADER_FLAT,mTransfromMatrix,vRed);
 triangleBatch.Draw();
 //スワップ・バッファを実行する
 glutSwapBuffers();
}

注目すべきは、ビューの移動は、ポイントの個別計算に加えて、行列を使って行われることですが、これは頂点データが多い場合には非常に非効率的です。ですから、行列を賢く使うことは、OpenGLを使う上で非常に重要な役割を果たします。

SpecialKeys()` :

SpecialKeysは、クリック後のキーボードボタンにmain()で追加されたコールバックをリッスンすると、コールバックはint型のキーを返すので、キーボードでクリックされたキーがどれかを判断することができ、後の計算を実現します。このメソッドは、キーを押すことによって画面上のビューを移動させる効果を制御するためのコアメソッドなので、ここでは主に上下左右のキーをキャプチャし、いくつかのデータ処理を行います。

void SpecialKeys(int key, int x, int y){
 
 GLfloat stepSize = 0.025f;
 if (key == GLUT_KEY_UP) {
 yPos += stepSize;
 }
 if (key == GLUT_KEY_DOWN) {
 yPos -= stepSize;
 }
 if (key == GLUT_KEY_LEFT) {
 xPos -= stepSize;
 }
 if (key == GLUT_KEY_RIGHT) {
 xPos += stepSize;
 }
 //衝突検出
 if (xPos < (-1.0f + blockSize)) {
 xPos = -1.0f + blockSize;
 }
 if (xPos > (1.0f - blockSize)) {
 xPos = 1.0f - blockSize;
 }
 if (yPos < (-1.0f + blockSize)) {
 yPos = -1.0f + blockSize;
 }
 if (yPos > (1.0f - blockSize)) {
 yPos = 1.0f - blockSize;
 }
 //これは再描画をトリガーするAPIで、setNeedsDisplay()を呼び出すのと似ている。
 glutPostRedisplay();
}

コード内の衝突検出は、実際には表示境界の問題で、移動中に正方形のビューが表示ビューエリアから外れるのを防いでいます。

Read next

パートVIII|Flink 1.10 Hive統合クイックスタート

Hiveはビッグデータ分野で最も早く登場したSQLエンジンで、豊富な機能と幅広いユーザベースを備えています。Spark SQLやImpalaなどの後発のSQLエンジンは、ある程度Hiveと統合する機能を提供しており、既存のデータウェアハウスを利用したり、ジョブマイグレーションを行ったりするのに便利です。 Flinkは1.9からHiveをサポートしています。

Jun 30, 2020 · 5 min read