【问题标题】:LWJGL Texture loading / mapping issueLWJGL 纹理加载/映射问题
【发布时间】:2014-11-22 14:06:16
【问题描述】:

我正在绘制一个具有 512 x 512 纹理的四边形,由 4 个具有 4 种不同颜色(黄色、蓝色、绿色、红色)的正方形组成。 当我查看图像时,它全是黄色,但 tex 坐标空间从 0 到 1,我很确定它们被正确映射......这是代码:

private void loadTexture(String textureFile) {
        TexHandle = glGenTextures();
        BufferedImage TextureBuffer = null;
        try {
            TextureBuffer = ImageIO.read(new File(textureFile));
        } catch (IOException ex) {
            System.err.println("Error while reading the texture: " + textureFile);
            System.exit(1);
        }
        Width = TextureBuffer.getWidth();
        Height = TextureBuffer.getHeight();
        AlphaChannel = TextureBuffer.getColorModel().hasAlpha();
        int pixel;
        int[] pixels = TextureBuffer.getRGB(0, 0, Width, Height, null, 0, Width);
        ByteBuffer Buffer = BufferUtils.createByteBuffer(Width * Height * 4);
        for(int i = 0; i < Height; i++){
            for(int j = 0; j < Width; j++){
                pixel = pixels[i * Width + j];

                Buffer.put((byte)( pixel        & 0xff));
                Buffer.put((byte)((pixel >> 8)  & 0xff));
                Buffer.put((byte)((pixel >> 16) & 0xff));

                if(AlphaChannel)
                    Buffer.put((byte)((pixel >> 24) & 0xff));
                else
                    Buffer.put((byte)0xff);
            }
        }
        glBindTexture(GL_TEXTURE_2D, TexHandle);

        Buffer.flip();
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Width, Height, 0, GL_BGRA, GL_UNSIGNED_BYTE, Buffer);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        glBindTexture(GL_TEXTURE_2D, 0);
    }

public void initOpenGL() {
        glClearColor(0f, 0f, 0.4f, 1f);

        glFrontFace(GL_CCW);

        glCullFace(GL_BACK);
        glEnable(GL_CULL_FACE);

        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glEnable(GL_BLEND);

        glDepthFunc(GL_LEQUAL);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_DEPTH_CLAMP);

        glEnable(GL_TEXTURE_2D);
    }

主要:

    while(!window.isClosing()){

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        program.updateUniform("TextureIndex", 0);
        glActiveTexture(GL_TEXTURE0 + 0);
        glBindTexture(GL_TEXTURE_2D, TexHandle);
        glBegin(GL_QUADS);
        glNormal3f(0, 0, 0);

        glTexCoord2f(0, 0);
        glVertex3f(-.5f, -.5f, -2f);

        glTexCoord2f(1, 0);
        glVertex3f(.5f, -.5f, -2f);

        glTexCoord2f(1, 1);
        glVertex3f(.5f, .5f, -2f);

        glTexCoord2f(0, 1);
        glVertex3f(-.5f, .5f, -2f);

        glEnd();

        window.update();
    }

顶点:

layout(location = 0) in vec3 in_position;
layout(location = 1) in vec2 in_texture_coord;
layout(location = 2) in vec3 in_normal;
out vec2 out_texture_coord;

void main(){

    gl_Position = vec4(in_position, 1.0);
    out_texture_coord  = in_texture_coord;

}

片段:

    out vec4 out_color;
    in vec2 in_texture_coord; // passed from the vertex shader
    uniform sampler2D TextureIndex;

    void main(){

        out_color = texture2D(TextureIndex, in_texture_coord);

    }

【问题讨论】:

  • 缺少的一件事是调用glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) 在绘图前清除窗口。除此之外,下一个猜测可能是顶点着色器的问题。
  • 我添加了该功能,但仍然出现错误。我还添加了顶点着色器

标签: java opengl lwjgl texture-mapping fragment-shader


【解决方案1】:

发布的代码以不受支持的方式将旧版 OpenGL 功能与现代 OpenGL 功能混合在一起。顶点规范代码使用旧式固定函数属性:

glNormal3f(0, 0, 0);
glTexCoord2f(0, 0);
glVertex3f(-.5f, -.5f, -2f);

虽然顶点着色器需要通用顶点属性:

layout(location = 0) in vec3 in_position;
layout(location = 1) in vec2 in_texture_coord;
layout(location = 2) in vec3 in_normal;

两者之间没有直接对应关系。规范中有一些语言说通用属性 0 映射到旧的顶点位置,但即使这样也并不总是对所有驱动程序都可靠地工作。并且假设使用glTexCoord2f() 指定的值将映射到顶点着色器中使用(location = 1) 的属性当然是无效的。

解决这个问题的主要方法有两种:

  1. 更改着色器代码以使用用于指定顶点数据的旧调用。这是通过删除顶点着色器代码中的in 变量声明并使用预定义的变量来访问属性值来完成的:

    gl_Vertex 表示顶点位置

    gl_MultiTexCoord0 用于纹理坐标

    gl_Normal 正常

  2. 使用 API 函数来设置通用顶点属性的值,而不是使用固定的函数属性。对于上面的代码片段,并匹配顶点着色器代码中的位置:

    glVertexAttrib3f(2, 0.0f, 0.0f, 0.0f);
    glVertexAttrib2f(1, 0.0f, 0.0f);
    glVertexAttrib3f(0, -0.5f, -0.5f, -2.0f);
    

如果您准备好转向现代 OpenGL,选项 2 将是更好的方向。该路径上的后续步骤之一是使用顶点缓冲区对象 (VBO) 来指定顶点数据,而不是当前代码中的立即模式调用。

【讨论】:

  • 感谢您的帮助,但是...我已经实施了您的 #2 修复,但我仍然得到一个完全黄色的矩形。我想我的问题在于纹理加载器/openGL 初始化。我正在处理的这段代码是我几年前做的一个旧应用程序,现在我正在尝试更新它并添加一些功能
【解决方案2】:

问题在于变量的命名:在 VS 中我有“out vec3 out_tex_coord”,而在 FS 中我有“in vec3 in_tex_coord”,因为它们与纹理的 UV 不匹配(0,0)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-27
    • 2011-08-30
    • 2014-11-19
    • 1970-01-01
    相关资源
    最近更新 更多