Sign in to follow this  
Zouflain

OpenGL Decoupling model and view matrices

Recommended Posts

I realized my lighting solution was inaccurate, but for a long time I couldn't see why. It wasn't until I learned more about the different spaces relevant to OpenGL that I understood that I was failing to convert between spaces. Unfortunately, OpenGL seems to skip over the required matrices to achieve the desired space I need. I have one set of coordinates in object space and another in world space. Converting the world space coordinates to object space can't be done without the model matrix (actually, it's inverse), and converting the world space coordinates to eyespace cant be done without the view matrix. From what I can see, openGL only provides the ModelView matrix, not the model or view matrix. How can I decouple the two to get just the model or just the view matrix?

Share this post


Link to post
Share on other sites
Just store the model and view matrices separately in your application.

Then whenever you change either of them, multiply them together and send the result to GL. This way GL still has its model-view as usual, but you've also got access to the current model and view matrices separately.

Share this post


Link to post
Share on other sites
Quote:
Original post by HuntsMan
You can easily do that using Shaders (GLSL).
Not according to the documentation. How would you do this? Merely saying that you can without actually giving any more than that isn't exactly helpful.

@Hodgman I don't have the model and view matrices, so I can't store them separately. That's really the problem. Are you saying that I should recalculate them, despite the fact that OpenGL must have already done this calculation and must, by necessity, have them stored somewhere?

All of my rotations are handled by quaternion. I convert to axis angle and pass this to openGL via gluLookAt and glRotate. Recalculating from that would be pretty slow, considering how much trig would be involved (and already is).

Share this post


Link to post
Share on other sites
hi,

i have made a program (with source code) which use world matrix, view matrix and projection matrix like in DirectX (my anim8or file viewer):
http://texel3d.free.fr/projets/liban8/index.html

it depend on GLGX (my math library, very close to D3DX):
http://texel3d.free.fr/projets/glgx/index.html

You need to use GLSL and a math library to use your own matrix. Do not use OpenGL function to create and handle matrices, this function are deprecated in OpenGL 3.1 and higher (Read the specs of OpenGL 3.1). If you start to write a new program it should be a good idea to remove all deprecated function of the Opengl 3.1 specs (even if you just use OpenGL 2.1 because a lot of functions of OpenGL 3.1 are already available in OpenGL 2.1).

Note: GLGX is not optimized with SSE instructions. Maybe you could find a better library if you need great performances (maybe GLM: http://www.g-truc.net)

Share this post


Link to post
Share on other sites
I've only just gotten comfortable with 2.1, and don't intend to change to 3.1 for quite some time. I would much rather not upset my learning by dumping what I know for some new system, but thank you for the suggestion anyway. I'll look into the source, but as most people have very different logical approaches to code, it would probably just be more helpful if you were to explain what you did.

Share this post


Link to post
Share on other sites
_ You can use Quaternion, translation... for your computation. And at the end, you create or update your world matrix (using a quternion to matrix function,...).
_ You store and update your view matrix somewhere (the same as the one from glulookat).
_ You store and update your projection matrix

When you render your scene, you send the 3 matrices to your GLSL shader.
In the GLSL shader, the final position of your vertex is something like:
vertexPos = inputVertexPos * WorldMatrix*ViewMatrix*ProjectionMatrix

But because you have always acces to you world,view and projection matrix in your C++ application And in your GLSL shader, you can compute what ever you want in any space (in the C++ application and/or in GLSL).

Share this post


Link to post
Share on other sites
nothing is stopping you from doing it in opengl 2.1, i.e. ogl3 is not required

as HuntsMan said use shaders be they glsl or cg

eg something like

-- vertex shader --
uniform mat44 viewmatrix;
uniform mat44 mmodelmatrix;
uniform mat44 projectionmatrix;

void main(void)
{
glPosition = projectionmatrix * viewmatrix * mmodelmatrix * vertex; // or whatever
}

Share this post


Link to post
Share on other sites
Note:
Do not use The gl_* default variables of OpenGL in your GLSL shader. Create your own to store and send your matrices.

Share this post


Link to post
Share on other sites
Quote:
Original post by zedz
eg something like...
The problem isn't that I don't know how to pass uniforms, the problem is I don't know how to aquire the matrices to be passed. Thank you for the explanation, but I can't pass a mat4 to the shader without the mat4 in the first place, which is what I'm asking.

@texel3D I understand getting a vertex from object space to eye space and clip space, that much is easy and pretty much handles itself. I'm not worried about clip space, and would only use eye space if necessary. I need two coordinates to share the same space, whatever space that may be - the actual difference between spaces, or the matrices involved in calculating that space don't matter - what matters is that I have all the variables I need to convert, which I don't. Like I said, I have one coordinate in world space and another in object space. Without the inverse of the model matrix or the view matrix, I can't get them both into the same space.

I can glGet the ModelView matrix, but I don't need the Model*View matrix, I need the model or the view matrix, and glGet has no parameter like "GL_MODEL_MATRIX." Is the only way to get this value to recalculate it, even though it must, by necessity, already be stored somewhere in openGL?

Share this post


Link to post
Share on other sites
Ok.

Solution 1:
Remember that the view matrix is just an "additionnal fake model matrix" used to put the scene in front of the camera. Working in the a modelview space is not a problem.
You can't get model matrix from modelview matrix. And it's not a problem. You just have to think in a different way.
Take a break, and think of what you exactely need and do not focus on getting model matrix.

Solution 2:
The world matrix you send to the shader is the final world matrix.
You can store the object local matrix for each of your object somewhere. these matrices will be updated when you move your objects.
When you need to have 2 objects in the same space, you compute the world matrix of each object.
In this solution: You Never use openGL Matrix, you never use gltranslate, glrotate, glget(GL_MODEL_MATRIX), glpushmatrix,gluLookat,glFustum,....


Share this post


Link to post
Share on other sites
model view are just the same matrix.

float view[16];
float model[16];
glPushMatrix();
glLoadIdentity();
gluLookAt();
// ONLY the view is stored
glGetFloatv(GL_MODELVIEW_MATRIX, view);
glLoadIdentity();
// do some transformations
glTranslatef();
glRotatef();
glScalef();
glGetFloatv(GL_MODELVIEW_MATRIX, model);
glPopMatrix();

// Set the matrices in your shader
// Render

if you want to test this then you could do
glPushMatrix()
glLoadMatrixf(view);
glMultMatrixf(model)
// render model with fixed function pipeline
glPopMatrix();

it should look the same as when you render things normally.

Share this post


Link to post
Share on other sites
Quote:
All of my rotations are handled by quaternion. I convert to axis angle and pass this to openGL via gluLookAt and glRotate. Recalculating from that would be pretty slow, considering how much trig would be involved (and already is).
It sounds like you're saying that adding a few additional trig operations per update cycle will have a negative impact on your app's performance. Have you actually observed this to be the case, or is this just a concern that you have? Also, out of curiosity, what programming language are you using, and what platform(s) are you targeting?

As others have said, the most straightforward method is to compute these transforms yourself, and then combine them as needed and upload them to OpenGL. Unless the circumstances are very unusual, there should be no technical or performance-related obstacles to doing it this way. If you're running into problems with this approach, perhaps you could tell us what exactly is hanging you up.

Share this post


Link to post
Share on other sites
Quote:
Original post by Nanoha
float view[16];
gluLookAt();
// ONLY the view is stored
glGetFloatv(GL_MODELVIEW_MATRIX, view);
Ah, thank you! This is precisely what I was asking. I wasn't sure of gluLookAt also changed the model matrix, so I wasn't sure if something like this would work. With the view matrix, I can transform World Space coordinates to Eye Space coordinates without issue, and therefore get the coordinates in question into the same space.

@texel3d I need both coordinates in the same space, and they aren't. To change them to the same space. I need the matrices to do that though, and modelview is the incorrect matrix - I can't use it because it will move it into some undefined space, which I still couldn't reach with the other coordinate.

@jyk For some odd reason, the time it takes to carry out just the render process varies widely between 10ms and 27ms when rendering about 200 display lists, each with something on the order of 500 polygons. That alone is unacceptable, so I'm avoiding any unnecessary operations that might add more to it. I already have computed the matrix, so why recompute it? It makes more sense, at least to me, to use what's there.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Forum Statistics

    • Total Topics
      627735
    • Total Posts
      2978854
  • Similar Content

    • By DelicateTreeFrog
      Hello! As an exercise for delving into modern OpenGL, I'm creating a simple .obj renderer. I want to support things like varying degrees of specularity, geometry opacity, things like that, on a per-material basis. Different materials can also have different textures. Basic .obj necessities. I've done this in old school OpenGL, but modern OpenGL has its own thing going on, and I'd like to conform as closely to the standards as possible so as to keep the program running correctly, and I'm hoping to avoid picking up bad habits this early on.
      Reading around on the OpenGL Wiki, one tip in particular really stands out to me on this page:
      For something like a renderer for .obj files, this sort of thing seems almost ideal, but according to the wiki, it's a bad idea. Interesting to note!
      So, here's what the plan is so far as far as loading goes:
      Set up a type for materials so that materials can be created and destroyed. They will contain things like diffuse color, diffuse texture, geometry opacity, and so on, for each material in the .mtl file. Since .obj files are conveniently split up by material, I can load different groups of vertices/normals/UVs and triangles into different blocks of data for different models. When it comes to the rendering, I get a bit lost. I can either:
      Between drawing triangle groups, call glUseProgram to use a different shader for that particular geometry (so a unique shader just for the material that is shared by this triangle group). or
      Between drawing triangle groups, call glUniform a few times to adjust different parameters within the "master shader", such as specularity, diffuse color, and geometry opacity. In both cases, I still have to call glBindTexture between drawing triangle groups in order to bind the diffuse texture used by the material, so there doesn't seem to be a way around having the CPU do *something* during the rendering process instead of letting the GPU do everything all at once.
      The second option here seems less cluttered, however. There are less shaders to keep up with while one "master shader" handles it all. I don't have to duplicate any code or compile multiple shaders. Arguably, I could always have the shader program for each material be embedded in the material itself, and be auto-generated upon loading the material from the .mtl file. But this still leads to constantly calling glUseProgram, much more than is probably necessary in order to properly render the .obj. There seem to be a number of differing opinions on if it's okay to use hundreds of shaders or if it's best to just use tens of shaders.
      So, ultimately, what is the "right" way to do this? Does using a "master shader" (or a few variants of one) bog down the system compared to using hundreds of shader programs each dedicated to their own corresponding materials? Keeping in mind that the "master shaders" would have to track these additional uniforms and potentially have numerous branches of ifs, it may be possible that the ifs will lead to additional and unnecessary processing. But would that more expensive than constantly calling glUseProgram to switch shaders, or storing the shaders to begin with?
      With all these angles to consider, it's difficult to come to a conclusion. Both possible methods work, and both seem rather convenient for their own reasons, but which is the most performant? Please help this beginner/dummy understand. Thank you!
    • By JJCDeveloper
      I want to make professional java 3d game with server program and database,packet handling for multiplayer and client-server communicating,maps rendering,models,and stuffs Which aspect of java can I learn and where can I learn java Lwjgl OpenGL rendering Like minecraft and world of tanks
    • By AyeRonTarpas
      A friend of mine and I are making a 2D game engine as a learning experience and to hopefully build upon the experience in the long run.

      -What I'm using:
          C++;. Since im learning this language while in college and its one of the popular language to make games with why not.     Visual Studios; Im using a windows so yea.     SDL or GLFW; was thinking about SDL since i do some research on it where it is catching my interest but i hear SDL is a huge package compared to GLFW, so i may do GLFW to start with as learning since i may get overwhelmed with SDL.  
      -Questions
      Knowing what we want in the engine what should our main focus be in terms of learning. File managements, with headers, functions ect. How can i properly manage files with out confusing myself and my friend when sharing code. Alternative to Visual studios: My friend has a mac and cant properly use Vis studios, is there another alternative to it?  
    • By ferreiradaselva
      Both functions are available since 3.0, and I'm currently using `glMapBuffer()`, which works fine.
      But, I was wondering if anyone has experienced advantage in using `glMapBufferRange()`, which allows to specify the range of the mapped buffer. Could this be only a safety measure or does it improve performance?
      Note: I'm not asking about glBufferSubData()/glBufferData. Those two are irrelevant in this case.
    • By xhcao
      Before using void glBindImageTexture(    GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format), does need to make sure that texture is completeness. 
  • Popular Now