首页 > 代码库 > 在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函数的效果,隐藏形状内部的直线,以及未做内部直线隐藏的效果:
隐藏形状内部的直线
显示全部的直线