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.
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.
fungus wrote: > 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.
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.
jg.campbell...@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!
Toby Douglass wrote: > jg.campbell...@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!
marcel.he...@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.
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).
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.
> 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... ;)
marcel.he...@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.
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.
marcel.he...@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.