Jump to content
  • Advertisement
Sign in to follow this  

Annoying problem with perspective projection

This topic is 2651 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been trying to figure this out forever!! I've got a small cross-like shape that I am drawing to the screen perfectly fine using a VBO and index buffer. When I don't use any projection matrix at all the cross shows up perfectly fine. When I use a perspective matrix the cross disappears entirely. Even stranger, when I use a simple orthogonal projection the cross becomes a tiny spec, and only returns when I upscale the model matrix by about 200x. I've tried various tutorials and examples and nothing I try to fit into what I've got so far works in MY demo.

Relevant code:

VBO / Index data

struct Vertex {
GLfloat XYZW[4];
GLfloat RGBA[4];

//create some data for the vbo
Vertex Vertices[] =
{ { 0.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
// Top
{ { -0.2f, 0.8f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } },
{ { 0.2f, 0.8f, 0.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } },
{ { 0.0f, 0.8f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f, 1.0f } },
{ { 0.0f, 1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } },
// Bottom
{ { -0.2f, -0.8f, 0.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } },
{ { 0.2f, -0.8f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } },
{ { 0.0f, -0.8f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f, 1.0f } },
{ { 0.0f, -1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } },
// Left
{ { -0.8f, -0.2f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } },
{ { -0.8f, 0.2f, 0.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } },
{ { -0.8f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f, 1.0f } },
{ { -1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } },
// Right
{ { 0.8f, -0.2f, 0.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } },
{ { 0.8f, 0.2f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } },
{ { 0.8f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f, 1.0f } },
{ { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } }

//create some indices
unsigned int Indices[] = {
// Top
0, 1, 3,
0, 3, 2,
3, 1, 4,
3, 4, 2,
// Bottom
0, 5, 7,
0, 7, 6,
7, 5, 8,
7, 8, 6,
// Left
0, 9, 11,
0, 11, 10,
11, 9, 12,
11, 12, 10,
// Right
0, 13, 15,
0, 15, 14,
15, 13, 16,
15, 16, 14

How I create my projection matrix

void Renderer::enableProjectionMode(ProjectionMode _mode) {
switch(_mode) {
case Perspective:
myProjectionMatrix = glm::perspective(
(float)myViewportDimensions.x / (float)myViewportDimensions.y,
-1.0f, 100.0f);
case Orthogonal:
myProjectionMatrix = glm::ortho(
-myViewportDimensions.x / 2, myViewportDimensions.x / 2,
myViewportDimensions.y / 2, -myViewportDimensions.y / 2,
-1.0f, 1.0f);

myProjectionMode = _mode;

How I update the matrices in the shaders
myProgram->setUniformMatrix4fv("ProjectionMatrix", 1, false, &myProjectionMatrix[0][0]); //these are all just simple wrappers, they do the same thing as the underlying GL calls
myProgram->setUniformMatrix4fv("ModelMatrix", 1, false, &myModelMatrix[0][0]);
myProgram->setUniformMatrix4fv("ViewMatrix", 1, false, &myViewMatrix[0][0]);

I can post the shaders if it really is necessary, but they're unbelievably simple. You could probably guess the contents biggrin.gif

Am I missing something in the above that's causing the projection matrix to not be created correctly? I've been looking for hours and can't find a single thing.

Share this post

Link to post
Share on other sites
The coordinates you specified are in pixels, when using a standard orthogonal matrix.
That means the object is barely a pixel wide. Of course it is going to be a tiny spec. Fix the coordinates or add a scaling matrix.

Using a perspective matrix can cause the vertex winding to change. Disable back-face culling to be sure.
It also causes the camera to look down -Z. Most likely your cross is behind the camera.

L. Spiro

Share this post

Link to post
Share on other sites
You can't just use fundamentally different projection types and expect similar behavior. You have fundamentally different projection matrices, and you get fundamentally different results; that is exactly what is expected to happen. You need to understand what each projection matrix really represent, and how it interacts with your scene. Let's go over your three cases:

I am, for simplicity, going to assume the model and view matrices are not set, unless otherwise stated in my points below.
  1. No projection matrix. This is equivalent to having a visible coordinate system which ranges from -1 to 1 along all three axes. So, covering your viewport is a coordinate system ranging from -1 to 1 on all axes, and your cross is on this scale as well. That's fine, the cross covers roughly the whole visible coordinate system, and consequently it will also cover roughly the whole viewport when drawn. What you get is a big cross.
  2. Orthographic projection. You set the visible coordinate system to range from -viewport/2 to viewport/2, probably meaning that each unit now exactly corresponds to a pixel. Your cross is on the order of 2 units, and since each unit covers one pixel, your cross will be on the order of 2 pixels when drawn.
  3. Perspective matrix. Let's assume, for simplicity of calculation, that your field of view is 90 degrees, and that the aspect ratio is 1; your reality is most likely not going to affect this reasoning to any greater extent if the values are not correct. First of all, having a near plane value of -1 may be accepted as a value itself in the particular formulas, but it doesn't make any sense mathematically. It has to be greater than zero. But let's assume you're setting the near plane to 1 instead and that there are no other transformations in the model and the view matrices. The object is then centered at Z=0, but the visible depth range is from -1 to -100, so no object is not visible at all.
    You therefore need to translate the object along the negative Z-axis. Let's say you translate it by -1 so it ends up on the near plane. It will the, with a FOV of 90 degrees, cover most of the viewport. Why? At 90 degrees, and a near plane to 1, means that at Z=-1, the visible X- and Y-axes range from -1 to 1. Your cross is on that scale, just like in the first point above, and is drawn large. Translate it to Z=-2 instead, and the visible X- and Y-axes on that depth is from -2 to 2; your cross is still the same size, but the visible coordinate range is twice as large, so your cross appears with half its size as it did at X=-1. Just like perspective is meant to do, the object becomes smaller the further away it is.
Three entirely different projections, three entirely different results. You cannot just swap matrices that are fundamentally different, nor matrices of the same type but with vastly different parameters, and expect comparable behavior. You did change the matrices, and the results were fundamentally different every time; nothing strange at all with that.

You need to read up on what the different matrices offer, and how they work. See the forum FAQ and look for a link to the Red Book for example. It has an interesting chapter on viewing.

Share this post

Link to post
Share on other sites
Oh man you guys are the best! I probably should have waited till the morning as it was late when I originally asked the question and didn't think it through properly. I've taken classes on this stuff at school and BELIEVE that I understand how projection matrices can differ, but I didn't recognize the error in having my perspective near-plane set to a negative. Changing that -1 to a 1 solved all of my problems.


Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!