Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie
Hi there,
There is an issue with role permissions that is being worked on at the moment.
If you are having trouble with access or permissions on regional forums please post here to get access: https://www.boards.ie/discussion/2058365403/you-do-not-have-permission-for-that#latest

OpenGL Holding a View Matrix

  • 30-05-2011 4:35pm
    #1
    Registered Users, Registered Users 2 Posts: 7,182 ✭✭✭


    I have a Scene Graph (Because I never implemented one before) and it runs down through all nodes and draws them, pushing and popping (fnar fnar) for each individual object.
    The problem with this is I have to keep track of all parent object and move the current one accordingly.

    To avoid this I would like to have each object pass the current view matrix into each child object, then each child object will manipulate it and draw.
    The problem is that once child1 is done with it and it's child2's turn, the matrix would have been changed to suit the last child in the branch of child1.

    Is there a way I could do something like

    GL_View_Matrix thisMatrix = getCurrentMatrix();
    for (each child)
    {

    child.Update();
    setCurrentMatrix(thisMatrix);

    }


Comments

  • Registered Users, Registered Users 2 Posts: 7,157 ✭✭✭srsly78


    Erm yes? Push and pop view matrix stack? The whole point of push/pop is to let you do stuff like this (ie revert back to the parent matrix when done with child). Please explain a bit more.

    If it's OpenGL ES 2.0 it's a different story tho, this has programmable pipeline. Just get handle to shadermatrixvariable then pass data in.

    edit: Ah right I think I see what you are trying to do. Firstly, it's Modelview matrix, not camera matrix right? Calling it View matrix can confuse people sometimes :) Your solution is easy, just store the matrix inside each object. Nothing to do with OpenGL at all. Then when you go child->Draw() you have the relevant parent matrix available for use, I assume you combine the parent matrix with child matrix somehow then? Many ways to set this up ofc, your child objects could hold a reference to parent would be easiest.

    edit2: I think your confusion stems from trying to do all the maths inside OpenGL. You don't need to do this, just do your matrix operations in local memory, then throw the result onto OpenGL Matrix stack :)


  • Registered Users, Registered Users 2 Posts: 7,182 ✭✭✭Genghiz Cohen


    srsly78 wrote: »
    edit: Ah right I think I see what you are trying to do. Firstly, it's Modelview matrix, not camera matrix right? Calling it View matrix can confuse people sometimes :) Your solution is easy, just store the matrix inside each object. Nothing to do with OpenGL at all. Then when you go child->Draw() you have the relevant parent matrix available for use, I assume you combine the parent matrix with child matrix somehow then? Many ways to set this up ofc, your child objects could hold a reference to parent would be easiest.

    edit2: I think your confusion stems from trying to do all the maths inside OpenGL. You don't need to do this, just do your matrix operations in local memory, then throw the result onto OpenGL Matrix stack :)

    float fvViewMatrix[ 16 ];
    glGetFloatv( GL_MODELVIEW_MATRIX, fvViewMatrix );

    To get a copy of the matrix.
    How do I push the copy back into GL?


  • Registered Users, Registered Users 2 Posts: 981 ✭✭✭fasty


    http://www.opengl.org/sdk/docs/man/xhtml/glLoadMatrix.xml

    Have a look at GLM to Handle all your matrix maths.


  • Registered Users, Registered Users 2 Posts: 7,157 ✭✭✭srsly78


    float fvViewMatrix[ 16 ];
    glGetFloatv( GL_MODELVIEW_MATRIX, fvViewMatrix );

    To get a copy of the matrix.
    How do I push the copy back into GL?

    No no no. You have gotten the wrong end of the stick :)

    Do NOT try to retrieve information from OpenGL, this is very slow. Instead store your matrix in your class (ie nothing to do with OpenGL). Yes store it as float[16]. Then push it into OpenGL when needed.

    Function you are looking for is : glLoadMatrix(), but I'm not sure. Haven't used your version in a long time.


  • Registered Users, Registered Users 2 Posts: 7,182 ✭✭✭Genghiz Cohen


    Have child objects moving and rotating with their parent objects now.
    Much simpler than having to keep track of the current position in worldspace.


  • Advertisement
  • Registered Users, Registered Users 2 Posts: 7,182 ✭✭✭Genghiz Cohen


    srsly78 wrote: »
    No no no. You have gotten the wrong end of the stick :)

    Do NOT try to retrieve information from OpenGL, this is very slow. Instead store your matrix in your class (ie nothing to do with OpenGL). Yes store it as float[16]. Then push it into OpenGL when needed.

    Function you are looking for is : glLoadMatrix(), but I'm not sure. Haven't used your version in a long time.

    So I apply all translations and rotations to the held Quaternion then push it into GL with glLoadMatrix() and then draw?


  • Registered Users, Registered Users 2 Posts: 7,157 ✭✭✭srsly78


    Pretty much yeah.

    But the whole point of push/pop is so children can base their transformation on their parents.

    Think of a 3d model for a tank, composed of body + turret. Turret is the child of the body here, first you would draw the tank, then apply an extra rotation then draw the turret. Is this what you are aiming for? In this case you don't need to do anything, just apply the turrets rotation to what is already on the stack (the parents matrix).

    Please excuse terrible pseudocode.

    glPushMatrix();

    APPLYTRANSLATION(bodyposition);
    APPLYROTATION(bodyorientation);
    DRAW(tankbody);
    APPLYROTATION(turretrotation);
    DRAW(turret);

    glPopMatrix();


  • Registered Users, Registered Users 2 Posts: 7,182 ✭✭✭Genghiz Cohen


    Have child objects moving and rotating with their parent objects now.
    Much simpler than having to keep track of the current position in worldspace.

    Well...
    
    	float fvViewMatrix[ 16 ];
    	glGetFloatv( GL_MODELVIEW_MATRIX, fvViewMatrix );
    
    	list<Node*>::iterator iter = this->children.begin();
    	for(;iter != this->children.end();iter++)
    	{
    		(*iter)->Node::Update(deltaT);//Updates position(relative to parent)
    		glLoadMatrixf(fvViewMatrix);
    	}
    
    

    This would work, except it seems to think every object is a child of the last one drawn. So I get this long snake thing even if I set an object as a Child of the Root node.

    161154.png


  • Registered Users, Registered Users 2 Posts: 7,157 ✭✭✭srsly78


    You are missing a pop, that's it. The pop will get rid of the current parent. Sorry for confusion, I could explain all this in 5 mins in person :D
    glLoadIdentity();
    
    for (blahblah iterate through parents)
    {
       glPushMatrix();
       applyparentmatrix(); // gets combined with identity matrix, same as just loading parent matrix
       drawparent();
    
       for (blahblah iterate through children)
       {
          glPushMatrix();
          applychildmatrix(); // gets COMBINED with parent matrix, doesnt replace it
          drawchild();
          glPopMatrix(); // now we are back to just the unmodified parent matrix, so the next child will draw properly
       }
    
       glPopMatrix();
    
    
    }
    


  • Registered Users, Registered Users 2 Posts: 7,182 ✭✭✭Genghiz Cohen


    srsly78 wrote: »
    You are missing a pop, that's it. The pop will get rid of the current parent. Sorry for confusion, I could explain all this in 5 mins in person :D
    glLoadIdentity();
    
    for (blahblah iterate through parents)
    {
       glPushMatrix();
       applyparentmatrix(); // gets combined with identity matrix, same as just loading parent matrix
       drawparent();
    
       for (blahblah iterate through children)
       {
          glPushMatrix();
          applychildmatrix(); // gets COMBINED with parent matrix, doesnt replace it
          drawchild();
          glPopMatrix(); // now we are back to just the unmodified parent matrix, so the next child will draw properly
       }
    
       glPopMatrix();
    
    
    }
    


    I thought the loadMatrix would set the matrix back to that of the parent.


  • Advertisement
  • Registered Users, Registered Users 2 Posts: 7,182 ✭✭✭Genghiz Cohen


    Oh my God....
    I'm a moron....


  • Registered Users, Registered Users 2 Posts: 7,157 ✭✭✭srsly78


    Ah you have reached enlightenment?

    There are two ways to manipulate the matrix stack.
    A: Replace current matrix with your own (ie glLoadMatrix)
    B: Apply transformation to current matrix (ie multiply matrix A with matrix B that is already on stack).


    Example of B:
    glTranslatef(some vector);
    glRotatef(axis, angle);

    Consider this:
    
    glLoadIdentity(); 
    // current matrix is now identity
    glTranslatef(1,0,0); 
    // current matrix now represents 1,0,0 translation
    glTranslatef(1,0,0);
    // current matrix now represent 2,0,0 translation
    
    glPushMatrix();
    // current matrix now represent 2,0,0 translation
    
    glLoadMatrix(crazy matrix);
    // current matrix now represents whatever you loaded
    
    glPopMatrix();
    // current matrix now represent 2,0,0 translation
    

    I can't remember the function offhand, but you are looking for an opengl matrixmultiply function that applies matrix A to current stack. THis combines transformations, but does not replace.


  • Registered Users, Registered Users 2 Posts: 7,182 ✭✭✭Genghiz Cohen


    It works now. Thanks to Srsly & Fasty...
    Enormous mistake on my part and I want to be alone for a while...


  • Registered Users, Registered Users 2 Posts: 981 ✭✭✭fasty


    Feels ****ing awesome to get stuff working though!


  • Registered Users, Registered Users 2 Posts: 7,182 ✭✭✭Genghiz Cohen


    fasty wrote: »
    Feels ****ing awesome to get stuff working though!

    ..yes


  • Registered Users, Registered Users 2 Posts: 7,157 ✭✭✭srsly78


    Genghiz this is how we all learn mate :)


  • Registered Users, Registered Users 2 Posts: 7,182 ✭✭✭Genghiz Cohen


    srsly78 wrote: »
    Genghiz this is how we all learn mate :)

    You know that episode of the Simpsons where Abe needs a kidney and Homer runs away to the Ship of Lost Souls?

    I feel like if I tell you how stupid my mistake was, I'll get a similar reaction.(Thrown off the boat by a disgusted Frenchman) :p


  • Registered Users, Registered Users 2 Posts: 981 ✭✭✭fasty


    Ha! Don't worry about it! This weekend I spent hours scratching my head at some texture coordinate problems with a new map building tool I'd written. This was the change to fix it...

    throw_overboard.png


Advertisement