【问题标题】:Texture Loading using PNGDecoder and LWJGL使用 PNGDecoder 和 LWJGL 加载纹理
【发布时间】:2021-02-04 07:58:19
【问题描述】:

我对 OpenGL 比较陌生,所以这个问题可能看起来有点琐碎。我的 Main.java 中有这段代码,它应该输出一个带有图像纹理的矩形:

float vertices[] = {
                // positions          // colors           // texture coords
                 0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f, // top right
                 0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f, // bottom right
                -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // bottom left
                -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f  // top left 
            };
            int indices[] = {  
                0, 1, 3, // first triangle
                1, 2, 3  // second triangle
            };
            int VBO = glGenBuffers(), VAO = glGenVertexArrays(), EBO = glGenBuffers();

            glBindVertexArray(VAO);

            glBindBuffer(GL_ARRAY_BUFFER, VBO);
            glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);

            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW);

            // position attribute
            glVertexAttribPointer(0, 3, GL_FLOAT, false, 8, 0);
            glEnableVertexAttribArray(0);
            // color attribute
            glVertexAttribPointer(1, 3, GL_FLOAT, false, 8, 2);
            glEnableVertexAttribArray(1);
            // texture coord attribute
            glVertexAttribPointer(2, 2, GL_FLOAT, false, 8, 5);
            glEnableVertexAttribArray(2);
        Texture texture = null;
        try {
            log.info("Loading texture");
            texture = Texture.loadTexture("texture.png");
        } catch (IOException e) {
            log.severe("Texture loading failed due to IOException: " + e.getMessage());
            e.printStackTrace();
        }
        
        
        while (!glfwWindowShouldClose(window))
            {
            
                

                glClear(GL_COLOR_BUFFER_BIT);
                
                if(mainProgram != null) {
                    mainProgram.use();
                }
                glBindTexture(GL_TEXTURE_2D, texture.getId());
                glBindVertexArray(VAO); 
                glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
                //...
            }

我的着色器如下: 顶点着色器:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout(location = 2) in vec2 aTexCoord;

out vec3 vertexColor;
out vec2 texCoord;

void main()
{
    gl_Position = vec4(aPos , 1.0);
    vertexColor = aColor;
    texCoord = aTexCoord;
}

片段着色器:

#version 330 core
out vec4 FragColor;

in vec3 ourColor;
in vec2 TexCoord;

// texture sampler
uniform sampler2D texture1;

void main()
{
    FragColor = texture(texture1, TexCoord);
}

上面引用的Texture类如下:

public class Texture {
   public static Texture loadTexture(String fileName) throws IOException{

       //load png file
       PNGDecoder decoder = new PNGDecoder(new java.io.FileInputStream(new File("C:/Users/Using/Absolute/Paths/For/Demonstration/texture.png")));

       //create a byte buffer big enough to store RGBA values
       ByteBuffer buffer = BufferUtils.createByteBuffer(4 * decoder.getWidth() * decoder.getHeight());

       //decode
       decoder.decode(buffer, decoder.getWidth() * 4, PNGDecoder.Format.RGBA);

       //flip the buffer so its ready to read
       buffer.flip();

       //create a texture
       int id = glGenTextures();

       //bind the texture
       glBindTexture(GL_TEXTURE_2D, id);

       //tell opengl how to unpack bytes
       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

       //set the texture parameters, can be GL_LINEAR or GL_NEAREST
       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

       //upload texture
       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, decoder.getWidth(), decoder.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

       // Generate Mip Map
       glGenerateMipmap(GL_TEXTURE_2D);

       return new Texture(id); 
   }
    private int id;

    public Texture(int id){
        this.id = id;
    }

    public int getId(){
        return id;
    }
}

请注意,纹理图像的路径不是问题,因为代码可以正常工作,没有任何异常或编译器错误。我使用的PNGDecoder可以在here找到。

【问题讨论】:

  • 不,它不是...我确实检查了我是否使用了您提供的值,但它仍然没有显示纹理
  • 所以还有另一个问题与贴图或解码纹理有关。

标签: java opengl textures lwjgl


【解决方案1】:

glVertexAttribPointer指定通用顶点属性数据数组时,strideoffset参数必须以字节为单位。
此外,uv 坐标是属性元组中的第 7 个和第 8 个元素:

glVertexAttribPointer(0, 3, GL_FLOAT, false, 8, 0);

glVertexAttribPointer(0, 3, GL_FLOAT, false, 8*4, 0);

glVertexAttribPointer(1, 3, GL_FLOAT, false, 8, 2);

glVertexAttribPointer(1, 3, GL_FLOAT, false, 8*4, 3*4);

glVertexAttribPointer(2, 2, GL_FLOAT, false, 8, 5);

glVertexAttribPointer(2, 2, GL_FLOAT, false, 8*4, 6*4);

【讨论】:

  • 这只是解决了一部分问题...现在可以正确渲染形状,但仍然看不到纹理
  • @PhoenixXKN 5*4 -> 6*4
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-27
  • 1970-01-01
  • 1970-01-01
  • 2014-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多