LWJGL:渲染天空盒的更有效方法

时间:2013-01-16 16:16:30

标签: java lwjgl skybox

我目前正在渲染一个像这样的天空盒:

        //Front Face
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, skybox[0].getTextureID());
    GL11.glBegin(GL11.GL_QUADS);
        GL11.glTexCoord2f(1f, 0.0f);
        GL11.glVertex3f(-player.x - offset, -player.y - offset, -player.z - offset);
        GL11.glTexCoord2f(1f, 1f);
        GL11.glVertex3f(-player.x - offset, -player.y + offset, -player.z - offset);
        GL11.glTexCoord2f(0.0f, 1f);
        GL11.glVertex3f(-player.x + offset, -player.y + offset, -player.z - offset);
        GL11.glTexCoord2f(0.0f, 0.0f);
        GL11.glVertex3f(-player.x + offset, -player.y - offset, -player.z - offset);
    GL11.glEnd();

    // Back Face
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, skybox[2].getTextureID());
    GL11.glBegin(GL11.GL_QUADS);
        GL11.glTexCoord2f(0.0f, 0.0f);
        GL11.glVertex3f(-player.x - offset, -player.y - offset, -player.z + offset);
        GL11.glTexCoord2f(1f, 0.0f);
        GL11.glVertex3f(-player.x + offset, -player.y - offset, -player.z + offset);
        GL11.glTexCoord2f(1f, 1f);
        GL11.glVertex3f(-player.x + offset, -player.y + offset, -player.z + offset);
        GL11.glTexCoord2f(0.0f, 1f);
        GL11.glVertex3f(-player.x - offset, -player.y + offset, -player.z + offset);
    GL11.glEnd();

    // Top Face
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, skybox[4].getTextureID());
    GL11.glBegin(GL11.GL_QUADS);
        GL11.glTexCoord2f(1f, 1f);
        GL11.glVertex3f(-player.x - offset, -player.y - offset, -player.z - offset);
        GL11.glTexCoord2f(0.0f, 1f);
        GL11.glVertex3f(-player.x + offset, -player.y - offset, -player.z - offset);
        GL11.glTexCoord2f(0.0f, 0.0f);
        GL11.glVertex3f(-player.x + offset, -player.y - offset, -player.z + offset);
        GL11.glTexCoord2f(1f, 0.0f);
        GL11.glVertex3f(-player.x - offset, -player.y - offset, -player.z + offset);
    GL11.glEnd();

    // Bottom Face
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, skybox[5].getTextureID());
    GL11.glBegin(GL11.GL_QUADS);
        GL11.glTexCoord2f(1f, 0f);
        GL11.glVertex3f(-player.x - offset, -player.y + offset, -player.z - offset);
        GL11.glTexCoord2f(1f, 1f);
        GL11.glVertex3f(-player.x - offset, -player.y + offset, -player.z + offset);
        GL11.glTexCoord2f(0f, 1f);
        GL11.glVertex3f(-player.x + offset, -player.y + offset, -player.z + offset);
        GL11.glTexCoord2f(0f, 0f);
        GL11.glVertex3f(-player.x + offset, -player.y + offset, -player.z - offset);
    GL11.glEnd();


    // Right face
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, skybox[3].getTextureID());
    GL11.glBegin(GL11.GL_QUADS);
        GL11.glTexCoord2f(0.0f, 0.0f);
        GL11.glVertex3f(-player.x - offset, -player.y - offset, -player.z - offset);
        GL11.glTexCoord2f(1f, 0.0f);
        GL11.glVertex3f(-player.x - offset, -player.y - offset, -player.z + offset);
        GL11.glTexCoord2f(1f, 1f);
        GL11.glVertex3f(-player.x - offset, -player.y + offset, -player.z + offset);
        GL11.glTexCoord2f(0.0f, 1f);
        GL11.glVertex3f(-player.x - offset, -player.y + offset, -player.z - offset);
    GL11.glEnd();

    // Left Face
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, skybox[1].getTextureID());
    GL11.glBegin(GL11.GL_QUADS);
        GL11.glTexCoord2f(1f, 0.0f);
        GL11.glVertex3f(-player.x + offset, -player.y - offset, -player.z - offset);
        GL11.glTexCoord2f(1f, 1f);
        GL11.glVertex3f(-player.x + offset, -player.y + offset, -player.z - offset);
        GL11.glTexCoord2f(0.0f, 1f);
        GL11.glVertex3f(-player.x + offset, -player.y + offset, -player.z + offset);
        GL11.glTexCoord2f(0.0f, 0.0f);
        GL11.glVertex3f(-player.x + offset, -player.y - offset, -player.z + offset);
    GL11.glEnd();

这似乎是一种非常低效的渲染天空盒的方法,因为我必须在纹理和四边形之间切换。此外,像这样渲染四边形往往归因于像单像素线(四边形之间的接缝)之类的视觉伪像。我听说过利用立方体贴图来提高效率,但我正在努力实现。如果你们有任何建议,请随时指出我正确的方向。感谢。

1 个答案:

答案 0 :(得分:2)

立方体贴图基本上将所有六个纹理放在一个纹理上。然后只改变你的坐标一次并使用glBindTexture一次这就像:

GL11.glBindTexture(GL11.GL_TEXTURE_2D, skybox.getTextureID());
GL11.glBegin(GL11.GL_QUADS);
    //Front Face
    GL11.glTexCoord2f(0.25f, 0.25f);
    GL11.glVertex3f(-player.x - offset, -player.y - offset, -player.z - offset);
    GL11.glTexCoord2f(0.25f, 0.5f);
    GL11.glVertex3f(-player.x - offset, -player.y + offset, -player.z - offset);
    GL11.glTexCoord2f(0.0f, 0.5f);
    GL11.glVertex3f(-player.x + offset, -player.y + offset, -player.z - offset);
    GL11.glTexCoord2f(0.0f, 0.25f);
    GL11.glVertex3f(-player.x + offset, -player.y - offset, -player.z - offset);

    // Back Face
    ...
GL11.glEnd();

要获得更多优化,请考虑在渲染天空盒时禁用深度缓冲区。您也可以停止清除颜色位。