天空盒纹理是透明的。

huangapple 未分类评论59阅读模式
英文:

Skybox textures is transparent

问题

我的天空盒被显示出来了,但是它并没有显示从图像加载的纹理。相反,如果我将 glTexImage2D 设置为 GL_RGBA,它显示透明颜色;如果我将 glTexImage2D 设置为 GL_RGB,它显示黑色颜色。

我正在使用带有多重采样帧缓冲支持的渲染器(链接)。

我的纹理加载代码如下:

private int loadSkyboxTextures() {
    // ... (代码和注释已省略)
    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);
    }
    // ... (代码和注释已省略)
    return texID;
}

立方体渲染代码:

private void drawSkybox() {
    // ... (代码和注释已省略)
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_CUBE_MAP, texId);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    // ... (代码和注释已省略)
}

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

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);
// ... (代码和注释已省略)
glRotated(cameraX, 1f, 0f, 0);
glRotated(cameraY, 0f, 1f, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawSkybox(texId);
// ... (代码和注释已省略)
英文:

My skybox is displayed, but does not display the textures that I load from the image. Instead, it shows the transparent color if i set glTexImage2D how GL_RGBA, or black color if i set glTexImage2D how GL_RGB.

I am using a render with MultisampledFbo support.

My texture loading code looks like this:

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 &lt; 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;
    }

Cube Render Code:

    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);
    }

The cube rendering call in the main render function:

                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

答案1

得分: 0

以下是翻译好的内容:

对于立方体贴图纹理,纹理坐标是三维的,并且被视为从立方体贴图的中心指向的向量。
由于绘制的是以 (0, 0, 0) 为中心的立方体,你也可以使用顶点坐标作为纹理坐标。由于你没有使用着色器程序,所以必须使用固定功能属性。通过 glVertexPointer 指定顶点坐标,通过 glTexCoordPointer 指定纹理坐标。通过 glEnableClientState 启用客户端能力 GL_VERTEX_ARRAYGL_TEXTURE_COORD_ARRAY

指定顶点数组对象。只需要在初始化时执行该代码一次:

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);
}

还存在一些其他问题:

英文:

For cube map textures, the texture coordinates are 3-dimensional and treated as a vector form the center of the cube map.
Since you draw a cube, which is centered around (0, 0, 0), you can use the the vertex coordinates for the texture coordinates, too. You do not use a shader program, so you have to use fixed function attributes. Specify the vertex coordinates by glVertexPointer and the texture coordinates by glTexCoordPointer. Enable the client-side capability (glEnableClientState) GL_VERTEX_ARRAY and GL_TEXTURE_COORD_ARRAY.

Specify the Vertex Array Object. It is sufficient to execute that code once at intialization:

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);

When you draw the skybox it is sufficient to bind the cubemap texture to enable cube-mapped texturing and to bind the 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);
}

There are some further issues:

huangapple
  • 本文由 发表于 2020年4月9日 19:35:18
  • 转载请务必保留本文链接:https://java.coder-hub.com/61120241.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定