首页 > 代码库 > 在3D空间中绘制四边形

在3D空间中绘制四边形

在3D空间中绘制四边形


四边形 GL_QUADS

         OpenGL的GL_QUADS图元用于绘制四边形,它根据每四个顶点绘制一个四边形。

         注意,在使用四边形时,必需记住一个重要规则:一个四边形的四个角必须位于同一个平面中(不存在弯曲的四边形)。如图所示

 


 

四边形带 GL_QUAD_STRIP

         该图元指定一个连接的四边形带。它们都保持相同方向的环绕。如图所示

 


 

通用多边形 GL_POLYGON

         我们可以用它绘制任意数量的多边形。与四边形一样,多边形的所有顶点也必须位于同一平面中。如果想越过这个规则,可以采用一种变通的方法,使用GL_TRIANGLE_FAN代替GL_POLYGON。如图所示

 

 

多边形的创建规则:

 

1、 第一个规则是所有的多边形都必须是平面的。也就是说,多边形的所有顶点必须位于同一个平面中。在空间中,多边形不能扭曲或弯曲。

2、 第二个规则是多边形的边必须不相交,多边形必须是凸的。

 

注意,OpenGL施加这些限制的原因,是为了使用一些非常快速的算法对多边形进行渲染。


细分和边界

         尽管OpenGL只能绘制凸多边形,但我们仍然能够创建非凸的多边形,那就是把两个或多个多边形排列在一起。我们使用OpenGL命令glPolygonMode可以把绘图模式切换到线框模式,这样就能看到组成较大表面区域的每一个较小的三角形。另外,我们还可以通过glEdgeFlag命令来通知OpenGL哪些线段属于边界线(围绕形状边缘的直线),哪些线段不属于边界线(形状内部的直线),这些形状内部的直线将不可见。下面的程序展示了glEdgeFlag函数的用法,当这个函数设置为true时,接下来所有的顶点都将作为多边形边界线的起点,反之则作为形状内部的直线。

 

/* 程序清单 3-11

 * 2014/5/6

 */

 

#include <glut.h>

#include <math.h>

 

// 设置渲染状态

void SetupRC()

{

         // 设置清除窗口的颜色(黑色背景)

         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

         // 设置绘图颜色为绿色

         glColor3f(0.0f, 1.0f, 0.0f);

}

 

// 绘制场景(显示回调函数)

void RenderScene()

{

         // OpenGL命令,清除颜色缓冲区(使用当前设置的颜色)

         glClear(GL_COLOR_BUFFER_BIT);

         // OpenGL命令,使用线框模式

         glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);

         // 开始绘制三角形

         glBegin(GL_TRIANGLES);

 

                  glEdgeFlag(false);

                  glVertex2f(-20.0f, 0.0f);

                  glEdgeFlag(true);

                  glVertex2f(20.0f, 0.0f);

                  glVertex2f(0.0f, 40.0f);

 

                  glVertex2f(-20.0f, 0.0f);

                  glVertex2f(-60.0f, -20.0f);

                  glEdgeFlag(false);

                  glVertex2f(-20.0f, -40.0f);

                  glEdgeFlag(true);

 

                  glVertex2f(-20.0f, -40.0f);

                  glVertex2f(0.0f, -80.0f);

                  glEdgeFlag(false);

                  glVertex2f(20.0f, -40.0f);

                  glEdgeFlag(true);

 

                  glVertex2f(20.0f, -40.0f);

                  glVertex2f(60.0f, -20.0f);

                  glEdgeFlag(false);

                  glVertex2f(20.0f, 0.0f);

                  glEdgeFlag(true);

 

                  glEdgeFlag(false);

                  glVertex2f(-20.0f, 0.0f);

                  glVertex2f(-20.0f, -40.0f);

                  glVertex2f(20.0f, 0.0f);

 

                  glVertex2f(-20.0f, -40.0f);

                  glVertex2f(20.0f, -40.0f);

                  glVertex2f(20.0f, 0.0f);

                  glEdgeFlag(true);

         // 结束绘制三角形

         glEnd();

        

         // 刷新绘图命令,此时所有未执行的OpenGL命令被执行

         glutSwapBuffers();

}

 

// 当窗口大小改变时由GLUT函数库调用

void ChangeSize(GLsizei w, GLsizei h)

{

         // 范围

         GLfloat nRange = 100.0f;

         // 纵横比

         GLfloat aspectRatio;

         // 防止被0所除

         if (0== h){

                  h = 1;

         }

         // 根据窗口大小设置视口

         glViewport(0, 0, w, h);

 

         // 选择投影矩阵,并重置坐标系统

         glMatrixMode(GL_PROJECTION);

         glLoadIdentity();

         // 计算窗口的纵横比(像素比)

         aspectRatio = (GLfloat) w / (GLfloat)h;

         // 定义裁剪区域(根据窗口的纵横比,并使用正投影)

         if (w<=h) {// <

                  glOrtho(-nRange, nRange,-nRange /aspectRatio, nRange / aspectRatio, -nRange, nRange);

         } else{// >

                  glOrtho(-nRange * aspectRatio,nRange *aspectRatio, -nRange, nRange,-nRange, nRange);

         }

         // 选择模型视图矩阵,并重置坐标系统

         glMatrixMode(GL_MODELVIEW);

         glLoadIdentity();

}

 

int main(int argc,char *argv[])

{

         // 传递命令行参数,并对GLUT函数库进行初始化

         glutInit(&argc, argv);

         // 设置创建窗口时的显示模式(双缓冲区、RGB颜色模式)

         glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);

         // 设置窗口的初始大小

         glutInitWindowSize(480, 320);

         // 创建窗口

         glutCreateWindow("Bounce");

         // 设置显示回调函数

         glutDisplayFunc(RenderScene);

         // 设置当窗口的大小发生变化时的回调函数

         glutReshapeFunc(ChangeSize);

         // 设置渲染状态

SetupRC();

         // 启动GLUT框架的运行,一经调用便不再返回,直到程序终止

         glutMainLoop();

 

         return0;

}

 

程序的运行结果如图所示,分别显示了调用glEdgeFlag函数的效果,隐藏形状内部的直线,以及未做内部直线隐藏的效果:

 

隐藏形状内部的直线

 

显示全部的直线