OpenGL 数组纹理根本不渲染

OpenGL array textures not rendering at all

我目前正在努力将一个项目从使用纹理图集转换为数组纹理,但对于我来说,我无法让它工作。

关于我的环境的一些注意事项:

我认为我已经排除的问题:

这是我创建数组纹理的代码:

public void createTextureArray() {
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    int handle = glGenTextures();
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D_ARRAY, handle);
    glPixelStorei(GL_UNPACK_ROW_LENGTH, Texture.SIZE);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, Texture.SIZE, Texture.SIZE, textures.size());

    try {
        int layer = 0;
        for (Texture tex : textures.values()) {
            // Next few lines are just for loading the texture. They've been ruled out as the issue.
            PNGDecoder decoder = new PNGDecoder(ImageHelper.asInputStream(tex.getImage()));
            ByteBuffer buffer = BufferUtils.createByteBuffer(decoder.getWidth() * decoder.getHeight() * 4);
            decoder.decode(buffer, decoder.getWidth() * 4, PNGDecoder.Format.RGBA);
            buffer.flip();

            glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layer, decoder.getWidth(), decoder.getHeight(), 1,
                    GL_RGBA, GL_UNSIGNED_BYTE, buffer);

            tex.setLayer(layer);

            layer++;
        }
    } catch (IOException ex) {
        ex.printStackTrace();
        System.err.println("Failed to create/load texture array");
        System.exit(-1);
    }
}

创建VAO/VBO的代码:

private static int prepareVbo(int handle, FloatBuffer vbo) {
    IntBuffer vaoHandle = BufferUtils.createIntBuffer(1);
    glGenVertexArrays(vaoHandle);
    glBindVertexArray(vaoHandle.get());
    glBindBuffer(GL_ARRAY_BUFFER, handle);

    glBufferData(GL_ARRAY_BUFFER, vbo, GL_STATIC_DRAW);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D_ARRAY, GraphicsMain.TEXTURE_REGISTRY.atlasHandle);

    glEnableVertexAttribArray(positionAttrIndex);
    glEnableVertexAttribArray(texCoordAttrIndex);

    glVertexAttribPointer(positionAttrIndex, 3, GL_FLOAT, false, 24, 0);
    glVertexAttribPointer(texCoordAttrIndex, 3, GL_FLOAT, false, 24, 12);

    glBindVertexArray(0);

    vaoHandle.rewind();
    return vaoHandle.get();
}

片段着色器:

#version 330 core

uniform sampler2DArray texArray;

varying vec3 texCoord;

void main() {
    gl_FragColor = texture(texArray, texCoord);
}

texCoord 工作正常;它从顶点着色器正确传递。)

我快没思路了,所以对于现代 OpenGL 还是有些陌生,我想知道我的代码是否有明显的错误。

一些注意事项:

  • 你不再需要拥有两个纹理的力量
  • 确保每一层的 levels/mipmaps 数量与 wiki says
  • 相同
  • 前四个 glTexParameteri 会影响当时 GL_TEXTURE_2D_ARRAY 绑定的内容 ,因此您最好将它们移到 [=12= 之后]
  • 如何指定要使用 glGenTextures() 创建多少个纹理?如果您有更具体的方法的可能性,请使用它
  • GL_UNPACK_ROW_LENGTH 如果大于 0,则定义一行中的像素数。我想 Texture.SIZE 并不是真正的纹理大小,而是一侧的尺寸(在您的情况下为 128)。反正你不需要设置,你可以跳过它
  • 仅当您的行长是它的倍数时才将 GL_UNPACK_ALIGNMENT 设置为 4。大多数时候人们在加载纹理之前将其设置为 1 以避免任何麻烦,然后在完成后将其设置回 4
  • glTexStorage3D 的最后一个参数预计是层数,我希望 textures.size() 更好 returns 而不是大小 (128x128)
  • glActiveTextureprepareVbo 里面的 glBindTexture 没用,它们不是 vao
  • 的一部分
  • 不要在 glsl 中使用 varying,它已被弃用,改用简单的 in out
  • 您可能想从 this sample
  • 中汲取灵感
  • 使用采样器,它们给你更多的灵活性
  • 如果可用,请使用 Debug Output,否则 glGetError(),渲染输出可能无法明确地看到一些静默错误
  • 你称它为 prepareVbo 但你确实在其中初始化了 vao 和 vbo