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照明的东西吗?常见问题解答提到:

如果您的光源是灯具的一部分,您可能还需要指定建模变换,以便灯光位置与周围的灯具几何体位于同一位置。

我认为这意味着您需要将光线转换为场景,这是一种不费吹灰之力的......但这是否意味着其他东西?

4

3 回答 3

1

这可能是次要的,但在这一行:

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

删除 & (地址运算符)。lp 已经为您提供了数组地址。

于 2010-12-06T15:37:46.723 回答
1

这是前一阵子,但我最终确实找出了问题所在。我认为我遇到的问题是灯光的位置翻译错误。想象一下:灯光位于 0,0,0,但随后我平移并旋转了我的网格。如果是这种情况,我必须按照其他答案中的建议进行操作,并确保我将 glLightfv 调用放在正确的位置。

事实证明,实际问题要简单得多,但也更加隐蔽。事实证明我没有正确设置 glNormalPointer,所以它被输入了垃圾数据。在调试时,我会渲染法线以检查它们是否正确,但这样做时我会根据我计算的位置手动绘制它们。对未来调试器的建议:在绘制调试信息法线时,请确保提供调试函数/与 openGL 获得的相同数据/。就我而言,这意味着将我的普通光线绘制函数的 glVertexPointer 指向与模型的 glNormalPointer 相同的位置。

于 2011-06-22T01:38:26.180 回答
0

基本上,OpenGL 灯的行为就像一个顶点。所以在你的代码中它被转换了cameraMatrix,而你的网格被转换了cameraMatrix * matrix。现在,它看起来像 bothcameraMatrixmatrixcontains mrot.QuatToMatrix(),也就是说:那里有一个旋转矩阵,灯光旋转一次,而对象旋转两次。除非您的实际代码不同,否则它对我来说看起来不正确;mRot您用于每个网格的矩阵应该是它自己的,例如mRot[meshIndex].

于 2010-12-06T14:11:48.857 回答