質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

Q&A

解決済

1回答

8821閲覧

OpenGL glViewport()の使い方について

t-prog

総合スコア7

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

0グッド

1クリップ

投稿2018/04/17 08:59

前提・実現したいこと

OpenGLプログラムの勉強をしています。
glViewport()を2回使用し、ウインドウの上下に図形を表示しようとするのですが、
2回glviewport()を使用し描画すると、意図しない挙動となります。
その原因と、対処法についてご教示ください。

発生している問題・エラーメッセージ

output1
は、緑と赤の三角形が、上下逆(意図と違う)に描画されている。
欲しいプログラムの出力は、以下で記載の output2,3を合成したもの(砂時計形状)
なぜoutput1のようになるのでしょうか?

エラーメッセージ

OpenGL コード #include <GL/glut.h> const GLfloat vertex[] = { -0.9, 0.9, 0.9, 0.9, 0, -0.9, -0.9, -0.9, 0.9, -0.9, 0, 0.9 }; int width, height; 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(); } void reshape(int w, int h) { width = w; height = 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
2)プログラム中 (A)3か所をコメントアウトした時の出力(output3)も意図通り
output3

補足情報(FW/ツールのバージョンなど)

特に何かに依存した現象と思えないので記載しません。
必要ならご指摘ください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

t-prog

2018/04/17 11:16

はい、同じ現象です。色は、2つの三角形がどちらの三角形かを区別するつもりで後から追加しました。YomogiKOBOさんの指摘するサイトでの出力結果も同じようになっています。
guest

回答1

0

ベストアンサー

glViewportで指定するビューポート座標は、原点(0,0)が左 で、(width,height)が右 、Y軸プラス方向は 上方向 です。
左上を原点とするウィンドウ座標とは、縦方向が逆になります。

AとBのglViewportの指定が逆ではないでしょうか。


また、glViewportは これから描画する物の座標を設定する 関数であって、既に描画された物の座標を設定する物ではありません。
(つまり、AのglViewport関数の座標に影響するのはその後に処理されるBの描画になります)
どうもglViewport関数の呼び出し場所がおかしいので、もしかするとそのあたりを勘違いされているとか?
気になったので、これも追記しておきます。


コメントを受けて。

その下にあるglViewport(0, height / 2, width, height / 2); の指示により画面上方に描かれていると思うのです。

これは、その通りです。
この認識があれば、私の説明で画面上部に描画される理由になると思うのですが。

c

1void disp(void) { 2 glClear(GL_COLOR_BUFFER_BIT); 3 glColor3d(1.0, 0.0, 0.0); //(A) 4 glDrawArrays(GL_POLYGON, 0, 3); //(A) 5 glViewport(0, height / 2, width, height / 2); //(A) 6 //glColor3d(0.0, 1.0, 0.0); //(B) 7 //glDrawArrays(GL_POLYGON, 3, 3); //(B) 8 //glViewport(0, 0, width, height / 2); //(B) 9 glFlush(); 10}

と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)の呼び出しで、ビューポート設定は、画面上部に設定される。

となると考えています。
つまり、最初の一フレームは画面全体に、それ以降は前フレームのビューポート設定が残っているので画面上部に描画されると考えてます。

投稿2018/04/17 17:08

編集2018/04/18 00:15
katsuko

総合スコア3469

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

t-prog

2018/04/17 23:11

katsukoさん 回答ありがとうございます。 (B)または(A)をコメントアウトして三角形を1個だけ描画した結果(output2,output3)の三角形の形を見て ビューポート座標のY軸プラス方向は画面上方向であることは理解できます。 また、(B)をコメントアウトした際、glDrawArrays(GL_POLYGON, 0, 3); で描画した三角形は その下にあるglViewport(0, height / 2, width, height / 2); の指示により画面上方に描かれていると思うのです。(A)をコメントアウトした際も、同様に思えます。 それはどのように考えればよいのでしょうか? katsukoさんのviewportに対する指摘を受け入れるとすると、(B)をコメントアウトした場合の三角形の位置は、ウインドウ下半分(上下向きは問題ない)でないとおかしいと思うのです。 よろしければ、 今回の場合、glViewport関数がそれぞれどのような挙動をしているかご説明頂けないでしょうか?
t-prog

2018/04/18 00:51

katuskoさん すべて了解です。glViewport()の位置を変更し望む出力が得られたことも追記しておきます。 glViewport()にモデリング変換の作用をさせて悩むくらいなら最初から必要な形状を作っておけと思われるでしょうが、これはこれで用途があるように思います。 初心者に対し、ご丁寧な説明本当にありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問