質問: h; disp(); } int main(int argc, char ** argv) { glutInit(&argc, argv); glutInitWindowPosition(100, 50); glutInitWindowSize(400, 300); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutCreateWindow("3DCGへの道遠し"); glutDisplayFunc(disp); glutReshapeFunc(reshape); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, vertex); glutMainLoop(); return 0; } ``` ### 試したこと 1)プログラム中 (B)3か所をコメントアウトした時の出力(output2)は意図通り ![output2](https://teratail.storage.googleapis.com/uploads/contributed_images/8b9353cf18bb0bd465742202625ed7a6.jpeg) 2)プログラム中 (A)3か所をコメントアウトした時の出力(output3)も意図通り ![output3](https://teratail.storage.googleapis.com/uploads/contributed_images/a48bb50e292af9cd1c83cb8a67bee8c0.jpeg) ### 補足情報(FW/ツールのバージョンなど) 特に何かに依存した現象と思えないので記載しません。 必要ならご指摘ください。
回答: glViewportで指定するビューポート座標は、原点(0,0)が左 **下** で、(width,height)が右 **上**、Y軸プラス方向は **上方向** です。 左上を原点とするウィンドウ座標とは、**縦方向が逆**になります。 AとBのglViewportの指定が逆ではないでしょうか。 また、glViewportは **これから描画する物の座標を設定する** 関数であって、既に描画された物の座標を設定する物ではありません。 (つまり、AのglViewport関数の座標に影響するのはその後に処理されるBの描画になります) どうもglViewport関数の呼び出し場所がおかしいので、もしかするとそのあたりを勘違いされているとか? 気になったので、これも追記しておきます。 コメントを受けて。 > > その下にあるglViewport(0, height / 2, width, height / 2); の指示により画面上方に描かれていると思うのです。 > > > これは、その通りです。 この認識があれば、私の説明で画面上部に描画される理由になると思うのですが。 ``` void disp(void) { glClear(GL_COLOR_BUFFER_BIT); glColor3d(1.0, 0.0, 0.0); //(A) glDrawArrays(GL_POLYGON, 0, 3); //(A) glViewport(0, height / 2, width, height / 2); //(A) //glColor3d(0.0, 1.0, 0.0); //(B) //glDrawArrays(GL_POLYGON, 3, 3); //(B) //glViewport(0, 0, width, height / 2); //(B) glFlush(); } ``` とBをコメントアウトした書いた時の動作を考えてみましょう。 1. 1回目のdisp関数呼び出し a. glDrawArrays関数の呼び出しで描画される。この時には、glViewport関数の呼び出しは行われていないので、ビューポート設定は(0, 0, width, height)になっている。 b. glViewport(0, height/2, width, height/2)の呼び出しで、ビューポート設定は、画面上部に設定される。 2. 2回目以降のdisp関数呼び出し a. glDrawArrays関数の呼び出しで描画される。この時には、**1-bのビューポート設定が残っているので**、ビューポート設定は(0, height/2, width, height/2)(画面上部)になっている。 b. glViewport(0, height/2, width, height/2)の呼び出しで、ビューポート設定は、画面上部に設定される。 となると考えています。 つまり、最初の一フレームは画面全体に、それ以降は前フレームのビューポート設定が残っているので画面上部に描画されると考えてます。