Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

matrix decomposition back to eye, direction and up?

172 views
Skip to first unread message

Toby Douglass

unread,
Nov 7, 2009, 3:52:41 PM11/7/09
to
Hi -

Given a matrix, as passed to glLoadMatrixf() in GL_MODELVIEW, is it in
theory possible to derive from that matrix the x,y,z of the eye,
direction of view and up?

My aim is to take the matrix (I'm intercepting it via a DLL wrapper),
extract the eye, direction and up, modify the eye position and recompose
the matrix before passing it on.

fungus

unread,
Nov 8, 2009, 6:02:00 PM11/8/09
to
On Nov 7, 9:52 pm, Toby Douglass <a...@b.com> wrote:
> Hi -
>
> Given a matrix, as passed to glLoadMatrixf() in GL_MODELVIEW, is it in
> theory possible to derive from that matrix the x,y,z of the eye,
> direction of view and up?
>

Not only possible in theory, possible in practice!!

> My aim is to take the matrix (I'm intercepting it via a DLL wrapper),
> extract the eye, direction and up, modify the eye position and recompose
> the matrix before passing it on.


Look at the rows of the top-left 3x3 part of
the matrix...they're your three 'axis' vectors.

--
<\___/>
/ O O \
\_____/ FTB.

Jonathan Campbell

unread,
Nov 9, 2009, 6:40:24 AM11/9/09
to

And a simple concrete example:

glMatrixMode(GL_MODELVIEW);
glLoadIdentity ();
matPrint(GL_MODELVIEW_MATRIX, "GL_MODELVIEW_MATRIX 0");

eye[0] = 0.0; eye[1] = 0.0; eye[2] = 1.0;
gluLookAt(eye[0], eye[1], eye[2], // camera centre
0.0, 1.0, 0.0, // pointing AT
0.0, 1.0, 0.0); // up vector

matPrint(GL_MODELVIEW_MATRIX, "GL_MODELVIEW_MATRIX 1");

GL_MODELVIEW_MATRIX 0
[( 1, 0, 0, 0)
( 0, 1, 0, 0)
( 0, 0, 1, 0)
( 0, 0, 0, 1)
]

GL_MODELVIEW_MATRIX 1
[( 1, 0, 0, 0)
( 0, 0.7071, 0.7071, -0.7071)
( 0, -0.7071, 0.7071, -0.7071)
( 0, 0, 0, 1)
]

The last column is the camera centre transformed to the new axes. The
top left 3 x 3 matrix is a rotation about the x-axis --- or, as fungus
says, the rows of it give the new axes.

Best regards,

Jon C.

--
Jonathan Campbell www.jgcampbell.com BT48, UK.

Toby Douglass

unread,
Nov 9, 2009, 1:20:07 PM11/9/09
to
jg.camp...@gmail.com wrote:
> fungus wrote:
> > On Nov 7, 9:52 pm, Toby Douglass <a...@b.com> wrote:

[snip]

Thank you both, very much, for your explanations.

Things have however taken an utterly bizzare turn, which make my
question obsolete.

As I mentioned, I've written a wrapper DLL. I log all the OpenGL
function calls. I have today implemented support for logging calls toe
extensions, but I've not populated that support.

I'm working to understand the co-ordinate system in use by a game, so I
can modify the eye position of the viewer; I thought there might be a
call to gluLookAt() or something similar, and I could change the eye co-
ordinates in the wrapper.

Well, turns out, the game goes to GL_MODELVIEW mode and simply calls
glLoadMatrixf() - it directly sets the matrix.

What's more, as far as I can tell, there are no calls to things like
glTranslate(), glScale(), etc...

I'm not familiar enough with OpenGL to know what's going on; I'm
guessing, though, obviously, there are other ways of doing these things
and the game is using them.

I wonder if the extensions are doing a lot of this work, somehow, which
is why today I've implemented support for logging them.

Now, the bizzare twist - the game has three diffrent matrixes which it
passes into GL_MODELVIEW. As far as I can tell, one of them represents
the avatars modelview (one of them, I'm pretty sure, is for the overlaid
GUI of buttons and controls and status information and the like; the
other, I'm not sure about).

What I have found, to my utter shock, is that if I do NOT pass that
avatar matrix down - e.g. I return in the wrapper DLL, without calling
the real function - THE GAME CONTINUES TO BEHAVE AS NORMAL.

At this point, I'm in uncharted territory. Why would the game bother
passing this matrix down, if it does nothing? and indeed, it does so
fairly often!

So I'm going to log the extensions and see if I can figure out what's
going on. Any suggestions incredibly gratefully received!

Marcel Heinz

unread,
Nov 9, 2009, 2:54:20 PM11/9/09
to
Hi,

Toby Douglass wrote:
> jg.camp...@gmail.com wrote:
>> fungus wrote:
>> > On Nov 7, 9:52 pm, Toby Douglass <a...@b.com> wrote:
>
> [snip]
>
> Thank you both, very much, for your explanations.
>
> Things have however taken an utterly bizzare turn, which make my
> question obsolete.
>
> As I mentioned, I've written a wrapper DLL. I log all the OpenGL
> function calls. I have today implemented support for logging calls toe
> extensions, but I've not populated that support.

There are already projects like GLIntercept or chromium which can do
this task. IIRC, mesa also has some #defines somewhere in the code which
can turn it into a GL logger easily.

> I'm working to understand the co-ordinate system in use by a game, so I
> can modify the eye position of the viewer; I thought there might be a
> call to gluLookAt() or something similar, and I could change the eye co-
> ordinates in the wrapper.

gluLookAt() isn't a GL function anyways. You might intercept GLU functions
too, but there is no point in doing so, as you have to handle the
underlying GL matrix manipulation functions in any case.

>
> Well, turns out, the game goes to GL_MODELVIEW mode and simply calls
> glLoadMatrixf() - it directly sets the matrix.
>
> What's more, as far as I can tell, there are no calls to things like
> glTranslate(), glScale(), etc...

There is no need to. Your game is carrying out these matrix
multiplications without the help of GL. This is what you should expect
from any sophisticated application, as these matrices are usually needed
also for a huge number of other tasks like culling, collsion dectection,
character animation etc. It would be a waste of time to let OpenGL
recalculate these very same matrices again.

> I'm not familiar enough with OpenGL to know what's going on; I'm
> guessing, though, obviously, there are other ways of doing these things
> and the game is using them.

Simply specifying the correct matrices is enough. However, if you are
looking for something like world coordinates, things get a bit messy, as
GL does not explicitely manage a world coordinate frame. MODELVIEW
brings you from object space to eye space. I've done such things as
guessing a world coordinate frame by identifying geometry blocks and
following their transformation state over different frames to approximate a
camera postion in world coordinates by finding the largest group of
objects which where tansformed identically, but this is more or less a
hack which works only in certain situations (it assumes a large number
of static objects to "define" the world frame).

> I wonder if the extensions are doing a lot of this work, somehow, which
> is why today I've implemented support for logging them.

Speaking of extensions, things will become really ugly if the app is using
shaders and isn't so nice to use the standard MODELVIEW and PROJECTION
matrices. In theory, you can still intercept the shader code and all
uniforms/attributes, but...

> Now, the bizzare twist - the game has three diffrent matrixes which it
> passes into GL_MODELVIEW. As far as I can tell, one of them represents
> the avatars modelview (one of them, I'm pretty sure, is for the overlaid
> GUI of buttons and controls and status information and the like; the
> other, I'm not sure about).
>
> What I have found, to my utter shock, is that if I do NOT pass that
> avatar matrix down - e.g. I return in the wrapper DLL, without calling
> the real function - THE GAME CONTINUES TO BEHAVE AS NORMAL.
>
> At this point, I'm in uncharted territory. Why would the game bother
> passing this matrix down, if it does nothing? and indeed, it does so
> fairly often!

Well, I can't tell what your game might be doing.

Regards,
Marcel

--
Marcel Heinz | <marcel...@informatik.tu-chemnitz.de> | PGP-KeyID: E78E9442

"Perfection is attained not when there is nothing more to add,
but when there is nothing more to remove." -- Antoine de Saint-Exup�ry

Toby Douglass

unread,
Nov 9, 2009, 3:25:18 PM11/9/09
to
marcel...@informatik.tu-chemnitz.de wrote:
> Toby Douglass wrote:

> > As I mentioned, I've written a wrapper DLL. I log all the OpenGL
> > function calls. I have today implemented support for logging calls toe
> > extensions, but I've not populated that support.
>
> There are already projects like GLIntercept or chromium which can do
> this task. IIRC, mesa also has some #defines somewhere in the code which
> can turn it into a GL logger easily.

Yes. However, I wanted to write a DLL wrapper, since I've not done one
before.

> > I'm working to understand the co-ordinate system in use by a game, so I
> > can modify the eye position of the viewer; I thought there might be a
> > call to gluLookAt() or something similar, and I could change the eye co-
> > ordinates in the wrapper.
>
> gluLookAt() isn't a GL function anyways. You might intercept GLU functions
> too, but there is no point in doing so, as you have to handle the
> underlying GL matrix manipulation functions in any case.

Indeed - I realised after I posted (I went to the gym) that what I had
written left this question open. I have also written a GLU wrapper.
The game actually makes *no* GLU calls at all.

> > Well, turns out, the game goes to GL_MODELVIEW mode and simply calls
> > glLoadMatrixf() - it directly sets the matrix.
> >
> > What's more, as far as I can tell, there are no calls to things like
> > glTranslate(), glScale(), etc...
>
> There is no need to. Your game is carrying out these matrix
> multiplications without the help of GL. This is what you should expect
> from any sophisticated application, as these matrices are usually needed
> also for a huge number of other tasks like culling, collsion dectection,
> character animation etc. It would be a waste of time to let OpenGL
> recalculate these very same matrices again.

That sounds reasonable.



> > I'm not familiar enough with OpenGL to know what's going on; I'm
> > guessing, though, obviously, there are other ways of doing these things
> > and the game is using them.
>
> Simply specifying the correct matrices is enough. However, if you are
> looking for something like world coordinates, things get a bit messy, as
> GL does not explicitely manage a world coordinate frame. MODELVIEW
> brings you from object space to eye space.

I'm inexperienced enough with OpenGL to not sure what's meant by what
you've written.

My understanding is that GL_MODELVIEW is the mechanism by which one
positions and points the 'camera'; the matrix moves and points the eye
location.

> I've done such things as
> guessing a world coordinate frame by identifying geometry blocks and
> following their transformation state over different frames to approximate a
> camera postion in world coordinates by finding the largest group of
> objects which where tansformed identically, but this is more or less a
> hack which works only in certain situations (it assumes a large number
> of static objects to "define" the world frame).

My expectation is that the game is using metric units, probably with 1mm
as the smallest unit. I don't need to know more than that, since the
eye adjustment is relative to the current position; I merely need to add
an offset to bring the OpenGL eye position. My thought was to take the
modelview matrix and glTranslate() it.

> > I wonder if the extensions are doing a lot of this work, somehow,
which
> > is why today I've implemented support for logging them.
>
> Speaking of extensions, things will become really ugly if the app is using
> shaders and isn't so nice to use the standard MODELVIEW and PROJECTION
> matrices. In theory, you can still intercept the shader code and all
> uniforms/attributes, but...

Oy vey :-) well, I'll see what I get when I've populated the extension
functions.

> > Now, the bizzare twist - the game has three diffrent matrixes which it
> > passes into GL_MODELVIEW. As far as I can tell, one of them represents
> > the avatars modelview (one of them, I'm pretty sure, is for the overlaid
> > GUI of buttons and controls and status information and the like; the
> > other, I'm not sure about).
> >
> > What I have found, to my utter shock, is that if I do NOT pass that
> > avatar matrix down - e.g. I return in the wrapper DLL, without calling
> > the real function - THE GAME CONTINUES TO BEHAVE AS NORMAL.
> >
> > At this point, I'm in uncharted territory. Why would the game bother
> > passing this matrix down, if it does nothing? and indeed, it does so
> > fairly often!
>
> Well, I can't tell what your game might be doing.

What an anti-climax! ;-)

Toby Douglass

unread,
Nov 9, 2009, 3:57:14 PM11/9/09
to
a...@b.com wrote:
> Now, the bizzare twist - the game has three diffrent matrixes which it
> passes into GL_MODELVIEW. As far as I can tell, one of them represents
> the avatars modelview (one of them, I'm pretty sure, is for the overlaid
> GUI of buttons and controls and status information and the like; the
> other, I'm not sure about).

The other appears to be for the pointer! :-)

Toby Douglass

unread,
Nov 9, 2009, 4:46:21 PM11/9/09
to
a...@b.com wrote:
> > Well, I can't tell what your game might be doing.
>
> What an anti-climax! ;-)

I note now also that glBegin() is not being called.

My current guess is that if glLoadMatrixf() in GL_MODELVIEW can be
safely ignored, then it must be that at some later point, perhaps in an
extension, that modeview is again being set.

Hmm.

If a function in a wrapped DLL calls a function in that wrapped DLL
(e.g. an OpenGL extension calls an OpenGL function), will that call pass
through the wrapper DLL, or will it have been compiled to directly use
code in the wrapped DLL?

I think in my logs I see OpenGL functions calling OpenGL functions, so
I'm thinking not, but if it is so, it might be an explanation - there
would be additional calls which I'm not seeing.

Marcel Heinz

unread,
Nov 9, 2009, 4:47:10 PM11/9/09
to
Hi,

Toby Douglass wrote:
>
> My understanding is that GL_MODELVIEW is the mechanism by which one
> positions and points the 'camera'; the matrix moves and points the eye
> location.

Yes and no. Many people like to think in a world coordinate frame where
the objects (model transformation) and the camera are placed (view
transformation). The modelview matrix contains both, hence the name.

> My expectation is that the game is using metric units, probably with 1mm
> as the smallest unit.

Well, units are a different cup of coffee.

> I don't need to know more than that, since the
> eye adjustment is relative to the current position; I merely need to add
> an offset to bring the OpenGL eye position. My thought was to take the
> modelview matrix and glTranslate() it.

A relative eye offset is very easy to achieve. Especially, you won't
need a world frame for that, eye space is perfect. But keep in mind that
you (most likely) want to _pre_multiply the translation. As a nice side
effect, all you have to intercept is LoadMatrix and LoadIdentity, as the
rest of the GL matrix functions won't undo this change. (As long as the
application doesn't do weird things like querying the current matrices
and correcting any differences to the expected values by another
multiplication... ;)

Toby Douglass

unread,
Nov 9, 2009, 4:57:23 PM11/9/09
to
marcel...@informatik.tu-chemnitz.de wrote:
> Toby Douglass wrote:

> > My understanding is that GL_MODELVIEW is the mechanism by which one
> > positions and points the 'camera'; the matrix moves and points the eye
> > location.
>
> Yes and no. Many people like to think in a world coordinate frame where
> the objects (model transformation) and the camera are placed (view
> transformation). The modelview matrix contains both, hence the name.

I think when you and people in general say 'contains both', you mean in
the sense that the transformation being done can be thought of as being
done to the camera, or being done to the world (the models); is that
what you mean?

For example, if I translate my camera (-5, -5, 0), it's exactly the same
as translating the world (5, 5, 0). I could in fact do both - move the
camera and move the world, hence - modelview contains both.

> > I don't need to know more than that, since the
> > eye adjustment is relative to the current position; I merely need to add
> > an offset to bring the OpenGL eye position. My thought was to take the
> > modelview matrix and glTranslate() it.
>
> A relative eye offset is very easy to achieve. Especially, you won't
> need a world frame for that, eye space is perfect. But keep in mind that
> you (most likely) want to _pre_multiply the translation.

Yes, I think so, too, which would mean decomposing what I receive in
glLoadMatrixf(). Well - if the game was using it at all, which it
appears not to be =-)

> As a nice side
> effect, all you have to intercept is LoadMatrix and LoadIdentity, as the
> rest of the GL matrix functions won't undo this change.

Ah, cunning. You imply I set my translation in LoadIdentity, when I
know the caller is clearing the matrix for the modelview that I want to
modify? this of course saves me having to decompose what I receive in
LoadMatrix.

> (As long as the
> application doesn't do weird things like querying the current matrices
> and correcting any differences to the expected values by another
> multiplication... ;)

Heh. Which it may! although it may not, too - I'm actually very
surprised it hasn't taken steps to defend itself from the DLL wrapping
I'm doing - I'm certain the application should be able to detect that it
is occurring.

Marcel Heinz

unread,
Nov 9, 2009, 5:09:47 PM11/9/09
to
Hi again,

Toby Douglass wrote:
> a...@b.com wrote:
>> > Well, I can't tell what your game might be doing.
>>
>> What an anti-climax! ;-)
>
> I note now also that glBegin() is not being called.

This isn't too unlikely. glBegin() has even been deprecated/removed
in the newest GL versions. You might consider learning some GL and computer
graphics basics before trying to do such an GL interceptor.

> My current guess is that if glLoadMatrixf() in GL_MODELVIEW can be
> safely ignored, then it must be that at some later point, perhaps in an
> extension, that modeview is again being set.

This sounds rather unlikely.

> Hmm.
>
> If a function in a wrapped DLL calls a function in that wrapped DLL
> (e.g. an OpenGL extension calls an OpenGL function), will that call pass
> through the wrapper DLL, or will it have been compiled to directly use
> code in the wrapped DLL?

This has nothing to do with GL at all. You might ask this kind of stuff
in some windows programming group.

Toby Douglass

unread,
Nov 9, 2009, 6:07:12 PM11/9/09
to
marcel...@informatik.tu-chemnitz.de wrote:
> Toby Douglass wrote:

> > I note now also that glBegin() is not being called.
>
> This isn't too unlikely. glBegin() has even been deprecated/removed
> in the newest GL versions.

Gosh - that's quite a change.

> You might consider learning some GL and computer
> graphics basics before trying to do such an GL interceptor.

My thought entirely. I'm currently re-reading the OpenGL red book.
I've done some OpenGL in the past and recently - written a few little
test apps to generate simple scenes with flat plains and 'tower blocks'
scattered around and the like - but I need to know quite a lot more now.

> > My current guess is that if glLoadMatrixf() in GL_MODELVIEW can be
> > safely ignored, then it must be that at some later point, perhaps in an
> > extension, that modeview is again being set.
>
> This sounds rather unlikely.

Yes, but it's the least unlikely theory I can come up with as to why not
making loading the matrix would causes no changes at all.



> > If a function in a wrapped DLL calls a function in that wrapped DLL
> > (e.g. an OpenGL extension calls an OpenGL function), will that call pass
> > through the wrapper DLL, or will it have been compiled to directly use
> > code in the wrapped DLL?
>
> This has nothing to do with GL at all. You might ask this kind of stuff
> in some windows programming group.

Yup.

0 new messages