OpenGL 三维图形编程基础 OpenGL 概述 主讲 : 李胜 参考书 OpenGL 编程指南, 机械工业出版社, 俗称 OpenGL 红宝书
第三章 OpenGL 概述 OpenGL 发展历史 OpenGL 基本特点 OpenGL 与 DirectX OpenGL 基本功能 OpenGL 语法特点 OpenGL 状态机制 OpenGL 渲染流水线 OpenGL 相关函数库 使用 GLUT 函数库 使用 WGL 函数库 OpenGL 相关资源 作业 建立 OpenGL 中的重要概念
OpenGL 发展历史 (1/8) 一幅图胜过千言万语 在研究三维图形的过程中, 人们开发了各种图形工具库 ( 软件包, 即一系列函数的集合 ) 第一个图形软件包 : 图形核心系统,GKS ISO( 国际标准化组织 ) 和 ANSI( 美国标准化所 ) 标准 : 层次结构交互图形系统,PHIGS, 扩充后形成 PHIGS+ SGI 的图形库 :GL, 扩充后形成 OpenGL, 实际上的图形工业标准
OpenGL 发展历史 (2/8) OpenGL( 开放性图形库 Open Graphics Library) 标准 GL: 美国 SGI 公司为图形工作站开发的一种功能强大的三维图形机制 经过长期发展, 在跨平台移植的过程中, 由 GL 扩充形成 背靠 SGI 公司, 技术实力强大 研发资金充盈, 由成立于 1992 年的独立财团 OpenGL Architecture Review Board (OARB) 控制
OpenGL 发展历史 (3/8) OpenGL 标准 由 SGI 等 OARB 成员以投票方式产生标准 OARB 公布规范文档 (Specification), 各软硬件厂商据此开发自己系统上的实现 只有通过了 OARB 规范全部测试的实现才能称为 OpenGL
OpenGL 发展历史 (4/8) OpenGL 标准 1.0 版,1992 年 7 月 1.1 版,1995 年 12 月 1.2 版,1998 年 3 月, 最常用版本 1.2.1 版,1998 年 10 月 1.3 版,2001 年 8 月 1.4 版,2002 年 7 月 1.5 版,2003 年 7 月, 2.0 版,2004 年 OpenGL2.0 版本发布 OpenGL 2.0 标准的主要制订者是逐渐在 ARB 中占据主动地位的 3Dlabs opengl2.0 支持 OpenGL Shading Language 新的 shader 扩展特性以及其他多项增强特性 智能手机和 Pocket PC 的 OpenGL ES 2.0 版, 2007
补充 2008 年 8 月初 Khronos 工作组在 Siggraph 2008 大会上宣布了 OpenGL 3.0 图形接口规范,GLSL1.30 shader 语言和其他新增功能将再次未来开放 3D 接口发展指明方向 OpenGL 3.0 API 开发代号为 Longs Peak, 和以往一样,OpenGL 3.0 仍然作为一个开放性和跨平台的 3D 图形接口标准, 在 Shader 语言盛行的今天,OGL3.0 增加了新版本的 shader 语言 :GLSL 1.30, 可以充分发挥当前可编程图形硬件的潜能 同时,OGL3.0 还引入了一些新的功能, 例如顶点矩阵对象, 全帧缓存对象功能,32bit 浮点纹理和渲染缓存, 基于阻塞队列的条件渲染, 紧凑行半浮点顶点和像素数据, 四个新压缩机制等等 2009 年 3 月又公布了升级版新规范 OpenGL 3.1, 也是这套跨平台免费 API 有史以来的第九次更新 OpenGL 3.1 将此前引入的 OpenGL 着色语言 GLSL 从 1.30 版升级到了 1.40 版, 通过改进程序增强了对最新可编程图形硬件的访问, 还有更高效的顶点处理 扩展的纹理功能 更弹性的缓冲管理等等 2009 年 8 月 Khronos 小组发布了 OpenGL 3.2, 这是一年以来 OpenGL 进行的第三次重要升级 该版本仍然延续了 OpenGL 发展的方向让图形程序开发者能在多种操作系统和平台下更好的利用新的 GPU 功能 OpenGL3.2 版本提升了性能表现 改进了视觉质量 提高了几何图形处理速度, 而且使 Direct3D 程序更容易移植为 OpenGL 除 OpenGL 之外,Khronos 还将其开发的其它标准进行了协调改进, 以求可以在更广泛的领域提供强大的图形功能和计算生态系统, 这些标准包括用于并行计算的 OpenCL 用于移动 3D 图形开发的 OpenGL ES 和用于网络 3D 开发的 WebGL 此后推出了 GLSL 1.5OpenGLShading Language(OpenGL 着色语言 ) 的升级版, 以及在 OpenGL3.2 框架下推出了两个新功能, 可以让开发者在开发新程序时能够在使用流水线内核特性或兼容性特性之间做出选择, 其中兼容性特性会提供与旧版 OpenGL 之间的兼容性 2010 年刚刚推出了 Opengl4.0 版, 特性待研究
OpenGL 发展历史 (5/8) OpenGL 成为高性能图形和交互式视景处理的工业标准 SGI IBM DEC SUN HP 等大型硬件厂商都采用 OpenGL 作为三维图形标准 动画软件 Soft Image 动画软件 3D Studio MAX 仿真软件 Open Inventor VR( 虚拟现实 ) 软件 World Tool Kit CAM( 计算机辅助制造 )ProEngineer GIS( 地理信息系统 ) 软件 ARC/INFO 等软件的制造厂商都以 OpenGL 为基础进行开发
OpenGL 发展历史 (6/8) OpenGL 成为高性能图形和交互式视景处理的工业标准 NVIDIA ATI 等显卡制造商支持 OpenGL 标准 Windows 系列 Linux Unix OS/2 等各平台都提供对 OpenGL 的支持
OpenGL 发展历史 (7/8) OpenGL 的普及应用 计算机硬件性能的提高和 OpenGL 本身的不断发展, 使得 OpenGL 不再只属于专用图形工作站 开发人员可以在各种硬件平台利用 OpenGL 进行图形软件开发 进行图形开发实践的必备工具
OpenGL 发展历史 (8/8) OpenGL 并不是唯一 OpenGL 是一个相当流行的高性能图形处理标准, 但并不是唯一的图形处理开发包 世界上还存在比 OpenGL 更优秀 更专业 ( 功能专一, 且纯粹 ) 的开发包, 也许并不是标准, 但应用于一些超高端的 更专业的图形工作站, 服务于一些特定应用 ( 电影制作 游戏等等 )
OpenGL 基本特点 (1/3) 跨平台的工业标准 标准支持灵活 各平台开发商可以自由地开发适合于各自系统的 OpenGL 执行实例 OpenGL 功能可由特定的硬件实现, 也可用纯软件例程实现, 或者以软硬件结合的方式实现, 只要支持标准即可
OpenGL 基本特点 (2/3) 运行稳定, 容易使用 只要硬件支持 OpenGL 标准即可使用 屏蔽硬件细节 具有良好的伸缩性 基于 OpenGL API 的图形应用程序可以运行在许多系统上, 包括各种用户电子设备 PC 工作站以及超级计算机
OpenGL 基本特点 (3/3) 具有良好的扩展性 OpenGL 标准提供了一套良好的功能扩充机制 硬件升级后, 可以遵循 OpenGL 扩展机制提供相应的 OpenGL 函数 一个成功的 OpenGL 扩展会被融入在未来的 OpenGL 版本之中 因此,OpenGL 能紧跟最新硬件发展和计算机图形绘制算法的发展
OpenGL 与 DirectX(1/5) DirectX 简介 DirectX 是 Microsoft 公司开发的底层应用程序接口, 用于 Windows 平台下游戏软件和多媒体系统的开发 DirectX 库采用 COM 组件思想设计, 提供二进制级的组件接口
OpenGL 与 DirectX(2/5) DirectX 简介 DirectX 提供多媒体程序开发所需的全面的 API 支持 图形,DirectX Graphics 声音,DirectSound,DirectMusic 交互,DirectInput 多人网络游戏,DirectPlay 流媒体,DirectShow 现在 DirectX 的稳定版本是 8.0 和 9.0C 最新的 DX10 是只支持 Vista 平台和 Win7 平台
OpenGL 与 DirectX(3/5) OpenGL 与 DirectX 的相同点 在图形绘制部分, 基于相同的计算机图形学原理实现 提供绘制能力相当的图形绘制 API( 现在 Windows 平台上常用的 OpenGL 库, 也是 Microsoft 依据 OpenGL 标准实现的 )
OpenGL 与 DirectX(4/5) OpenGL 与 DirectX 的不同点 OpenGL 是跨平台标准, 且有各个平台的实现 ; DirectX 仅仅应用于 Windows, 由 Microsoft 独立开发 OpenGL 仅仅提供图形绘制功能, 甚至没有交互功能 ;DirectX 则提供了多媒体程序开发所需的全部 API OpenGL 是函数库 ;DirectX 则是组件库 OpenGL 各版本向后兼容 ;DirectX 的体系结构则在不停变化, 并不向后兼容
OpenGL 与 DirectX(5/5) 目前应用 一般显卡厂商都支持 OpenGL 和 DirectX, 同时针对两者进行硬件优化 教学 科研方面 OpenGL 是主流, 游戏开发 商业应用则基本采用 DirectX 需要跨平台应用时, 只能用 OpenGL
OpenGL 基本功能 (1/11) 物体建模与图元 (Primitive) 绘制 矩阵变换 颜色管理 光照和材质 纹理映射 (Texture mapping) 反走样 (Antialiasing) 图像特效 双缓存 (Double buffering) 动画
OpenGL 基本功能 (2/11) 物体建模与图元 (Primitive) 绘制 OpenGL 认为, 所有的物体都是由点 线 多边形构成的, 点 线 多边形被称为图元 (Primitive) OpenGL 一共定义了十种图元 (Primitive)
OpenGL 基本功能 (3/11) 物体建模与图元 (Primitive) 绘制 GL_POINTS GL_LINES GL_LINE_STRIP GL_LINE_LOOP GL_POLYGON GL_TRIANGLES GL_TRIANGLE_STRIP GL_TRIANGLE_FAN GL_QUADS GL_QUAD_STRIP
OpenGL 基本功能 (4/11) 物体建模与图元 (Primitive) 绘制 物体建模的意思就是将物体用图元 (Primitive) 表示, 由于三点决定一个平面, 所以物体常用三角面片来表示, 三角面片越多, 物体越复杂 OpenGL 提供了各种图元的绘制函数, 以及一些复杂三维物体 ( 球 锥 多面体 茶壶 ) 曲线曲面 ( 贝塞尔 NURBS) 的绘制函数
OpenGL 基本功能 (5/11) 矩阵变换 无论多复杂的图形都是由基本图元组成并经过一系列变换来实现的 OpenGL 提供四种基本变换 : 平移 旋转 按比例缩放 镜像 OpenGL 提供两种投影变换 : 平行投影 ( 正射投影 ) 透视投影
OpenGL 基本功能 (6/11) 颜色管理 OpenGL 提供了两种颜色模式 :RGBA 模式, 颜色索引模式 (Color index) RGBA 模式为每个像素点指定颜色, 可提供丰富多彩的色彩效果, 其中 A 是混合因子, 用于各种特效处理 对于显示能力不足的硬件, 可采用颜色索引模式, 系统提供一个颜色表, 通常有 256 或 4096 种颜色, 各像素点通过索引颜色表项得到颜色值
OpenGL 基本功能 (7/11) 光照和材质 在现实生活中, 物体因为受光照射和自身对各种频率光波的吸收与反射能力的不同, 而呈现各自不同的颜色 OpenGL 的实现 假设光仅仅由三原色 (RGB) 组成 物体对三原色分别有不同的反射率 ( 即材质 ) 利用物理光学模型, 计算物体实际的颜色
OpenGL 基本功能 (8/11) 纹理映射 (Texture mapping) 由于物体采用图元 (Primitive) 表示 ( 点 线 多边形 ), 绘制时, 有效渲染的地方也仅仅是这些点 线 多边形, 其它位置的颜色值则通过插值实现, 这就造成了物体绘制的不真实 纹理映射通过贴图的方式, 为物体表面贴上真实的色彩花纹, 这些被指定贴上的图片, 就称作纹理 (Texture) OpenGL 提供了完善的纹理映射机制
OpenGL 基本功能 (9/11) 反走样 (Antialiasing) 线段在计算机中是通过一系列的像素来近似逼近的, 而这些像素实际上是一个个的小正方形, 因此线段常常呈锯齿状, 这被称为走样 (Aliasing) OpenGL 通过计算线段对各个像素的不同覆盖率来实现反走样 (Antialiasing)
OpenGL 基本功能 (10/11) 图像特效 融合 (Blending) 为了使三维图形更加具有真实感, 经常需要处理半透明或透明的物体图像, 这就需要用到融合技术 雾 (fog) 正如自然界中存在烟雾一样,OpenGL 提供了 "fog" 的基本操作来达到对场景进行雾化的效果
OpenGL 基本功能 (11/11) 双缓存 (Double buffering) 动画 出色的动画效果是 OpenGL 的一大特色 OpenGL 通过双缓存实现动画 前台缓存显示当前帧 后台缓存同时进行后续帧的场景计算, 生成画面
OpenGL 语法特点 (1/5) 所有 OpenGL 函数都使用 gl 作为前缀 如 glclearcolor() 所有 OpenGl 常量都使用 GL_ 开头, 并且所有字母都大写 如 GL_FALSE
OpenGL 语法特点 (2/5) OpenGL 函数后缀说明 后缀中的阿拉伯数字一般表示参数的数目 如 glvertex2i(1, 3), 表示该函数有两个参数 阿拉伯数字后的小写字符 ( 一个或多个 ) 表示参数类型 如 glvertex2i(1, 3), 表示该函数的两个参数都为 32 位整数 (Integer) 表示参数类型的后缀定义见下表
OpenGL 语法特点 (3/5) OpenGL 函数后缀说明
OpenGL 语法特点 (4/5) OpenGL 函数后缀说明 有些函数最后一个字母为 v, 则表示该函数参数为向量 (Vector), 即数组 此时, 前面的阿拉伯数字表示可接受向量 ( 数组 ) 的长度 如 glcolor3fv(color_array), 表示 color_array 为一数组, 该数组有三个元素, 每个元素的类型都为 32 位浮点数 (Float)
OpenGL 语法特点 (5/5) OpenGL 数据类型 开发 OpenGL 程序时, 为便于程序移植, 最好使用 OpenGL 的数据类型定义 例如, 尽量使用 GLint, 而不是用 C 或 C++ 的 int
OpenGL 状态机制 (1/2) OpenGL 是一个状态机 (State machine) 设置的状态将一直保持, 直到显示改变 例如, 调用 glcolor3f(1.0, 1.0, 0.0) 设置当前颜色为黄色之后, 除非再次调用 glcolor* 函数, 系统的当前颜色将一直保持为黄色 状态变量通过函数 glenable() 和 gldisable() 进行激活或取消的设置
OpenGL 状态机制 (2/2) 每一个状态变量都有系统默认的缺省值 状态变量的当前值可以通过一系列函数查询 glgetbooleanv() glgetdoublev() glgetfloatv() glgetintegerv() glgetpointerv() glisenabled()
OpenGL 渲染流水线 (1/20) 大多数 OpenGL 应用程序都采用一个相似的操作顺序, 这一系列处理阶段被称作 OpenGL 的渲染流水线 (Pipeline)
OpenGL 渲染流水线 (2/20 ) OpenGL 渲染流水线 顶点数据 Vertex data 求值器 Evaluators 对每个顶点的操作以及图元装配 Per-vertex operations and primitive assembly 显示列表 Display list 光栅化 Rasterization 对每个片元的操作 Per-fragment operations 帧缓存 Framebuffer 像素数据 Pixel data 像素操作 Pixel operations 纹理装配 Texture assembly
OpenGL 渲染流水线 (3/20 ) OpenGL 的渲染流水线的构架基于计算机图形学的基本原理 对于一个实际的 OpenGL 程序, 并不一定会应用渲染流水线中的每一步操作
OpenGL 渲染流水线 (4/20 ) 熟练掌握渲染流水线是学习好 OpenGL 和图形学的关键, 渲染流水线也是学习 OpenGL 和图形学的纲领 以后的每一章节基本上是对流水线某一部分的展开阐述 总而言之, 对于 OpenGL 本身, 这套流水线机制是最重要的, 应该时时复习和回顾
OpenGL 渲染流水线 (5/20) OpenGL 渲染流水线的两条数据处理路径 顶点数据, 基本的几何数据 像素数据, 图像特效, 纹理数据 顶点数据 Vertex data 求值器 Evaluators 对每个顶点的操作以及图元装配 Per-vertex operations and primitive assembly 显示列表 Display list 光栅化 Rasterization 对每个片元的操作 Per-fragment operations 帧缓存 Framebuffer 像素数据 Pixel data 像素操作 Pixel operations 纹理装配 Texture assembly
OpenGL 渲染流水线 (6/20) 顶点数据 物体都用图元 (Primitive) 表示, 图元的实质就是点集, 在 OpenGL 中, 所有的物体 几何元素最终都以顶点的形式描述 顶点数据包括顶点位置 ( 即空间坐标 ) 大小 颜色 顶点法向量 ( 用于光照计算 ) 纹理坐标 ( 可能有多个 ) 等等 顶点数据 Vertex data
OpenGL 渲染流水线 (7/20) 求值器 参数化的曲面曲线 ( 如贝塞尔,NURBS 曲面曲线 ) 并不直接给出顶点, 而是给出一系列控制点及其生成曲面曲线的函数 求值器的功能就是, 通过控制点和生成函数, 得到实际使用的顶点数据 对于非参数化曲面曲线, 这一步是被忽略的 顶点数据 Vertex data 求值器 Evaluators
OpenGL 渲染流水线 (8/20) 对每个顶点的操作 通过模型 视图变换矩阵, 将所有顶点坐标变换为以人眼坐标系下一致的坐标 确定要绘制的场景区域 ( 视图变换, 改变视点的位置和方向 ) 确定模型与要绘制的场景区域的位置关系 ( 模型变换, 移动模型 ) OpenGL 中, 将模型视图变换结合为一个统一的矩阵 变换矩阵同样改变物体的顶点法向量 顶点数据 Vertex data 求值器 Evaluators 对每个顶点的操作以及图元装配 Per-vertex operations and primitive assembly
OpenGL 渲染流水线 (9/20) 对每个顶点的操作 如果激活了纹理, 还可能进行纹理坐标转换, 以及自动纹理坐标的生成 如果激活了光照, 则还需要利用光源 材质 转换后的顶点位置和法向量计算每一个顶点的颜色 顶点数据 Vertex data 求值器 Evaluators 对每个顶点的操作以及图元装配 Per-vertex operations and primitive assembly
OpenGL 渲染流水线 (10/20) 图元装配 通过投影变换, 定义一个适当的视图体 透视投影视图体, 平截台体, 形成正常观察场景 正交投影视图体, 成直角的平行六面体, 应用于建筑设计及计算机辅助设计 顶点数据 Vertex data 求值器 Evaluators 对每个顶点的操作以及图元装配 Per-vertex operations and primitive assembly
OpenGL 渲染流水线 (11/20) 图元装配 某些情况下, 需要进行透视除法, 以得到归一化的设备坐标 对于落在视图体之外的物体, 需要进行裁剪 (Clip) 操作 点裁剪, 直接删除落在视图体之外的顶点 直线 多边形裁剪, 在删除顶点的同时需要增加顶点 ( 即直线 多边形和视图体形成的交点 ) 顶点数据 Vertex data 求值器 Evaluators 对每个顶点的操作以及图元装配 Per-vertex operations and primitive assembly
OpenGL 渲染流水线 (12/20) 图元装配 视区变换, 用来确定最终图像的显示位置和大小 顶点数据 Vertex data 求值器 Evaluators 对每个顶点的操作以及图元装配 Per-vertex operations and primitive assembly
OpenGL 渲染流水线 (13/20) 对每个顶点的操作和图元装配 对象坐标 人眼坐标 裁剪 归一化 窗口坐标 Object Eye Clip Normalize Window 顶点 模型视图矩阵 投影矩阵 透视除法 视区变换 Vertex Modelview matrix Project matrix Perspective division Viewport transform 顶点数据 Vertex data 求值器 Evaluators 对每个顶点的操作以及图元装配 Per-vertex operations and primitive assembly
OpenGL 渲染流水线 (14/20) 光栅化 (Rasterization) 光栅化负责将几何数据和像素数据转换为片元 (Fragment) 片元和将来要显示的像素一一对应 为每一个片元指定颜色和深度值 雾 (Fog) 纹理(Texture) 操作 顶点数据 Vertex data 求值器 Evaluators 对每个顶点的操作以及图元装配 Per-vertex operations and primitive assembly 光栅化 Rasterization
OpenGL 渲染流水线 (15/20) 对每个片元 (Fragment) 的操作 在片元数据最终写入帧缓存前, 还有一系列测试和处理过程 剪取 (Scissor) 测试 alpha 测试 模板 (Stencil) 测试 深度 (Depth) 测试 融合 (Blending) 抖动 (Dithering) 逻辑操作 顶点数据 Vertex data 求值器 Evaluators 对每个顶点的操作以及图元装配 Per-vertex operations and primitive assembly 光栅化 Rasterization 对每个片元的操作 Per-fragment operations
OpenGL 渲染流水线 (16/20) 帧缓存 帧缓存内的数据将直接输出到显示器 可以激活双缓存模式 顶点数据 Vertex data 求值器 Evaluators 对每个顶点的操作以及图元装配 Per-vertex operations and primitive assembly 光栅化 Rasterization 对每个片元的操作 Per-fragment operations 帧缓存 Framebuffer
OpenGL 渲染流水线 (17/20) 像素数据 像素数据的两种获取模式 由程序指定, 直接存放在内存中 从帧缓存中取得上一帧输出图像的数据 像素数据可以直接传递给光栅化过程 像素数据 Pixel data
OpenGL 渲染流水线 (18/20) 像素操作 像素数据的读取 写入 拷贝 像素传递 像素映射 图像的放大 缩小 翻转 其它针对像素的操作 光栅化 Rasterization 对每个片元的操作 Per-fragment operations 帧缓存 Framebuffer 像素数据 Pixel data 像素操作 Pixel operations
OpenGL 渲染流水线 (19/20) 纹理装配 OpenGL 提供了一整套纹理映射的机制 纹理数据的两种获取方式 : 由程序指定, 直接存放在内存中 从帧缓存中取得上一帧输出图像作为纹理数据 纹理数据直接传递给光栅化过程 对每个片元的操作光栅化 Per-fragment Rasterization operations 帧缓存 Framebuffer 纹理装配 Texture assembly
OpenGL 渲染流水线 (20/20) 显示列表 (Display list) 显示列表就是一组函数集, 可以用来反复执行, 以提高绘制速度 对顶点数据和像素数据的处理都可以用显示列表进行组织
OpenGL 相关函数库 (1/9) OpenGL 核心库 (GL) OpenGL 实用库 (GLU) OpenGL 辅助库 (GLAUX) OpenGL 工具库 (GLUT) OpenGL 对窗口系统的扩展 (WGL, 等等 )
OpenGL 相关函数库 (2/9) 对于各个库, 函数功能可分为两大类 渲染功能 提供图形绘制所需的各种功能函数 窗口管理功能 管理窗口系统的所有相关功能, 如键盘鼠标的响应, 各种窗口事件等等
OpenGL 相关函数库 (3/9) OpenGL 核心库 (GL) 这部分函数用于常规的 核心的图形处理, 是 OpenGL 的核心部分 包含 300 多个函数, 函数名前缀一律是 gl Windows 平台上 头文件 GL.H 库文件 OPENGL32.LIB 动态链接库 OPENGL32.DLL 核心库可以在所有的 OpenGL 平台上运行
OpenGL 相关函数库 (4/9) OpenGL 实用库 (GLU) 这部分函数通过调用核心库的函数, 为开发者提供相对简单的用法, 实现一些较为复杂的操作 如 : 坐标变换 纹理映射 绘制椭球 茶壶等简单多边形 包含约 50 个函数, 函数名前缀一律是 glu Windows 平台上 头文件 GLU.H 库文件 GLU32.LIB 动态链接库 GLU32.DLL 实用库可以在所有的 OpenGL 平台上运行
OpenGL 相关函数库 (5/9) OpenGL 辅助库 (GLAUX) 这部分函数提供窗口管理 输入输出处理以及绘制一些简单三维物体 包含约 30 个函数, 函数名前缀一律是 aux Windows 平台上 头文件 GLAUX.H 库文件 GLAUX.LIB 动态链接库 GLAUX.DLL OpenGL 中的辅助库不能在所有的 OpenGL 平台上运行
OpenGL 相关函数库 (6/9) OpenGL 工具库 (GLUT) 由 Mark Kilgard 开发 这部分函数主要提供基于窗口的工具, 以及一些绘制较复杂物体的函数 包含大约 30 多个函数, 函数名前缀为 glut Windows 平台上 头文件 GLUT.H 库文件 GLUT32.LIB 动态链接库 GLUT32.DLL glut 中的窗口管理函数不依赖于运行环境的, 可以在所有的 OpenGL 平台上运行
OpenGL 相关函数库 (7/9) OpenGL 对窗口系统的扩展 对于各类窗口系统,OpenGL 都提供了一个扩展库 对于 Windows 系统,OpenGL 提供 WGL 库 并不是所有的函数前缀都是 wgl 用于连接 OpenGL 和 Windows, 在 Windows 平台上设置 OpenGL 环境 头文件是 WINGDI.H 只能在 Windows 平台上运行
OpenGL 相关函数库 (8/9) OpenGL 程序开发中, 常用的函数库组合 GL + GLU + GLUT( 跨平台 ) 窗口控制 GLUT, 采用 GLUT 的消息处理机制 图形绘制 GL + GLU + GLUT 中的绘制函数 GL + GLU + WGL( 仅限于 Windows 程序 ) 窗口控制 WGL, 采用 Windows 的消息处理机制 图形绘制 GL + GLU + WGL 中的绘制函数 入门阶段, 最好是使用 GLUT 编制较高级的 Windows 相关的绘制程序时, 最好使用 WGL
OpenGL 相关函数库 (9/9) 函数库的使用方式 包含各个库的头文件 程序中直接声明 include *.h 引用各个库的库文件 在开发工具的工程设置中加入对 *.lib 的引用 将各个库的动态链接库放在系统目录 ( 对于 Windows2000 来说是 WINNT\System32 目录 ) 下或者是程序的运行目录下
使用 GLUT 函数库 (1/25) 创建窗口及初始化操作 回调函数 (Callback function) 程序主循环 使用双缓存 绘制三维物体 一个简单的例子
使用 GLUT 函数库 (2/25) 创建窗口及初始化操作 一共五个函数, 一般在程序开始时连续调用 glutinit(int *argc, char **argv) 初始化 GLUT glutinitdisplaymode(unsigned int mode) 指定所创建窗口的特性, 如, 是 RGBA 模式还是颜色索引模式, 单缓存模式还是双缓存模式, 是否有深度缓存
使用 GLUT 函数库 (3/25) 创建窗口及初始化操作 glutinitwindowposition(int x, int y) 窗口左上角在屏幕上的位置 glutinitwindowsize(int width, int size) 窗口的尺寸, 以屏幕像素为单位 int glutcreatewindow(char *string) 创建 OpenGL 场景窗口,string 是窗口名称, 并返回一个新窗口的标识符
使用 GLUT 函数库 (4/25) 回调函数 (Callback function) 回调函数是一个重要的概念, 是 GLUT 的重要实现机制 在 Windows 所提供的 API 和 DirectX 中, 也有大量的回调函数
使用 GLUT 函数库 (5/25) 回调函数 (Callback function) 回调函数由用户提供, 但由系统 ( 这里是 GLUT) 调用 用户按照系统给定的格式提供回调函数 系统通过注册函数给定回调函数的格式 注册函数和回调函数一一对应, 注册函数负责在系统中登记回调函数
使用 GLUT 函数库 (6/25) 回调函数 (Callback function) 注册函数原型 : RegisterFunc(Type (*func)(parameterlist)) Type 定义了回调函数的返回值类型 ParameterList 定义了回调函数的参数列表 该注册函数对应的回调函数原型 : Type func(parameterlist)
使用 GLUT 函数库 (7/25) 使用回调函数 两个步骤 : 根据注册函数的格式, 声明并定义回调函数 在程序合适的地方, 以回调函数名为参数调用注册函数
使用 GLUT 函数库 (8/25) 常用的 GLUT 回调函数 显示 (Display) 形状改变 (Reshape) 键盘 (Keyboard) 鼠标 (Mouse) 鼠标按键并移动 (Motion) 后台处理
使用 GLUT 函数库 (9/25) 回调函数 - 显示 (Display) 注册函数 void glutdisplayfunc(void (*func)(void)) 回调函数 void func(void) 窗口需要重新绘制时调用该回调函数
使用 GLUT 函数库 (10/25) 重新绘制的显式激活函数 可以在程序中显式的激活绘制回调函数 void glutpostredisplay(void)
使用 GLUT 函数库 (11/25) 回调函数 - 形状改变 (Reshape) 注册函数 void glutreshapefunc(void (*func)(int width, int height)) 回调函数 void func(int width, int height) 窗口移动或者缩放时调用该回调函数 参数 width 和 height 表示新的窗口大小
使用 GLUT 函数库 (12/25) 回调函数 - 键盘 (Keyboard) 注册函数 void glutkeyboardfunc(void (*func)(unsigned int key, int x, int y)) 回调函数 void func(unsigned int key, int x, int y) 按下生成 ASCII 字符的键时调用该回调函数 key 值是生成的 ASCII 字符 x 和 y 是当前鼠标位置
使用 GLUT 函数库 (13/25) 回调函数 - 鼠标 (Mouse) 注册函数 void glutmousefunc(void (*func)(int button, int state, int x, int y)) 回调函数 void func(int button, int state, int x, int y) 按下或释放鼠标按键时调用该回调函数 button 表示是那一个鼠标键 state 表示鼠标键是按下还是释放 x 和 y 是当前鼠标位置
使用 GLUT 函数库 (14/25) 回调函数 - 鼠标按键并移动 (Motion) 注册函数 void glutmotionfunc(void (*func)(int x, int y)) 回调函数 void func(int x, int y) 按下一个或多个鼠标键并拖动鼠标时调用该回调函数 x 和 y 是当前鼠标位置
使用 GLUT 函数库 (15/25) 回调函数 - 后台处理 注册函数 void glutidlefunc(void (*func)(void)) 回调函数 void func(void) 没有其它待处理的事件时, 就执行该回调函数, 可以用来实现无需交互的连续动画处理或进行其它后台处理
使用 GLUT 函数库 (16/25) 程序主循环 void glutmainloop(void) 初始化完成后, 调用该函数, 进入程序主循环 ( 即事件处理循环 ) 循环过程中, 如果有键盘 鼠标 重绘等事件, 系统自动调用相应的回调函数, 回调函数结束后, 程序自动返回主循环
使用 GLUT 函数库 (17/25) 使用双缓存 以 GLUT_DOUBLE 为参数调用 glutinitdisplaymode, 设置双缓存的窗口模式 在显示回调函数的最后调用 glutswapbuffers() 函数
使用 GLUT 函数库 (18/25) 绘制三维物体 GLUT 提供了一些复杂三维模型的绘制函数 每个三维模型都提供了两种绘制模式 线框模式, 仅显示模型的线框图 实体模式, 显示包括阴影效果的完整模型
使用 GLUT 函数库 (19/25) 一个简单的例子 - 程序构成 由五个函数组成 main 函数, 程序主入口 出口函数 init 函数,OpenGL 自身内容初始化, 如设定视点位置, 设置投影矩阵等等 mouse 函数, 响应鼠标消息的回调函数 keyboard 函数, 响应键盘消息的回调函数 display 函数, 响应重新绘制窗口消息的回调函数
使用 GLUT 函数库 (20/25) 一个简单的例子 -main 函数 int main(int argc, char** argv) { glutinit(&argc, argv); glutinitdisplaymode (GLUT_DOUBLE GLUT_RGB); glutinitwindowsize (250, 250); 创建窗口及初始化操作 glutinitwindowposition (100, 100); glutcreatewindow ("hello"); init (); glutdisplayfunc(display); glutkeyboardfunc(keyboard); glutmousefunc(mouse); glutmainloop(); 初始化 OpenGL 自身内容 注册各个回调函数 进入程序主循环 } return 0;
使用 GLUT 函数库 (21/25) 一个简单的例子 -init 函数 简单初始化 OpenGL 自身 void init (void) { glclearcolor (0.0, 0.0, 0.0, 0.0); glmatrixmode(gl_projection); glloadidentity(); glortho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); }
使用 GLUT 函数库 (22/25) 一个简单的例子 - 显示回调函数 绘制一个矩形 void display(void) { glclear (GL_COLOR_BUFFER_BIT); glcolor3f (1.0, 1.0, 1.0); glbegin(gl_polygon); glvertex3f (0.25, 0.25, 0.0); glvertex3f (0.75, 0.25, 0.0); glvertex3f (0.75, 0.75, 0.0); glvertex3f (0.25, 0.75, 0.0); glend(); glutswapbuffers(); }
使用 GLUT 函数库 (23/25) 一个简单的例子 - 键盘消息回调函数 当按下 ESC 键时程序退出 void keyboard(unsigned char key, int x, int y) { } switch (key) { } case 27: exit(0); break;
使用 GLUT 函数库 (24/25) 一个简单的例子 - 鼠标消息回调函数 当点击鼠标左键时程序退出 void mouse(int button, int state, int x, int y) { } switch (button) { } case GLUT_LEFT_BUTTON: break; exit(0);
使用 GLUT 函数库 (25/25) 一个简单的例子 - 通用模板 所有使用 GLUT 的 OpenGL 程序的模式都与本例相似 实现 main 函数, 初始化 OpenGL 环境, 调用 init, 注册各个回调函数, 进入主循环 实现 init 函数 实现各个回调函数
OpenGL 相关资源 (1/2) OpenGL 官方网站 http://www.opengl.org/ NVIDIA 显卡厂商网上技术论坛 http://developer.nvidia.com/page/home ATI 显卡厂商网上技术论坛 http://www.ati.com/developer/ MSDN 上关于 OpenGL 部分的帮助文档 Platform SDK Documentation\Graphics and Multimedia Services\OpenGL
OpenGL 相关资源 (2/2) 辅助资料 OpenGL2.0 Specification OpenGL state machine GLUT 开发包 GLUT3.0 Specification 红宝书电子版 ( 英文 ) 及源码 N.Robins 的 OpenGL 教程