1
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

//set viewpoint
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(VIEW_ANGLE,Screen_Ratio,NEAR_CLIP,FAR_CLIP);
gluLookAt(0,5,5, 0,0,0, 0,1,0);

//transform model 1
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(Theta, 0,1,0);

//draw model 1
glBegin(GL_QUADS);
...
glEnd();

上記のコードは正常に動作しますが、gluPerspective への呼び出しを削除する方法はありますか?

つまり、各レンダリング中に繰り返し呼び出すのではなく、初期化時に一度だけ呼び出したいということです。

4

3 に答える 3

6

そこに属しているので、そこでgluPerspectiveを呼び出します。OpenGLは、物事を初期化するシーングラフではありません。これは、状態駆動型の描画APIです。投影行列は状態であり、すべての深刻なグラフィックアプリケーションは、単一のフレームレンダリング全体でこの状態を複数回変更します。

OpenGLは、幾何学的なオブジェクト、位置、およびカメラを認識していません。処理パイプラインを介して点、線、三角形をプッシュし、結果を画面に描画します。何かが描かれた後、OpenGLはそれをまったく思い出しません。

私はそれを初期化で一度だけ呼び出すことを意味します。

OpenGLは初期化されません(レンダリングコンテキストの作成を除きますが、実際にはこれはオペレーティングシステムのグラフィックスタックの一部であり、OpenGLではありません)。もちろん、テクスチャをアップロードしてオブジェクトデータをバッファリングしますが、それはいつでも発生する可能性があります。

于 2011-08-28T18:17:35.767 に答える
4

射影マトリックスでは使用しないでくださいgluLookAt。これは、カメラ/ビューを定義するため、モデル ビュー マトリックスに属し、通常は左端の変換 ( の後の最初glLoadIdentity) として、モデル ビューという単語のビュー部分を構成するためです。それはあなたのやり方でも機能しますが、概念的には間違っています。これにより、フレームごとに射影行列に触れる必要がないため、問題も解決します。

しかし実際には、OpenGL のステート マシン アーキテクチャに関しては、datenwolf のアプローチの方が概念的にクリーンです。

于 2011-08-28T18:30:56.693 に答える
1

フレームごとに呼び出さずにglLoadIdentity()(現在の行列を単位行列にリセットする、つまり、行ったことを元に戻します)、代わりに変換行列を慎重にプッシュ/ポップする場合は、初期化時にのみ呼び出すだけで問題ありません。通常、描画を開始するたびに load identity を呼び出してからリセットする方がはるかに簡単です。例えば:gluPerspective()

// Initalisation
glLoadIdentity();
gluPerspective(...);

その後、次のようになります。

// Drawing each frame
glClear(...);

glPushMatrix();
gluLookAt(...);

//draw stuff

glPopMatrix();
于 2011-08-28T17:38:20.770 に答える