首页 > 代码库 > OpenGL学习05-绘制实心物体

OpenGL学习05-绘制实心物体

       使用三角形或者多边形结合在一起,我们可以绘制实心物体(3D物体)。本篇中使用三角形绘制圆锥形。

下面测试第一个OpenGL程序:

void renderScene(void)  
{  
float angle;float x, y;
static int triangleNum = 1;
//清除颜色缓冲区和深度缓冲区
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
glPushMatrix();
 
glEnable(GL_DEPTH_TEST);//使能深度测试功能
glFrontFace(GL_CW);//将环绕方式更改为顺时针
glShadeModel(GL_FLAT); //使用单调着色模式
 
glBegin(GL_TRIANGLE_FAN);
 
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
 
glBegin(GL_TRIANGLE_FAN);	//绘制三角扇形
glVertex3f(0.0f, 0.0f, 50.0f);	//顶点坐标
for(angle = 0.0f; angle <= 2*GL_PI; angle+=(GL_PI/32),triangleNum++){
x = 50.0f * cos(angle);	//计算其他点的坐标
y = 50.0f * sin(angle);
 
if(triangleNum % 2 == 1)
glColor3f(0.0f, 1.0f, 0.0f);
if(triangleNum % 2 == 0)
glColor3f(1.0f, 0.0f, 0.0f);
 
glVertex3f(x, y, -50.0f);
}
glEnd();
glPopMatrix();
glutSwapBuffers();
}  

运行结果,如下图:

 

(1)设置多边形颜色

       颜色实际上是以顶点为单位指定的,而不是以多边形为单位。着色模式决定了多边形是单调着色(最后一个顶点的颜色就是作为整个多边形的填充颜色)还是渐变着色的(根据每个顶点的颜色进行平滑着色)。

       glShadeModel(GL_FLAT);

       告诉OpenGL用当前颜色(也就是这个多边形的最后一个顶点的颜色)填充这个多边形。这就是我们三角形扇中指定下一个顶点前简单的将颜色修改为红色或则绿色的原因。

       glShadeModel(GL_SMOOTH);

       告诉OpenGL根据每一个顶点对三角形进行渐变着色,相邻顶点颜色进行均和。

使用GL_SMOOTH着色方案效果,如下图:


(2)隐藏表面消除

       按下一个箭头键,旋转这个圆锥体,可以发现一些令人不舒服的现象:这个圆锥看上去好像在180度和-180度之间来回摆动,而不是完整的旋转360度。

       之所以出现来回摆动现象的原因是圆锥的底面是在圆锥边花完后才进行绘制的,不管这个圆锥的方向如何,它的底总是出现在最前面,从而产生了来回摆动的幻觉。可以使用一种称为深度测试的特性来消除这种现象。

       深度测试:当一个像素被绘制时,它将被设置一个值(z值),以表示它和观察者之间的距离。以后,当这个屏幕位置需要绘制另外一个像素时,新像素的z值就会和原先已经存在像素的z值比较;如果新像素的z值更高,他就更靠经观察者,因此位于以前那个像素的前面;反之,就不能遮住前面的像素。

       启动深度测试:

              glEnable(GL_DEPTH_TEST);

       关闭深度测试:

              glDisable(GL_DEPTH_TEST);

       在内部,深度测试的任务是由深度缓冲区实现的,它存储屏幕上每个像素的深度值,故每次渲染前需要清空深度缓存区,如下:

       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

       GL_DEPTH_BUFFER_BIT代表的是深度缓存区。

(3)剔除隐藏表面,提高性能

       如果一个表面被隐藏,就不应该绘制这个表面。这样可以获得更好的视觉效果;还能提高渲染的性能,因为每个被绘制的像素必须与以前的像素进行z值比较,如果知道一个表面不需要绘制,就不向硬件发送这个几何图形,就可以显著的提高性能。我们可以使用的剔除技巧之一是背面剔除,它用于消除一个便面的背面。

       启动背面剔除:

              glEnable(GL_CULL_FACE);

       关闭背面剔除:

              glDisable(GL_CULL_FACE);

效果如下图,左边开启了背面剔除,右边未开启背面剔除

 

       当然为了更好的使用背面剔除功能,需要设置环绕方式,默认逆时针方向为正面,顺时针方向为背面;在程序中使用了绘图方式与默认方式相反(程序中三角扇形都是顺时针环绕的),故需要将顺时针设置为正面:

       glFrontFace(GL_CW);

       在绘制闭合物体或者实心物体时,背面剔除是非常有用的。

(4)多边形模式

       多边形并不一定要用当前颜色进行填充。在默认情况下,多边形被绘制成实心的。但是,也可以改变这个行为,指定只绘制多边形外框,甚至只绘制点(只有顶点被绘制)。

       void glPolygonMode (GLenum face, GLenum mode);

       glPolygonMode 函数允许多边形作为实心图形、外框或者点进行渲染。另外,可以对多边形的两个面都应用这个渲染模式,也可以只对多边形的正面或则背面应用这个模式。

       在上面程序中使用glPolygonMode(GL_BACK, GL_LINE);

运行结果,如下图:

 

OpenGL学习05-绘制实心物体