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

标签 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();

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

最佳答案

立方体贴图基本上是将所有六个纹理放在一个纹理上。然后仅更改一次坐标并使用一次 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();

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

关于java - LWJGL:渲染天空盒的更有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14362839/

相关文章:

unity3d - 默认的 Unity 天空盒改变了吗?

java - Skybox 是全黑的

java - Android WebView - JWT 身份验证

java - 无法为象限检查程序创建正确的方法

Java 对数时钟给出不准确的答案

opengl - LWJGL - glEnableVertexAttribArray(1) 后游戏崩溃

java - 我应该在一个类中实现所有接口(interface)还是为每个接口(interface)创建一个类?

java - LWJGL:加载库失败

java - 添加Slick jvm后不再找到Main类

c++ - Z-Buffer 的奇怪行为