Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct Way to Texture Square Made of Two Triangles?

I using OpenGL 4.1 and GLSL 410. I am attempting to texture a square that I made using the following coordinates:

float points[] = {
    -0.5,  0.5,
    -0.5, -0.5,
     0.5, -0.5,
    -0.5,  0.5,
     0.5, -0.5,
     0.5,  0.5
};

I draw the square like this:

glDrawArrays (GL_TRIANGLES, 0, 6);

From all of the tutorials I have read, the author uses an element buffer to draw the square or has just four vertices. This means that all the tutorials I have read have texture coordinates that line up with each vertex. For me, I'm using 6 vertices, so I'm not sure how to line up the texture coordinates.

Would coordinates like this work for my case:

float texcoords[] = {
    0.0, 1.0,
    0.0, 0.0,
    1.0, 0.0,
    0.0, 1.0,
    1.0, 0.0,
    1.0, 1.0
};

I've done lots of reading, but haven't come across anyone else who is using six vertices like I am.

Would my texture coordinates work and if not, what is the best way to come up with texture coordinates.

like image 755
foobar5512 Avatar asked Jan 05 '14 20:01

foobar5512


1 Answers

Yes, that will work. You've divided the sqaure into 2 triangles and mapped the tex coords to the vertices of the triangles. What are your results?

See this question. The code uses one array for the vertices (although there each vertex has xyz values) and another array for the texture coords.

You need to be careful when defining the vertex attributes.

E.g. to setup the vertex data uisng 2 buffers

glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);

glGenBuffers(1, &texbuffer);
glBindBuffer(GL_ARRAY_BUFFER, texbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(texcoords), texcoords, GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

glVertexAttribPointer(0,        // attribute 0
                      2,        // 2 floats per vertex
                      GL_FLOAT, // type
                      GL_FALSE, // normalized?
                      0,        // stride -> tightly packed so make it zero
                      0);       // array buffer offset

glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, texbuffer);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);

glDrawArrays(GL_TRIANGLES, 0, 6);  

To load the texture (Update and setup the sampler, see comments)

glGenTextures(1, &tex);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex);
GLuint TextureID = glGetUniformLocation(programID, "texture");
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);

Vertex shader

#version 410 core

layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texcoord;    
out vec2 texture_coordinates;    
uniform mat4 MVP;

void main() {
    gl_Position = position;
    texture_coordinates = texcoord;
}

Fragment shader

in vec2 texture_coordinates;
uniform sampler2D texture;
out vec4 colour;

void main() {
    colour = texture2D(basic_texture, texture_coordinates);
}
like image 193
robor Avatar answered Nov 06 '22 23:11

robor