描述
开 本: 16开纸 张: 胶版纸包 装: 平装-胶订是否套装: 否国际标准书号ISBN: 9787512427358
本书适用于熟悉C、C 、C#或Java等任何面向对象编程语言的读者,本书会对这些相关的基础内容进行必要的介绍。读者只需认真实践,完全可以掌握本书内容。
1.1从这里开始认识1
1.2OpenGL是什么1
1.3如何使用OpenGL2
1.4Hello
OpenGL6
1.5辅助工具22
1.6不含位置属性的顶点29
1.7总结31
1.8问题31
第2章纹理33
2.1二维纹理33
2.2其他类型的纹理40
2.3多个纹理43
2.4多个渲染方法46
2.5总结48
2.6问题48
第3章空间和矩阵50
3.1如何理解矩阵50
3.2空间和矩阵的关系52
3.3Pipeline中的空间60
3.4实例化渲染61
3.5总结63
3.6问题63
第4章几何着色器64
4.1介绍64
4.2示例:渲染法线66
4.3总结69
4.4问题69
第5章光照70
5.1BlinnPhong光照模型70
5.2光源70
5.3反射光70
5.4BlinnPhong算法75
5.5同时使用多个光源77
5.6阴影80
5.7凹凸映射80
5.8噪声84
5.9总结88
5.10问题88
第6章帧缓存89
6.1名词术语90
6.2附着点90
6.3将Texture附着到Framebuffer91
6.4附着Renderbuffer95
6.5示例:Render to Texture95
6.6总结99
6.7问题100
第7章阴影101
7.2Shadow
Volume110
7.3模板缓存的初始化122
7.4多光源下的阴影123
7.5总结124
7.6问题124
第8章拾取125
8.1基础125
8.2在DrawArraysCmd命令下的拾取140
8.3在DrawElementsCmd命令下的拾取146
8.4拖拽顶点157
8.5总结162
8.6问题163
第9章文字164
9.1固定尺寸且始终面向Camera164
9.2字形信息169
9.3三维世界的文字174
9.4总结177
9.5问题177
第10章简单的用户界面178
10.1指定区域的贴图178
10.2控件的布局机制179
10.3控件的事件机制188
10.4CtrlImage193
10.5CtrlLabel196
10.6CtrlButton200
10.7总结202
10.8问题202
第11章轨迹球203
11.1轨迹球203
11.2使用204
11.3设计205
11.4四元数209
11.5总结210
11.6问题210
第12章体渲染211
12.1什么是体渲染211
12.2静态切片212
12.3动态切片215
12.4Raycasting217
12.5总结223
12.6问题224
第13章半透明渲染225
13.1跳跃着色法225
13.2与顺序无关的半透明渲染226
13.3Front
to Back Peeling235
13.4总结240
13.5问题240
第14章Transform Feedback Object241
14.1Transform
Feedback如何工作241
14.2使用Transform Feedback Object244
14.3轮流更新245
14.4粒子系统251
14.5总结254
14.6问题254
第15章Compute Shader255
15.1Compute
Shader简介255
15.2图像处理257
15.3粒子系统261
15.4总结262
15.5问题263
附录264
附录AGithub入门264
附录BC#和面向对象入门277
附录C解析简单的wavefront(*.obj)文件格式298
附录D自制体数据的2种方法302
本书由浅入深地讲解OpenGL的概念和用法,通过一个个简单的实例让读者一目了然地认识OpenGL的各个知识点。本书包括渲染管道(Pipeline)、着色器(Shader)、缓存(Buffer)、纹理(Texture)、矩阵(Matrix)、光照模型(Lighting)、阴影(Shadow)、帧缓存(Framebuffer)、拾取(Picking)、文字(Text)、用户界面(UI)、体渲染(Volume Rendering)、透明(Transparency)和通用计算(Compute Shader)等内容。读者掌握这些内容后,就可以自由设计、编写中等规模的三维图形程序了,并且能够渲染百万数量级顶点的模型。
本书的网络资料包含了书中所有的完整代码,读者可以从北航出版社网站(www.buaapress.com.cn)的“下载专区”的相关页面获取。另外,读者也可以在CSharpGL托管页面(https://github.com/bitzhuwei/CSharpGL)找到本书的全部代码。如果读者对本书内容有任何疑问、指错或想进一步深入讨论,还可以在托管页面进行提问、讨论。本书最后的附录也提供了简单的Github入门教程。
感谢北京航空航天大学出版社提供的机会与平台,感谢家人以及业界的朋友在本书编写的过程中给予的支持和帮助,这里还要特别感谢编辑剧艳婕在本书出版的过程中提出的宝贵意见。希望本书能够帮助读者打开计算机图形学的大门。
SetLastError = true)] // C# Attribute
static extern void glClear(uint mask);但如果是扩展的OpenGL函数(例如uint glCreateShader(uint
shaderType);),则要使用动态加载的方式,从系统文件opengl32.dll中找到函数指针。 接着,创建Render Context。
没有这个Context,任何对OpenGL函数的调用都是无效的。创建Context的步骤很繁琐,其中任何一点出错,就可能产生各种奇怪的问题,而且难以查找。 然后准备模型。
为了便于学习,可以只用一个三角形当模型,但在学习光照等环节时,没有恰当的模型很难体会到算法的精髓。 最后,要先领会很多孤立的函数和矩阵变换。
把模型数据正确地传送到显卡,并渲染出来,中间涉及几十个函数、各种神似的参数和复杂的绑定关系。其中任何一点出错,都很难调试,让人心态崩溃。矩阵也是OpenGL里很难理解的一个工具。为了实现各种方位变换、光照效果,矩阵变换也是绕不开的问题。
综上所述,晦涩繁琐、易错难改是初学OpenGL的最大困难。为了解决这些问题,本书以CSharpGL为基础,讲解如何开始使用OpenGL。其好处之一就是,上述准备工作都可以省了。
1.3.2开源库
开源库(CSharpGL)是笔者设计编写维护的,它包含下述部分:
① CSharpGL:这是一个OpenGL库,封装了OpenGL的功能,编译出来的是一个库文件CSharpGL.dll;
② CSharpGL.Windows:封装了在Windows下使用OpenGL的准备工作。编译出来的是一个库文件CSharpGL.Windows.dll;
③ Infrastructures\:有一些辅助代码。既有必要出现,又不属于上述部分;
④ 其他:使用CSharpGL的示例集合。
有了CSharpGL,读者只需做如下准备工作:
下载安装Visual
Studio 2013;
在本书网络资料中找到CSharpGL.zip,用Visual Studio 2013打开CSharpGL.sln解决方案;
完毕。读者可以直接运行各个示例项目,看看CSharpGL都能做些什么。
1.3.3渲染流程
OpenGL应用程序开发者只需告知OpenGL想做些什么(渲染三维场景、执行并行计算等),而不需知道OpenGL如何去完成这些任务。OpenGL会在一系列复杂的处理之后完成这些任务,这一系列复杂的处理过程就是OpenGL的渲染流程(Pipeline)。这类似《植物大战僵尸》这样的塔防游戏,玩家只需放置需要的植物(坚果墙、向日葵、豌豆炮、南瓜、磁力菇等),它们就会自动发挥自己的作用,玩家不必关心豌豆是如何神奇地修炼成精并发出炮弹的。
这里来初次认识一下简化的Pipeline。OpenGL处理模型数据主要分3步,如图11所示。
图11简化的OpenGL Pipeline1.
准备数据
三维世界里的物体,可以由组成物体的点以及点之间的连线(直线)来描述。例如图12就用点和连线描述了一个立方体和一个球体。
图12用点和连线描述的立方体和球体一个点最重要的数据就是其位置和颜色,该点就是OpenGL中的顶点(Vertex)。用这种方式描述的物体称为一个模型(Model)。
OpenGL处理的模型,是由一个个顶点组成的。对于每个顶点,都可能需要指定它的位置、颜色、法线和纹理坐标等属性(Attribute)。顶点的位置属性一般必须指定,而其他属性则未必。但是从程序的角度看,位置属性和其他属性是并列关系。
为了便于解释,这里以一个立方体Cube模型为例。立方体具有很特殊的性质,以后也将用它学习观察OpenGL的各种功能用法。CSharpGL中用图13所示的注释来记录立方体的顶点顺序和坐标轴。这样的方式既直观,又不像图片那样占用大量的空间。
图13用字符画描述Cube根据图13,首先指定立方体8个顶点的位置属性:private
const float halfLength = 0.5f;
private static readonly vec3[] positions
= new vec3[]
{
new vec3( halfLength, halfLength,
halfLength),// 0
new vec3( halfLength, halfLength,
-halfLength),// 1
new vec3( halfLength, -halfLength,
halfLength),// 2
new vec3( halfLength, -halfLength,
-halfLength),// 3
new vec3(-halfLength, halfLength,
halfLength),// 4
new vec3(-halfLength, halfLength,
-halfLength),// 5
new vec3(-halfLength, -halfLength,
halfLength),// 6
new vec3(-halfLength, -halfLength,
-halfLength),// 7
};这里只指定位置属性,其他属性暂不涉及。
有了位置,下面要指定这些顶点的连接关系。立方体有6个面,用12个三角形来描述这6个面,每个三角形需要指定3个顶点。用一个uint[]类型的数组indexes指定12个三角形,代码如下:private static readonly uint[] indexes = new uint[]
{
0, 2, 1,1, 2, 3, // X faces.
0, 1, 5,0, 5, 4, // Y faces.
0, 4, 2,2, 4, 6, // Z faces.
7, 6, 4,7, 4, 5, // -X faces.
7, 5, 3,3, 5, 1, // -Z faces.
7, 3, 2,7, 2, 6, // -Y faces.
};上述代码中,每3个数值描述一个三角形,每个数值指定此三角形的顶点在positions里的索引。例如,indexes[0]、 indexes[1]、 indexes[2]指定了第一个三角形,其顶点位置分别为positions[ indexes[0] ]、 positions[
indexes[1] ]和positions[ indexes[2] ]。
2. 顶点着色器
着色器(Shader)是一段负责给图形上色(或为上色做准备)的程序,其形式类似于C语言。OpenGL开始渲染后,首先会对每个顶点都执行一个简短的程序,这个程序就叫Vertex Shader。
Vertex Shader有2个用处:
指定顶点在Clip Space里的位置(即设置内置变量vec4 gl_Position;的值)。Clip Space的相关内容将在矩阵章节具体介绍。现在只需知道,为立方体指定的顶点位置是在三维空间里的,而这最终要画到二维的窗口上,所以必然要进行坐标变换。坐标变换就是矩阵的功能。
向后续的Fragment Shader传递数据。为了实现各种光照效果,向Fragment
Shader传递顶点的位置、颜色、纹理坐标等属性。
3. 线性插值
立方体只有8个顶点,然而OpenGL却要画出成片的三角形,这是通过OpenGL内部的插值功能实现的。在Vertex Shader完成后,OpenGL会根据indexes生成所有的三角形,然后根据三角形的三个顶点的位置、颜色等属性,通过插值的方式,为三角形覆盖到的各个像素生成其位置、颜色等属性值。上文说明了Vertex Shader可以向Fragment Shader传递数据。这些数据,也将作为顶点的属性,一并进行插值。
具体的插值过程完全由OpenGL自动完成,OpenGL应用程序不需也无法干预。
4. Fragment Shader
经过插值处理,画布上的一个像素所在的位置,每被三角形覆盖一次,就会产生一个富含顶点属性的片段(Fragment)。Fragment Shader会对每个Fragment执行一次,其输出结果就是它所在像素的候选颜色值。
在Fragment Shader中,一个像素的颜色是由四维向量vec4(r, g, b, a);描述的。其中r、g、b、a的范围都是[0, 1]。如果Shader输出的值超出此范围,OpenGL会自动将其裁切到范围内。
1.3.4小结
这是首次认识Pipeline,因此省略了很多环节。真正完整的Pipeline要复杂得多,本书将逐步展开予以介绍。
Pipeline是OpenGL的核心,是一个高度灵活的算法(可以自定义Shader、控制开关)。充分利用Pipeline,就可以实现光照、阴影、拾取、透明等各种效果和功能。
1.4Hello OpenGL
本节一步步地介绍如何完成第一个OpenGL程序,画出一个立方体。读者可在本书网络资料上的c01d00_Cube项目中找到此示例的完整代码。建议读者先打开此项目,以逐步执行的方式调试运行几次,对项目代码建立一些感性的了解,再详细阅读下面的章节。请注意随时记得Pipeline。OpenGL所做的一切都是围绕Pipeline进行的。
Pipeline需要三类信息:模型、Shader和状态开关。最后调用OpenGL的渲染命令即可。状态开关用于控制OpenGL的各种状态,例如控制多边形渲染模式的glPolygonMode(..),控制线宽度的glLineWidth(..)等。
1.4.1新建项目
首先,在本书网络资料中找到CSharpGL.zip进行解压缩,用Visual Studio打开CSharpGL.sln解决方案。将解决方案中的Demos文件夹和OpenGLviaCSharp文件夹下的所有项目都删除,以便从零开始创建新项目。然后,新建一个项目,如图14所示。
图14新建项目c01d00_Cube新建一个“Windows窗体应用程序”,项目命名为“c01d00_Cube”。然后,为该项目引用必要的DLL库项目,如图15所示。
图15添加引用只需引用CSharpGL.dll和CSharpGL.Windows.dll。CSharpGL.dll封装了OpenGL函数,类似于在C 中引用了gl.h头文件。CSharpGL.Windows.dll封装了在Windows下使用OpenGL的初始化工作,类似于在C 中引用了glut.h头文件。
评论
还没有评论。