【问题标题】:Skybox textures is transparent天空盒纹理是透明的
【发布时间】:2020-04-13 14:59:46
【问题描述】:

我的天空盒已显示,但不显示我从图像加载的纹理。相反,如果我将glTexImage2D 设置为GL_RGBA,它会显示透明颜色,如果我将glTexImage2D 设置为GL_RGB,它会显示黑色。

我正在使用a render with MultisampledFbo support

我的纹理加载代码如下所示:

private int loadSkyboxTextures(){
         glGenBuffers(vbo);
         glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
         glBufferData(GL_ARRAY_BUFFER, POINTS, GL_STATIC_DRAW);
         glBindBuffer (GL_ARRAY_BUFFER, 0);
         glGenVertexArrays(vao);
         glBindVertexArray(vao[0]);
         glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
         glVertexPointer(3, GL_FLOAT, 3 * Float.BYTES, NULL);
         glTexCoordPointer (3, GL_FLOAT, 3 * Float.BYTES, NULL);        
         glBindBuffer (GL_ARRAY_BUFFER, 0);
         glEnableClientState(GL_VERTEX_ARRAY);
         glEnableClientState(GL_TEXTURE_COORD_ARRAY);

        int texID = glGenTextures();
        glBindTexture(GL_TEXTURE_CUBE_MAP, texID);
        for(int i = 0; i < TEXTURE_FILES.length; i++){
            InputStream file = getClass().getResourceAsStream(TEXTURE_FILES[i]);
            byte[] pixelData = new byte[0];
            try {
                pixelData = new byte[file.available()];
                file.read(pixelData);
            } catch (IOException e) {
                e.printStackTrace();
            }
            ByteBuffer byteBuffer = ByteBuffer.wrap(pixelData);
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, 512, 512, 0,
                    GL_RGB, GL_UNSIGNED_BYTE, byteBuffer);
        }

        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

        return texID;
    }

立方体渲染代码:

    private void drawSkybox(){
        glColor4f(1,1,1,1);
        glDepthMask(false);
        glEnable(GL_TEXTURE_CUBE_MAP);
        glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
        glBindVertexArray(vao[0]);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_CUBE_MAP, texId);
        glDrawArrays(GL_TRIANGLES, 0, 36);
        glBindVertexArray(0);
        glBindBuffer (GL_ARRAY_BUFFER, 0);
        glDepthMask(true);
        glDisable(GL_TEXTURE_CUBE_MAP);
    }

主渲染函数中的立方体渲染调用:

                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                view = viewX || viewY || viewZ;
                if(view)
                    glPushMatrix();

                int rot = 180;

                glDisable(GL_LIGHTING);
                glViewport(0, 0, WIDTH, HEIGHT);
                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                glOrtho(-max, max, -1, 1, 10, -10);
                glRotated(cameraX, 1f, 0f, 0);
                glRotated(cameraY, 0f, 1f, 0);
                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();
                drawSkybox(texId);

                glViewport(0, 0, WIDTH, HEIGHT);
                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                ...
                //render camera and other objects

【问题讨论】:

  • 您没有指定任何纹理坐标。你使用着色器吗?
  • @Rabbid76 My points (coordinate) array 不。我不使用着色器
  • @Rabbid76 我按照你的建议做了并更改了我的程序和主帖中的代码,但纹理仍然是黑色的

标签: java opengl lwjgl skybox


【解决方案1】:

对于立方体贴图纹理,纹理坐标是 3 维的,并被视为形成立方体贴图中心的矢量。
由于您绘制了一个以 (0, 0, 0) 为中心的立方体,因此您也可以使用顶点坐标作为纹理坐标。您不使用着色器程序,因此您必须使用固定的函数属性。用glVertexPointer指定顶点坐标,用glTexCoordPointer指定纹理坐标。启用客户端功能 (glEnableClientState) GL_VERTEX_ARRAYGL_TEXTURE_COORD_ARRAY

指定Vertex Array Object。在初始化时执行该代码一次就足够了:

glGenBuffers(vbo);
glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, POINTS, GL_STATIC_DRAW);
glBindBuffer (GL_ARRAY_BUFFER, 0);

glGenVertexArrays(vao);
glBindVertexArray(vao[0]);

glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
glVertexPointer(3, GL_FLOAT, false, 3 * Float.BYTES, NULL);
glTexCoordPointer (3, GL_FLOAT, false, 3 * Float.BYTES, NULL);
glBindBuffer (GL_ARRAY_BUFFER, 0);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glBindVertexArray(0);

当您绘制天空盒时,绑定立方体贴图纹理以启用立方体贴图纹理并绑定 VAO 就足够了:

private void drawSkybox(){
    GL11.glColor4f(1,1,1,1);
    glDepthMask(false);        

    glEnable(GL_TEXTURE_CUBE_MAP);
    glBindTexture(GL_TEXTURE_CUBE_MAP, texID);

    glBindVertexArray(vao[0]);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glBindVertexArray(0);

    glDepthMask(true);
    glDisable(GL_TEXTURE_CUBE_MAP);
}

还有一些问题:

【讨论】:

  • 我按照你的建议做了,更改了我的程序和主帖中的代码,但纹理仍然是黑色的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 2020-07-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多