每个模型的局部旋转会破坏 openGL 光照

发布于 2024-10-06 05:29:26 字数 1567 浏览 4 评论 0原文

我在使用 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 光照吗?常见问题解答提到:

如果您的光源是 灯具,您可能还需要 指定建模变换,因此 灯光位置在同一位置 作为周围夹具的几何形状。

我认为这意味着您需要将光线转换到场景中,这是理所当然的……但这还有其他含义吗?

I'm having trouble with OpenGL lighting. My issue is this: When the object has 0 rotation, the lighting is fine- otherwise the lighting works, but rotates with the object, instead of staying fixed in regards to the scene.

Sounds simple, right? The OpenGL FAQ has some simple advice on this: coordinates passed to glLightfv(GL_LIGHT0, GL_POSITION...) are multiplied by the current MODELVIEW matrix. So I must be calling this at the wrong place... except I'm not. I've copied the MODELVIEW matrix into a variable to debug, and it stays the same regardless of how my object is rotated. So it has to be something else, but I'm at a loss as to what.

I draw the model using glDrawArrays, and position my model within the world using glMatrixMult on a matrix built from a rotation quaternion and a translation. All of this takes place within glPushMatrix/glPopMatrix, so shouldn't have any side effect on the light.

A cut down version of my rendering process looks like this:

//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();

I thought the normals might be messed up, but when I render them out they look fine. Is there anything else that might effect openGL lighting? The FAQ mentions:

If your light source is part of a
light fixture, you also may need to
specify a modeling transform, so the
light position is in the same location
as the surrounding fixture geometry.

I took this to mean that you'd need to translate the light into the scene, kind of a no-brainer... but does it mean something else?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

烏雲後面有陽光 2024-10-13 05:29:26

它可能很小,但在这一行中:

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

删除 & (地址运算符)。 lp 已经给你了数组地址。

It might be minor, but in this line:

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

remove the & (address operator). lp will already give you the array-address.

无语# 2024-10-13 05:29:26

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

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

This was awhile back, but I did eventually figure out the problem. The issue I thought I was having was that the light's position got translated wrong. Picture this: the light was located at 0,0,0, but then I translated and rotated my mesh. If this had been the case, I'd have to do as suggested in the other answers and make certain I was placing my glLightfv calls in the right place.

The actual problem turned out to be much simpler, yet much more insidious. It turns out I wasn't setting the glNormalPointer correctly, and so it was being fed garbage data. While debugging, I'd render the normals to check that they were correct, but when doing so I'd manually draw them based on the positions I'd calculated. A recommendation to future debuggers: when drawing your debug info normal rays, make sure you feed the debug function /the same data/ as openGL gets. In my case, this would mean pointing my normal ray draw function's glVertexPointer to the same place as the model's glNormalPointer.

Bonjour°[大白 2024-10-13 05:29:26

基本上,OpenGL 光的行为就像一个顶点。因此,在您的代码中,它由 cameraMatrix 转换,而您的网格体由 cameraMatrix * 矩阵 转换。现在,看起来cameraMatrix和matrix都包含mrot.QuatToMatrix(),也就是说:那里有一个旋转矩阵,并且光旋转一次,而物体旋转两次。它对我来说看起来不正确,除非你的实际代码不同;用于每个网格的mRot矩阵应该是它自己的,例如mRot[meshIndex]

Basically an OpenGL light behaves like a vertex. So in your code it's transformed by cameraMatrix, while your meshes are transformed by cameraMatrix * matrix. Now, it looks like both cameraMatrix and matrix contain mrot.QuatToMatrix(), that is: there is a single rotation matrix there, and the light gets rotated once, while the objects get rotated twice. It doesn't look right to me, unless your actual code is different; the mRot matrix you use for each mesh should be its own, e.g. mRot[meshIndex].

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文