Correct Way to Texture Square Made of Two Triangles?
Asked Answered
A

1

6

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.

Aalii answered 5/1, 2014 at 20:19 Comment(1)
"I've done lots of reading", probably not, found an article with my first Google search! ... Though you basically do the same!Culpa
B
4

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);
}
Baltoslavic answered 5/1, 2014 at 20:50 Comment(3)
I did this exact same thing except in the fragment shader I'm using texture() instead of texture2D() as it was removed. I am getting what appears to be just a very small piece of my image. (My image is white and red, but I'm just getting a white square.) I am using this as well:Aalii
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);Aalii
Yes, you'll need a sampler (or set the sampler settings).Baltoslavic

© 2022 - 2024 — McMap. All rights reserved.