主题:[讨论]求助openGL中的消隐
nansure
[专家分:0] 发布于 2010-08-20 14:35:00
最近在做一个可视化的网格,遇到一个消隐问题
首先我画网格的原理是画单个立方体,然后将他们累加起来
代码如下:
glColor4f(1, 1, 1, 1);
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
for(k=0;k<m_public.NE;k++)
{
for(m=0;m<8;m++)
for(n=0;n<3;n++)
vertex_list[m][n]=m_public.IP[m_public.NEM[k][m+1]-1][n+1];
glBegin(GL_QUADS);
for(i=0; i<6; ++i)
for(j=0; j<4; ++j)
glVertex3fv(vertex_list[index_list[i][j]]);
glEnd();
}
对于单个立方体实现了消隐,但多个累加后一些应该消去的线仍旧看的见,如何解决(整体消隐)
最后更新于:2010-08-20 14:40:00
回复列表 (共3个回复)
沙发
eastcowboy [专家分:25370] 发布于 2010-08-21 04:49:00
思路:如果一条线会被遮挡,则这条线就不应该被绘制。可以利用深度测试来解决此问题。
分两步走。第一步,用GL_FILL方式绘制所有的面,此时应该把颜色缓冲区设置为只读,这样既可以在深度缓冲区里面填入正确的深度值,同时又不影响任何一个像素的颜色。第二步,用GL_LINE方式绘制所有的面,此时,如果某一条边是被遮挡的,则它的各个像素都不会通过深度测试,于是不会被绘制,如果某一条边是不被遮挡的,则它的各个像素都(几乎)能通过深度测试,于是被绘制出来。
注意这个“几乎”,这个涉及到z-fighting的问题,可以使用多边形偏移来解决。具体的做法是,在第一步绘制的时候,让计算得到的深度值加上一个偏移,从而使第二步绘制的像素更加容易通过深度测试。
可能描述不是很清楚,还是看代码吧:
[code=c]#include <GL/glut.h>
GLfloat rotate = 0.0f;
void DrawObjects() {
glPushMatrix();
glRotatef(rotate, 0.0f, 1.0f, 0.0f);
// 在(0, 0, 0)处,显示大小为50的立方体
glPushMatrix();
glTranslatef(0, 0, 0);
glutSolidCube(50);
glPopMatrix();
// 在(30, 0, 20)处,显示大小为50的立方体
glPushMatrix();
glTranslatef(30, 0, 20);
glutSolidCube(50);
glPopMatrix();
// 在(-20, 0, 30)处,显示大小为30的球
glPushMatrix();
glTranslatef(-20, 0, 30);
glutSolidSphere(30, 10, 10);
glPopMatrix();
// 在(10, 25, 0)处,显示大小为20的茶壶
glPushMatrix();
glTranslatef(10, 25, 0);
glutSolidTeapot(20.0);
glPopMatrix();
glPopMatrix();
}
void display() {
// 清除颜色缓冲和深度缓冲
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 设置可视范围
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, 1.0, 1.0, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 100, -300, 0, 0, 0, 0, 1, 0);
// 第一遍绘制
// 把颜色缓冲设置为只读,这样一来,只有深度缓冲区受到影响
// 此时应该把绘制方式设置为GL_FILL
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
DrawObjects();
// 第二遍绘制
// 把颜色缓冲区恢复为可写模式
// 把绘制方式设置为GL_LINE
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
DrawObjects();
glutSwapBuffers();
}
void idle() {
rotate += 1.0f;
if (rotate >= 360.0f) {
rotate = 0.0f;
}
glutPostRedisplay();
}
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition(100, 100);
glutInitWindowSize(512, 512);
glutCreateWindow("test");
glutDisplayFunc(&display);
glutIdleFunc(&idle);
// 启用深度测试和多边形偏移
glEnable(GL_DEPTH_TEST);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(1.0f, 1.0f);
glutMainLoop();
return 0;
}[/code]
[img]http://blog.pfan.cn/upfile/201008/20100821044836.gif[/img]
板凳
nansure [专家分:0] 发布于 2010-08-21 16:58:00
谢谢,按照你的方法已经做好了
3 楼
moke9 [专家分:30] 发布于 2010-09-02 07:16:00
你好.我是全职网赚工作者.
如果你有时间有电脑.
想在网络上创业.请联系我..
项目绝对真实.详情QQ空间资料
加盟请联系 QQ908889846
我来回复