PDA

View Full Version : Drawing with stencil test - GL_NOTEQUAL/GL_EQUAL i



AllForum
10-05-2010, 09:02 AM
Hello,

I am trying to test a method to cap a clipped object using the stencil buffer.
I learned this method with this page (source code inside) :
http://developer.amd.com/archive/legacyd...s/default.aspx# (http://developer.amd.com/archive/legacydemos/Rage128SDKSampleCodeandDemos/StencilingonRage128withOpenGL/Pages/default.aspx#)

When I draw my clip plane using the stencil test I do not understand the results :
1- using the test glStencilFunc(GL_NOTEQUAL, 1, 1) : it is ok. My plane has a hole where the object (a sphere) is clipped.
2- using the test glStencilFunc(GL_EQUAL, 1, 1) : it is not ok : the hole is drawn but also another object is drawn too (a sphere behind the clip plane).
I join images (my scene and the results).

"1-" means that my stencil buffer contains 1 only in a circle. But 2- means something different. This only by inverting the stencil test...

As I am a real beginner I think that I did something wrong or that I do not understand the results.
Could you help me ?

Thanks in advance.

BionicBytes
10-06-2010, 03:05 AM
A fragment is drawn if it passes the stencil test and depth test. What values are you assigning to the stencil buffer for each circle drawn in the first pass? You can then test for these values on the sencond pass using glStencilFunc. Incidentally, the last argument of StencilFunc is the mask. You have specified only 1 bit (so that's the values 0 and 1). The usual case is $FF (all values between 0-255). Was that intentional?

AllForum
10-06-2010, 09:33 AM
Hello,

Thanks for your answer.
Yes, my stencil buffer is a boolean buffer.
I did not post the code because I thought that I did big mistake...

Here are the steps of the method (link in my first post) :
# Turn on the user clip plane.
# Render the FRONT faces of the object to be capped.
# Program the stencil operations to set the stencil buffer to 1 for pixels that pass the z test.
# Render the BACK faces of the object to be capped. This creates a stencil buffer like the one shown in Figure 2.
# Turn off the user clip plane.
# Program the stencil operations to reject pixels if the stencil buffer is not set to 1.
# Draw a polygon which is exactly co-planar with the user clip plane. This provides the cap.

I join my code : I think it will be easier to read than on the forum (I can't upload with a .cpp extension...).

I can't see what is wrong...

AllForum
10-06-2010, 09:44 AM
I can not see the attached file in my previous message so I put the code here too :


// Clear Screen, Depth Buffer & Stencil Buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

// Clip Plane Equations
double eqr2[] = {0.0f,0.0f, -1.0f, 0.0f};

glLoadIdentity();
glTranslatef(0.0f, -0.6f, zoom);

glDepthRange(0,1);

// only updates the depth buffer
glColorMask(0,0,0,0);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);

// enable the clip plane
glEnable(GL_CLIP_PLANE0);
glClipPlane(GL_CLIP_PLANE0, eqr2);

// draw the front faces
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);

DrawSpheres();
// ==> - the sphere in front of the clip plane is clipped => not drawn
// - the sphere clipped by the clip plane : no front face to draw
// - the sphere behind the clip plane : drawn

// Clear and activate the stencil buffer and test
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);

// draw the back faces
glCullFace(GL_FRONT);

DrawSpheres();
// ==> - the sphere in front of the clip plane is clipped => not drawn
// - the sphere clipped by the clip plane : the back faces are drawn
// - the sphere behind the clip plane : not drawn because the the front faces of this sphere are in the depth buffer
// ==> the stencil buffer contains 1 where to cap the middle sphere


glColorMask(1,1,1,1);
glClear(GL_COLOR_BUFFER_BIT);

// I clear the depth buffer to be sure that the plane passes
// If it does not passe then it is due to the stencil test
glClear(GL_DEPTH_BUFFER_BIT);


// turn off culling and user clip plane 0
glDisable(GL_CULL_FACE);
glDisable(GL_CLIP_PLANE0);

// draw where stencil buffer is 1
glStencilFunc(/*GL_NOTEQUAL*/ GL_EQUAL, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

// draw the clip plane
DrawFloor();

AllForum
10-07-2010, 09:27 AM
My stencil buffer is a boolean buffer (1 bit buffer).

How is it possible to have something drawn when I test a value less than 0 ? :confused:
glStencilFunc(GL_LESS, 0, 1); // the 2 spheres/disks are drawn !

With glStencilFunc(GL_EQUAL, 0, 1) I have the plane with the hole. Ok.
With glStencilFunc(GL_EQUAL, 1, 1) I have nothing... it is maybe an error in my code but it is possible.
But something with a value less than zero, it's impossible...

The stencil buffer is initialized...

Does this give an idea about an error in my code ?

I will try another method to do the same to test...

AllForum
10-11-2010, 07:56 AM
Do not forget to disable the stencil when it is no more needed...

Stupid bug ! :mad: