2017-09-25 15 views
3

私はたくさんの頂点を計算して、3Dサーフェスプロットのために四角いストリップでそれらを表示しています。glPushMatrix()とglBegin()の間に接続がありますか?

私は、いくつかの頂点に対して、予想外のやり方で色を変える奇妙な動作をしました。私はそれを修正しようとしたと偶然に、私はglPushMatrix()glPopMatrixを前後に入れて、問題が解決されたことを発見した。根本的な問題は誰が知っていますか?私は一般的にプッシュ/ポップアップをglBegin/glEndで使うべきですか?

ここに私の作業コード:

for (int i = 1; i < vec.size(); i++) { 
    glPushMatrix(); 
    glBegin(GL_QUAD_STRIP); 
     for (int j = 0; j < vec[i].size(); j++) { 
      glNormal3dv(vertex_normal[i][j]); 
      glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, reflectance[i][j]); 
      glVertex3d(vec[i][j].x(), vec[i][j].y(),vec[i][j].z()); 

      glNormal3dv(vertex_normal[i-1][j]); 
      glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, reflectance[i-1][j]); 
      glVertex3d(vec[i-1][j].x(), vec[i-1][j].y(), vec[i-1][j].z()); 
     } 
    glEnd(); 
    glPopMatrix(); 
} 
+0

廃止予定のAPIは使用しないでください。 –

答えて

5
  1. スタックサイズは制限されています!

    のでvec.size()を小さくしたりのOpenGL実装マトリックススタック・サイズと等しくなければならない - ループ前の層を使用します。それはあなたのハックを少し危険にしています。

  2. 使用glGetError

    あなたが使うすべての主要なglものの後glGetErrorをチェック(デバッグ中にもそれがエラーを返さないまでそれを適用する)必要があります。 glInterceptのようなツールもあります。問題が本当にどこにあるのかを明らかにする必要があります。古いAPIがループする前に数回glEnd();を追加しようと使用していたよう

  3. glEnd()がありません。それがglEnd;のようなルーキーとの通常のバグである場合、どこかで逃したglEnd();を逃すのに役立ちますが、何もしません。

    マトリックスプッシュ/ポップの後にOpenGLでリセットできますが、それは私の側からの純粋な推測です。

  4. 呼び出すglMaterialfv

    glBegin/glEnd内部OpenGL docs状態は:

    材料パラメータは、随時更新することができます。特に、 glMaterialは、glBeginへの呼び出しと、対応するglEndへの呼び出しの間で呼び出すことができます。ただし、1つのマテリアルパラメータが に変更される場合は、 glMaterial(glColorMaterialを参照)よりもglColorMaterialが優先されます。

    私の経験は、(インテルのような)悪いOpenGLの実装が手紙にスペックに従わず、いくつかのプラットフォーム上の問題を引き起こすことがあると私はglBegin/glEndglMaterialを使用して回避しよう/ 珍しい用法状況将来的には今、その後ない場合は...

だから、あなたの質問に答えるために:ませglBegin/glEndglPushMatrix/glPopMatrixとVIの影響を受けないべきではありませんそれらが正しく使用されているかどうかを確認してください(プッシュ/ポップはglBegin/glEndの内部では許可されず、スタック制限を超えてはいけません)。

+1

私は 'glMaterial'呼び出しを取り除いたので、これで問題は解決しました。非常に便利な答えをありがとう。 –

4

私は別の位置を取るつもり、追加のプッシュとポップを追加すると何の違いを作るべきではないと言っています。

旧式のOpenGLでは、いくつかのマトリックススタックがあります。スタックの一番上にあるものを変更する一連の操作だけでなく、プッシュとポップが用意されています。スタックの最上部にあるものは何でも複製します。したがって、スタックがA B C Dの場合、A B C D Dになります。スタックの最上部にあるものは、ポップだけで削除されます。A B C D DからA B C Dに戻ります。

これは、コールスタックにうまく収まる構造を提供します。古いトップのコピーを取得することによって、現在までの変更を継承します。あなたはあなたが望む変更をしてから、取り消すことができます。あなたが誰と呼んでいるかは問題ではありません。

これは、単に「ジオメトリのバッチを開始する」および「ジオメトリのバッチを終了する」と言う、glBeginおよびglEndから完全に直交しています。ジオメトリは、適切なスタックの最上部にある現在の値の影響を受けますが、実際には値を変更していません。

私はあなたが未定義の動作に苦しんでいると仮定し、あなたの特定のマシンのプラセボ修正で起こったと仮定します。

関連する問題