PDA

View Full Version : Problem with mirror recursion

Catman
05-12-2003, 01:48 PM
Hello! I've implemented a simple stencil mirror. It works fine with one mirror. But when I make two mirrors facing each other, the (recursive) mirrors appear in the wrong location.
Here is the code:

// check mirror recursion count
if (MirrorRecursion >= MAX_MIRROR_RECURSION)
return DM_MIRROR_NO_ERROR;

MirrorRecursion++;

glClear(GL_STENCIL_BUFFER_BIT);
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(a.x, a.y, a.z);
glVertex3f(b.x, b.y, b.z);
glVertex3f(c.x, c.y, c.z);
glVertex3f(d.x, d.y, d.z);
glEnd();

// draw mirrored scene
glStencilFunc(GL_EQUAL, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

glEnable(GL_CLIP_PLANE0);
glClipPlane(GL_CLIP_PLANE0, p);

dmFlipFaces();
glPushMatrix();
glMultMatrixf(m);
glClear(GL_DEPTH_BUFFER_BIT);
Scene->Render();
glPopMatrix();
dmFlipFaces();

glDisable(GL_CLIP_PLANE0);
glDisable(GL_STENCIL_TEST);

MirrorRecursion--;

p is the mirror's plane equation, m is the following matrix (yoyo gave me):

m[0] = 1 -2 * p[0] * p[0];
m[1] = - 2 * p[1] * p[0];
m[2] = - 2 * p[2] * p[0];
m[3] = 0.0;
m[4] = - 2 * p[0] * p[1];
m[5] = 1 - 2 * p[1] * p[1];
m[6] = - 2 * p[2] * p[1];
m[7] = 0.0;
m[8] = - 2 * p[0] * p[2];
m[9] = - 2 * p[1] * p[2];
m[10] = 1 - 2 * p[2] * p[2];
m[11] = 0.0;
m[12] = - 2 * p[0] * p[3];
m[13] = - 2 * p[1] * p[3];
m[14] = - 2 * p[2] * p[3];
m[15] = 1.0;

and dmFlipFaces() changes the polygon facing (GL_CW if it was GL_CCW, and GL_CCW if it was GL_CW). Have you any idea what am I making wrong? Thanks.

errno
05-12-2003, 11:52 PM
hello!
what do you mean by wrong location.
there is a problem with the stencil buffer.
you clear the stencil each time you render the mirrored scene and you only draw where stencil==1 (where the mirror where rendered).
you shouldn't clear the stencil each reflection and replace

glStencilFunc(GL_ALWAYS, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);

before mirror rendering, by

glStencilFunc(GL_EQUAL, MirrorRecursion, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);

and the scene must be rendered where the stencil is MirrorRecursion+1.

errno
05-12-2003, 11:54 PM
i've just read my post ...
sorry for my english http://www.opengl.org/discussion_boards/ubb/biggrin.gif

Catman
05-13-2003, 06:17 AM
Thanks. Meanwhile I've found Mike Kilgard's stencil tutorial, and now almost everything works. My only problem is how can I determine if the mirror is facing the camera or not? If not I would only draw a grey quad else draw the mirrored scene.

05-13-2003, 07:33 AM
Originally posted by Catman:
Thanks. Meanwhile I've found Mike Kilgard's stencil tutorial, and now almost everything works. My only problem is how can I determine if the mirror is facing the camera or not? If not I would only draw a grey quad else draw the mirrored scene.

uhm..dot product of the mirror normal and your view plane normal?

It would be a standard back-face-cull test, right?

Granted, I'm at home with a fever. I probably missed what you're actually trying to do. This sounds too simple...LOL

/Henrik

Catman
05-13-2003, 11:58 AM
Maybe it is simple but it's not clear for me. The problem is that I don't know the view plane's normal. I'm sure I could extract it from the modeview matrix but I'm not very good at matrix math... http://www.opengl.org/discussion_boards/ubb/smile.gif So could you help me out please?

Jan
05-13-2003, 12:26 PM
No garanty, but this way should be correct:

// get the modelview matrix
float mat[16];
glGetFloatv(GL_MODELVIEW_MATRIX, mat);

// get the right, up and front vector
vRight.SetVector (mat[0], mat[4], mat[8]);
vUp.SetVector (mat[1], mat[5], mat[9]);
vFront.SetVector (mat[2], mat[6], mat[10]);

The "front" vector is what you are looking for, i think.

Jan.

Catman
05-13-2003, 02:42 PM
Thanks, I'll try it tomorrow. I'm too tired now... http://www.opengl.org/discussion_boards/ubb/smile.gif

Catman
05-14-2003, 06:47 AM
I realized that what I wanted to do won't work. What I need is the camera position not the view vector. So my next question is how can I extract the camera position from the modelview matrix? http://www.opengl.org/discussion_boards/ubb/smile.gif

dare
05-14-2003, 09:47 PM
I think that the dot product between your line-of-sight vector and mirror normal vector should do...
Anyway, here is how you can find position of the camera, if you have modelview matrix :
posx = -(mat[0]*mat[12]+mat[1]*mat[13]+mat[2]*mat[14])
posy = -(mat[4]*mat[12]+mat[5]*mat[13]+mat[6]*mat[14])
posz = -(mat[8]*mat[12]+mat[9]*mat[13]+mat[10]*mat[14])
It's a bit unexpectedly complicated http://www.opengl.org/discussion_boards/ubb/smile.gif

Catman
05-14-2003, 10:42 PM
That dot product is not working because eg. the two vectors can be perpendicular while you are in front of the mirror and in this case the mirror won't be rendered. I think the checking the camera's position relative to the mirror's plane (is it in front of it or behind) is a better idea.

Thanks for the equations. It is a "bit" complicated... http://www.opengl.org/discussion_boards/ubb/smile.gif

Catman
05-15-2003, 05:37 AM
Finally almost everything works. Thanks everyone for the help. http://www.opengl.org/discussion_boards/ubb/smile.gif

One interesting thing. The program runs at ~8 fps on my 633Mhz/Gef2MX200 (recursion depth is 2). But the same program at 2-3 fps on a 1700Mhz/Gef3Ti200. The main difference between the two machines is that mine has an intel chipset motherboard while the other has sis. First I thought this is the problem. But then we ran 3DMark2001 and it was ok. Why is this? Is it because of the stencil buffer? Does the Gef3 switches back to software? I use 32 bit color depth with 8 bit stencil buffer so I think it shouldn't switch to software...