I'm trying to apply a texture to a plane made up of 6 vertexes drawn using glDrawArrays() The first triangle drawn seems to be drawn correctly but the texture for the second triangle doesn't seem to align correctly and seems squished. I had the same issue when trying to draw using an index buffer using glDrawElements() as well.
My vertex array Object creation looks like this
// Position and Color data
GLfloat verts[] = {
// Vertex Positions // Colors (r,g,b,a) //Texture Coordinates
-5, -1, 5, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // front left vertex
-5, -1, -5, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, // back left vertex
5, -1, 5, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, // front right vertex
-5, -1, -5, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, // back left vertex
5, -1, -5, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,// back right vertex
5, -1, 5, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f // front right vertex
};
const GLuint floatsPerVertex = 3;
const GLuint floatsPerColor = 4;
const GLuint floatsPerUV = 2;
glGenVertexArrays(1, &mesh.vao); // we can also generate multiple VAOs or buffers at the same time
glBindVertexArray(mesh.vao);
// Create buffer: for the vertex data
glGenBuffers(1, &mesh.vbo);
glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo); // Activates the buffer
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); // Sends vertex or coordinate data to the GPU
// Strides between vertex coordinates is 9 (x, y, z, r, g, b, a). A tightly packed stride is 0.
GLint stride = sizeof(float) * (floatsPerVertex + floatsPerColor + floatsPerUV);// The number of floats before each
mesh.nVertices = 6;
// Create Vertex Attribute Pointers
glVertexAttribPointer(0, floatsPerVertex, GL_FLOAT, GL_FALSE, stride, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, floatsPerColor, GL_FLOAT, GL_FALSE, stride, (char*)(sizeof(float) * floatsPerVertex));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, floatsPerColor, GL_FLOAT, GL_FALSE, stride, (char*)(sizeof(float) * (floatsPerVertex + floatsPerColor)));
glEnableVertexAttribArray(2);
My Vertex and Fragment Shader are:
// Vertex Shader source code
const GLchar* vertexShaderSource = GLSL(440,
layout(location = 0) in vec3 position; // Vertex data from Vertex Attrib Pointer 0
layout(location = 1) in vec4 color; // Color data from Vertex Attrib Pointer 1
layout(location = 2) in vec2 textureCoordinate; // Texture cooridnates from vertex attirb pointer 2
out vec4 vertexColor; // Variable to transfer color data to the fragment shader
out vec2 vertexTextureCoordinate; // Varible to transfer texture coordinates to fragment shaders
// Global variables for the transform matrices
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(position, 1.0f); // Transforms vertices to clip coordinates
vertexColor = color; // References incoming color data
vertexTextureCoordinate = textureCoordinate; // references income texture data
}
);
// Fragment Shader Source Code
const GLchar* fragmentShaderSource = GLSL(440,
in vec4 vertexColor; // Variable to hold incoming color data from vertex shader
in vec2 vertexTextureCoordinate;
out vec4 fragmentColor;
uniform sampler2D uTexture;
void main()
{
fragmentColor = texture(uTexture, vertexTextureCoordinate); // sends texture to GPU for rendering
}
);
Here is the code in my render function (I've cut out code to just where I draw the plane and variable set up:
// Enable z-depth
glEnable(GL_DEPTH_TEST);
// Clear the frame and z buffers
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
// Scales object
glm::mat4 scale = glm::scale(glm::vec3(1.0f, 1.0f, 1.0f));
// Rotate shape
glm::mat4 rotation = glm::rotate(45.0f, glm::vec3(1.0f, 1.0f, 0.0f));
// Place object at x, y, z
glm::mat4 translation = glm::translate(glm::vec3(-1.0f, 0.0f, 0.0f));
// Model matrix: transformations are applied right-to-left order
glm::mat4 model = translation * rotation * scale;
// Transforms the camera: move the camera back (z axis)
glm::mat4 view = gCamera.GetViewMatrix();
glm::mat4 projection;
// Create perspective projection
if (!perspectiveSwitch)
{
projection = glm::perspective(45.0f, (GLfloat)WINDOW_WIDTH / (GLfloat)WINDOW_HEIGHT, 0.1f, 100.0f);
}
else
{
projection = glm::ortho(-5.0f, 5.0f, -5.0f, 5.0f, 0.1f, 100.0f);
}
// Select shader program to be used
glUseProgram(gProgramId);
// Retrives and passes transfrom matrices to the shader program
GLint modelLoc = glGetUniformLocation(gProgramId, "model");
GLint viewLoc = glGetUniformLocation(gProgramId, "view");
GLint projLoc = glGetUniformLocation(gProgramId, "projection");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
// Object remains same size
scale = glm::scale(glm::vec3(1.0f, 1.0f, 1.0f));
// object remains unrotated
rotation = glm::rotate(0.0f, glm::vec3(1.0f, 1.0f, 1.0f));
// Place object at the origin
translation = glm::translate(glm::vec3(0.0f, 0.0f, 0.0f));
// Model matrix: transformations are applied right-to-left order
model = translation * rotation * scale;
//Send updated model information for next object
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
// Activate the VBO contained within the mesh's VAO
glBindVertexArray(gPlane.vao);
// Bind texture for draw
glBindTexture(GL_TEXTURE_2D, tableTexture);
//Draws the triangles
glDrawArrays(GL_TRIANGLES, 0, gPlane.nVertices);
// Deactivate the Vertex Array Object
glBindVertexArray(0);
// glfw: swap buffers and poll IO events
glfwSwapBuffers(gWindow); // Flips the back buffer with the front buffer
Here is what my rendered object with the texture applied looks like and the original image of the texture.
the original image of the texture.
(I can't seem to add multiple images to the post so I had to link one of them)
Discovered I was passing the wrong value in my attribute pointer for the number of values.
I had accidentally passed in the number of values for the color attribute instead of the number of values for the texture coordinate attributes.