OpenGL深度问题,z-fighting,不正确遮挡

可爱的小灵儿 2013-11-18 09:51:27
大家好,我是一位OpenGL的初学者,在学习过程中遇到了一些问题。
希望有经验的好心人帮我解答我遇到的问题。
直接进入主题。

时间:2013-11-15
操作系统:windows 7
显卡:Intel(R) HD Graphics
编译环境:visual studio 2008
使用库:glut库

程序目的:
使用OpenGL绘制一个长方体,长宽高分别为:0.618, 0.618^2, 0.618^3
基本设计:
通过绘制长方体的六个面来绘制长方体,六个面用不同的颜色绘制。

问题描述:
在设置了 DEPTH_TEST 并 清除深度缓存的情况下, 六个面并没有按照深度规则遮挡,而是按照绘制顺序遮挡。
代码附再最后。
效果如下图所示。


初步原因分析:
综合检索内容,opengl 的 depth buffer 只保留整数位,而此例中的深度最多没有超过 正负0.618F,
因此,各个面的深度在buffer中是一样的,此时出现了所谓z-fighting问题,造成图形间遮蔽不正确。

解决办法:

我找不到,求好心人解答。
由于我是小菜鸟儿,希望能够给出一定的代码,演示一下怎么操作。


以下是代码:

#include<GL/glut.h>
/*
* Tips:
*
* OpenGL 使用右手直角坐标系, 屏幕左为X, 屏幕上为Y, 屏幕外为Z
*/

static const float X_LEN = 0.618F;
static const float Y_LEN = X_LEN * 0.618F * 0.618F ;
static const float Z_LEN = X_LEN * 0.618F ;

static const float fVertexList[8][3] =
{
{X_LEN * -1.0F, Y_LEN, Z_LEN },
{X_LEN * -1.0F, Y_LEN * -1.0F, Z_LEN },
{X_LEN, Y_LEN * -1.0F, Z_LEN },
{X_LEN, Y_LEN, Z_LEN },
{X_LEN * -1.0F, Y_LEN, Z_LEN * -1.0F },
{X_LEN * -1.0F, Y_LEN * -1.0F, Z_LEN * -1.0F },
{X_LEN, Y_LEN * -1.0F, Z_LEN * -1.0F },
{X_LEN, Y_LEN, Z_LEN * -1.0F }
};

static const float fColorList[6][3] =
{
{0.7F, 0.1F, 0.1F},
{0.1F, 0.7F, 0.1F},
{0.1F, 0.1F, 0.7F},
{0.7F, 0.7F, 0.1F},
{0.7F, 0.1F, 0.7F},
{0.1F, 0.7F, 0.7F}
};

static const GLint iIndexList[6][4] =
{
{0, 1, 2, 3},
{2, 3, 7, 6},
{0, 3, 7, 4},
{0, 1, 5, 4},
{1, 2, 6, 5},
{4, 5, 6, 7}
};

void DrawCube(void)
{
int i = 0;
int j = 0;

glBegin(GL_QUADS);
for (i=0; i<6; i++)
{
// Set color by RGB value.
glColor3fv(fColorList[i]);

// Draw a quad
for (j=0; j<4; j++)
{
glVertex3fv(fVertexList[iIndexList[i][j]]);
}
}
glEnd();

}

static float rotate = 0;
static int times = 0;

void renderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearDepth(1.0F);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();

//glTranslatef(-0.2, 0, 0); // 平移

//glScalef(0.001, 0.001, 0.001); // 缩放
times++;
if(times > 100)
{
times = 0;
}

if(times % 100 == 0)
{
rotate += 0.3;
}

glColor3f(0.4, 0.4, 0.4);

glRotatef(30, 0, 1, 0);
glRotatef(30, 1, 0, 0);
//glRotatef(rotate, 0, 0, 1);

DrawCube();

glPopMatrix();
glutSwapBuffers();
}

void main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(600, 600);
glutCreateWindow("GLDemo");
glutDisplayFunc(renderScene);
glutIdleFunc(renderScene);
glutMainLoop();
}

...全文
199 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
可爱的小灵儿 2013-11-19
  • 打赏
  • 举报
回复
引用 2 楼 jiangcaiyang123 的回复:
开启深度测试,在main()中:
void main(int argc, char **argv) 
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(100,100);
	glutInitWindowSize(600, 600);
	glutCreateWindow("GLDemo");
	glEnable( GL_DEPTH_TEST );// 重点
	glutDisplayFunc(renderScene);
	glutIdleFunc(renderScene);
	glutMainLoop();
}
好吧,我错了。 原来我没开深度测试。 谢谢你的解答。 早知道这么简单,我就不给100分了。
彩阳 2013-11-18
  • 打赏
  • 举报
回复
开启深度测试,在main()中:
void main(int argc, char **argv) 
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(100,100);
	glutInitWindowSize(600, 600);
	glutCreateWindow("GLDemo");
	glEnable( GL_DEPTH_TEST );// 重点
	glutDisplayFunc(renderScene);
	glutIdleFunc(renderScene);
	glutMainLoop();
}
可爱的小灵儿 2013-11-18
  • 打赏
  • 举报
回复
唔唔唔,没人理。

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧