PDA

View Full Version : Need Matrix Math to work correctly



TamusRoyce
08-07-2003, 10:22 PM
I've tired many ways of getting matrix math to do what I need it to do, and all ways have failed. I have posted a previous message because of this problem (I just though it was another problem). I can't get OpenGL's Projection Matrix to function like I need it under C++...

What I want is a matrix set up as so:
{2.0f/ScreenWidth, 0.0f, 0.0f, 0.0f,
0.0f, 2.0f/ScreenHeight, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1/Depth,
-1.0f, -1.0f, -1.0f, 0.0f};

but 1/Depth changes to z/depth, and then is multiplied through with depth/z. I want z/depth to multiply though. Is this a bug in which OpenGL was built upon?

Thus,

NewX = ((2.0f / ScreenWidth - 1.0f) * x) *
(Depth / z);
NewY = ((2.0f / ScreenHeight - 1.0f) * y) *
(Depth / z);

Instead of what I want, which is:

NewX = ((2.0f / ScreenWidth - 1.0f) * x) *
(z / Depth);
NewY = ((2.0f / ScreenWidth - 1.0f) * y) *
(z / Depth);

percent = z / depth;
garbage = depth / z;

Any help in flipping z with Depth in this equation would be most helpful. I can't do anything with OpenGL unless I can set it up in a way that I can use, and with this equation I want, I am able to convert 3D points on the screen into there 2D points and 2D /w z value into 3D points. Cad like calculations (and like actually getting info from OpenGL w/out using OpenGL functions).

This is my most desprate question I have ever had with programming. This stupid equation has almost made me give up programming all together... Hobbies should be fun, not frustrating. Thanks for reading my problem.

Deiussum
08-08-2003, 05:02 AM
I'm not quite sure what you are trying to achieve here, but maybe an explanation of what the PROJECTION matrix does will help.

Basically, the PROJECTION matrix creates a transformation, whereby all visible values will be within a 1x1x1 cube. These values are then caculated into screen coordinates based upon the glViewport settings.

Also, not quite sure if you have your matrix displayed in column-major or row-major order, but your calculations seem off given the matrix you describe. It would actually be something like:

newX = x*2.0f/ScreenWidth + y*0 + z*0 + w*0 = x*2.0f/ScreenWidth;
newY = x*0 + y*2.0f/ScreenHeight + z*0 + w*0 = y*2.0f/ScreenHeight;
newZ = x*0 + y*0 + z*0 + w*1/Depth = w/Depth;
newW = x*-1 + y*-1 + z*-1 + w*0 = -x - y - z;

Or if you have your matrix described the other way:
newX = x*2.0f/ScreenWidth + y*0 + z*0 + w*-1 = x*2.0f/ScreenWidth - w;
newY = x*0 + y*2.0f/ScreenHeight + z*0 + w*-1 = y*2.0f/ScreenHeight - w;
newZ = x*0 + y*0 + z*0 + w*-1 = -w;
newW = x*0 + y*0 + z*1/Depth + w*0 = z/Depth;

The technical FAQ (http://www.opengl.org/developers/faqs/technical/transformations.htm#tran0005) can possibly explain a bit better than I can about how OpenGL expects the matrices to be laid out in memory.

Edit: Fixed matrix calculations. I think they are right now.

Note: If the order you show your matrix above is the order it is in your array, the second set of calculations will apply.

Edit: Fixed them again... had the wrong calculation for z, and added calculations for w.

Note that since x = x/w, y = y/w, etc... and your w is z/Depth, x will end up being x/z/Depth or x * Depth/z.

[This message has been edited by Deiussum (edited 08-08-2003).]

TamusRoyce
08-08-2003, 07:20 AM
I know that's how the matrix works, exept that it took me day's upon day's to relize that NewW inverse is multiplied my NewX, NewY, NewZ, and NewW so that NewW = 1. I just need to know how to get

NewW = Depth / z;

rather than,

NewW = (1 / Depth) * z;

before it is multiplied through the matrix by its inverse. It always turns up being:
NewX = x * Recipical(z / Depth);
NewY = y * Recipical(z / Depth);
I want
NewN = N * Recipical(Depth / z);

I still can't find any help on how to do this. There must be a way so that I can have a mathmatical way of computing my coordinate system, instead of just doing what looks good. Why does everyone base there graphics on what looks good?

NewX = x * z / depth;
NewY = y * z / depth;

(z / depth)is a percentage which does nothing but perfectly zoom x and y so that the larger z is, the smaller of a square, centered, that you can draw on. Each Increase and Decrease of z would add or subtract 1 pixel on each side of the centered square you have to draw on.

Deiussum
08-08-2003, 10:50 AM
I don't know what exactly you mean by "just doing what looks good," but unless there is some special effect you are going for, there is absolutely nothing wrong with glFrustum, gluPerspective, glOrtho, and gluOrtho2D.

With that being said, I don't think there is any way of doing what you want. You would have to change the properties of vector/matrix multiplication. The newW value is always going to be x*m41 + y*m42 + z*m43 + w*m44. (Or m14, m24, m34, m44, I never remember what the exact notation is.) In order to do what you want, you'd need the z*m43 to change to z/m43.

About the only way that it might be possible, is if you changed 1/Depth to Depth, and for all your Vertex data use 1/z instead of z.


[This message has been edited by Deiussum (edited 08-08-2003).]

TamusRoyce
08-15-2003, 03:44 PM
Thanks. I've came to the same conclusion as well. I'm not really looking for a special effect, but rather a 2D tile rendering system that decreases pixel by pixel as the z buffer decreases. I aslo wanted
Transelate(); and Rotate(); to manipulate the system. I've learned a lot about OpenGL just by researching my own questions, along with your advice. Thanks for all the help you've given...

adams_antics
08-15-2003, 04:57 PM
Originally posted by TamusRoyce:
This is my most desprate question I have ever had with programming. This stupid equation has almost made me give up programming all together... Hobbies should be fun, not frustrating. Thanks for reading my problem.

programming is harder to quit than drugs. and the best part about programming is getting the frustrating things to work.