简体   繁体   English

使用 PNGDecoder 和 LWJGL 加载纹理

[英]Texture Loading using PNGDecoder and LWJGL

I am relatively new to OpenGL, so this question might seem a bit trivial.我对 OpenGL 比较陌生,所以这个问题可能看起来有点微不足道。 I have this code in my Main.java, which is supposed to output a rectangle with the texture of the image on it:我的 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);
                //...
            }

My shaders are the following: Vertex Shader:我的着色器如下: 顶点着色器:

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

Fragment Shader:片段着色器:

#version 330 core
out vec4 FragColor;

in vec3 ourColor;
in vec2 TexCoord;

// texture sampler
uniform sampler2D texture1;

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

The Texture class referenced above is the following:上面引用的 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;
    }
}

Note that the path of the texture image is not the problem, as the code works without any Exceptions or Compiler errors.请注意,纹理图像的路径不是问题,因为代码工作时没有任何异常或编译器错误。 The PNGDecoder i used can be found here .我使用的 PNGDecoder 可以在这里找到。

The stride and offset argument must be set in bytes when specifying the array of generic vertex attribute data by glVertexAttribPointer .当通过glVertexAttribPointer指定通用顶点属性数据数组时,必须以字节为单位设置步幅偏移量参数。
Furthermore, the uv coordinates are the 7th and 8th element in the attribute tuple:此外, 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM