So I am trying to move to a more modern, shader-based rendering system in OpenGL, and part of that, as I understand, is performing the projections that used to be accomplished with the built-in matrix stack in older OpenGL by instead feeding my own matrices to a shader. Here is my shader (Apologies, for some reason I can't get whitespace to appear in code formatting):
//Vertex
attribute vec3 coord3d;
attribute vec3 v_color;
varying vec3 f_color;
uniform mat4 projection;
uniform mat4 model;
uniform mat4 view;
void main(void)
{
gl_Position = projection * view * model * vec4(coord3d, 1.0);
f_color = v_color;
}
//Fragment
varying vec3 f_color;
void main(void)
{
gl_FragColor = vec4(f_color.x, f_color.y, f_color.z, 1.0);
}
I've been having some problems, though, in that multiplication by projection and/or view matrices makes my test object disappear. If I change the shader to this:
gl_Position = model * vec4(coord3d, 1.0);
The object appears as expected on-screen, flat and positioned relative to the [-1, 1] space of the screen. Let's go through this step by step.
I have three relevant classes, let's call them Scene, Object and Camera. In Scene's constructor, these GLuints are set:
//Model - must be changed for each model
Object::ModelUniform = glGetUniformLocation(ObjectShader, "model");
//View - must be changed once per frame
m_ViewUniform = glGetUniformLocation(ObjectShader, "view");
//Projection - must only be set once
m_ProjectionUniform = glGetUniformLocation(ObjectShader, "projection");
glm::mat4 projection = glm::perspective(60.0f, 1.33f, 0.1f, 512.f);
glUniformMatrix4fv(m_ProjectionUniform, 1, GL_FALSE, glm::value_ptr(projection));
Then, once per frame (still in Scene; I have other objects in the background running on old shaders+glMultMatrixf() code, but I don't think there's any interaction between the two):
glm::vec3 Eye = glm::vec3(CameraPos.x, CameraPos.y, CameraPosz);
glm::vec3 Center = glm::vec3(ObjectPos.x, ObjectPos.y, ObjectPosz);
glm::vec3 Up = glm::vec3(0.0, 1.0, 0.0);
glm::mat4 view = glm::lookAt(Eye, Center, Up);
glUniformMatrix4fv(m_ViewUniform, 1, GL_FALSE, glm::value_ptr(view));
glUseProgram(ObjectShader);
Object->Cycle();
Then, in Object::Cycle():
glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(Position.x, Position.y, Position.z));
glUniformMatrix4fv(Object::ModelUniform, 1, GL_FALSE, glm::value_ptr(model));
glEnableVertexAttribArray(CoordinateAttribute);
glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
glVertexAttribPointer(CoordinateAttribute, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), 0);
glEnableVertexAttribArray(ColorAttribute);
glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
glVertexAttribPointer(ColorAttribute, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*) (3 * sizeof(GLfloat)));
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(ColorAttribute);
glDisableVertexAttribArray(CoordinateAttribute);
glDisable(GL_BLEND);
glBindBuffer(GL_ARRAY_BUFFER, 0);
All of the matrices I use work fine in old OpenGL using deprecated functions like glMultMatrixf().
As mentionned above, using only the model matrix works fine. Rotating the camera around doesn't locate the missing object.
What could be the problem here?