概述
OpenGL
OpenGL是渲染2D、3D矢量图形硬件的一种软件接口。本质上说,它是一个3D图形和模型库,具有高度的可移植性,并且具有非常快的渲染速度。OpenGL并不是一种语言,而是更像一个C运行时函数库。它提供了一些预包装的功能,帮助开发人员编写功能强大的三维应用程序。 OpenGL可以再多种操作系统平台上运行,例如各种版本的Windows、UNIX/Linux、Mac OS 和 OS/2等。如今,OpenGL广泛流行于游戏、医学影像、地理信息、气象模拟等领域,是高性能图像和交互性场景处理的工业标准。
OpenGL的高效实现(利用了图形加速硬件)存在于Windows,部分UNIX平台和Mac OS。这些实现一般由显示设备厂商提供,而且非常依赖于该厂商提供的硬件。
OpenGL ES与WebGL
OpenGL ES (OpenGL for Embedded Systems) 是 OpenGL 三维图形 API 的子集,针对手机、PDA和游戏主机等嵌入式设备而设计
WebGL(全写Web Graphics Library)是一种3D绘图协议,这种绘图技术标准允许把JavaScript和OpenGL ES 结合在一起,通过增加OpenGL ES 的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化。
OpenGL发展史
2006年,SGIG公司把OpenGL标准的控制从ARB移交给一个新的工作组:Khronos小组(www.khronos.org)。 Khronos是一个由成员提供资金的行业协会,专注于开放媒体标准的创建和维护。
软件安装
在正式开始学习OpenGL之前,我们需要先配置好OpenGL的软件环境。
IDE
支持OpenGL的IDE有很多,OpenGL的开发环境我们选择的是Visual Studio,可以从Visual Studio官 下载最新的版本。
GLFW
OpenGL是一个图形库,而要画图,就需要先创建一个窗口。不幸的是,OpenGL并没有提供创建窗口的功能,必须自己创建窗口。而创建窗口在每一个操作系统上都不同的(在Windows上代码量也不少),为了方便,我们会使用一个窗口库来简化这一过程。常用的OpenGL窗口库有GLUT、GLFW和SDL,此处为我们选择使用得比较多的GLFW。
Visual Studio对于OpenGL(gl.h)只支持到1.1,而我们使用的是OpenGL 3.3。但是,OpenGL是由显卡支持的,显卡已经提供了我们需要的OpenGL函数。因此就需要在运行程序时动态地获取函数地址。在Windows下,以glGenBuffers为例,大概是这样的:
当然,GLFW可以从它的官方 站上下载。然后,你可以直接下载它的binaries,或者自己使用CMake编译。如果自己使用CMake编译,可以参考下面的文章: GLFW 环境配置,创建窗口
如果下载已经编译好的binaries,解压并打开,可以找到一个include文件夹和若干lib-xxxx文件夹(xxxx是编译器名)。include文件夹里含有一个GLFW文件夹,里面有glfw3.h(还有一个glfw3native.h不用管)
详细文档可以参考官方的介绍,或者直接从GLFW官方 站的下载页上获取源代码包。
OpenGL基础知识
数据类型和函数名
OpenGL的数据类型定义可以与其它语言一致,但建议在ANSI C下最好使用以下定义的数据类型,例如GLint、GLfloat等。
前缀 | 数据类型 | 相应C语言类型 | OpenGL类型 |
---|---|---|---|
b | 8-bit integer | signed char | GLbyte |
s | 16-bit integer | short | GLshort |
i | 32-bit integer | long | GLint,GLsizei |
f | 32-bit floating-point | float | GLfloat,GLclampf |
d | 64-bit floating-point | double | GLdouble,GLclampd |
ub | 8-bit unsigned integer | unsigned char | GLubyte,GLboolean |
us | 16-bit unsigned integer | unsigned short | GLushort |
ui | 32-bit unsigned integer | unsigned long | GLuint,GLenum,GLbitfield |
从上表可以看出,OpenGL的库函数命名方式很有规律,了解这种规律后阅读和编写程序都比较容易方便。
首先,每个库函数有前缀gl、glu、glx或aux,表示此函数分属于基本库、实用库、X窗口扩充库或辅助库,其后的函数名头字母大写,后缀是参数类型的简写,取i、f。例如:
如上,有的函数参数类型后缀前带有数字2、3、4。其中,2代表二维,3代表三维,4代表alpha值。
除此之外,有些OpenGL函数最后带一个字母v,表示函数参数可用一个指针指向一个向量(或数组)来替代一系列单个参数值。下面两种格式都表示设置当前颜色为红色,二者等价。
除了以上基本命名方式外,还有一种带“”星 的表示方法,例如glColor(),它表示可以用函数的各种方式来设置当前颜色。同理,glVertex*v()表示用一个指针指向所有类型的向量来定义一系列顶点坐标值。
示例
例如有下面一个示例程序,也是一个初学者学习的第一个示例程序。源码如下:
运行效果如下:
多边形
OpenGL中定义的多边形是由一系列线段依次连结而成的封闭区域。这些线段不能交叉,区域内不能有空洞,多边形必须在凸多边形,否则不能被OpenGL函数接受。
图元标志
点函数glBegin(GLenum mode)标志描述一个几何图元的顶点列表的开始,其参数mode表示几何图元的描述类型。所有类型及说明见下表:
类型 | 说明 |
---|---|
GL_POINTS | 单个顶点集 |
GL_LINES | 多组双顶点线段 |
GL_POLYGON | 单个简单填充凸多边形 |
GL_TRAINGLES | 多组独立填充三角形 |
GL_QUADS | 多组独立填充四边形 |
GL_LINE_STRIP | 不闭合折线 |
GL_LINE_LOOP | 闭合折线 |
GL_TRAINGLE_STRIP | 线型连续填充三角形串 |
GL_TRAINGLE_FAN | 扇形连续填充三角形串 |
GL_QUAD_STRIP | 连续填充四边形串 |
上面表用几何图形表示的化,如下图。 
在glBegin()和glEnd()之间最重要的信息就是由函数glVertex*()定义的顶点,必要时也可为每个顶点指定颜色、法向、纹理坐标或其他,即调用相关的函数,如下表。
函数 | 说明 |
---|---|
glVertex*() | 设置顶点坐标 |
glColor*() | 设置当前颜色 |
glIndex*() | 设置当前颜色表 |
glNormal*() | 设置法向坐标 |
glCallList(),glCallLists() | 执行显示列表 |
glTexCoord*() | 设置纹理坐标 |
glEdgeFlag*() | 控制边界绘制 |
glMaterial*() | 设置材质 |
看一个示例:
示例
为了更好的理解OpenGL几何图形的绘制,下面看一个综合的示例。
运行效果如下图:
坐标空间
openGL 空间分为:
- 局部空间(Local Space,或者称为物体空间(Object Space))
- 世界空间(World Space)
- 观察空间(View Space,或者称为视觉空间(Eye Space))
- 裁剪空间(Clip Space)
- 屏幕空间(Screen Space)
局部空间
局部空间是指物体所在的坐标空间,即对象最开始所在的地方。想象你在一个建模软件中创建了一个立方体。你创建的立方体的原点有可能位于(0, 0, 0),即便它有可能最后在程序中处于完全不同的位置。甚至有可能你创建的所有模型都以(0, 0, 0)为初始位置。所以,你的模型的所有顶点都是在局部空间中,它们相对于你的物体来说都是局部的。
世界空间
如果我们将我们所有的物体导入到程序当中,它们有可能会全挤在世界的原点(0, 0, 0)上,这并不是我们想要的结果。我们想为每一个物体定义一个位置,从而能在更大的世界当中放置它们。世界空间中的坐标正如其名:是指顶点相对于世界的坐标。如果你希望将物体分散在世界上摆放(特别是非常真实的那样),这就是你希望物体变换到的空间。物体的坐标将会从局部变换到世界空间;该变换是由模型矩阵(Model Matrix)实现的。
模型矩阵是一种变换矩阵,它能通过对物体进行位移、缩放、旋转来将它置于它本应该在的位置或朝向。你可以将它想像为变换一个房子,你需要先将它缩小(它在局部空间中太大了),并将其位移至郊区的一个小镇,然后在y轴上往左旋转一点以搭配附近的房子。你也可以把上一节将箱子到处摆放在场景中用的那个矩阵大致看作一个模型矩阵;我们将箱子的局部坐标变换到场景/世界中的不同位置。
观测空间
观察空间经常被人们称之OpenGL的摄像机(Camera)(所以有时也称为摄像机空间(Camera Space)或视觉空间(Eye Space))。观察空间是将世界空间坐标转化为用户视野前方的坐标而产生的结果。因此观察空间就是从摄像机的视角所观察到的空间。而这通常是由一系列的位移和旋转的组合来完成,平移/旋转场景从而使得特定的对象被变换到摄像机的前方。这些组合在一起的变换通常存储在一个观察矩阵(View Matrix)里,它被用来将世界坐标变换到观察空间。
裁剪空间
在一个顶点着色器运行的最后,OpenGL期望所有的坐标都能落在一个特定的范围内,且任何在这个范围之外的点都应该被裁剪掉(Clipped)。被裁剪掉的坐标就会被忽略,所以剩下的坐标就将变为屏幕上可见的片段。这也就是裁剪空间(Clip Space)名字的由来。
因为将所有可
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!