I'm learning OpenGL and I don't understand why my texture is flipped if I give as UVs the "matching" vec2 of the mesh's vertex (vec3).
Example:
vert -256 -256
uv 0 0
vert 256 256
uv 1 1
I've had to try a different order for the UVs to be able to get the correct result...
Can someone explain why is that so? Thanks.
Screenshots:
http://imgur.com/a/49ZVp
This are the snippets of code I use:
// Create texture
GLuint texDebugId;
// RGBA Texture:
// R G
// B A
unsigned char texDebugBuf[] = {
255, 0, 0, 255,
0, 255, 0, 255,
0, 0, 255, 255,
0, 0, 0, 0,
};
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &texDebugId);
glBindTexture(GL_TEXTURE_2D, texDebugId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDebugBuf);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
//------------------------------
// Prepare VBOs
static const GLfloat verts[] = {
-256.0f, -256.0f, 0.0f,
256.0f, -256.0f, 0.0f,
-256.0f, 256.0f, 0.0f,
256.0f, 256.0f, 0.0f
};
/*
// FLIPPED (but why?)
static const GLfloat uvs[] = {
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
};
*/
// OK
static const GLfloat uvs[] = {
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
};
// Upload vertices
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// Upload UVs
glBindBuffer(GL_ARRAY_BUFFER, vbo_tex_id);
glBufferData(GL_ARRAY_BUFFER, sizeof(uvs), uvs, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//------------------------------
// Render
glBindTexture(GL_TEXTURE_2D, texId);
glEnableVertexAttribArray((GLuint) pd.vertex_a);
glEnableVertexAttribArray((GLuint) pd.uv_a);
// Vertices
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
glVertexAttribPointer(
(GLuint) pd.vertex_a, // attribute id
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void *)0 // array buffer offset
);
// UVs
glBindBuffer(GL_ARRAY_BUFFER, vbo_tex_id);
glVertexAttribPointer(
(GLuint) pd.uv_a, // attribute id
2, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void *)0 // array buffer offset
);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableVertexAttribArray((GLuint) pd.uv_a);
glDisableVertexAttribArray((GLuint) pd.vertex_a);
glBindTexture(GL_TEXTURE_2D, 0);
Note:
proj matrix:
proj = glm::ortho(-320, 320, -240, 240, -1.0f, 100.0f); // 640x480 with 0,0 at center
camera matrix:
cam_target = glm::vec3();
cam_up = glm::vec3(0.0, 1.0f, 0.0f);
cam_pos = glm::vec3(0.0f, 0.0f, 5.0f);
camera = glm::lookAt(cam_pos, cam_target, cam_up);
MVP matrix:
glm::mat4 mvp = proj * camera;