Hi all,
trying to learn OpenGL using lwjgl3, got stuck at texturing a triangle, nothing is displayed. Decoding png texture to a bytebuffer using Manns PNGDecoder.
The whole thing seems straight forward to me but all i get is black screen. As far as i figured out the texture should be bound automatically to the sampler, i dont need to set the uniform myself in the code.
Decoding the texture and uploading to GPU:
public static Texture getPNGTexture(String fileName)
{
int id;
ByteBuffer buf = null;
int imageWidth = 0;
int imageHeight = 0;
try {
InputStream is = new FileInputStream(new File("res/textures/" + fileName + ".png"));
PNGDecoder decoder = new PNGDecoder(is);
imageWidth = decoder.getWidth();
imageHeight = decoder.getHeight();
if (imageWidth == 0 || imageHeight == 0)
{
throw new IOException("Image is zero sized!");
}
PNGDecoder.Format format = PNGDecoder.RGBA;
try{
buf = BufferUtils.createByteBuffer(imageHeight*imageWidth*format.getNumComponents());
decoder.decode(buf, imageWidth*format.getNumComponents(), format);
}catch(IOException e){
e.printStackTrace();
}finally {
is.close();
}
buf.flip();
} catch (IOException e) {
e.printStackTrace();
}
id = glGenTextures();
glBindTexture(GL_TEXTURE_2D, id);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA, imageWidth, imageHeight);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, imageWidth, imageHeight, GL_RGBA, GL_UNSIGNED_BYTE, buf);
return new Texture(id);
}
Getting texture and mesh data:
texture = Texture.getPNGTexture("box");
test = new Mesh();
float[] vertices = {
-0.5f, 0.5f, 0f,
-0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
};
int[] indices = {
0,1,2
};
float[] texCoords = {
0,0,
0,1,
1,1
};
test.addVertices(vertices, texCoords, indices);
public void addVertices(float[] vertices, float[] texCoords, int[] indices)
{
size = indices.length;
glBindVertexArray(vao); //Bind VAO
int vbo = glGenBuffers(); //Create new VBO
int ibo = glGenBuffers();
int tbo = glGenBuffers();
buffers.add(vbo);
buffers.add(ibo);
buffers.add(tbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo); //Bind vbo
glBufferData(GL_ARRAY_BUFFER, Util.createFlippedBuffer(vertices), GL_STATIC_DRAW); //Put data in it
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0); //Put VBO in VAO on pos 0
glBindBuffer(GL_ARRAY_BUFFER, tbo);
glBufferData(GL_ARRAY_BUFFER, Util.createFlippedBuffer(texCoords), GL_STATIC_DRAW);
glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); //Bind vbo
glBufferData(GL_ELEMENT_ARRAY_BUFFER, Util.createFlippedBuffer(indices), GL_STATIC_DRAW); //Put data in it
}
Binding texture bit and drawing mesh:
public void render()
{
texture.bind();
shader1.bind();
shader1.SetUniform("transform", transform1.getProjectedTransformation());
test.draw();
}
public void bind()
{
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, id);
}
public void draw()
{
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
}
Shaders:
#version 430 core
layout (location=0) in vec3 position;
layout (location=1) in vec2 texCoords;
out vec2 pass_texCoords;
uniform mat4 transform;
void main()
{
pass_texCoords = texCoords;
gl_Position = transform * vec4(position, 1.0);
}
#version 430 core
in vec2 pass_texCoords;
layout (binding=0) uniform sampler2D sampler;
out vec4 color;
void main()
{
color = texture(sampler, pass_texCoords);
}