Pushing and popping matrices

Started by
7 comments, last by adam17 18 years, 10 months ago
right now im building a particle engine and im trying to figure out the best optimizations for billboarding and particle locations. which is better to do? call glPushMatrix() and make all of my transformations and rotations and then call glPopMatrix(), or should i just negate the transformations and rotations i made? i read somewhere that pushing and popping matrices does it for ALL attributes, not just the modelview matrix. is that true?
Advertisement
I think there are other specialized functions for pushing and popping attributes - glPushMatrix() and glPopMatrix() only affect the current matrix (projection/modelview/texture). Also, as far as I know this is the standard method for applying and then undoing a transform; no 'reverse' transforms should be necessary.
just out of curiosity (so i dont have to dig through google) how many pushes can i do before the stack cant handle anymore?
Quote:Original post by adam17
i read somewhere that pushing and popping matrices does it for ALL attributes, not just the modelview matrix. is that true?


No, as jyk mentioned, you will need to use the glPushAttrib, glPopAttrib functions to work with attributes.

For your question though, I say it'd be better to simply call glPushMatrix/glPopMatrix with your transformations in the middle because it is just the 'smart' thing to do. Imagine for a sec you have your long list of transformations made, then you generate the 'negations' for it afterwords. What if you made a mistake and need to change some of those? You then will have to go and recalcualte the negations, which will be a pain I promise down the line. That and it's very prone to bugs. It would be in your best intrest to simply Push, modify, then Pop and save youself all the headaches that the other method would give you.
Quote:Original post by adam17
just out of curiosity (so i dont have to dig through google) how many pushes can i do before the stack cant handle anymore?


Quote:There is a stack of matrices for each of the matrix modes. In GL_MODELVIEW mode, the stack depth is at least 32. In the other two modes, GL_PROJECTION and GL_TEXTURE, the depth is at least 2. The current matrix in any mode is the matrix on the top of the stack for that mode.
...
It is an error to push a full matrix stack, or to pop a matrix stack that contains only a single matrix. In either case, the error flag is set and no other change is made to the OpenGL state.


I guess it's dependent on the users video card then as well as the system memory and stuff like that.
You can actually get the size of the projection or model view stacks.. This determines how many times you can push...

// The max depths of the stacks
int max_MV_depth, max_P_depth;

glGetIntegerv (GL_MAX_MODELVIEW_STACK_DEPTH, &max_MV_depth);
glGetIntegerv (GL_MAX_PROJECTION_STACK_DEPTH, &max_P_depth);

I actually have a great interactive program that allows you to interactively push and pop matrices, edit those matrices using the mouse, and at the same time see their effect on an object on the screen.

I wish I can post a screen shot now.. Do you know how I can do so...
adam17: to me it sounds like you're using a matrix pr particle. this is REALLY not a good idea. instead, batch them up something like this:

void draw_particles(Particle particles[], unsigned n_particles) {	// fetch modelview to determine up and left vectors	GLfloat matrix[16];	glGetFloatv(GL_MODELVIEW_MATRIX, matrix);	Vector3 left(matrix[0], matrix[4], matrix[8]);	Vector3 up(-matrix[1], -matrix[5], -matrix[9]);			glBegin(GL_QUADS);	Vector3 tmp;	for (unsigned i = 0; i < n_particles; ++i) {		glColor4f(1,1,1, particles.alpha);		Vector3 modleft = left*particles.size;		Vector3 modup = up*particles.size;		glTexCoord2f(0.0f, 1.0f);		tmp = particles.pos - modleft - modup;		glVertex3fv((float *)&tmp);		glTexCoord2f(0.0f, 0.0f);		tmp = particles.pos - modleft + modup;		glVertex3fv((float *)&tmp);        		glTexCoord2f(1.0f, 0.0f);		tmp = particles.pos + modleft + modup;		glVertex3fv((float *)&tmp);        		glTexCoord2f(1.0f, 1.0f);		tmp = particles.pos + modleft - modup;		glVertex3fv((float *)&tmp);	}	glEnd();}


ofcourse, you could do something like filling a vertexarray (or even a vbo), but unless you have a really huge amound of small particles, i doubt you'll experience much performance-boost.

Hi,

depends mostly on the implementation, IIRC; use the tool "GLInfo2" from delphigl.com to find out what stack depth you have on your current software/hardware combination.
(Stackdepth for matrixstack<->modevielstack ect. may differ)

Alex BakerComputer science is dealing with computers as much as astronomy is dealing with telescopes.
Quote:Original post by kusma
adam17: to me it sounds like you're using a matrix pr particle. this is REALLY not a good idea. instead, batch them up something like this:

*** Source Snippet Removed ***

ofcourse, you could do something like filling a vertexarray (or even a vbo), but unless you have a really huge amound of small particles, i doubt you'll experience much performance-boost.


that looks like it would be a huge improvement. if i understand it, u take the right and up vectors of the modelview matrix, and multiply it by the vertices of the particle? as of right now im just taking the pitch and yaw angles of the user's position (which is alot of nasty math) once for EACH particle, pushing a matrix, calling glRotate and then drawing the particle. i think your way is MUCH faster.

This topic is closed to new replies.

Advertisement