PDA

View Full Version : Stencil and Blending problem...



c0de
03-14-2008, 02:20 PM
I try to draw a cylindrical object having 6 holes from the top side to the bottom side. I used stencil to cut the holes and gluCylinder to draw them. The top and bottom faces are drawn with gluDisk. The color of the cylinder and holes are set with glMaterial, alpha = 1.0. The problem is that the faces where i used stencil are not totally opaque. In some particular positions of the object the back side is displayed (the holes on the backside). Here are the screenshots of the object (front and back side view):

http://rrg.utcluj.ro/~c0de/front.jpg

http://rrg.utcluj.ro/~c0de/back.jpg

I wonder if I'm setting wrong the stencil or blending. Here is the function which generates the object:


GLuint GLWidget::solidHarmonicDrive(GLuint listid)
{
static GLUquadricObj *disk, *cylinder;
int inc = 0;
GLuint list = glGenLists(listid);
glNewList(list, GL_COMPILE);
setMaterial(SILVER);
disk = gluNewQuadric();
cylinder = gluNewQuadric();
glClear(GL_STENCIL_BUFFER_BIT);
glEnable(GL_STENCIL_TEST);
glClearStencil(0);
glStencilMask(0x1);
glColorMask(0,0,0,0);
glDepthMask(GL_FALSE);
glStencilFunc(GL_ALWAYS, 0x1, 0x1);
glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE);
glPushMatrix();
for (inc = 0; inc < 6; inc++)
{
glRotatef(60,0,0,1);
glPushMatrix();
glTranslatef(0,135,0);
gluDisk(disk,0,8,256,256);
glPopMatrix();
}
glPopMatrix();
glPushMatrix();
glTranslatef(0,0,24);
for (inc = 0; inc < 6; inc++)
{
glRotatef(60,0,0,1);
glPushMatrix();
glTranslatef(0,135,0);
gluDisk(disk,0,4.5,256,256);
glPopMatrix();
}
glPopMatrix();
glColorMask(1,1,1,1);
glDepthMask(GL_TRUE);
glStencilFunc(GL_NOTEQUAL, 0x1, 0x1);
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
gluDisk(disk, 112,146,512,512);//fi A
glPushMatrix();
glTranslatef(0,0, 24);
gluDisk(disk, 112,146,512,512);
glPopMatrix();
glDisable(GL_STENCIL_TEST);
setMaterial(GOLD);
glPushMatrix();
for (inc = 0; inc < 6; inc++)
{
glRotatef(60,0,0,1);
glPushMatrix();
glTranslatef(0,135,0);
gluCylinder(cylinder,8,8,5,256,256);
glTranslatef(0,0,4.4);
gluDisk(disk,4.5,8,256,256);
gluCylinder(cylinder,4.5,4.5,19,256,256);
glPopMatrix();
}
glPopMatrix();
setMaterial(SILVER);
gluCylinder(cylinder, 112,112,24,256,256);
gluCylinder(cylinder, 146,148,2,256,256);
glPushMatrix();
glTranslatef(0,0,2);
gluCylinder(cylinder, 148, 148,20,256,256);
glTranslatef(0,0,20);
gluCylinder(cylinder, 148, 146,2,256,256);
glPopMatrix();
glEndList();
return list;
}


...and the initial setup of the scene:


void GLWidget::initializeGL()
{
object1= solidHarmonicDrive(1);
glMatrixMode(GL_MODELVIEW);
glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable (GL_DEPTH_TEST);
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
glEnable (GL_LIGHT1);
// glEnable (GL_LIGHT2);
// glEnable (GL_LIGHT3);
glEnable (GL_LIGHT4);
glEnable (GL_NORMALIZE);
}


Any help would be appreciated. Thank you

c0de
03-14-2008, 02:55 PM
Solved. sorry:)
I didnt knew I need to use/clear stencil for different faces.

Solution:


GLuint GLWidget::solidHarmonicDrive(GLuint listid)
{
static GLUquadricObj *disk, *cylinder;
int inc = 0;
GLuint list = glGenLists(listid);
glNewList(list, GL_COMPILE);
setMaterial(SILVER);
disk = gluNewQuadric();
cylinder = gluNewQuadric();
glClear(GL_STENCIL_BUFFER_BIT);
glEnable(GL_STENCIL_TEST);
glClearStencil(0);
glStencilMask(0x1);
glColorMask(0,0,0,0);
glDepthMask(GL_FALSE);
glStencilFunc(GL_ALWAYS, 0x1, 0x1);
glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE);
glPushMatrix();
for (inc = 0; inc < 6; inc++)
{
glRotatef(60,0,0,1);
glPushMatrix();
glTranslatef(0,135,0);
gluDisk(disk,0,8,256,256);
glPopMatrix();
}
glPopMatrix();
glColorMask(1,1,1,1);
glDepthMask(GL_TRUE);
glStencilFunc(GL_NOTEQUAL, 0x1, 0x1);
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
gluDisk(disk, 112,146,512,512);//fi A
glDisable(GL_STENCIL_TEST);
glClear(GL_STENCIL_BUFFER_BIT);
glEnable(GL_STENCIL_TEST);
glClearStencil(0);
glStencilMask(0x1);
glColorMask(0,0,0,0);
glDepthMask(GL_FALSE);
glStencilFunc(GL_ALWAYS, 0x1, 0x1);
glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE);
glPushMatrix();
glTranslatef(0,0,24);
for (inc = 0; inc < 6; inc++)
{
glRotatef(60,0,0,1);
glPushMatrix();
glTranslatef(0,135,0);
gluDisk(disk,0,4.5,256,256);
glPopMatrix();
}
glPopMatrix();
glColorMask(1,1,1,1);
glDepthMask(GL_TRUE);
glStencilFunc(GL_NOTEQUAL, 0x1, 0x1);
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
glPushMatrix();
glTranslatef(0,0, 24);
gluDisk(disk, 112,146,512,512);
glPopMatrix();
glDisable(GL_STENCIL_TEST);
setMaterial(GOLD);
glPushMatrix();
for (inc = 0; inc < 6; inc++)
{
glRotatef(60,0,0,1);
glPushMatrix();
glTranslatef(0,135,0);
gluCylinder(cylinder,8,8,5,256,256);
glTranslatef(0,0,4.4);
gluDisk(disk,4.5,8,256,256);
gluCylinder(cylinder,4.5,4.5,19,256,256);
glPopMatrix();
}
glPopMatrix();
setMaterial(SILVER);
gluCylinder(cylinder, 112,112,24,256,256);
gluCylinder(cylinder, 146,148,2,256,256);
glPushMatrix();
glTranslatef(0,0,2);
gluCylinder(cylinder, 148, 148,20,256,256);
glTranslatef(0,0,20);
gluCylinder(cylinder, 148, 146,2,256,256);
glPopMatrix();
glEndList();
return list;
}