设置立方体贴图

时间:2013-09-26 17:58:39

标签: opengl textures glsl lwjgl

以下是我尝试用于在LWJGL中设置多维数据集地图的代码。

public static int setUpCubeMap(String filename, int anisotropyLevel, boolean clamp,   boolean pixelated, boolean mipmapped) {
    IntBuffer tmp = BufferUtils.createIntBuffer(1);
    glGenTextures(tmp);
    tmp.rewind();
    try {
        InputStream in = new FileInputStream(filename);
        PNGDecoder decoder = new PNGDecoder(in);
        glEnable(GL_TEXTURE_CUBE_MAP);
        ByteBuffer buf = ByteBuffer.allocateDirect(4 * decoder.getWidth() * decoder.getHeight());
        decoder.decode(buf, decoder.getWidth() * 4, PNGDecoder.Format.RGBA);
        buf.flip();

        glBindTexture(GL_TEXTURE_CUBE_MAP, tmp.get(0));
        org.lwjgl.opengl.ARBTextureStorage.glTexStorage2D(GL_TEXTURE_CUBE_MAP, (int)(Math.log(Math.max(decoder.getHeight(), decoder.getWidth()))/Math.log(2))+1, GL_RGBA8, decoder.getWidth(), decoder.getHeight());
        glTexSubImage2D(GL_TEXTURE_CUBE_MAP, 0, 0, 0, decoder.getWidth(), decoder.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, buf);

        if(mipmapped)
            org.lwjgl.opengl.GL30.glGenerateMipmap(GL_TEXTURE_CUBE_MAP);

        if(clamp) {
            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);
        } else {
            glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_S);
            glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_TEXTURE_WRAP_T);
        }

        if(pixelated) {
            glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        } else {
            glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        }

        if(mipmapped)
            glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
        else
            glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

        if(anisotropyLevel > 1)
            glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropyLevel);

        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, decoder.getWidth(), decoder.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
        glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, decoder.getWidth(), decoder.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, decoder.getWidth(), decoder.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
        glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, decoder.getWidth(), decoder.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, decoder.getWidth(), decoder.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
        glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, decoder.getWidth(), decoder.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
        System.out.println("Loaded texture successfully from: " + filename + " with dimensions of " + decoder.getWidth() + "x" + decoder.getHeight());

    } catch (java.io.FileNotFoundException ex) {
        System.err.println("Error " + filename + " not found");
    } catch (java.io.IOException e) {
        System.err.println("Error decoding " + filename);
    }
    tmp.rewind();
    return tmp.get(0);
}

然后我将纹理传递到着色器中的samplerCube并调用textureCube()来显示它。可悲的是,屏幕显示为黑色,当我拨打glGetError()时,我会收到GL_INVALID_OPERATIONGL_INVALID_ENUM。我在这里做错了什么?

2 个答案:

答案 0 :(得分:1)

我建议你使用gDEBugger;它给出了一个非常容易理解的问题描述以及它何时发生。

答案 1 :(得分:1)

有几个问题,这些都无法阻止代码工作,无论如何我都会列出它们。

一开始的glTexSubImage2D调用是多余的。

  • 使用GL_TEXTURE_CUBE_MAP调用它会导致错误glTexSubImage2D
  • 您正在以正确的方式填写数据

与此相关的是,对glGenerateMipmap的调用应该在其他六个glTexSubImage2D调用之后发生。

在本节中,在else子句中,两个函数调用的第三个参数都是错误的。

if(clamp) {
    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);
} else {
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_S);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_TEXTURE_WRAP_T);
}