1

OpenGL ライティングに問題があります。私の問題は次のとおりです。オブジェクトの回転が 0 の場合、照明は問題ありません。それ以外の場合、照明は機能しますが、シーンに関して固定されたままではなく、オブジェクトとともに回転します。

シンプルですね。OpenGL FAQには、これに関するいくつかの簡単なアドバイスがあります: glLightfv(GL_LIGHT0, GL_POSITION...) に渡される座標は、現在の MODELVIEW 行列で乗算されます。だから私は間違った場所でこれを呼んでいるに違いない...私がそうではないことを除いて。MODELVIEW マトリックスを変数にコピーしてデバッグしましたが、オブジェクトがどのように回転されても同じままです。だからそれは何か別のものでなければなりませんが、私は何について途方に暮れています.

glDrawArrays を使用してモデルを描画し、回転クォータニオンと平行移動から構築されたマトリックス上で glMatrixMult を使用して、モデルをワールド内に配置します。これはすべて glPushMatrix/glPopMatrix 内で行われるため、ライトに副作用はありません。

私のレンダリング プロセスの簡易バージョンは次のようになります。

//Setup our camera
glMatrixMode(GL_MODELVIEW);             
glLoadIdentity();
cameraMatrix = translate(Vector3D(Pos.mX,Pos.mY,Pos.mZ)) * camRot.QuatToMatrix();
glMultMatrixf((GLfloat*)&cameraMatrix);

//Position the light now
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
GLfloat lp[4] = {lightPos.mX, lightPos.mY, lightPos.mZ, 1.0f};
glLightfv(GL_LIGHT0, GL_POSITION,(GLfloat*)  lp);

//Loop, doing this for each model: (mRot, mPos, and mi are model member variables)
matrix = translate(Vector3D(mPos.mX,mPos.mY,mPos.mZ)) * mRot.QuatToMatrix();
glPushMatrix();
glMultMatrixf((GLfloat*)&matrix);
glBindBuffer(GL_ARRAY_BUFFER, mi->mVertexBufHandle);  //Bind the model VBO.
glDrawArrays(GL_TRIANGLES, 0, mi->verts); //Draw the object
glPopMatrix();

法線が乱れているのではないかと思っていましたが、レンダリングすると問題なく表示されます。openGLライティングに影響を与える可能性のあるものは他にありますか? FAQ には次のように記載されています。

光源が照明器具の一部である場合は、モデリング変換も指定する必要がある場合があります。これにより、照明の位置が周囲の器具ジオメトリと同じ場所になります。

これは、ライトをシーンに変換する必要があることを意味すると解釈しました。

4

3 に答える 3

1

これはしばらく前のことですが、私は最終的に問題を理解しました。私が抱えていた問題は、ライトの位置が間違って翻訳されたということでした。これを想像してみてください。ライトは0,0,0にありましたが、メッシュを平行移動して回転させました。この場合、他の回答で提案されているように実行し、glLightfv呼び出しを正しい場所に配置していることを確認する必要があります。

実際の問題ははるかに単純であるが、はるかに陰湿であることが判明しました。glNormalPointerを正しく設定していなかったため、ガベージデータが供給されていたことがわかりました。デバッグ中は、法線をレンダリングして正しいことを確認しましたが、そうするときは、計算した位置に基づいて法線を手動で描画しました。将来のデバッガーへの推奨事項:デバッグ情報の通常の光線を描画するときは、openGLが取得するのと同じデータ/デバッグ関数をフィードするようにしてください。私の場合、これは、通常の光線描画関数のglVertexPointerをモデルのglNormalPointerと同じ場所に向けることを意味します。

于 2011-06-22T01:38:26.180 に答える
1

マイナーかもしれませんが、この行では:

glLightfv(GL_LIGHT0, GL_POSITION,(GLfloat*)  &lp);

&(アドレス演算子)を削除します。lpはすでに配列アドレスを提供します。

于 2010-12-06T15:37:46.723 に答える
0

基本的に、OpenGL ライトは頂点のように動作します。したがって、コードでは によってcameraMatrix変換されますが、メッシュは によって変換されcameraMatrix * matrixます。cameraMatrixこれで、両方とmatrixが含まれているように見えますmrot.QuatToMatrix()。つまり、単一の回転マトリックスがあり、ライトが 1 回回転するのに対し、オブジェクトは 2 回回転します。実際のコードが異なる場合を除き、私には正しく見えません。各メッシュに使用するmRotマトリックスは、独自のものにする必要がありますmRot[meshIndex]

于 2010-12-06T14:11:48.857 に答える