PDA

View Full Version : Open a 'hole' on the surface?



jxruan
07-19-2001, 05:46 AM
Suppose there is a shpere. Now I want to drill a 'hole' on it surface to let me see what is inside. The intended 'hole' is formed by clipping the sphere with three orthodox planes. For example, if all these planes pass the center of the sphere, then 1/8 of the surface will be cut off.

How can I do? I tried openGL clipping plane.
It didn't work as what I expected.

DFrey
07-19-2001, 06:43 AM
Well, generally, if implemented correctly, the user clipping planes should work. Assuming the number of clipping planes required is actually supported by the particular OpenGL implementation (which should be at least 6). So using 3 clipping planes shouldn't be a problem. However for simple holes, you can use the stencil buffer to achieve the same effect.

jxruan
07-19-2001, 07:20 AM
Yes, the clipping plane worked, but not as I excepted. I was supposed to remove 1/8 of the surface and keep the other 7/8. However, by defining 3 clipping planes, I got only 1/8 left and 7/8 removed. Moreover, the clipping planes are not controlled by ModelView transformation.

DFrey
07-19-2001, 07:30 AM
The clipping planes are transformed by the modelview matrix's inverse when they are specified. Its just that subsequent changes to the modelview matrix do not change the stored plane equations. So if you want to update the plane equations, you have to re-establish them.

[This message has been edited by DFrey (edited 07-19-2001).]

jxruan
07-19-2001, 08:07 AM
Well, now modelview matrix has its impact on the clipping plane. But the first one is not that simple as inversing the normals of the clipping plane. A clipping plane will always divide a rendering space into two parts. The more planes defined, the less space can be used to put your objects. As for 3 clipping planes, only 1/2^3=1/8 is left. Am I right?

Thank you for your answer. I have learned a lot by asking questions here.

DFrey
07-19-2001, 08:43 AM
Yes, in your example, there will always be 1/8 showing. That's simply because there are 8 combinations of 3 planes, and each combination is an octant, and so rejects the other 7 octants. If you want to get the 7/8 and cut the 1/8, you can use the stencil buffer. You basically draw into the stencil buffer, the 1/8 part you don't want. Then draw the whole sphere with stencil testing, to reject the pixels that are in the 1/8 hole.

DFrey
07-19-2001, 10:42 AM
You need to draw the back faces and front faces of the sphere. That alone will make a hollow sphere with a hole cut in it. If you want to make it look like a solid sphere with an octant removed, then you need to draw the planes using stencil testing to draw only where a back face of the sphere was drawn. There is an easier to do this with out using clip planes of course. You do essentially the same thing except you draw a cube into the stencil buffer that is where the hole will be, and then you draw the sphere's front faces, then back faces, and then you can draw the back faces of the cube along with stencil testing to close the hole off and make it look solid. There is an example somewhere that shows how to use the stencil buffer to simulate most all of the various CSG operations. Do a search on the board for CSG and I'm sure you come across it.

jxruan
07-19-2001, 10:42 AM
Ok. The 'hole' has formed. But it is not a dead-end hole but a cut-through hole --- the backward surface is also removed. Have you any good suggestion?

The following is my code:

void redraw() {
double plane0[] = {1.0, 0.0, 0.0, 0.0 };
double plane1[] = {0.0, 1.0, 0.0, 0.0 };
double plane2[] = {0.0, 0.0, 1.0, 0.0 };

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

glPushMatrix();

glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);

glEnable(GL_STENCIL_TEST);

glStencilFunc(GL_ALWAYS, 1, 1);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
glClipPlane(GL_CLIP_PLANE0, plane0);
glClipPlane(GL_CLIP_PLANE1, plane1);
glClipPlane(GL_CLIP_PLANE2, plane2);
glEnable(GL_CLIP_PLANE0);
glEnable(GL_CLIP_PLANE1);
glEnable(GL_CLIP_PLANE2);


glColor3f(1.0f, 1.0f, 0.0f);
glutSolidSphere(50, 40, 30);

glDisable(GL_CLIP_PLANE0);
glDisable(GL_CLIP_PLANE1);
glDisable(GL_CLIP_PLANE2);

// glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_NOTEQUAL, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

glColor3f(1.0f, 1.0f, 0.0f);
glutSolidSphere(50, 40, 30);

glColor3f(1.0f, 0.0f, 0.0f);
glutSolidSphere(10, 40, 30);

glDisable(GL_STENCIL_TEST);

glColor3f(0.0f, 0.0f, 1.0f);
glutSolidCube(40);

glPopMatrix();

// Show the graphics
glutSwapBuffers();
}

jxruan
07-19-2001, 10:54 AM
I agree with you on how to make a solid sphere, but I doubt that drawing a cube to stencil buffer work the same as clipping-plane. With cube in stencil buffer, the stencil will make a hole of shape "cube" on the surface, dependent on what the current projection is. However, what clipping-plane put in the stencil buffer is a octant of a sphere, thus the hole is of shape "octant".

DFrey
07-19-2001, 11:01 AM
Believe me, it works the same. Find that CSG link and read up on the details.

DFrey
07-19-2001, 11:07 AM
See here: http://www.opengl.org/discussion_boards/ubb/Forum2/HTML/004558.html

jxruan
07-19-2001, 11:07 AM
Thank you.
I'll try.