我正在尝试使用普通glColor4f()渲染两个不同的对象。场景包含一个具有均匀细分曲面的巨大平面和一个小于平面的简单立方体,并被平面分成两半。
问题1:当我试图转动视图时,立方体似乎完全在飞机上方。它看起来就像埃舍尔的形象。如何正确修复深度测试?
问题2:小立方体应该是透明的并且透视类型,但透明度不起作用。
我的初始化方法。
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);
}
调整大小的方法:
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);
}
ObjectX类的绘制方法:(平面)
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();
}
DomainX方法的绘制方法:(小方块)
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();
}
答案 0 :(得分:2)
1)绘图顺序是原因。
需要深度排序的面部绘图(从远到近)。如果发生交叉,则必须对交叉定义的每个子面应用深度排序。 对于您的具体情况,将立方体的几何体按平面分成两半然后按顺序绘制面将理论上完成工作。
编辑:如果立方体是唯一的透明对象,则渲染平面后,立方体的深度排序图(不拆分几何图形)也可以。
另一个解决方案是使用深度剥离等着色器技术进行基于片段的深度排序。
2)如上所述,必须在面部剔除的情况下绘制半透明物体的背面。