[QUOTE=Cubby208;1266615]@AlfonseReinheart
Thanks for the reply! My problem is that I need to change the camera position and not use orthographic projections. This is because it is a 3d platformer.[/QUOTE]
You’re drawing the UI; it doesn’t matter if it’s a 3D platformer, FPS, RTS, or whatever other genre you want. Unless you’re placing the UI in the world somewhere (like the inside of a visor), the UI generally stays put. The camera moves, but the UI doesn’t.
Unless you want the UI to interact with the world (and considering that you said specifically you wanted it on top of everything, that seems unlikely), then the matrix the world is transformed with is irrelevant. As are camera positions and so forth.
You said earlier that “I suppose I really don’t understand the transformation pipeline,” which seems to be part of the problem. Fortunately, you’re using shaders, so at least you’re aware of some of what’s going on.
Specifically, you’re aware of gl_Position
. You know that you need to write something to this value in order to get triangles. And you know that you generate that value by transforming positions (taken from input values).
What you don’t seem to understand is exactly what gl_Position
means. gl_Position
is the position of that vertex in what is called “clip-space”.
I’m going to lie to you right now about what clip-space looks like. I’m lying because the truth will only confuse you, but I want you to know first that I’m lying.
Think of clip-space as a region of space that goes from -1.0 to 1.0 on all three sides. So it’s a cube, centered around the origin. Again, that’s a lie, and I’ll explain the truth at the end, but it’s a useful lie.
So the “world” of clip-space is just a cube. You’re probably wonder where the camera comes in. Well… it doesn’t. The camera is a fiction created by you in your transformation process.
Think about it from a relativistic point of view. You can think of a camera moving through a fixed world. Or you can think of it as the world moving around a fixed camera. However egocentric that last notion may be, that’s how it works in rendering. The camera is just a trick you played on the world by transforming it into a region of space in front of a fixed camera.
There is no camera in clip-space; every triangle that lies at least partially within the clip-space cube will be rendered. Everything that happens to lie outside of that cube will not be rendered.
Anyway, my point is this. OpenGL doesn’t care about how you generated the vertices in gl_Position
. You could use a camera matrix to generate it or not. As far as OpenGL is concerned, one gl_Position
is no better than another.
Because the camera is a fictional construct defined by you, if you want to have an object that remains at a position relative to the camera, all you have to do is not pass it through the various transformations that you used for the rest of the world. gl_Position
is naturally camera-local; it’s all of those tricks that you do in your vertex shader that makes it seem like it’s not.
So you don’t need to transform your UI elements to be relative to your camera. Just don’t do any camera or world stuff with your UI elements at all. That’s why it’s OK to transform them with an orthographic projection instead of a perspective one. In clip-space, OpenGL does not care. Again, one gl_Position
is no better than another. As long as it is within the box, it’s fine.
Go ahead and try it out. Generate a quad who’s positions are the square (0, 0), (1, 1) in XY, with a Z coordinate of 0. Render this quad as a white square, and do no transformations on the positions. Have your shader simply do this: [var]gl_Position = vec4(in_pos.xyz, 1.0);[/var]. Turn off depth testing too.
I guarantee you that you’ll see a white square covering the top-right portion of the screen. No matter what you do with your camera, it’ll stay in the top-right portion of the screen.
The Truth
OK, clip space is not actually a [-1, 1] box. It’s actually a [-Wc, Wc] box, where Wc is the W component of gl_Position
. Yes, I know that sounds very odd, since Wc is part of the clip-space position, and yet I just said that it defines the extents of that space. Also, different positions of the same triangle will have different Wc coordinates. Which makes it even harder to visualize.
That’s why I didn’t want to talk about it; it muddles the main issue, which is that gl_Position
is already relative to the camera.