Hello, I started with lwjgl and openGL and I have problems binding a texture to a simple quad. The texture is stretched, that the whole quad has a uniform color, no matter what the texture is. I suspect that I use VAOs and VBOs incorrectly, but I don’t see my mistake:
First, the two shaders, which should be correct:
Vertex Shader:
#version 410
in vec3 position;
in vec2 textureCoords;
out vec2 pass_textureCoords;
void main(void){
gl_Position = vec4(position,1.0);
pass_textureCoords = textureCoords;
}
Fragment Shader:
#version 410
uniform sampler2D textureSampler;
in vec2 pass_textureCoords;
out vec4 out_Colour;
void main(void){
out_Colour = texture(textureSampler,pass_textureCoords);
}
My vertices, indices and texture coordinates.
float[] vertices = {
-0.5f, 0.5f, 0f,
-0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
0.5f, 0.5f, 0f
};
int[] indices = {
0, 1, 2,
2, 3, 0
};
float[] textureCoords = {
0,0,
0,1,
1,1,
1,0
};
How I load the texture:
private int load(String path) {
IntBuffer width = BufferUtils.createIntBuffer(1);
IntBuffer height = BufferUtils.createIntBuffer(1);
IntBuffer components = BufferUtils.createIntBuffer(1);
ByteBuffer data = stbi_load(path,width,height,components,4);
if (data == null)
throw new RuntimeException("Could not load texture!");
textureID = glGenTextures();
this.width = width.get();
this.height = height.get();
glBindTexture(GL_TEXTURE_2D,textureID);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,this.width,this.height,0,GL_RGBA,GL_UNSIGNED_BYTE,data);
stbi_image_free(data);
glBindTexture(GL_TEXTURE_2D, 0);
return textureID;
}
How I create the VAOs and VBOs and store the indices, vertices and texture coordinates (I suppose that the error is here or/and in the renderer:)
I start by creating a VAO:
private int createVAO(){
int vaoID = glGenVertexArrays();
glBindVertexArray(vaoID);
return vaoID;
}
I store the vertex coordinates first in a Buffer, and then in a VBO:
FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
buffer.put(data);
buffer.flip(); //we finished writing, and prepare to read the data
int vboID = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER,vboID);
FloatBuffer buffer = storeDataInFloatBuffer(data);
glBufferData(GL_ARRAY_BUFFER,buffer,GL_STATIC_DRAW); //static data, we won't edit it
glVertexAttribPointer(0,3, GL_FLOAT,false,0,0);
glBindBuffer(GL_ARRAY_BUFFER,0);//unbind VBO
glBindVertexArray(0);
I store the indices:
int vboIndicesID = glGenBuffers();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,vboIndicesID);
IntBuffer buffer = storeDataInIntBuffer(indices); //the same as the FloatBuffer above
glBufferData(GL_ELEMENT_ARRAY_BUFFER,buffer,GL_STATIC_DRAW);
glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
and finally, I store my texture coordinates, with the same method as I use for the vertex coordinates, except for one line:
glVertexAttribPointer(1,2, GL_FLOAT,false,0,0);
I finish by unbinding the VAO:
glBindVertexArray(0);
The rendering part:
I bind the texture, I bind the VAO, I enable the VAO (although I’m not completely sure what this step does in the code), I then bind the VBO of the vertices and draw them using drawElements. At the end, I unbind everything:
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texturedModel.getTexture().getTextureID());
// Bind to the VAO that has all the information about the vertices
glBindVertexArray(model.getVaoID());
glEnableVertexAttribArray(0);
// Bind to the index VBO that has all the information about the order of the vertices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model.getVboIndicesID());
// Draw the vertices
glDrawElements(GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
// Put everything back to default (deselect)
glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(0);
glBindVertexArray(0);
Can anybody help me out here, what is wrong with this setup of storing data in VBOs and VAOs, as well as loading a texture? Thank you!