在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函数的效果,隐藏形状内部的直线,以及未做内部直线隐藏的效果:

隐藏形状内部的直线

显示全部的直线

在3D空间中绘制四边形

时间: 2024-10-06 22:19:40

在3D空间中绘制四边形的相关文章

OpenGl学习进程(9)在3D空间的绘制实例

    本节将演示在3D空间中绘制图形的几个简单实例:     (1)在3D空间内绘制圆锥体: #include <GL/glut.h> #include <math.h> #pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"") #define PI 3.1416 GLfloat xRot = 0; GLfloat yRot =

3D空间中射线与轴向包围盒AABB的交叉检测算法

引言 在上一节中,我讲述了如何实现射线与三角形的交叉检测算法.但是,我们应该知道,在游戏开发中,一个模型有很多的三角形构成,如果要对所有的物体,所有的三角形进行这种检测,就算现在的计算机运算能力,也是无法高效的完成.所以,我们需要通过其他的手段来提早剔除一些不可能发生交叉的物体,这种早退的思想,大量的运用在3D游戏技术中.在本篇文章中,我将像大家讲述如何实现射线与轴向包围盒AABB的交叉检测.如果读者不明白什么是轴向包围盒,请看这篇文章. Ray-AABB交叉检测算法 现如今,有很多的Ray-A

Qt_OpenGL:3D空间中移动图像

Qt_OpenGL:3D空间中移动图像 //.h #ifndef GLWIDGET_H #define GLWIDGET_H #include <QGLWidget> #include <QtOpenGL> class QGLWidget; class QTimer; typedef struct Stars{ public: int r, g, b; GLfloat dist, angle; }Stars; class GLWidget : public QGLWidget {

使3D空间中物体朝向和其速度方向一致的旋转矩阵计算方案

在3D空间中的物体以某一速度运动,有时候需要这个物体的朝向和速度的方向一致, 为了实现这个目标我们一般借助旋转矩阵 M 来将物体旋转到对应的朝向. 例如速度方向矢量 spdV: Vector3D(1,2,3), X轴基向量为 axis_x: Vector3D(1,0,0), 这个矢量的方向和3D物体不做任何旋转时候的默认朝向一致 3D矢量 cross_x 记录了 axis_x 叉乘 spdV 的结果. 算出矩阵 M 的方法一: 先计算出 spdV 和 axis_x 两矢量之间的弧度值 rad(可

3D空间中射线与三角形的交叉检测算法

引言 射线Ray,在3D图形学中有很多重要的应用.比如,pick操作就是使用射线Ray来实现的,还有诸如子弹射线的碰撞检测等等都可以使用射线Ray来完成.所以,在本次博客中,将会简单的像大家介绍下,如何进行Ray-Triangle的交叉检测. Ray-Triangle交叉检测算法 在Tomas Moller的MT97论文中,提出了一种新的算法.这种算法能够减少以前进行Ray-Triangle交叉检测所需要的内存消耗.在以前,进行Ray-Triangle交叉检测,主要是计算射线与三角形所构成的平面

2D和3D空间中计算两点之间的距离

自己在做游戏的忘记了Unity帮我们提供计算两点之间的距离,在百度搜索了下. 原来有一个公式自己就写了一个方法O(∩_∩)O~,到僵尸到达某一个点之后就向另一个奔跑过去 /// <summary> /// 3维中如何计算两点之间的距离 /// </summary> /// <param name="p1"></param> /// <param name="p2"></param> /// &l

3D空间中射线与轴向包围盒AABB的交叉检测算法【转】

引言 在上一节中,我讲述了如何实现射线与三角形的交叉检测算法.但是,我们应该知道,在游戏开发中,一个模型有很多的三角形构成,如果要对所有的物体,所有的三角形进行这种检测,就算现在的计算机运算能力,也是无法高效的完成.所以,我们需要通过其他的手段来提早剔除一些不可能发生交叉的物体,这种早退的思想,大量的运用在3D游戏技术中.在本篇文章中,我将像大家讲述如何实现射线与轴向包围盒AABB的交叉检测.如果读者不明白什么是轴向包围盒,请看这篇文章. Ray-AABB交叉检测算法 现如今,有很多的Ray-A

3D空间中射线与轴向包围盒AABB的交叉检测算法 【转】

http://blog.csdn.net/i_dovelemon/article/details/38342739 引言 在上一节中,我讲述了如何实现射线与三角形的交叉检测算法. 但是,我们应该知道,在游戏开发中,一个模型有很多的三角形构成,如果要对所有的物体,所有的三角形进行这种检测,就算现在的计算机运算能力,也是无法高 效的完成.所以,我们需要通过其他的手段来提早剔除一些不可能发生交叉的物体,这种早退的思想,大量的运用在3D游戏技术中.在本篇文章中,我将像大家讲 述如何实现射线与轴向包围盒A

Direct3D 11 Tutorial 4: 3D Spaces_Direct3D 11 教程4:3D空间

概述 在上一个教程中,我们在应用程序窗口的中心成功渲染了一个三角形. 我们没有太注意我们在顶点缓冲区中拾取的顶点位置. 在本教程中,我们将深入研究3D位置和转换的细节. 本教程的结果将是渲染到屏幕的3D对象. 虽然之前的教程侧重于将2D对象渲染到3D世界,但在这里我们展示了一个3D对象. 资源目录 (SDK root)\Samples\C++\Direct3D11\Tutorials\Tutorial04 Github仓库 3D空间 在上一个教程中,三角形的顶点被有策略地放置,以在屏幕上完美地对