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

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

ただいまの
回答率

90.83%

  • OpenGL

    148questions

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

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

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 202

t-prog

score 1

 前提・実現したいこと

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/ツールのバージョンなど)

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • YomogiKOBO

    2018/04/17 19:55

    ぱっと見、http://wisdom.sakura.ne.jp/system/opengl/gl13.htmlとの違いは色指定ぐらですが、色指定をはずしても同様の現象ですかね?

    キャンセル

  • t-prog

    2018/04/17 20:16

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

    キャンセル

回答 1

checkベストアンサー

+2

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

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/04/18 08: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関数がそれぞれどのような挙動をしているかご説明頂けないでしょうか?

    キャンセル

  • 2018/04/18 09:51

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

    キャンセル

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

  • ただいまの回答率 90.83%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • OpenGL

    148questions

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