I have a very simple vertex shader that largely emulates the fixed pipeline. The fixed pipeline works fine but I can’t get my vertex program to work properly. It works but 1/4 of the rendered textures are missing. I’m using GLM to create the necessary matrices. I’m rendering simple quads.
[I’d put an image here but this website says that .jpg isn’t a valid image!]
Here is the setup code for the matrices and the vertex structures:
static float vertex_coordinates[] =
{
-0.5f, +0.5f, +0.5f, +0.5f,
-0.5f, -0.5f, +0.5f, -0.5f
};
static float texture_coordinates[] =
{
0.0f, 1.0f, 1.0f, 1.0f,
0.0f, 0.0f, 1.0f, 0.0f
};
void create_vertex_attribute(const char *attribute, float *attribute_data, size_t data_size)
{
GLuint attribute_buffer_id;
GLint location;
location = get_vertex_attribute_location(attribute);
glEnableVertexAttribArray(location);
generate_and_bind_opengl_object(GL_ARRAY_BUFFER, &attribute_buffer_id);
glBufferData(GL_ARRAY_BUFFER, data_size, attribute_data, GL_STATIC_DRAW);
glVertexAttribPointer
(
location, // vertex_attribute_location
2, GL_FLOAT, // two floats per vertex
GL_FALSE, // don't normalize
0, // stride (packed)
(GLubyte*)NULL // no offset
);
OpenGL_error_check(__FILE__, __LINE__, __FUNC__);
}
void setup_vertex_shader_pipeline(void)
{
mat4 ortho_matrix;
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
set_uniform_variable(GL_BOOL, "use_vertex_shader_pipeline", GL_TRUE);
// creates a matrix for projecting two-dimensional coordinates onto the screen.
ortho_matrix = glm::ortho(0.0f, (float)viewport[2], 0.0f, (float)viewport[3], -1.0f, +1.0f);
set_uniform_matrix4_variable("ortho_matrix", ortho_matrix);
generate_and_bind_opengl_object(GL_VERTEX_ARRAY, &vertex_array_object_handle);
create_vertex_attribute("vertex_coordinates", vertex_coordinates, sizeof(vertex_coordinates));
create_vertex_attribute("texture_coordinates", texture_coordinates, sizeof(texture_coordinates));
OpenGL_error_check(__FILE__, __LINE__, __FUNC__);
printf(" GLSL vertex shader pipeline setup
");
}
void OpenGL_GLM_render_tile(TILE *tile)
{
mat4 translation_matrix, rotation_matrix, scale_matrix;
translation_matrix = glm::translate(glm::mat4(1.0f), glm::vec3((float)tile->x, (float)tile->y, 0.0f));
// the tile angle is in radians for GLM and rotates about z-axis
rotation_matrix = glm::rotate(glm::mat4(1.0), (float)tile->angle, glm::vec3(0.0, 0.0, 1.0));
scale_matrix = glm::scale(glm::mat4(1.0), glm::vec3(tile->width * (float)tile->scale, tile->length * (float)tile->scale, 1.0));
// have the GPU multiply these matrices to compute the transform matrix
set_uniform_matrix4_variable("translation_matrix", translation_matrix);
set_uniform_matrix4_variable("rotation_matrix", rotation_matrix);
set_uniform_matrix4_variable("scale_matrix", scale_matrix);
glDrawArrays(GL_QUADS, 0, 4);
glutPostRedisplay();
}
Here is the vertex shader. As you can see I can switch it from fixed pipeline to programmable very easily.
in vec2 vertex_coordinates; // from vertex buffer object
in vec2 texture_coordinates; // from vertex buffer object
uniform bool use_vertex_shader_pipeline;
uniform mat4 ortho_matrix; // these are from the OpenGL GLM matrix code
uniform mat4 translation_matrix;
uniform mat4 rotation_matrix;
uniform mat4 scale_matrix;
uniform mat4 transform_matrix;
out vec2 fragment_texture_coordinates;
void main(void)
{
if(use_vertex_shader_pipeline)
{
fragment_texture_coordinates = texture_coordinates;
// make the GPU do the matrix multiplications
// a cascade of transformations in the appropriate order
gl_Position = ortho_matrix
* translation_matrix
* rotation_matrix
* scale_matrix
* vec4(vertex_coordinates, 0.0, 1.0);
}
else
{
// This relies on the old fixed-pipeline facilities there is no
// need to set up the matrix operations in the OpenGL code
fragment_texture_coordinates = gl_MultiTexCoord0.st;
gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
}
}
I’ve been looking at this for a couple of days and can’t seem to find the problem. :doh:
Please help!