# my total matrix is missing something...

let’s say i want to find exactly where a point will project onto my window.

i generate my own projection matrix, and my own view matrix.

i figured something like:

Vector World( 0,0,0,1 );
Vector Screen = ViewMatrixProjectionMatrixWorld;

but my z translations are missing…

i know about normalized device coordinates, and that at this point z doesn’t matter, w does, and that w ranges [-1,1]…

my z is != 0, and w is huge…

what matrix am i missing… anybody?

I think the order in which you are multplying your matrices is incorrect. I think it should be like:

Vector Screen=ProjectionMatrixViewMatrixWorld;

Anyway, I don’t know if I understood exactly what you are looking for.

i’m doing some lod optimizations, where eventually i’m going to need to find the screen distance between two points, but first i have to find a single point, which is what i posted about.

all of the doc i’ve read on the ogl matrix multiplication is ordered modelview -> projection -> perspective division -> viewport, or modelview*projection, then what i’m not sure about.

at least the redbook, eberly, watt, haines, and ogl web page on transformations all say that’s the order…

also, i know that the matrices i’ve generated are correct, because i don’t call gluPerspective or glFrustum. I just call a glLoadMatrix for the projection matrix and the modelview matrix, and everything renders correctly.

what i’m doing to check here is taking a point, rendering it in a perspective state, then loading a -1x1 ortho projection, and redrawing it.

i’d assume that for a -1x1 ortho projection that the actual dimensions of the viewport would be irrelevant, but this seems to be where my problem is…

[This message has been edited by Succinct (edited 12-26-2000).]

If you mean that “ViewMatrix” is the model view matrix, then I can reassure you that the order of muliplication you mentioned above is incorrect, because if it was like you posted, i.e:

Screen=ViewMatrixProjectionMatrixWorld

then that means that “World” is getting multiplied with “ProjectionMatrix” befor it is multiplied with “ViewMatrix”, in other words, it’s getting projected “then” transformed ,which makes no sense.

Anyway it depends on how you imagine the matrix itself, in either way, the vector “World” should be multiplied with the model view matrix “first” then multiplied with the projection matrix:

with row vectors:

Screen=WorldViewMatrixProjectionMatrix

with column vectors:

Screen=ProjectionMatrixViewMatrixWorld

well, i’ve been trying it both ways, and it’s still not the same as gluProject, which is working, but is far to slow…

Can you post the code in which you are multiplying the two matrices and the vector, so that we can check it?

ok, i was a math minor, so they’re in column major format (i’m still working on my working, but unoptimized, implementation)

(i also replaced all of the [] used in array idexing to | | cuz the forum is getting mad at me and interpreting brackets around i…)

inline Matrix MultiplyMatrix( const Matrix& m1,const Matrix& m2 )
{
Matrix Product;
for( int i = 0; i < 4; i++ )
for( int j = 0; j < 4; j++ )
Product|i| |j| = m1|i| |0|*m2|0| |j|
+ m1|i| |1|*m2|1| |j|
+ m1|i| |2|*m2|2| |j|
+ m1|i| |3|*m2|3| |j|;

return Product;
}

inline Vector4d MultiplyMatrix( const Vector4d& v,const Matrix& m )
{
return Vector4d
(
float( v.xm|0| |0| + v.ym|0| |1| + v.zm|0| |2| + v.wm|0| |3| ),
float( v.xm|1| |0| + v.ym|1| |1| + v.zm|1| |2| + v.wm|1| |3| ),
float( v.xm|2| |0| + v.ym|2| |1| + v.zm|2| |2| + v.wm|2| |3| ),
float( v.xm|3| |0| + v.ym|3| |1| + v.zm|3| |2| + v.wm|3| |3| )
);
}

Vector3d Camera::TransformPoint( const Vector3d& v )
{
// return mProjectionMatrixmViewMatrixv;
// return mViewMatrixmProjectionMatrixv;

Vector3d p = mViewMatrixmProjectionMatrixv;
return Vector3d( p.x/p.w,p.y/p.w,p.z/p.w );
}

oh, i’m using screen coords to reduce geometrey, not for culling.

i don’t usually like just posting code and saying “hey, debug this for me, cuz i cant”, but this time you asked i just like to compare algorithms, in plain english, maybe pseudocode.

thx, though, softland… but i’m not sure its the code, and not cuz i’m suffering from the “i’m right” syndrome that plagues so many programmers, it’s just cuz the code works for me in other places.

i use the multiply matrix in composing my view matrix. first i generate a translation matrix for the -position of the camera, rotate to the camera’s orientation, then translate to the near plane. that stuff all works out

the only thing i can see is maybe my MultiplyMatrix( m1,m2 ) is actually performing m2*m1, but that’s easily fixed, and i can write around that if it wasn’t, but now thinking about it, the vector matrix function isn’t even being used in this program, but i just cut and pasted it from my old ray-tracing program, where it worked.

basically, what my question really is: what ogl does after it gets these coordinates, called clip coordinates, i believe. ogl says that all the axis coords should be in the range [-1,1], but i’m not sure what w should be. shouldn’t z be 0 here? well, -(1,1,1) <= (x,y,z) <= (1,1,1), z != 0, w is large and positive

i know that next is the transformation to Normalized device coords, and that’s performed by dividing by w, but right now w is around 500… it’s making x and y very close to 0, cuz [-1,1]/500 = [-1/500,1/500]

man, i hope it’s the code, cuz that’s easier to fix!

thx again, softland

[This message has been edited by Succinct (edited 12-28-2000).]

I’m sorry for not replying soon, but I have some exams and I was experiencing some weird problems with my modem that kept me unconnected for a while. Anyway, I don’t know what’s the real problem in your code, that’s if there are any. However I want to make sure of 3 things:

1. How can you write p = mViewMatrixmProjectionMatrixv?
did you override the * operator? If so, are you sure how C is determining their precedence?
2. Are you sure that
Vector3d Camera::TransformPoint( const Vector3d& v )
is correct and that it shouldn’t be
Vector3d Camera::TransformPoint( const Vector4d& v )
3. Are you sure that
Vector3d p = mViewMatrixmProjectionMatrixv
is correct and that it shouldn’t be
Vector4d p = mViewMatrixmProjectionMatrixv

I’m sorry, but I’m a Delphi programmer and my experience with C is not as good. Anyway, I don’t know if you made some mistakes while you were posting the code.

it’s c++, and i overrided the * operator.

it evaluates from left to right, and that’s the same as

(v*mViewMatrix)*mProjectionMatrix

the parameters are supossed to be 3d, cuz w is just 1, but yeah, p is 'spossed to be 4d. i just wrote that off the top of my head, cuz i deleted it before i decided to put it in the post good eyes.

i’m just curious what ogl does after the projection, but before the viewport scaling.

i dunno, is the source for glu open? like gluUnproject? /that/ works…

p.s., thx again, softland, no one’s ever seemed this interested in my coding questions

You’re welcome

If the parameter of the last function is 3D, how can you pass it to the function MultiplyMatrix, which uses the w component?

I’m sorry, maybe my replies don’t satisfy you but “your problem doesn’t seem to float on the surface” so I’m trying to figure out what’s wrong.

As for your other question I can’t answer you because I’m not quite sure.

[This message has been edited by softland_gh (edited 01-02-2001).]

Hi

1. something about matrix multiplication :
the right order to execute the multiplications is:
ModelViewMatrixv = v1
ProjectonMatrix
v1 = v2
which may be written so:
v2 = ProjectionMatrix*(ModelViewMatrixv)
but the matrix mults are associative:
(A
B)C = A(BC), which means that
you can also write v2 = (ProjectionMatrix
ModelViewMatrix)v
and the result is same (a fine optimisation is to compute TransfomMatrix = ProjectionMatrix
ModelVeiwMatrix when you get them and then to calc v2 = TransformMatrix*v; this will spare one matrix mult which is not so fast anywhere…
I’m not sure, but I think that your code doesn’t make the multiplications in this order. Please check it
2. You must also count one last tranformation: glViewport() which is applied over the vector v2 to get the (X,Y) window coords.
you must apply the same transform too… (see glViewport() info in MSDN for the correct expressions…)

One thing more:
the matrix mults are NOT comutative, which means that AB != BA (in the most cases