【问题标题】:Problems with OpenGL lighting in Java/lwjglJava/lwjgl 中的 OpenGL 光照问题
【发布时间】:2012-01-31 09:32:04
【问题描述】:

我在 Java/lwjgl 中创建了一个带有旋转立方体的场景。 如果我启用照明,无论我将光源放置在哪里,我都会获得一种逼真的行为,就好像光源位于相机位置一样。

这是我初始化openGL的方法:

private void initGL() throws LWJGLException {
    Display.create();
    Display.setFullscreen(true);
    Display.setVSyncEnabled(true);

    GL11.glViewport(0, 0, WIDTH, HEIGHT);
    GL11.glMatrixMode(GL11.GL_PROJECTION);
    GL11.glLoadIdentity();
    GLU.gluPerspective(70, 4f / 3f, 1, 10000);
    GL11.glMatrixMode(GL11.GL_MODELVIEW);

    GL11.glEnable(GL11.GL_DEPTH_TEST);
    GL11.glDepthMask(true);

    GL11.glEnable(GL11.GL_CULL_FACE);

    // ----IMPORTANT PART----
    GL11.glEnable(GL11.GL_LIGHTING);
    GL11.glEnable(GL11.GL_LIGHT0);

    FloatBuffer position = ByteBuffer.allocateDirect(16).asFloatBuffer();
    position.mark();
    position.put(new float[] { -5f, 5f, 10f, 0f }); // even values about 10e3 for the first three parameters aren't changing anything
    position.reset();

    GL11.glLight(GL11.GL_LIGHT0, GL11.GL_POSITION, position);

    FloatBuffer ambient = ByteBuffer.allocateDirect(16).asFloatBuffer();
    ambient.mark();
    ambient.put(new float[] { 0.5f, 0.5f, 0.5f, 1f });
    ambient.reset();

    GL11.glLight(GL11.GL_LIGHT0, GL11.GL_AMBIENT, ambient);

    // Textures...
}

当我开始渲染时,调用了这段代码:

private void renderGL() {
    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);

    for (RenderObject ro : renderObjects) {
        ro.render();
    }
}

这会绘制立方体。法线是正确的,我认为,颠倒它们会阻止面部被绘制,至少在我的测试中是这样。

public void render() {
    GL11.glEnable(GL11.GL_TEXTURE_2D);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, texID);
    GL11.glColor3f(1f, 1f, 1f);

    GL11.glPushMatrix();

    GL11.glTranslatef(x, y, z);
    GL11.glRotatef(rotation, 1, 1, 1);
    GL11.glTranslatef(-x, -y, -z);

    GL11.glBegin(GL11.GL_QUADS);

    GL11.glNormal3f(0, 0, -1f);
    GL11.glTexCoord2f(0, 0);
    GL11.glVertex3f(x - dx, y - dy, z - dz);
    GL11.glTexCoord2f(0, 1);
    GL11.glVertex3f(x - dx, y + dy, z - dz);
    GL11.glTexCoord2f(1, 1);
    GL11.glVertex3f(x + dx, y + dy, z - dz);
    GL11.glTexCoord2f(1, 0);
    GL11.glVertex3f(x + dx, y - dy, z - dz);

    // the other five faces

    GL11.glEnd();

    GL11.glPopMatrix();
}

我在灯光方面做错了什么?

编辑:有关错误的其他信息

当我将灯光位置数组的最后一个值设置为 0 时,整个场景都是黑色的。将其设置为任何其他值,光会按照描述从视口中出来。环境光不会改变任何东西,当光源不工作时,我要绘制的立方体保持黑暗。我试图将照明的东西放在代码中的其他位置,例如直接在GLU.gluPerspective(70, 4f / 3f, 1, 10000); 行之后,或进入循环,不改变任何描述的效果。

【问题讨论】:

    标签: java opengl lwjgl lighting


    【解决方案1】:

    我在灯光方面做错了什么?

    照明位置与模型视图矩阵相乘。因此,当您的模型视图矩阵包含查看转换时,您必须正确调用glLightfv(GL_LIGHT_, GL_POSITION, …);

    从技术上讲,您在 initGL 函数中编写的所有内容都属于绘图函数。 OpenGL 不是你初始化的场景图。

    更新:

    像这样更改您的代码:

    public void render() {
        GL11.glEnable(GL11.GL_TEXTURE_2D);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, texID);
        GL11.glColor3f(1f, 1f, 1f);
    
        GL11.glPushMatrix();
    
        // this is where you set up your view:
        GL11.glTranslatef(x, y, z);
        GL11.glRotatef(rotation, 1, 1, 1);
        GL11.glTranslatef(-x, -y, -z);
    
        // and now it's time to set the light position:
        GL11.glLight(GL11.GL_LIGHT0, GL11.GL_POSITION, position);
    
        GL11.glBegin(GL11.GL_QUADS);
    
        GL11.glNormal3f(0, 0, -1f);
        GL11.glTexCoord2f(0, 0);
        GL11.glVertex3f(x - dx, y - dy, z - dz);
        GL11.glTexCoord2f(0, 1);
        GL11.glVertex3f(x - dx, y + dy, z - dz);
        GL11.glTexCoord2f(1, 1);
        GL11.glVertex3f(x + dx, y + dy, z - dz);
        GL11.glTexCoord2f(1, 0);
        GL11.glVertex3f(x + dx, y - dy, z - dz);
    
        // the other five faces
    
        GL11.glEnd();
    
        GL11.glPopMatrix();
    }
    

    那你应该彻底放弃initGL,把它的代码移到绘图函数中,变成:

    public void render() {
    
        GL11.glViewport(0, 0, WIDTH, HEIGHT);
    
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GLU.gluPerspective(70, 4f / 3f, 1, 10000);
    
        GL11.glMatrixMode(GL11.GL_MODELVIEW);   
        glLoadIdentity();
        GL11.glPushMatrix();
    
        // this is where you set up your view:
        GL11.glTranslatef(x, y, z);
        GL11.glRotatef(rotation, 1, 1, 1);
        GL11.glTranslatef(-x, -y, -z);
    
        // and now it's time to set the light position:
        GL11.glLight(GL11.GL_LIGHT0, GL11.GL_POSITION, position);
    
        // we do the rest of the light here as well
        GL11.glLight(GL11.GL_LIGHT0, GL11.GL_AMBIENT, ambient);
    
        GL11.glEnable(GL11.GL_DEPTH_TEST);
        GL11.glDepthMask(true);
        GL11.glEnable(GL11.GL_CULL_FACE);
    
        // we enable lighting right before rendering
        GL11.glEnable(GL11.GL_LIGHTING);
        GL11.glEnable(GL11.GL_LIGHT0);    
    
        GL11.glEnable(GL11.GL_TEXTURE_2D);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, texID);
    
        GL11.glColor3f(1f, 1f, 1f);
    
        GL11.glBegin(GL11.GL_QUADS);
    
        GL11.glNormal3f(0, 0, -1f);
        GL11.glTexCoord2f(0, 0);
        GL11.glVertex3f(x - dx, y - dy, z - dz);
        GL11.glTexCoord2f(0, 1);
        GL11.glVertex3f(x - dx, y + dy, z - dz);
        GL11.glTexCoord2f(1, 1);
        GL11.glVertex3f(x + dx, y + dy, z - dz);
        GL11.glTexCoord2f(1, 0);
        GL11.glVertex3f(x + dx, y - dy, z - dz);
    
        // the other five faces
    
        GL11.glEnd();
    
        GL11.glPopMatrix();
    }
    

    【讨论】:

    • 感谢您的回答! GL11.glLight() 方法是 C 中 glLightfv() 方法的 lwjgl 版本。请看我的编辑,我想我之前没有正确描述我的问题。
    • @Sibbo:你必须在设置view矩阵之后把灯光定位。这不是投影。请参阅我的答案编辑。
    • 所以我使用 glRotation 的矩阵围绕立方体旋转视图,而不是围绕视图旋转立方体?因为x、y、z变量是立方体的坐标,旋转应该是立方体围绕1/1/1轴旋转。
    • @Sibbo:嗯,从技术上讲,您只是在移动立方体。 OpenGL 没有相机之类的东西。但如果你想一想,移动相机与移动世界是一样的。模型视图矩阵结合了模型转换和视图转换,因此是“模型视图”。投影矩阵可以认为是OpenGL的“镜头”。
    • 啊,谢谢 :) 但是我刚刚发现我的问题在代码的另一个地方,如果复制在这里什么都没有...我创建了 FloatBuffers 错误,没有使用 Flip() 和 order() .现在它可以工作了,但是光源会随着立方体旋转 :) 但现在我可以自己工作了,谢谢。
    猜你喜欢
    • 2012-01-06
    • 1970-01-01
    • 1970-01-01
    • 2015-01-31
    • 1970-01-01
    • 2011-05-09
    • 1970-01-01
    • 1970-01-01
    • 2021-05-11
    相关资源
    最近更新 更多