1

我正在尝试构建一个场景,其中有一个透视纹理的立方体和一盏灯。

应该发生的是,光应该停留在立方体上方的某个地方,而立方体在该光下方旋转(相对于其中心)。

实际发生的是,当立方体旋转时,灯光也会旋转。

我试过用谷歌搜索这个并寻找类似的 SO 问题,但我发现没有任何帮助。遵循 OpenGL 文档,我了解到灯光位置受模型视图矩阵变换的影响,但我也理解在所述变换之前/之后推动/弹出矩阵会使灯光不再受它们的影响。但是我无法让它工作,无论我是否将模型视图转换(对于立方体)隔离为推送/弹出,或者我之后加载单位矩阵,灯光都会继续旋转。

这是代码(它在 Java 中使用 JOGL):

//this array goes into lightPositionBuffer 
private float[] lightPosition = {0, 0, 0, 1.0f};

public void display(GLAutoDrawable gLDrawable) {
    //code for clearing screen, binding the textures, etc.

    gl.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
    gl.glEnableClientState(GLPointerFunc.GL_TEXTURE_COORD_ARRAY);
    gl.glFrontFace(GL2.GL_CCW);
    gl.glVertexPointer(3, GL.GL_FLOAT, 0, cubeVerticesBuffer);
    gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, cubeTextureCoordsBuffer);

    //rotate the cube
    gl.glPushMatrix();    
    gl.glTranslatef(cubeCenterXInitial,cubeCenterYInitial,cubeCenterZInitial);
    gl.glRotatef(rotationAmountY, 1, 0, 0);
    gl.glTranslatef(-cubeCenterXInitial,-cubeCenterYInitial,-cubeCenterZInitial);
    rotationAmountY+=1.5f;
    gl.glDrawElements(GL.GL_TRIANGLE_STRIP, cubeIndexes.length, GL.GL_UNSIGNED_BYTE, cubeIndexesBuffer);
    gl.glPopMatrix();

    gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);
    gl.glDisableClientState(GL2.GL_TEXTURE_COORD_ARRAY);

    //Position The Light:
    gl.glPushMatrix();
    //lightPositionBuffer is a FloatBuffer containing the lightPosition float array declared above:
    gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, lightPositionBuffer);
    gl.glPopMatrix();
    //Enable Light 0
    gl.glEnable(GL2.GL_LIGHT0); 
    gl.glEnable(GL2.GL_LIGHTING);
}

这是正在发生的事情:

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

4

2 回答 2

1

好的,我已经修好了。这里有两个重要的点:

  1. 正如卢克在他的回答中提到的那样,就转换而言,我的代码没有任何问题。事实上,变换只影响网格,光线实际上保持静止。

  2. 它看起来像我的立方体有一个围绕它旋转的光(实际上光是静止的)的原因是,总而言之,NORMALS。

换句话说:这是我的立方体面缺少法线声明。是的,谁知道,我没有。当您有一些面(如三角形和四边形)和灯光时,不声明法线不会简单地让您的表面不受灯光影响。他们实际上受到了影响,但这一切都很奇怪(从我在问题文本中的屏幕截图中可以看出)。

所以基本上我所做的修复它是看看 Nehe(我爱那些家伙)第 07 课:

http://nehe.gamedev.net/tutorial/texture_filters_lighting__keyboard_control/15002/

在页面底部有大量语言和库的代码,我个人使用的是 JOGL 版本,但任何一个都可以。

然后我还查看了 OpenGL 文档,以了解如何将我的顶点/索引/法线声明为数组(而不是单独声明):

http://www.songho.ca/opengl/gl_vertexarray.html

于 2012-03-15T11:33:14.530 回答
0

尝试在第二次通话之前添加glLoadIdentity() :glPushMatrix()

gl.glPushMatrix();
gl.glLoadIdentity(); // This
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, lightPositionBuffer);
gl.glPopMatrix();

正如您在原始帖子中所显示的那样,该推送/弹出对没有做任何事情。它们之间没有任何矩阵运算。 glPushMatrix()不会重置活动矩阵,它只会保留当前值集,以便您可以返回到该状态。

我认为您的错误不在您发布的代码中。您能否提供一个仍然显示您的问题的最小工作示例?

于 2012-03-14T11:24:06.027 回答