计算机图形学试验指导书.doc_第1页
计算机图形学试验指导书.doc_第2页
计算机图形学试验指导书.doc_第3页
计算机图形学试验指导书.doc_第4页
计算机图形学试验指导书.doc_第5页
已阅读5页,还剩56页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

计算机图形学计算机图形学 实实 验验 指指 导导 书书 Ver 2 0 傅由甲 卢宇 编 重庆理工大学计算机科学与工程学院重庆理工大学计算机科学与工程学院 2008 年 10 月 I 目目 录录 目目 录录 I 1 1 OPENGLOPENGL 与三维图形与三维图形 1 1 1 OPENGL 介绍 1 1 2 OPENGL 函数的语法 3 1 3 OPENGL 是状态机 4 1 4 OPENGL 相关的函数库 4 1 5 OPENGL 的缓冲区 4 2 2 MICROSOFTMICROSOFT VISUALVISUAL C C 6 06 0 MFCMFC 编程基础编程基础 6 2 1 MFC 事件驱动简介 6 2 2 MFC 事件驱动编程 6 2 3 在 VC 下实现 OPENGL 程序的编译 12 实验实验 1 WINDOWS 操作系统图形开发基础操作系统图形开发基础 13 一 实验要求和目的 13 二 相关知识提要 13 三 实验内容及步骤 15 四 实验习题 18 实验实验 2 基本光栅图形生成基本光栅图形生成 19 一 实验要求和目的 19 二 相关知识提要 19 三 实验内容及题目 22 实验实验 3 图形变换图形变换 24 一 实验要求和目的 24 二 相关知识提要 24 三 实验内容及步骤 26 四 实验习题 27 实验四实验四 交互式绘图技术交互式绘图技术 28 一 实验要求和目的 28 二 实验内容及步骤 28 三 实验习题 33 实验五实验五 光照处理光照处理 34 一 实验要求和目的 34 二 相关知识提要 34 三 实验内容及步骤 37 四 实验习题 40 II 实验六实验六 纹理映射纹理映射 41 一 实验要求和目的 41 二 相关知识提要 41 三 实验内容及步骤 44 四 实验习题 45 实验七实验七 曲面生成曲面生成 46 一 实验要求和目的 46 二 相关知识提要 46 三 实验内容及步骤 49 四 实验习题 54 实验八实验八 综合实验 供优秀学生选做 综合实验 供优秀学生选做 55 一 实验要求和目的 55 二 实验内容 55 三 实验步骤 55 1 1 OpenGL 与三维图形 1 1 OpenGL 介绍 我们生活在一个充满三维物体的三维世界中 为了使计算机能精确地再现这些物体 必须能在三维空间描绘这些物体 最近几年计算机图形学的发展使得三维表现技术得以形 成 这些三维表现技术使我们能够再现三维世界中的物体 能够用三维形体来表示复杂的 信息 这种技术就是可视化 Visualization 技术 OpenGL 已被认为是高性能图形和交互 式视景处理的标准 目前包括 ATT 公司 UNIX 软件实验室 IBM 公司 DEC 公司 SUN 公司 HP 公司 Microsoft 公司和 SGI 公司在内的几家在计算机市场占领导地位的大公司都采用 了 OpenGL 图形标准 值得一提的是 由于 Microsoft 公司在 Windows NT Windows97 及后 续版本中提供 OpenGL 图形标准 OpenGL 在微机中广泛应用 人们可以在微机上实现三维 图形应用 如 CAD 设计 仿真模拟 三维游戏等 OpenGL 实际上是一种图形与硬件的接口 它包括了 100 多个图形函数 开发者可以用 这些函数来建立三维模型和进行三维实时交互 为了实现一个完整功能的图形处理系统 设计一个与 OpenGL 相关的系统结构为 其最底层是图形硬件 第二层为操作系统 第三层 为窗口系统 第四层为 OpenGL 第五层为应用软件 由于许多在计算机界具有领导地位的计算机公司纷纷采用 OpenGL 作为三维图形应用 程序设计界面 OpenGL 应用程序具有广泛的移植性 因此 OpenGL 已成为目前的三维图形 开发标准 是从事三维图形开发工作的技术人员所必须掌握的开发工具 OpenGL 作为一个与硬件独立的图形接口 它不提供与硬件密切相关的设备操作函数 同时 它也不提供描述类似于飞机 汽车 分子形状等复杂形体的图形操作函数 用户必 须从点 线 面等最基本的图形单元开始构造自己的三维模型 OpenGL 提供了以下的对三维物体的绘制方式 1 线框绘图方式 wireframe 这种方式仅绘制三维物体的网格轮廓线 2 深度优先线框绘图方式 depth cued 用线框方式绘图 增加模拟人眼看物体 一样的效果 远处的物体比近处的物体要暗些 3 反走样线框绘图方式 antialiased 用线框方式绘图 绘图时采用反走样技 术以减少图形线条的参差不齐 4 平面消隐绘图方式 flat shade 对模型的隐藏面进行消隐 对模型的平面单 元按光照程度进行着色但不进行光滑处理 5 光滑消隐绘图方式 smooth shade 对模型进行消隐按光照渲染着色的过程中 再进行光滑处理 这种方式更接近于现实 6 加阴影和纹理的绘图方式 shadows textures 在模型表面贴上纹理甚至于 加上光照阴影 使得三维景观象照片一样 7 运动模糊的绘图方式 motion blured 模拟物体运动时人眼观察所感觉的动 感现象 8 大气环境效果 atmosphere effects 在三维景观中加入如雾等大气环境效果 使人身临其境 9 深度域效果 depth of effects 类似于照相机镜头效果 模型在聚焦点处清 晰 反之则模糊 2 整个 OpenGL 的基本工作流程如下图 几何顶点数据 显示列表 评价器 逐个顶点操作 和图元组装 纹理映射 光栅化片元操作帧缓冲区 像素数据像素操作 图 1 1 OpenGL 基本工作流程 其中几何顶点数据包括模型的顶点集 线集 多边形集 这些数据经过流程图的上部 包括运算器 逐个顶点操作等 像素数据包括像素集 影像集 位图集等 像素数据的处 理方式与几何顶点数据的处理方式是不同的 但它们都经过光栅化 逐个片元 Fragment 处理直至把最后的光栅数据写入帧缓冲器 在 OpenGL 中的所有数据包括几何顶点数据和像 素数据都可以被存储在显示列表中或者立即可以得到处理 OpenGL 要求把所有的几何图形单元都用顶点来描述 这样运算器和逐个顶点计算操作 都可以针对每个顶点进行计算和操作 然后进行光栅化形成图形片元 对于像素数据 像 素操作结果被存储在纹理组装用的内存中 再象几何顶点操作一样光栅化形成图形片元 整个流程操作的最后 图形片元都要进行一系列的逐个片元操作 这样最后的像素值 被送入帧缓冲器实现图形的显示 在 OpenGL 中进行主要的图形操作直至在计算机屏幕上渲染绘制出三维图形景观的基 本步骤为 1 根据基本图形单元建立景物模型 并且对所建立的模型进行数学描述 OpenGL 中把点 线 多边形 图像和位图都作为基本图形单元 2 把景物模型放在三维空间中的合适的位置 并且设置视点 viewpoint 以观察 所感兴趣的景观 3 计算模型中所有物体的色彩 其中的色彩根据应用要求来确定 同时确定光照 条件 纹理粘贴方式等 4 把景物模型的数学描述及其色彩信息转换至计算机屏幕上的像素 这个过程也 就是光栅化 rasterization 在这些步骤的执行过程中 OpenGL 可能执行其他的一些操作 例如自动消隐处理等 另外 景物光栅化之后被送入帧缓冲器之前还可以根据需要对像素数据进行操作 OpenGL 能够对整个三维模型进行渲染着色 从而绘制出与客观世界十分类似的三维景 象 另外 OpenGL 还可以进行三维交互 动作模拟等 具体的功能主要有以下这些内容 1 模型绘制 OpenGL 能够绘制点 线和多边形 应用这些基本的形体 可以构造出几乎所有的三维 模型 OpenGL 通常用模型的多边形的顶点来描述三维模型 2 模型观察 在建立了三维景物模型后 就需要用 OpenGL 描述如何观察所建立的三维模型 观察 三维模型是通过一系列的坐标变换进行的 模型的坐标变换使观察者能够在视点位置观察 与视点相适应的三维模型景观 在整个三维模型的观察过程中 投影变换的类型决定观察 3 三维模型的观察方式 不同的投影变换得到的三维模型的景象也是不同的 最后的视窗变 换则对模型的景象进行裁剪缩放 即决定整个三维模型在屏幕上的图像 3 颜色模式的指定 OpenGL 应用了一些专门的函数来指定三维模型的颜色 程序开发者可以选择二个颜色 模式 即 RGBA 模式和颜色表模式 在 RGBA 模式中 颜色直接由 RGB 值来指定 在颜色表 模式中 颜色值则由颜色表中的一个颜色索引值来指定 开发者还可以选择平面着色和光 滑着色二种着色方式对整个三维景观进行着色 4 光照应用 用 OpenGL 绘制的三维模型必须加上光照才能更加与客观物体相似 OpenGL 提供了管 理四种光 自发光 环境光 镜面光和漫反射光 的方法 另外还可以指定模型表面的反射 特性 5 图像效果增强 OpenGL 提供了一系列的增强三维景观的图像效果的函数 这些函数通过反走样 混合 和雾化来增强图像的效果 反走样用于改善图像中线段图形的锯齿而更平滑 混合用于处 理模型的半透明效果 雾使得影像从视点到远处逐渐褪色 更接近于真实 6 位图和图像处理 OpenGL 还提供了专门对位图和图像进行操作的函数 7 纹理映射 三维景物因缺少景物的具体细节而显得不够真实 为了更加逼真地表现三维景物 OpenGL 提供了纹理映射的功能 OpenGL 提供的一系列纹理映射函数使得开发者可以十分方 便地把真实图像贴到景物的多边形上 从而可以在视窗内绘制逼真的三维景观 8 实时动画 为了获得平滑的动画效果 需要先在内存中生成下一幅图像 然后把已经生成的图像 从内存拷贝到屏幕上 这就是 OpenGL 的双存技术 double buffer OpenGL 提供了双缓存 技术的一系列函数 9 交互技术 目前有许多图形应用需要人机交互 OpenGL 提供了方便的三维图形人机交互接口 用 户可以选择修改三维景观中的物体 1 2 OpenGL 函数的语法 OpenGL 函数以 gl 为前缀 并把组成函数名的每个单词的首字母进行大写 glClearColor 类似地 OpenGL 还定义了以前缀 GL 开头的常量 所有单词使用大写 形式 并以下划线分割 例如 GL COLOR BUFFER BIT 此外 有些函数 同一函数有 多个不同版本 如 glColor3f glColor3ub glColor3bv 等都用于设置当前绘图颜色 其 中 3 表示函数接受 3 个参数 f 表示参数类型为浮点数 ub 表示参数类型为 8 位 无符号整数 bv 表示参数是含 3 个元素的数组 数组中每个元素为 8 位无符号整数 OpenGL 为同一函数定义不同参数类型的版本主要为了方便用户根据自己的数据格式向 OpenGL 传递参数 表 1 1 列出用于指定数据类型的后缀字母 以供参考 后缀数据类型对应典型 C 语言OpenGL 类型定义 b8 位整数signed charGLbyte s16 位整数shortGLshort 4 i32 位整数int 或 longGLint GLsizei f32 位浮点数floatGLfloat GLclampf d64 位浮点数doubleGLdouble GLclampd ub8 位无符号整数unsigned charGLubyte GLboolean us16 位无符号整数unsigned shortGLushort ui32 位无符号整数unsigned int 或 unsigned longGLuint GLenum GLbitfield 1 3 OpenGL 是状态机 OpenGL 是个状态机 设置它的各种状态 或模式 则这些状态一直生效 直到它们 被修改 OpenGL 所维护的状态变量很多 例如颜色 控制当前视图和投影变换 直线和 多边形点画模式 多边形绘图模式 像素包装约定 光照位置和特征 被绘制物体的材料 属性等 许多表示模式的状态变量可以用 glEnable 和 glDisable 函数进行启用和禁用 每个状态变量 或模式 都有一个默认值 任何时候 都可以向系统查询每个状态变量的 当前值 使用 6 个函数之一完成这个任务 glGetBooleanv glGetDoublev glGetFloatv glGetIntegerv glGetPointerv glIsEnabled 所选择的具体函数取决于希望返回的结果 的数据类型 有些状态变量还有更为特定的查询函数 可以查阅 OpenGL 编程指南 等 参考书 在此不在详述 1 4 OpenGL 相关的函数库 OpenGL 提供了一组功能强大但又比较原始的渲染函数 所有高层绘图操作必须根据 这些函数完成 同样 OpenGL 程序必须使用窗口系统的底层机制 有一些函数库可以用 来帮助简化任务 它们是 1 OpenGL 工具函数库 GLU 包含了一些函数 它们利用低层 OpenGL 函数来执行诸 如为特定视图定向和投影设置矩阵 多边形分格化以及表面渲染等任务 所有 OpenGL 实现都把这个函数库作为它的一部分 GLU 函数都使用前缀 glu 2 所有的窗口系统都提供一个函数库 对该窗口系统的功能进行扩展 以支持 OpenGL 渲染 对于 Microsoft Windows WGL 函数提供了 Windows 到 OpenGL 的 接口 所有的 WGL 函数都使用前缀 wgl 3 OpenGL 实用工具包 GLUT 是 Mark Kilgard 所编写的一个独立于窗口系统的工 具包 其目的是隐藏不同窗口系统 API 的复杂性 GLUT 函数使用前缀 glut 1 5 OpenGL 的缓冲区 OpenGL 需要用到 4 个缓冲区进行图形显示 它们分别是 颜色缓存 深度缓存 模 板缓存和累积缓存 这里我们只介绍颜色缓存和深度缓存的基本概念 更多内容请参阅 OpenGL 编程指南 1 5 1 颜色缓存 颜色缓存由红 绿 蓝 alpha 位等位平面 bitplane 组成的 有前缓存 front 5 buffer 后缓存 back buffer 左前 front left 和右前 front right 缓存 左后 back left 和右后 back right 缓存 左前缓存是必须的颜色缓存 前缓存是可见缓存 后缓存是不可见缓存 前后缓存技术可以实现动画操作 与颜色缓存相关的主要函数有 1 清除颜色缓存 glClear GL COLOR BUFFER BIT 用于清除当前显示缓冲区内 容 为开始新的绘制做好准备 2 设置清除颜色 glClearColor red green blue alpha 用当前颜色 red green blue alpha 清除当前显示缓冲区内容 为开始新的绘制做好准备 3 屏蔽颜色缓存 glColorMask 分别设置红 绿 蓝和 alpha 的可写属性 4 选择颜色缓存 glDrawBuffer 对双缓存中的一个进行选择 5 交换颜色缓存 swapBuffer 交换前后缓存中的颜色 以实现动画 1 5 2 深度缓存 深度缓存也叫 Z buffer 它记录每个像素点所对应的物体点到视点的距离 由此决定 表面的可见性 在进行消隐的时候 OpenGL 必须知道各物体间的相对位置关系 从而模 拟出物体相互遮挡的效果 因此 需要进行深度测试 而深度测试的结果就生成了深度缓 存 与深度缓存相关的 OpenGL 操作主要有 1 清除深度缓存 glClear GL DEPTH BUFFER BIT 用于清除当前显示缓冲区内容 为开始新的绘制做好准备 2 设置清除值 glClearDepth 1 0 1 0 为最大深度 3 屏蔽深度缓存 glDepthMask GL TRUE 表示可以写深度缓存 glDepthMask GL FALSE 表示禁止写深度缓存 4 启动和关闭深度测试 glEnableGL DEPTH TEST 表示开启深度测试 glDisable GL DEPTH TEST 表示禁止深度测试 5 确定测试条件 glDepthFunc 根据函数参数确定测试方式 具体的参数说明请参 考实验五 6 确定深度范围 glDepthRange GLclampd zNear GLclampd zFar 参数 zNear 和 zFar 分别说明视景体的前景和后景面向窗口坐标映射的规格化坐标 便于后续使用 6 2 Microsoft Visual C 6 0 MFC 编程基础 2 1 MFC 事件驱动简介 用 OpenGL 编写的程序结构类似于用其他语言编写的程序 实际上 OpenGL 是一个 丰富的三维图形函数库 编写 OpenGL 程序并非难事 只需在基本 C 语言中调用这些函数 用法同 Turbo C VC 等类似 微软基础类库 Microsoft foundation class MFC 是微软为 Windows 程序员提供的一 个面向对象的 Windows 编程接口 它大大简化了 Windows 编程工作 使开发人员不必从 头设计创建和管理一个标准 Windows 应用程序所需的程序 节省了时间 同时它提供了大 量代码 指导用户编程时实现某些技术和功能 在事件驱动编程方面 通过 MFC 的核心 消息映射机制 定义一个消息与处理函 数的对照表 实现消息处理的分离编程 每当产生一个事件 便可通过这个对照表找到相 应的消息处理函数 执行这个函数完成相应功能 相应的 程序员只需利用 VC 集成开发 环境提供的工具指定当鼠标在哪个 GUI 对象上操作时执行哪个函数即可 MFC 事件驱动 编程模式如图 2 1 所示 2 1 MFC 中事件驱动编程模式 为了提高交互式绘图性能 为以后二维 三维开发打下基础 考虑到 Microsoft Visual C 的 MFC 开发环境提供了 GDI 工具及相对较好的交互式绘图环境 所以 本书采用该 环境进行二维 三维图形的实验 2 2 MFC 事件驱动编程 2 2 1 建立 MFC 工程 步骤一 打开 Microsoft Visual C 6 0 应用程序 在菜单中选择 文件 新建 打开建立用户应用程序对话框 在对话框的 工程 页面左边选择 MFC AppWizard exe 在右边 位置 编辑框中键入要建的项目存放位置 例如 D 盘根目录 在右边 工程 编 辑框中键入要建的项目的名称 例如 MFCTest 这时我们会看到 位置 编辑框中信息变 7 为 D MFCTest 表示我们的项目文件都将存放在这个目录中 如图 2 2 所示 图 2 2 建立 MFC 应用程序 步骤二 我们点击 确定 按钮进行下一步设置 在 MFC AppWizard Step 1 对 话框中有 S 单个文档 M 多个文档 D 基本对话框 三个选项 S 单个文档 表示 用户程序一次只能打开一个文档窗口 M 多个文档 表示用户程序除了一个文档主窗口 外 还可以打开若干个显示不同文档的小窗口 即子窗口 D 基本对话框 表示用户程 序的界面是对话框形式的 这里我们选择 S 单个文档 然后 单击 下一个 按钮 如 图 2 3 所示 图 2 3 MFC AppWizard Step 1 步骤三 MFC AppWizard Step 2 of 6 对话框是关于所建立的程序是否用到数据库 我们选择 否 然后 单击 下一个 按钮 步骤四 MFC AppWizard Step 3 of 6 对话框是关于所建立的程序是否用到复合文 档 我们选择 否 然后 单击 下一个 按钮 步骤五 MFC AppWizard Step 4 of 6 对话框是关于所建立的程序的特点及是否支 持打印及预览 我们选择其默认设置 单击 下一个 按钮 8 步骤六 MFC AppWizard Step 5 of 6 对话框是关于所建立的程序的风格等的设置 我们选择其默认设置 单击 下一步 按钮 步骤七 MFC AppWizard Step 6 of 6 对话框我们看到 VC 开发环境已经为我们的 用户程序生成了四个类 包括它们的类名 头文件 h 实现文件 cpp 及基类 单击 完 成 按钮 完成 MFC 应用程序框架的建立 如图 2 4 所示 图 2 4 MFC AppWizard Step 6 of 6 完成了 MFC 应用程序框架后我们看到 MFC 用户程序开发环境 如图 2 5 所示 图 2 5 MFC 用户程序开发环境 开发环境的左边是项目工作区 有三页 依次为类视图 ClassView 资源视图 ResourceView 及文件视图 FileView 分别对应生成的类 项目资源及相应文件 开 发环境右边文档区中则显示相应类的具体代码 9 2 2 2 编译和运行 MFC 用户程序项目 现在开发环境已为我们搭建好了框架 我们只需对其进行编译和连接就可以得到一个 用户程序的框架 步骤一 在前面打开 MFCTest 项目中 选择菜单的 编译 Build 全部重建 Rebuild All 对刚才生成的应用程序框架进行编译和连接 成功后在开发环境的输出栏里 看到 MFCTest exe 0 error s 0 warning s 提示 步骤二 选择菜单的 编译 执行 MFCTest exe 可看到生成的 MFC 应用程序 框架 如图 2 6 所示 图 2 6 MFCTest 应用程序框架 2 2 3 关闭和打开用户程序项目 要关闭 MFCTest 项目 只需选择菜单的 文件 关闭工作区 Close Workspace 反之 要打开一个已存在的用户程序项目 选择菜单项 文件 打开工 作区 Open Workspace 在弹出的文件对话框中找到要打开的项目名称 这里是 D MFCTest MFCTest dsw 如图 2 7 所示 图 2 7 打开 MFCTest 项目 10 2 2 4 在 MFC 中建立新类的方法 右键单击项目工作区的类视图页面的项目名称 在右键菜单中选择 New Class 弹出如图 2 8 所示 新类 New Class 对话框 图 2 8 建立新类 在 Class type 中选择新建类的类型 其中 Generic Class 表示新建一般类 这也是本 书实验中建类时经常用到的选项 在 Name 栏中键入类名 按照 VC 约定 新类以 C 作为 前缀 表示建立的是一个类 VC 将新建的类按头文件 h 和实现文件 cpp 分开保存 并 以去掉 C 前缀的类名作为文件名 如果建立的类是一个派生类 则在 Bass class 栏 中选择基类 最后点 OK 键完成类的建立 2 2 5 在 MFC 中添加类成员变量和成员函数的方法 右键单击项目工作区的类视图页面中需添加成员的类名 在右键菜单中选择 Add Member Function 添加成员函数 或者 Add Member Variable 添加成员变量 根 据约定 类的成员变量名一律以 m 为前缀 以便和临时变量或全局变量区别 2 2 6 在 MFC 中添加菜单项方法 步骤一 切换到项目左边工作区的资源视图页 ResourceView 双击 Menu 文件 夹下的 IDR MAINFRAME 则项目右边出现菜单栏 如图 2 9 所示 11 图 2 9 菜单编辑界面 步骤二 双击菜单栏上的预留菜单项 弹出菜单项属性对话框 在其标题栏中输入菜 单项标题 如 茶壶 在 ID 栏中给菜单项取一个 ID 号 如图 2 10 所示 如果没有取 系统自动命名该菜单项 ID 如果对自动命名的 ID 不满意 大多数情况 可以再次打开属 性对话框 给菜单项取一个自己满意的 ID 2 10 菜单项属性对话框 2 2 7 在 MFC 中添加消息响应的方法 按照 MFC 规定 对于窗口类 如视图类 对话框类等可以添加事件响应处理函数 方法如下 切换到项目左边工作区的类视图页 ClassView 鼠标右击需添加事件响应的 窗口类 在弹出的下拉列表中选择 Add Windows Message Handler 弹出 New Windows Message and Event Handlers for class 对话框 如图 2 11 所示 该对话框左边框 中以 WM 开头列出所有可供响应的事件消息 右上角框中列出项目中已作处理的响应 事件消息 右下角则列出某个事件消息是哪个类或对象的 当我们要处理某个事件时 如 鼠标左键按下 我们在弹出的对话框中左边双击 WM LBUTTONDOWN 将其添 加到右边的 Existing message Event handlers 列表框中 如图 2 11 所示 然后选择 Add and Edit 则 VC 会自动添加该事件的处理函数 并将界面切换到处理函数位置 供程序 员编写相应的处理代码 菜单栏 预留菜项 单 12 2 11 消息 事件处理对话框 2 3 在 VC 下实现 OpenGL 程序的编译 OpenGL 包括 h 库 lib 库和 dll 库三部分 一般情况下 Windows 操作系统已包含 OpenGL 的核心库 设 VC 安装在 C Program Files 下 则在 VC 6 0 中 h 核心库存放在 C Program Files Microsoft Visual Studio VC98 Include GL 中 lib 核心库存放在 C Program Files Microsoft Visual Studio VC98 Lib 中 dll 核心库存放在 C WINDOWS system32 中 对于 OpenGL 的其它函数库 可放在与核心库相同的文件 夹下 具有 OpenGL 所需的函数库后 在 VC 6 的 Project 菜单下 选择 Setting 项 弹出 Project Setting 对话框 选择 Link 项 在 Libaray 栏目中加入 OpenGL 提供的函数库 opengl32 lib glu32 lib glaux lib 最后 在调用 OpenGL 函数的 C 文件中将函数所在头文件包含进来 就可以使用 OpenGL 了 13 实验实验 1 Windows 操作系统图形开发基础操作系统图形开发基础 一 实验要求和目的 掌握 Windows 图形环境及图形程序开发方法 掌握 MFC 应用程序中 OpenGL 程序开发基本方法 掌握 VC 程序设计方法 二 相关知识提要 1 GDI 工具的使用 1 GDI 工具主要指 MFC 中各种 GDI 图形设备接口 函数 包含了可用于绘制点 线 矩形 多边形 椭圆 位图以及文本的功能函数 VC 中对其进行封装 形成 GDI 对 象类 并派生出以下各类 CBitmap CBrush CPen CFont CPalette CRgn 2 在 MFC 类库中 CPen 类封装了 GDI 的画笔工具 CBrush 类封装了 GDI 的画刷 工具 在定义画笔和画刷工具时 都要调用构造函数创建默认的画笔 黑色 实线 宽度 为一个像素 和画刷 将封闭图形内部填充为白色 绘图时使用画笔和画刷步骤如下 创建 CPen 类对象或 CBrush 类对象 调用合适的成员函数初始化画笔或画刷 将画笔或画刷对象选入当前设备文本对象 并保存原先的画笔或画刷对象 调用绘图函数绘制图形 将原先的画笔或画刷对象选入设备文本对象 以便恢复原来状态 3 颜色的数据类型是COLORREF 表示RGB值是一个32位整数 由RGB 红 绿 蓝 的形式指定 每个分量值从0到255 0最低 255最高 3种颜色分量结合起来产生实际颜色 指定RGB值可以用手工 如0 x00FF0000是纯蓝 也可以用宏RGB 指定 如 RGB 255 0 0 为红色 4 GDI定义画笔风格与含义如表S1 1 表表S1 1 画笔风格与含义画笔风格与含义 画笔风格含义画笔风格含义 PS DASH划线 即虚线PS INSIDEFRAME在边界区域内实线 PS DASHDOT点划线PS NULL空画笔 PS DASHDOTDOT双点划线PS SOLID实线 PS DOT点线 14 5 CBrush 的成员函数 CreateSolidBrush 用颜色来初始化填充画刷 函数原型如下 BOOL CreateSolidBrush COLORREF crColor 此外 还可调用成员函数 CreateHatchBrush 用某种影线来初始化填充画刷 函数原型 为 BOOL CreateHatchBrush int nIndex COLORREF crColor 其中参数 nIndex 用于指定影线模式 其值如表 S1 2 crColor 用于指定画刷颜色 表表 S1 2 画刷影线模式及含义画刷影线模式及含义 阴影模式含义阴影模式含义 HS BDIAGONAL反斜线HS FDIAGONAL斜线 HS CROSS十字线HS HORIZONAL水平线 HS DIAGCROSS斜十字线HS VERTICAL竖线 6 除了使用定制的画笔和画刷外 MFC 中也库存了一部分绘图工具 使用时只需 调用 CDC 成员函数 SelectStockObject 即可 函数原型是 virtual CGdiObject SelectStockObject int nIndex 如果调用成功 返回指向 CGdiObject 对象的指针 实际指向的对象是 CPen 或 CBrush 对象 否则返回 NULL nIndex 是所要选入的库存对象 对于画笔和画刷 值如表 S1 3 表表 S1 3 GDI 库存对象含义库存对象含义 宏代码库存对象宏代码库存对象 BLACK BRUSH黑色画刷NULL BRUSH空画刷 内部不填充 DKGRAY BRUSH深灰色画刷WHITE BRUSH白色画刷 GRAY BRUSH灰色画刷BLACK PEN黑色画笔 HOLLOW BRUSH透明窗口画刷NULL PEN空画笔 什么也不画 LTGRAY BRUSH浅灰色画刷WHITE PEN白色画笔 2 Windows 下开发 OpenGL 程序的基本方法 1 在 MFC 单文档应用程序中 视图类用来显示图形 需要修改该类的成员函数代 码实现 OpenGL 绘图 主要过程如下 改造 OnCreate 函数 开发 OpenGL 绘图程序时 需要设置像素格式 像素格式告诉 OpenGL 绘制风格 颜 色模式 颜色位数和深度位数等重要信息 Windows 平台下 OpenGL 提供了专门函数进行 处理 可以在 OnCreate 函数中定义像素格式 并创建一个 OpenGL 操作所必须的绘图上下文 RC rendering context 使用 PIXELFORMATDESCRIPTOR 结构指定像素格式 使用 wglCreateContext 函数创建绘图上下文 RC 改造 OnSize 函数 当视图发生变化时 应及时将新的客户区尺寸通知 OpenGL 才能够正确在窗口客户 区域显示三维场景的二维影像 通过命令 glViewport 完成该工作 改造 OnDestroy 函数 在 OnDestory 成员中用 wglMakeCurrent 和 wglDeleteContext 断开 OnCreate 成员中 RC 与设备描述表 DC 的连接 并释放 RC 所占资源 改造 OnDraw 函数 在 OnDraw 函数完成每次屏幕的绘制 15 2 在每次绘制场景前 先要清除 OpenGL 显示缓存中的信息 以免影响绘图效果 用 glClearColor 设置屏幕背景颜色 用 glClear 清除显示缓存 这两个函数为 void glClearColor red green blue alpha 背景的 RGBA 信息 void glClear mask 清除标志缓冲区 mask 参数如表 S1 4 所示 表表 S1 4 OpenGL 缓冲区代码及含义缓冲区代码及含义 缓冲区名称缓冲区名称 颜色缓冲区GL COLOR BUFFER BIT累加缓冲区GL ACCUM BUFFER BIT 深度缓冲区GL DEPTH BUFFER BIT模板缓冲区GL STENCIL BUFFER BIT 三 实验内容及步骤 1 创建 My2D 项目和 My3D 项目 建立两个单文档 MFC 项目 一个为 My2D 另一个为 My3D My2D 项目用于二维 GDI 绘图 My3D 项目用于三维 OpenGL 绘图 2 用 GDI 工具绘制不同颜色 线型和线宽的直线 在 My2D 项目中 在 CMy2DView 类中添加 DrawLine 函数如下 void CMy2DView DrawLine CDC pDC CPoint startPoint CPoint endPoint COLORREF color int width unsigned short type 画笔风格 CPen pOldPen CPen newPen 创建一个新画笔 newPen CreatePen type width color 设置画笔属性并初始化画笔 pOldPen pDC SelectObject 将新画笔选进当前设备 并保存原画笔 pDC MoveTo startPoint x startPoint y 将画笔移到直线起点 pDC LineTo endPoint x endPoint y 将画笔移到直线终点 实现绘制 pDC SelectObject pOldPen 将原画笔选进当前设备 恢复原来状态 在 CMy2DView 类中的 OnDraw 函数中调用 DrawLine 函数 粗体为添加部分 画一条 从 300 200 到 600 100 宽度为 2 颜色为红色的虚线 void CMy2DView OnDraw CDC pDC CMy2DDoc pDoc GetDocument ASSERT VALID pDoc DrawLine pDC CPoint 300 200 CPoint 600 100 RGB 255 0 0 2 PS DASH 16 3 用 GDI 工具绘制不同颜色的填充矩形 在 CMy2DView 类中添加 DrawSolidRectangle 函数如下 void CMy2DView DrawSolidRectangle CDC pDC int left int top int right int down COLORREF filledcolor CBrush pOldBrush NULL CBrush SolidBrush SolidBrush CreateSolidBrush filledcolor 设置画刷颜色 并初始化一个实画刷 pOldBrush CBrush pDC SelectObject pDC Rectangle left top right down 绘制矩形 参数分别为左上角点及右下角点x y 坐标 pDC SelectObject pOldBrush 在 CMy2DView 类中的 OnDraw 函数中调用 DrawSolidRectangle 函数 粗体为添加 部分 绘制从左上角 10 20 到右下角 300 500 颜色为绿色的矩形 void CMy2DView OnDraw CDC pDC CMy2DDoc pDoc GetDocument ASSERT VALID pDoc DrawSolidRectangle pDC 10 20 300 500 RGB 0 255 0 4 创建 OpenGL 绘图环境 在 My3D 项目中 在 CMy3DView 头文件中添加包含文件 include 在 CMy3DView 中添加成员变量 HGLRC m hRC CDC m pDC 在 CMy3DView 中添加成员函数 InitOpenGL 如下 BOOL CMy3DView InitOpenGL static PIXELFORMATDESCRIPTOR pfd sizeof PIXELFORMATDESCRIPTOR pfd大小 1 结构版本号 PFD DRAW TO WINDOW 支持窗口 PFD SUPPORT OPENGL 支持OpenGL PFD DOUBLEBUFFER 双缓存 PFD TYPE RGBA RGBA颜色模式 24 24位颜色深度 0 0 0 0 0 0 color bits ignored 0 no alpha buffer 0 shift bit ignored 17 0 不使用累积缓存 0 0 0 0 accum bits ignored 32 32位Z缓冲 0 不使用模板缓存 0 no auxiliary buffer PFD MAIN PLANE 选择主层面 0 保留 0 0 0 layer masks ignored 得到客户区设备上下文 m pDC new CClientDC this if m pDC NULL MessageBox 获得设备上下文失败 return false int pixelFormat ChoosePixelFormat m pDC GetSafeHdc BOOL success SetPixelFormat m pDC GetSafeHdc pixelFormat if success return FALSE 创建绘图上下文RC m hRC wglCreateContext m pDC GetSafeHdc if m hRC 0 MessageBox 绘图上下文RC创建失败 return FALSE if wglMakeCurrent m pDC GetSafeHdc m hRC FALSE MessageBox 关联当前RC失败 return FALSE glShadeModel GL SMOOTH 启用光顺渲染 glClearColor 0 0f 0 0f 0 0f 0 0f 黑色背景 return TRUE 在 CMy3DView 中添加 OnCreate 消息响应函数 并在其中调用 InitOpenGL 函数 在 CMy3DView 中添加 OnSize 消息响应函数如下 void CMy3DView OnSize UINT nType int cx int cy C3DView OnSize nType cx cy if 0 cx 0 cy return select the full client area 18 glViewport 0 0 cx cy 在 CMy3DView 中添加 OnDestroy 消息响应函数如下 void CMy3DView OnDestroy CView OnDestroy wglMakeCurrent NULL NULL wglDeleteContext m hRC if m pDC 释放释放DC delete m pDC m pDC NULL 在 CMy3DView 中添加成员函数 DrawOGLScene 如下 void CMy3DView DrawOGLScene glClear GL COLOR BUFFER BIT 清颜色缓存 glLoadIdentity 在此处添加场景绘制代码 glFinish 强制发出的OpenGL命令完成执行 SwapBuffers m pDC GetSafeHdc 将绘制好的后台缓存内容交换到前台显示 在 OnDraw 函数中调用 DrawOGLScene 函数 5 OpenGL 中绘制渐变三角形 在 DrawOGLScene 函数的 场景绘制代码 处添加如下代码 void CMy3DView DrawOGLScene 在此处添加场景绘制代码 绘制渐变三角形绘制渐变三角形 glBegin GL TRIANGLES 每三个顶点组成一个三角形每三个顶点组成一个三角形 glColor3f 1 0 0 0 0 0 设置顶点颜色设置顶点颜色 glVertex3f 1 0 0 0 0 0 顶点坐标顶点坐标 glColor3f 0 0 1 0 0 0 glVertex3f 0 0 1 0 0 0 glColor3f 0 0 0 0 1 0 glVertex3f 1 0 0 0 0 0 glEnd 19 四 实验习题 1 用 GDI 工具绘制不同颜色 宽度 线型边框 不同填充模式及颜色的矩形 2 用 GDI 工具绘制不同颜色 宽度 线型的折线 折线端点用数组事先存储 3 用 GDI 工具绘制不同颜色 宽度 线型边框 不同填充模式及颜色的椭圆 4 用 OpenGL 在 MFC 应用程序中绘制不同颜色的多边形 20 实验实验 2 基本光栅图形生成基本光栅图形生成 一 实验要求和目的 了解 MFC 常用绘图函数 掌握用中点画圆法绘制二次曲线的方法 掌握常用种子填充算法 掌握用 OpenGL 生成基本图形的方法 二 相关知识提要 1 常用 MFC 绘图函数介绍 绘图函数都要求坐标按逻辑坐标给出 默认时 图形坐标系统的左上角位于 0 0 处 逻辑单位为像素 下面介绍常用 CDC 类的画图成员函数 更多画图函数请参照 MSDN 1 设置像素 画点 COLORREF SetPixel int x int y COLORREF crColor COLORREF SetPixel POINT point COLORREF crColor 2 设置当前位置 CPoint MoveTo int x int y CPoint MoveTo POINT point 3 画直线 BOOL LineTo int x int y BOOL LineTo POINT point 4 画弧 BOOL Arc int x1 int y1 int x2 int y2 int x3 int y3 int x4 int y4 BOOL Arc LPCRECT lpRect POINT ptStart POINT ptEnd 边界矩形由左上角参数 x1 y1 和右下角 x2 y2 或者 lpRect 定义 x3 y3 或者 ptStart 是 弧的起始点 x4 y4 或者 ptEnd 是弧的终止点 5 画矩形 BOOL Rectangle int x1 int y1 int x2 int y2 BOOL Rectangle LPCRECT lpRect 6 画椭圆或圆 BOOL Ellipse int x1 int y1 int x2 int y2 BOOL Ellipse LPCRECT lpRect 21 7 画多边形 BOOL Polygon LPPOINT lpPoints int nCount 参数 lpPoints 为多边形顶点数组地址 nCount 为指定数组的顶点数 8 用指定画刷填充一个矩形区域 但不画边线 void FillRect LPCRECT lpRect CBrush pBrush 9 用指定画刷填充一个封闭区域 BOOL FloodFill int x int y COLORREF crColor 参数 x y 是填充开始点坐标 crColor 是指定边界颜色 该函数用当前画刷从逻辑 点 x y 开始填充某个 crColor 颜色边界的区域 如果点 x y 颜色为 crColor 或者在区 域外 则返回零

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论