Java / lwjgl中OpenGL照明的问题

时间:2012-01-01 15:07:53

标签: java opengl lwjgl lighting

我在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);行之后,或进入循环,不改变任何描述的效果。

1 个答案:

答案 0 :(得分:2)

  

我对照明材料做错了什么?

照明位置与模型视图矩阵相乘。因此,当您的模型视图矩阵包含查看转换时,您必须立即调用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();
}