PDA

View Full Version : overlay with stencil buffer?



binium
09-18-2002, 05:22 AM
I have a big 2d art as background and a couple of small 3d stuffs. If the 3d objects are moved, the whole scene is redrawn. That's awkward.

Now I don't want the complex 2d art that already exits to be written over each frame. I know stencil buffer can do it. But I don't know how? Could you explain or recommend code examples to me? Thanks a lot!

nexusone
09-18-2002, 05:53 AM
How are you loading the image?

How about posting your code? so we can look at how you are managing the image.


Originally posted by binium:
I have a big 2d art as background and a couple of small 3d stuffs. If the 3d objects are moved, the whole scene is redrawn. That's awkward.

Now I don't want the complex 2d art that already exits to be written over each frame. I know stencil buffer can do it. But I don't know how? Could you explain or recommend code examples to me? Thanks a lot!

binium
09-18-2002, 06:24 AM
my code is quite simple. Just draw a 2d picture over a 3d graphics world, as discussed a lot in this forum. Here is my display function:

void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadIdenity();
gluPerpsective(...);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();/* draw 3d stuffs: movable balls */
glTranslatef(x, y, 0);
glutSolidSphere(...);
glPopMatrix();

glutSolidTeapot(...);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(...);
glMatrixMode(GL_MODELVIEW);
/* draw 2d stuff: map texture on a quad */
glRasterPos2i(...);
glDrawPixels(...);
glMatrixMode(GL_PROJECTION_MATRIX);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);

glutSwapBuffers();
}
If the values of x, y changes, the whole scene will be redraw. That's a unnecessary big calculation.

what I want to do is keep the 2d stuff that already exists from being written over while 3d stuffs have to be redraw. I know stencil buffer can do it. But I need some explanation and code examples. Thanks!

pATChes11
09-18-2002, 10:44 AM
Well, unless you're using single buffering, you'll have to redraw the whole scene anyway. And if you have a 3D accelerator, what're you so worried about? It's so simple that it doesn't matter whether you redraw the entire scene or not (unless it's gotta run on an age-old 3D card), and if you *are* worried about it, then you should consider using some kind of software rasterization API. But, considering that pretty decent GeForce class cards can be had for under $50 now, there's really no excuse for not having one.

Just redraw the whole thing every frame and don't fret about it :P


If you must know, you could draw the 2D object with a stencil of one, and the 3D objects with a stencil test for anything that's not one, and to not do anything if it is. Look around for stencil buffer tutorials... you can find a lot of OGL stuff here: http://nehe.gamedev.net/

binium
09-18-2002, 09:55 PM
Thanks for info!

I still want to try stencil tests anyway coz the funcy 2d stuffs really made the moving of 3d geometries sluggish.

I've looked at Nehe's tutorials on stencil buffer. All of them are about reflection. After struggling I've not got the trick yet:-(

My scene is: some simple 3d stuffs float over a complex 2d art. My purpose of using stencil test is to prevent the 2d from being redrawn (that is expensive, but I am not sure) when the 3d things are redrawn.

Look at the cockpit as example:

// Now draw the panel to stencil buffer:
glStencilFunc(GL_ALWAYS, 1, 1);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
DrawStencilPanel();

// Now draw the panel:
glDisable(GL_STENCIL_TEST);
glClear(GL_COLOR_BUFFER_BIT);
DrawPanel();

// Now draw a textured quad over the whole screen, but only where the stencil was written with 0 before:
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_NOTEQUAL, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
DrawWorld();

The stencil let the 3d world be drawn only in the window area with the stencil of 0. that's good. However stencil buffer does not keep the static panel from being redrawn each frame, well, as far as I can see. How can I make it?

(my problem is a little more complex the cockpit emulation. the 2d and 3d things overlap in my scene.)

I am newbie, please bear with me if my question does not make sense at all.

I also posted my question in Nehe's forum to get more advice.

I appreciate if any help. Thanks!

Deiussum
09-19-2002, 04:18 AM
/* draw 2d stuff: map texture on a quad */
glRasterPos2i(...);
glDrawPixels(...);


I hate to break it to you, but glDrawPixels is not drawing a textured quad. glDrawPixels also tends to be somewhat slow, so you might get some speedup if you use a true textured quad like so:




void InitTexture()
{
// Just call this at the start
// Note: if it isn't already, you should resize the image to be
// dimensions that are a power of two
glGenTextures(1, &g_nTexID);
glBindTexture(GL_TEXTURE_2D, g_nTexID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

glTexImage2d(...);

}

void Display()
{
...

glBindTexture(g_nTexID);
glBegin(GL_QUADS);
glTexCoord(0, 0);
glVertex3f(lower left corner);
glTexCoord(1, 0);
glVertex3f(lower right corner);
glTexCoord(1, 1);
glVertex3f(upper right corner);
glTexCord(0, 1);
glVertex3f(upper left corner);
glEnd();
}