Display NDC

So for an assignment, I need to have the option to show everything from the camera in NDC format, with objects farther from the camera being smaller.

I know that there is some way to do this by using a custom projection matrix (as opposed to loading the identity and using glFrustum), but I really am unsure where to go.

Some pointers would be greatly appreciated, I don’t need the work done for me, but I am bit stumped here.

What is “NDC format”?

Normalized Device Coordinates: the coordinates system right after the perspective division.

That’s said, I don’t understand much dzk87’s question.

dzk87: Are you looking for displaying the scene with the camera in it, like the illustration “Projection illustrates OpenGL projection and viewing transformations and clipping.” on this OpenGL course:

http://www.opengl.org/resources/code/samples/s2001/

Is so, the source code is available on the same page.

No, that’s not really it. You know how opengl takes the NDC version, performs the viewport transformation, and then thats what we see? I want to undo the viewport transformation, so that what gets shown is literally a cube, the NDC, rather then the pyramid shape.
Please note that I mean the viewing window should be a cube, not showing a cube.

You know how opengl takes the NDC version, performs the viewport transformation, and then thats what we see? I want to undo the viewport transformation, so that what gets shown is literally a cube, the NDC, rather then the pyramid shape.

That’s not how perspective projection works. The projection is accomplished by the transform to NDC space, not the viewport transform. The transformation to NDC space divides the coordinates by W, which is what makes the math for the perspective projection work.

What you seem to be asking for is an orthographic projection.

No, that is not it, I know.

http://www.songho.ca/opengl/gl_transform.html

This is the pipeline, right?

Window coordinates are what is shown, if I understand this right.

I want to show the step before that, the NDC version. In such a view, it woudld be a cube, rather then the pyramid.

I want to show the step before that, the NDC version. In such a view, it woudld be a cube, rather then the pyramid.

NDC space is [-1, 1] in X, Y and Z. So it is a cube. As is window space (technically, it is a rectangular parallelepiped).

Perspective projection is a way of transforming a frustum (or pyramid if you insist) into a cube. Using that diagram, perspective projection is done by the steps labeled “Projection Matrix” and “Divide by W”. This leads to NDC space which is a cube.

What you are asking for is the ability to not do perspective projection. And that means doing an orthographic projection.

Here is a more in-depth explanation of perspective projection.

I understand what you are saying, but doing an orthographic projection isn’t right. I can post a screenshot, but I need to retain the ability to scale what I am seeing. Will post some screenshots.

Here is some info. The right hand panel is a cube. The right side sliders alter this cube. The middle sliders alter the camera looking at the cube. The left side is look at the view volume looking at the cube…

This is the assignment info:

It’s also possible to draw the scene using normalized device coordinates. In this case, the view volume is projectively mapped to the cube at the origin with x,y,z in the range [-1,1], with the near plane at z=-1. In such a view, objects will appear distorted: geometry farther from the camera is smaller. This is a result of dividing the projective division: dividing each of x,y,z by w. It turns out it’s easy to do this in the OpenGL pipeline by just putting the appropriate matrix on the stack, and relying on the fact that OpenGL will divide by w later.

Implement a view of the normalized device coordinates (exactly how you do this is up to you). Make sure your clipping planes and wireframe cube still work, too! You’ll know when you get it right since when you draw the view volume, it will turn into a cube without any changes to your code to draw the view volume.

On another note, what is the proper term then for what acutally appears on my screen. I mean to go back ONE step from that, to the step right after the divide by w.

And one last note, is there any way that I can simply change the dimensions of the far clipping plane instead, so that the viewing frustum is a cube?

So you’re asking us to do your homework for you.

I will give you two hints, though.

1: There is nothing special about the projection matrix itself. It’s just another type of transformation matrix. You can do other transforms before and after it. So you can project into a space, then apply some transformation to the post-projection values. Oh, and remember that the order of transforms in OpenGL is reversed, so if you want to translate after the projection, you have to call glTranslate before glFrustum/gluPerspective.

2: The last matrix operation you have any control over happens before the division by W. However, due to the nature of homogenous math, you can actually continue to transform points by matrices after the multiplication by the perspective projection matrix. The projection will still work, but the division will still project the points in the plane that they were originally projected into.

Yes, I said it was homework at the start…
And I asked for pointers, not a solution :).

Thank you. I totally forgot to call the translate before the glFrustum, I was doing it after…

Bump. I have been working on this for quite awhile, trying different things, with no luck, so I am posting the relevant code, and hoping that somebody can tell me where it’s wrong.

gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
double w=((double) 2/width);
double h=((double) 2/height);
gl.glScaled(w,h,1);
gl.glTranslated((double)-width/2, (double)-height/2, 0);
gl.glFrustum(-1, 1, -1, 1, -1, 1);

So if I understand correctly, in order to “re-normalize” the coordinates, I need to reverse what is done during the viewport transformation, only ahead of time.

Since the original transformation was a scaling, then a translation, in regular order, I would do a translation, then a scaling. Since openGl does it backwards, I do the scale, then the translate, then call frustum.

Looks like you need to read this:

Generally speaking, you only put glLoadIdentity followed by glFrustum, gluPerspective, glOrtho, OR gluOrtho2D on the GL_PROJECTION matrix. The rest go on the GL_MODELVIEW matrix.

glFrustum and gluPerspective (which calls glFrustum) both load/multiply “perspective” projection transforms. While glOrtho and gluOrtho2D (which calls glOrtho) both load/multiply “orthographic” projection transforms.

Thanks for the info, but I understood that. I know it’s not the “proper” place to put it, but I that’s all code that only is run if they check a box. I was trying to manipulate the projection matrix.

I will try it out with manipulating the modelview matrix, but I am not sure if I can do this through that…