Reputation: 505
I'm trying to render two different objects using normal glColor4f(), The scene contains a huge plane with evenly subdivided surface and a simple cube in the center which is smaller than the plane and is divided in half by the plane.
Problem 1: When I try to turn the view around, the cube seems to be completely above the plane. It looks just like an Escher figure.How to fix depth testing properly?
Problem2: the small cube is supposed to be transparent and see through type, but transparency isn't working.
My initialization method.
void GWidget::initializeGL()
{
setFormat(QGLFormat(QGL::DoubleBuffer|QGL::DepthBuffer|QGL::Rgba|QGL::DepthBuffer));
glEnable(GL_POINT_SMOOTH);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_POLYGON_SMOOTH);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.0f);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_SRC_ALPHA);
glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST);
glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);
glCullFace(GL_BACK);
glDepthFunc(GL_LEQUAL);
glDepthMask(GL_TRUE);
glFrontFace(GL_CCW);
glMatrixMode(GL_MODELVIEW);
glTranslatef(0,0,-1);
glClearColor(0.4,0.5,0.4,0);
glClearDepth(1.0f);
glPushMatrix();
glShadeModel(GL_SMOOTH);
glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_MULTISAMPLE);
// glScalef(0.1f,0.1f,0.1f);
}
Resizing method:
void GWidget::resizeGL(int width, int height)
{
glViewport( 0, 0, (GLint)width, (GLint)height );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho ( -width,width,-height,height, 0.0, 200.0 );
glPushMatrix();
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef(0,0,-3);
glScalef(0.7,0.7,0.7);
glPushMatrix();
glEnable (GL_DEPTH_TEST);
}
Draw Method for ObjectX class:(The Plane)
void ObjectX::GDraw(int i)
{
qint32 count,iter;
MeshX *dmesh;
VertX *dvert;
EdgeX *dedge;
FaceX *dface;
QList<VertX* > *vlist;
dmesh=this->Meshes[i];
vlist=dmesh->getVList();
iter=0;
int a,b;
int c,d;
glColor4f(0.81,0.71,0.51,1);
glBegin(GL_QUADS);
foreach(iter,dmesh->QFaces)
{
dface=dmesh->getFaceX(iter);
a=dface->getA();b=dface->getB();c=dface->getC();d=dface->getD();
dvert=vlist->at(a);
glVertex3fv(dvert->getV());
dvert=vlist->at(b);
glVertex3fv(dvert->getV());
dvert=vlist->at(c);
glVertex3fv(dvert->getV());
dvert=vlist->at(d);
glVertex3fv(dvert->getV());
}
glEnd();
glFlush();
glColor4f(0.51,0.41,0.51,1);
glBegin(GL_TRIANGLES);
foreach(iter,dmesh->TFaces)
{
glBegin(GL_QUADS);
dface=dmesh->getFaceX(iter);
a=dface->getA();b=dface->getB();c=dface->getC();d=dface->getD();
dvert=vlist->at(a);
glVertex3fv(dvert->getV());
dvert=vlist->at(b);
glVertex3fv(dvert->getV());
dvert=vlist->at(c);
glVertex3fv(dvert->getV());
}
glEnd();
glFlush();
iter=0;
glLineWidth(3.0f);
glColor4f(0.31,0.27,0.51,1.0);
glBegin(GL_LINES);
count=dmesh->getEListLength();
while(iter<count)
{
dedge=dmesh->getEdgeX(iter);
a=dedge->getA();b=dedge->getB();
dvert=vlist->at(a);
glVertex3fv(dvert->getV());
dvert=vlist->at(b);
glVertex3fv(dvert->getV());
iter++;
}
glEnd();
glFlush();
iter=0;
glColor4f(1,1,1,1.0);
glPointSize(3.0f);
glBegin(GL_POINTS);
count=dmesh->getVListLength();
while(iter<count)
{
dvert=dmesh->getVertX(iter);
glColor4fv(dvert->getColorV());
glVertex3fv(dvert->getV());
iter++;
}
glEnd();
glFlush();
}
Draw method for DomainX method:(The small cube)
void DomainX::drawDomain()
{
qint32 count,iter;
MeshX *dmesh;
VertX *dvert;
EdgeX *dedge;
FaceX *dface;
QList<VertX* > *vlist;
dmesh=this->DMesh;
vlist=dmesh->getVList();
iter=0;
int a,b;
int c,d;
glColor4f(0.1,0.1,0.1,0.01);
glBegin(GL_QUADS);
foreach(iter,dmesh->QFaces)
{
dface=dmesh->getFaceX(iter);
a=dface->getA();b=dface->getB();c=dface->getC();d=dface->getD();
dvert=vlist->at(a);
glVertex3fv(dvert->getV());
dvert=vlist->at(b);
glVertex3fv(dvert->getV());
dvert=vlist->at(c);
glVertex3fv(dvert->getV());
dvert=vlist->at(d);
glVertex3fv(dvert->getV());
}
glEnd();
glFlush();
glColor4f(0.51,0.41,0.51,0.01);
glBegin(GL_TRIANGLES);
foreach(iter,dmesh->TFaces)
{
glBegin(GL_QUADS);
dface=dmesh->getFaceX(iter);
a=dface->getA();b=dface->getB();c=dface->getC();d=dface->getD();
dvert=vlist->at(a);
glVertex3fv(dvert->getV());
dvert=vlist->at(b);
glVertex3fv(dvert->getV());
dvert=vlist->at(c);
glVertex3fv(dvert->getV());
}
glEnd();
glFlush();
iter=0;
glLineWidth(3.0f);
glColor4f(0.71,0.27,0.51,1.0);
glBegin(GL_LINES);
count=dmesh->getEListLength();
while(iter<count)
{
dedge=dmesh->getEdgeX(iter);
a=dedge->getA();b=dedge->getB();
dvert=vlist->at(a);
glVertex3fv(dvert->getV());
dvert=vlist->at(b);
glVertex3fv(dvert->getV());
iter++;
}
glEnd();
glFlush();
iter=0;
glColor4f(1,1,1,1.0);
glPointSize(3.0f);
glBegin(GL_POINTS);
count=dmesh->getVListLength();
while(iter<count)
{
dvert=dmesh->getVertX(iter);
glColor4f(0.3,0.7,0.6,1);
glVertex3fv(dvert->getV());
iter++;
}
glEnd();
glFlush();
}
Upvotes: 0
Views: 1873
Reputation: 7858
1) The drawing order is the cause.
Depth sorted drawing of faces is required (from far to near). If intersection occurs, depth sorting must be applied for each sub face defined by intersection. For your specific case, splitting the cube's geometry by the plane in two halves and then draw the faces in order will theoretically do the job.
EDIT: If the cube is the only transparent object, depth sorted drawing of the cube (without splitting up the geometry) after rendering the plane works aswell.
Another solution is fragment based depth sorting using shader techniques like depth peeling.
2) As mentioned, backfaces of a semitransparent object must be drawn with face culling off.
Upvotes: 2