Microsoft PowerPoint - chapter09.ppt

Similar documents
高级计算机图形学

高级计算机图形学

高级计算机图形学

Microsoft PowerPoint - OpenGL简介.ppt [兼容模式]

高级计算机图形学

OpenGL三维图形编程

Microsoft PowerPoint - cg_ch02_01

PowerPoint Presentation

高级计算机图形学


Microsoft Word - 09.doc

C++ 程序设计 告别 OJ1 - 参考答案 MASTER 2019 年 5 月 3 日 1

OpenCL


地 理 志 鏡 止 煞, 來 達 到 安 宅 的 效 果 4. 門 神 符 紙 : 於 門 板 繪 製 門 神, 作 為 宅 第 的 守 護, 民 宅 所 使 用 的 門 神 題 材, 多 為 天 官 賜 福 或 文 武 官 員 符 紙 是 以 畫 了 符 咒 的 紙 懸 掛 室 內, 或 加 框

绘制OpenCascade中的曲线

fvalue = (pdata[y][i] + pdata[y][i + 1]) / 2; pdata[y][nhalfw + i] -= fvalue; fvalue = (pdata[y][nhalfw - 1] + pdata[y][nhalfw - 2]) / 2; pdata[y][nwi

高级计算机图形学

Microsoft Word - xiuxinduanyu-2-doc.doc

FY.DOC

Photoshop CS6 艺术设计案例教程 ( 第二版 ) 1.1 Photoshop 的应用领域 Photoshop,,, Photoshop Photoshop 的用途 Photoshop CIS ( ) ( ) 案例展现 ~ 1

第3章.doc

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点

C 1

<C8EBC3C5C6AAA3A8B5DA31D5C2A3A92E696E6464>


蘇櫻 慧雪蘇紅櫻 2

内科自诊自疗

Untitiled


chap07.key

BOOL EnumWindows(WNDENUMPROC lparam); lpenumfunc, LPARAM (Native Interface) PowerBuilder PowerBuilder PBNI 2

计算机图形学

Microsoft PowerPoint - cg_ch09_02

C6_ppt.PDF

无类继承.key

《C语言程序设计》教材习题参考答案

Guava学习之Resources

:,, OpenGL,, OpenGL, Windows Visual C ++ OpenGL,,,, CAD CG, : ,,,, ;,, ( CIP) /,,. :, ( 21 ) ISBN

概述

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.07.doc

PowerPoint Presentation

全國寺院宮廟基本資料調查表

handsome-招股书-新规则-final-version-0422.PDF

! " # " " $ % " " # # " $ " # " #! " $ "!" # "# # #! &$! ( % "!!! )$ % " (!!!! *$ ( % " (!!!! +$ % " #! $!, $ $ $ $ $ $ $, $ $ "--. %/ % $ %% " $ "--/

《C语言程序设计》第2版教材习题参考答案

Microsoft PowerPoint - 5. 指针Pointers.ppt [兼容模式]

在挑选合适的 SDK 的时候需要注意, 标准 windows 平台应用选择 FBX SDK VS2015,windows 应用商店和全平台通用的不用考虑 windows 全平台通用的应用是 windows10 新推出的功能, 可以打通 windows phone windows s

“国家高等职业教育会计专业

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基

你的第一本 Photoshop 书 图 1.3 图 1.4 RGB 图 1.5 图 三原色光的概念 R Red G Green B Blue RGB RGB R B 3 1 RGB RGB 256 0~ RGB

res/layout 目录下的 main.xml 源码 : <?xml version="1.0" encoding="utf 8"?> <TabHost android:layout_height="fill_parent" xml


Visual C++ 1 Page no. 1

软件概述

目 录(目录名)

安全注意事项 2. 设置对焦模式 3. 变焦 1. 安装和卸下镜头 4. 固定变焦环 1 2 CHI-2

计算机网络实验说明

Microsoft Word - 文档 1

OOP with Java 通知 Project 4: 5 月 2 日晚 9 点

哈尔滨应用职业技术学院2012年教育教学质量报告

Microsoft PowerPoint - 3. 函数Functionl.ppt [兼容模式]

int *p int a 0x00C7 0x00C7 0x00C int I[2], *pi = &I[0]; pi++; char C[2], *pc = &C[0]; pc++; float F[2], *pf = &F[0]; pf++;

Transcription:

第 9 章 OpenGL 三维建模初步实现 1

主要内容 OpenGL 概述 OpenGL 编程基础

9.1 OpenGL 概述 9.1.1 OpenGL 使人们进入三维图形世界 9.1.2 OpenGL 提供直观的三维图形开发环境 9.1.3 OpenGL 成为目前三维图形开发标准

9.1.1 OpenGL 使人们进入三维图形世界 最近几年的发展使得三维表现技术得以形成, 这些三维表现技术使我们能够再现三维世界中的物体, 能够用三维形体来表示复杂的信息, 这种技术就是可视化 ( Visualization ) 技术 可视化技术赋予人们一种仿真的 三维的并且具有实时交互的能力, 这样人们可以在三维图形世界中用以前不可想象的手段来获取信息或发挥自己创造性的思维 机械工程师可以从二维平面图中得以解放直接进入三维世界, 从而很快得到自己设计的三维机械零件模型 医生可以从病人的三维扫描图象分析病人的病灶 军事指挥员可以面对用三维图形技术生成的战场地形, 指挥具有真实感的三维飞机 军舰 坦克向目标开进并分析战斗方案的效果

9.1.1 OpenGL 使人们进入三维图形世界 人们对计算机可视化技术的研究已经历了一个很长的历程, 而且形成了许多可视化工具, 其中 SGI 公司推出的 GL 三维图形库表现突出, 易于使用而且功能强大 GL 已经进一步发展成为 OpenGL,OpenGL 已被认为是高性能图形和交互式视景处理的标准, 目前包括 ATT 公司 UNIX 软件实验室 IBM 公司 DEC 公司 SUN 公司 HP 公司 Microsoft 公司和 SGI 公司在内的几家在计算机市场占领导地位的大公司都采用了 OpenGL 图形标准

9.1.2 OpenGL 提供直观的三维图形开发环境 OpenGL 实际上它是图形软件和硬件的接口, 有 115 个核心函数, 可以在任何 OPENGL 平台上使用, 函数以 gl 开头 ; 实用库 41 个, 比上面这 115 个函数高一级, 提供高级调用, 函数以 glu 开头 ; 辅助库 31 个, 函数以 aux 开头 ;Windows 专用库函数 6 个, 以 wgl 开头 ;Win32API 函数 5 个, 函数前无专门前缀 OpenGL 提供一系列的三维图形单元供开发者调用 OpenGL 提供一系列的图形变换函数 OpenGL 提供一系列的外部设备访问函数, 使开发者可以方便地访问鼠标 键盘 空间球 数据手套等这种直观的三维图形开发环境体现了 OpenGL 的技术优势, 这也是许多三维图形开发者热衷于 OpenGL 的缘由所在

9.1.3 OpenGL 成为目前三维图形开发标准 没有一种三维工具软件包在交互式三维图形建模能力 外部设备管理以及编程方便程度上能够 OpenGL 相比拟 OpenGL 作为一个三维图形软件包, 它提供了建模 变换 颜色模式设置 光照和材质设置 双缓存动画 纹理映射 位图显示和图像增强七大功能 OpenGL 在硬件 窗口 操作系统方面是相互独立的 OpenGL 是网络透明的, 在客户 服务器 (Client- Server) 体系结构中,OpenGL 允许本地和远程绘图 OpenGL 应用程序具有广泛的移植性 因此,OpenGL 已成为目前的三维图形开发标准, 是从事三维图形开发工作的技术人员所必须掌握的开发工具

9.2 OpenGL 编程基础 9.2.1 OpenGL 基本概念 9.2.2 OpenGL 工作流程 9.2.3 OpenGL 基本语法与程序结构

9.2.1 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)

9.2.2 OpenGL 工作流程 OpenGL 的工作顺序就是一个从定义几何要素到把像素段写入帧缓冲区的过程 1). 构造几何要素 ( 点, 线, 多边形, 图象, 位图 ), 创建对象的数学描述 在三维空间上放置对象, 选择有利的场景观察点 2). 计算对象的颜色, 这些颜色可能直接定义, 或由光照条件及纹理间接给出 图 9-1OpenGL 基本工作流程 3). 光栅化, 把对象的数学描述和颜色信息转换到屏幕的像素 图 9-2-1

1. 数据类型与函数名 2. 状态机制 3. OpenGL 程序的基本结构

1. 数据类型与函数名 OpenGL 的数据类型定义可以与其它语言一致, 但建议在 ANSI C 下最好使用以下定义的数据类型 ( 以 GL 开头 ), 例如 GLint GLfloat 等 具体类型见表 9-1 OpenGL 函数按以下格式命名 : < 库前缀 >< 根命令 >< 可选定参数个数 >< 可选参数类型 > 例如 glcolor4f( ),glusphere( );

2. 状态机制 OpenGL 的工作方式是一种状态机, 它可进行各种状态或模式设置, 这些状态或模式在重新改变它们之前一直有效例 :LSX 中 void CGLView::OnInitialUpdate() { // glenable(gl_line_smooth); // glenable(gl_blend); // 去掉注释观看效果 } void CMannequinView::ShowAllLinesAndPts() { gldisable(gl_lighting); glenable(gl_lighting); // 加上注释观看效果 }

3. OpenGL 程序的基本结构 初始化 : 主要是设置一些 OpenGL 的状态开关 设置观察坐标系下的取景模式和取景框位置及大小 使用 OpenGL 的库函数构造几何物体对象的数学描述, 包括点线面的位置和拓扑关系, 几何变换, 光照处理等等 ( 结合例子分析 )

例 : 圆柱相交程序分析 1. 头文件 2. 主体程序 3. 主要函数简介 4. 实例

1. 头文件 #include <windows.h> #include <gl/gl.h> #include <gl/glu.h> #include <gl/glut.h> #include <math.h> // 数学运算库 这些头文件包含了程序所用的函数原型 所有 Windows 应用程序都需要 windows.h 头文件, 它包含大多数 WIN32 函数原型 其实 GULT 的 WIN32 版本的 glut.h 中包含了 windows.h 接下来的几个头文件定义 OpenGL 的 gl glu glut 函数库的函数原型 math.h 则定义了数学运算库的函数原型

2. 主体程序 int main(int argc, char* argv[]) { glutinit(&argc, argv); glutinitdisplaymode(glut_double GLUT_RGB GLUT_DEPTH); glutcreatewindow(" 两圆柱相交 "); SetupRC(); glutreshapefunc(changesize); glutspecialfunc(specialkeys); glutkeyboardfunc(keyboardhandler); glutdisplayfunc(renderscene); cylinder= glunewquadric(); glutmainloop(); return 0; }

3. 主要函数简介 glutinitdisplaymode(glut_double GLUT_RGB GLUT_DEPTH); // 改成 GLUT_SINGLE, 看效果 SetupRC(); // 改变一些控制开关, 看效果 ChangeSize(); 将 glortho (-nrange*w/h, nrange*w/h, -nrange, nrange, -nrange*2.0f, nrange*2.0f); 替换为 glortho (-nrange, nrange, -nrange, nrange, -nrange*2.0f, nrange*2.0f); 效果??

OpenGL 变换 (1) 相机模拟 图 9-2-2

OpenGL 变换 图 9-2-3

OpenGL 变换 实际上, 从三维空间到二维平面, 就如同用相机拍照一样, 通常都要经历以下几个步骤 1 将相机置于三角架上, 让它对准三维景物 ( 视点变换,Viewing Transformation); 2 将三维物体放在适当的位置 ( 模型变换,Modeling Transformation ); 3 选择相机镜头并调焦, 使三维物体投影在二维胶片上 ( 投影变换,Projection Transformation ) 4 决定二维像片的大小 ( 视口变换,Viewport Transformation )

OpenGL 变换 图 9-2-4 (1) 模型变换 视图变换 ( 两者合称几何变换 ) glmatrixmode (GL_MODELVIEW ) gltranslate (); // 模型 视图变换 glrotate (); // 模型 视图变换 glscale (); // 模型变换 glulookat(); // 视图变换

OpenGL 变换 (2) 投影变换 图 9-2-5 正投影 : void glortho(gldouble left,gldouble right,gldouble bottom,gldouble top,gldouble near,gldouble far) 图 9-2-6 透视投影 : void glfrustum(gldouble left,gldouble Right,GLdouble bottom,gldouble top,gldouble near,gldouble far);

OpenGL 变换 (3) 裁剪变换 图 9-2-7 附加裁平面和视景体 void glclipplane(glenum plane,const GLdouble *equation); 函数定义一个附加的裁剪平面 其中参数 equation 指向一个拥有四个系数值的数组, 这四个系数分别是裁剪平面 Ax+By+Cz+D=0 的 A B C D 值 因此, 由这四个系数就能确定一个裁剪平面 参数 plane GL_CLIP_PLANEi(i=0,1,...), 指定裁剪面号 GLdouble eqn[4] = {1.0, 0.0, 0.0, 0.0}; glclipplane (GL_CLIP_PLANE0, eqn); glenable (GL_CLIP_PLANE0);

OpenGL 变换 (4) 视口变换 图 9-2-8 视景体到视口的映射 定义视口 glviewport(glint x,glint y,glsizei width, GLsizei height); 注意 : 在实际应用中, 视口的长宽比率总是等于视景体裁剪面的长宽比率 如果两个比率不相等, 那么投影后的图像显示于视口内时会发生变形!

4. 显示回调函数 RenderScene(); glmatrixmode(); 该函数指定哪个矩阵为当前的矩阵, 参数为 GL_MODELVIEW GL_PROJECTION GL_TEXTURE; 指定当前的矩阵之后, 接下来的所有矩阵变换都是针对当前的矩阵进行的 RenderScene 中接下来的平移 旋转操作都是对视图矩阵进行的 而在 ChangeSize 函数中要修改修剪区则必须把当前矩阵设为投影矩阵 glpushmatrix() glpopmatrix(); 这两个函数主要是压入和弹出当前模型视图矩阵, 具体作用在前面的矩阵堆栈中有说明 glucylinder(cylinder, 20.0, 20.0, 40.0, 40, 2); void glucylinder( GLUquadricObj * qobj, GLdouble baseradius, GLdouble topradius, GLdouble height, GLint slices, GLint stacks);

glutswapbuffers(); 该函数执行缓冲区的交换, 同时隐含一次刷新, 即让所有尚未执行的 OpenGL 命令都被执行 双缓冲技术使得用户看到的始终是完整的最终合成好的复杂图形 ; 对于动画制作来说, 每一帧都在缓冲区绘制, 完成后再很快的交换到屏幕上, 使得动画效果平滑流畅 5. 建立圆柱体的函数 RenderShaft(void) glbegin(gl_quad_strip); glend(); glbegin/glend 对中可以包括多个顶点, 但它们必须是用于相同的图元类型, 如 glvertex glcolor glindex glnormal glevalcoord glcalllist glcalllists gltexcoord gledgeflag glmaterial

GlBegin 函数中的参数为指定要构造的图元, 它支持以下 OpenGL 图元 :GL_POINTS GL_LINES GL_LINE_STRIP GL_LINE_LOOP GL_TRIANGLES GL_TRIANGLE_STRIP GL_TRIANGLE_FAN GL_QUADS GL_QUAD_STRIP GL_POLYGON 图 9-2-9

ReduceToUnit(normal); OpenGL 中, 通过点光源和法线之间的夹角来判断多边形表明的明暗效果 glnormal3fv(normal); 指定随后顶点或顶点集合定义一个表面法线

glutinitdisplaymode(glut_double GLUT_RGB GLUT_DEPTH); // glutinitdisplaymode(glut_single GLUT_RGB GLUT_DEPTH); GLfloat nrange = 100.0f; //50; glenable(gl_depth_test); // 隐藏被挡住的表面 //gldisable(gl_depth_test); glenable(gl_lighting); // 打开光照 //gldisable(gl_lighting);

4.Bolt 程序步骤浅析 建立一个工程 添加工程所需的 OpenGL 文件和库 添加控件 创建 OpenGL 图形类实现 MFC 中的三维图形绘制 关联 draw 对象 m_list 到 IDC_LIST1 控件中 CBoltView 初始化 PreCreateWindow() 函数注册窗口风格 响应窗口消息命令

设置 OpenGL 绘图窗口的风格 cs.style = WS_CLIPSIBLINGS WS_CLIPCHILDREN CS_OWNDC 创建 OpenGL 的绘图设备 OpenGL 绘图的机制是 : 先用 OpenGL 的绘图上下文 RC 把图画好, 再把所绘结果通过 SwapBuffer() 函数传给 Window 的绘图上下文 DC 注意, 程序运行过程中, 可以有多个 DC, 但只能有一个 RC 因此当一个 DC 画完图后, 要立即释放 RC, 以便其它 DC 使用 SetWindowPixelFormat(hDC) 函数设置像素格式, 为执行 OpenGL 绘制任务的窗口专门指定像素格式 CreateViewGLContext(hDC) 创建绘制描述表并使之为当前设备描述表 OpenGL 场景的常规初始设置

断开 DC 和 RC 的关联, 释放 DC, 删除 RC wglmakecurrent(null,null);// 解除 RC 和 DC 关联 wgldeletecontext(m_hglcontext); // 删除 RC 其他 处理 OnEraseBkgnd() //return CListCtrl::OnEraseBkgnd(pDC);// 把这句话注释掉, 若不然,Window 会用白色背景来刷新, 导致画面闪烁 处理 OnPaint() 处理 OnSize()---setprojectmodel() 显示列表的使用

创建两个视图 m_wndsplitter.createstatic(this, 1, 2,WS_CHILD WS_VISIBLE) m_wndsplitter.createview(0, 0, RUNTIME_CLASS (CFormCommandView), CSize(200,200), pcontext) 访问视图指针 CToolApp *papp = (CToolApp *)AfxGetApp(); CMainFrame *pmainframe = (CMainFrame *)papp- >m_pmainwnd; CChildFrame *pframe = (CChildFrame *)pmainframe-> GetActiveFrame(); CView *pview = (CView *)pframe- >m_wndsplitter.getpane(0,1); CRenderView::OnCreate() 中初始化 OpenGL CRenderView::OnDestroy() 销毁 OpenGL 场景 CRenderView::OnSize()

设置背景色与光源颜色 设置 OpenGL 属性 设置转动 设置缩放

Curve 程序演示要点 SetViewportOrg 与 SetWindowOrg 函数使用 参数交互输入控制图形图形坐标系的设置与图形的绘制满屏显示 : m_rect=crect(0,0,2*m_radius,2*m_radius) ; pdc->setmapmode(mm_isotropic) ; pdc>setwindowext(m_rect.right,m_rect.bottom) ; pdc->setviewportext(rc.right,rc.bottom) ;