Applying a perspective matrix

Started by
6 comments, last by Brother Bob 11 years, 4 months ago
Hi,
I'm having problems applying a perspective matrix to my 3d cube in OpenGL (3.3)

I'm uploading the perspective matrix (along with the vertex color) through uniform buffers. I can confirm this uniform buffer process works if I upload the identity matrix, but when I try the perspective variant it does not work (nothing gets drawn),

So when I set the perspective matrix like this:


uint16_t h = mEngine->GetRenderer().GetScreenMode().ScreenHeight;
uint16_t w = mEngine->GetRenderer().GetScreenMode().ScreenWidth;
shaderData.mPerspMatrix = CreatePerspectiveMatrix(45.0f, w/(float) h, 0.5f, 3.0f);


it dosn't work, but when I set it to the identity matrix it draws, but of course with no perspective


shaderData.mPerspMatrix = Mat4(1.0f);


Here's the cube data:


const float vertexPositions[] =
{
// front vertices
0.0f, 0.5f, 0.0f,
0.5f, 0.5f, 0.0f,
0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
// back vertices
0.0f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.0f, 0.5f,
0.0f, 0.0f, 0.5f
};
const GLshort indexData[] =
{
// back
5, 4, 7,
5, 7, 6,
// right
1, 5, 6,
1, 6, 2,
// left
0, 4, 7,
0, 7, 3,
// top
5, 4, 0,
5, 0, 1,
// bottom
6, 7, 3,
6, 3, 2,
// front
1, 0, 3,
1, 3, 2
};


Buffer and draw it like this:


// buffer data
glBindBuffer(GL_ARRAY_BUFFER, mVBO_VertexShader);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexData), indexData, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

// setup VAO
glBindVertexArray(mVAO);
glBindBuffer(GL_ARRAY_BUFFER, mVBO_VertexShader);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);


//.... and drawing
glBindVertexArray(mVAO);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0);
glBindVertexArray(0);


Here's my vertex + fragment shader:


const std::string gVertexShader = "#version 330 \n \
\n \
layout(std140) uniform Uni \n \
{ \n \
vec4 mColor; \n \
mat4 mPerspMatrix; \n \
}; \n \
\n \
in vec3 in_position; \n \
out vec3 ex_color; \n \
void main() \n \
{ \n \
vec4 camPos = vec4(in_position, 1.0f); \n \
ex_color = mColor.xyz; \n \
gl_Position = mPerspMatrix * camPos; \n \
} \n";

const std::string gFragmentShader = "#version 330 \n \
in vec3 ex_color; \n \
out vec4 outColor; \n \
void main() \n \
{ \n \
outColor = vec4(ex_color, 1.0f); \n \
} \n";


What am I missing to apply a perspective?

EDIT: Sorry I hope its readable, dosn't seem copy-paste works too well?
Advertisement
The cube extends from 0 to 0.5 along all axes, including the Z-axis, and the near clip plane of the projection matrix is 0.5. As expected, the cube is clipped entirely because it is outside the view volume.
Sounds reasonable; but I set the nearest Z-values of the cube to 0.2f and change to CreatePerspectiveMatrix(45.0f, w/(float) h, 0.1f, 3.0f); for example and the problem still persists
I don't know, why don't you try and see?

I'm not saying that is the only problem, just one I saw. I could see another potential problem in that only the far side of the cube remains, and with back face culling, you won't see the back of the cube (which would be viewed with the inside towards the viewpoint) assuming the winding order of all faces are consistent. A better idea than adjusting the near clip plane is to simply move the cube inside the view volume instead. Move it 1 or 2 units into the scene so that the Z-range becomes, say, 1 to 1.5 instead.
I tried that; still the same result. I'm puzzled to what else could cause this.
Perhaps the perspective matrix is similar to the one in gluPerspective where the Z-range is actually negative. A near and far clip plane parameter pair of 0.5 and 3.0 corresponds to a visible Z-range of -0.5 to -3.0.
Yes, that nailed it, I had to supply negative values. Thanks.

On a sidenote, what is the reason behind it?
That's the result of making the fairly arbitrary decision of using a bottom-left origin and a right-handed-based coordinate system; the negative Z-axis points into the screen.

This topic is closed to new replies.

Advertisement