OpenGL 学习1 OpenGL 概述
2010年06月29日
OpenGL 学习1 OpenGL 概述
Table of Contents
1 概述
2 设计实现:client-server 模式
3 状态机
4 OpenGL 渲染管线
4.1 显示列表 Display List
4.2 顶点操作 Vertex operation
4.3 图元装配 primitive assembly
4.4 像素操作 pixel operation
4.5 纹理内存 texture memory
4.6 光栅化 Rasterization
4.7 片元操作 Fragment Operation
5 OpenGL 图元
6 刷新缓冲
1 概述
OpenGL 是一个跨平台,跨编程语言的编程接口,用于生成二维、三维图像。OpenGL 是一个直接操纵硬件的软件接口。OpenGL 可以工作在网络模式下,客户端和服务器不是同一台机器:客户端是OpenGL执行命令,而服务器端是用来显示渲染结果。我们所说的 OpenGL 命令对应一个 OpenGL API操作。 2 设计实现:client-server 模式
OpenGL 是一种 client-server 模式,当你的应用程序调用 OpenGL 函数时, 它将告诉 OpenGL client, 然后 client 将渲染命令传送给 server. 这里client 和 server 可能是不同的计算机,或是同一台计算机上的不同进程。一般来说 server 是在 GPU 上处理的,而 client 是在 CPU 上处理的,这样分担了 CPU 的负担, 同时高效利用了 GPU. 3 状态机
OpenGL 内部有一个状态机, 使用 OpenGL 的 API,实际上是来操纵这个状态机来设置状态,你可以设置当前的颜色,光照,混色等等, 当渲染的时候,会使用状态机的当前设置。状态机中的大多数变量(两种状态的)的可以使用 glEnable() , glDisable() 来设置, 可以通过 glIsEnabled() 来查询状态. 可以通过 glPushAttrib() , glPopAttrib() 来自动保存恢复状态机中的变量。 4 OpenGL 渲染管线
OpenGL 的核心部分是渲染管线,这个太核心,所以你不必完全理解它的工作流程。
4.1 显示列表 Display List
显示列表是一系列的 OpenGL 命令, 压缩存储起来以备以后执行。执行的时候, 将按照顺序执行。所有的数据,几何体(顶点),和像素数据可以放到显示列表中。使用显示列表可以提高性能,尤其在网络模式中,client 和 server 是不同的计算机。显示列表是 server 状态的一部分,它们驻留在 server中, 因此避免通过网络重复发送这些数据, 从而降低网络开销。 4.2 顶点操作 Vertex operation
对于顶点数据,接下来的处理步骤是"顶点操作":将顶点转换为图元。对于有些类型的顶点数据(如空间坐标),使用 4*4 的浮点型矩阵对齐进行变换。三维空间坐标被投影到屏幕。
如果启用了高级特性,这个阶段需要完成的工作将更多。如果使用了纹理映射,将可能生成纹理坐标,并对其进行变换。如果光照功能被启用,将执行光照计算:根据变换后的顶点、面法线和其他关照信息计算颜色值。 4.3 图元装配 primitive assembly
图元装配的一个主要内容就是裁剪,它的任务是消除位于半空间(half-space)之外的那部分几 何图元,这个半空间是由一个平面所定义的。点裁剪就是简单地接受或拒绝顶点,直线或多边形裁剪 则可能需要添加额外的顶点,具体取决于直线或多边形是如何进行裁剪的。 在有些情况下,接下来需要执行一个叫做透视除法(perspective division)的步骤。它使远处的 物体看起来比近处的物体更小一些。接下来所进行的是视口(viewport)和深度(z坐标)操作。如 果启用了剔除功能(culling)并且该图元是一个多边形,那么它就有可能被剔除测试所拒绝。根据多边形模式,多边形可能画成点的形式或者直线的形式。
这个阶段产生的结果就是完整的几何图元,也就是根据相关的颜色、深度(有时还有纹理坐标值 以及和光栅化处理有关的一些指导信息)进行了变换和裁剪的顶点。 4.4 像素操作 pixel operation
首先将系统内存中的像素数据进行拆封:从某种格式转换为合适数目的分量。接下来对数据进行缩放,偏移和像素映射。然后将得到的数据进行截取,并将其写入纹理内存后发送给光栅化操作进行处理。
如果是从帧缓存中读取像素数据,则对其进行像素转移(缩放、偏移、映射和截取)操作。然后将其封装为合适格式,并存储到系统内存的数组中。
有一些特殊的像素复制操作,可以用于将数据从帧缓存中复制到帧缓存的其他地方后纹理内存中。数据被写入到纹理内存后帧缓存之前,只经过一遍像素转移操作。 4.5 纹理内存 texture memory
纹理图像被加载到纹理内存中,等待被映射到几何多边形对象上。 4.6 光栅化 Rasterization
光栅化是将几何数据和像素数据转换为片元(fragment).一个片元对应帧缓冲区中一个像素, 包含了颜色,深度,线宽,点宽和反走样信息。如果设置了 GL_FILL 模式,多边形区域内的像素点会被填充。 4.7 片元操作 Fragment Operation
将片元写入帧缓存之前,会执行一系列的操作,其中的每一步操作都可以启用和禁用。
第一个操作是纹理生成,从纹理内存中选取一个纹理对象,然后应用到对应片元上。然后执行雾计算。之后进行一系列的测试:裁剪测试 -> Alpha 测试 -> 模板测试 -> 深度测试,如果未通过某项测试,后续的测试将不再执行。再之后,执行混色,抖动,逻辑运算和屏蔽。最后处理后的片元被绘制到合适的缓存中,成为像素。 5 OpenGL 图元
一切复杂的物体都可以分解为细小的三角形或四边形。看游戏中的3D人物,去除纹理贴图之后,就是一个个的顶点连成的线面组成。OpenGL 提供了一些基本的图元,包括点、线、三角形、四边形、多边形等等, 而绘制图元是利用 glBegin() 和 glEnd() 来进行。如我们绘制几个点:
glBegin(GL_POINTS); glVertex3f (0.0f, 0.0f, 0.0f); glVertex3f (1.0f, 0.0f, 0.0f); glVertex3f (1.0f, 1.0f, 0.0f); glEnd(); 6 刷新缓冲
如同我们在操作文件流的时候,我们通过 fwrite 并不能及时的回馈到文件中, 而是写入到了缓冲区中,当缓冲区满的时候才将之写入文件, 我们可以手动通过 fflush 来将缓冲区内容刷新到文件中去。在 OpenGL 中类似,OpenGL 的命令并不能及时执行, 所有的命令先储存在缓冲区中,(网络缓冲区或是显卡加速缓冲区),当缓冲区满的时候才会发送给GPU(server)去执行。 glFlush() 函数可以将缓冲区命令全部送到GPU, 然后不管GPU那边有没有将命令全部执行完,就立即返回。而 glFinish() 和 glFlush() 的功能一样,清空缓冲区,发送给 server, 但是会等待 server 执行完毕后返回给应用程序。区别大似 Windows 消息处理中的 PostMessage 和 SendMessage . Date: 2010-07-01 21:47:39 HTML generated by org-mode 6.33x in emacs 23
2010年06月29日
OpenGL 学习1 OpenGL 概述
Table of Contents
1 概述
2 设计实现:client-server 模式
3 状态机
4 OpenGL 渲染管线
4.1 显示列表 Display List
4.2 顶点操作 Vertex operation
4.3 图元装配 primitive assembly
4.4 像素操作 pixel operation
4.5 纹理内存 texture memory
4.6 光栅化 Rasterization
4.7 片元操作 Fragment Operation
5 OpenGL 图元
6 刷新缓冲
1 概述
OpenGL 是一个跨平台,跨编程语言的编程接口,用于生成二维、三维图像。OpenGL 是一个直接操纵硬件的软件接口。OpenGL 可以工作在网络模式下,客户端和服务器不是同一台机器:客户端是OpenGL执行命令,而服务器端是用来显示渲染结果。我们所说的 OpenGL 命令对应一个 OpenGL API操作。 2 设计实现:client-server 模式
OpenGL 是一种 client-server 模式,当你的应用程序调用 OpenGL 函数时, 它将告诉 OpenGL client, 然后 client 将渲染命令传送给 server. 这里client 和 server 可能是不同的计算机,或是同一台计算机上的不同进程。一般来说 server 是在 GPU 上处理的,而 client 是在 CPU 上处理的,这样分担了 CPU 的负担, 同时高效利用了 GPU. 3 状态机
OpenGL 内部有一个状态机, 使用 OpenGL 的 API,实际上是来操纵这个状态机来设置状态,你可以设置当前的颜色,光照,混色等等, 当渲染的时候,会使用状态机的当前设置。状态机中的大多数变量(两种状态的)的可以使用 glEnable() , glDisable() 来设置, 可以通过 glIsEnabled() 来查询状态. 可以通过 glPushAttrib() , glPopAttrib() 来自动保存恢复状态机中的变量。 4 OpenGL 渲染管线
OpenGL 的核心部分是渲染管线,这个太核心,所以你不必完全理解它的工作流程。
4.1 显示列表 Display List
显示列表是一系列的 OpenGL 命令, 压缩存储起来以备以后执行。执行的时候, 将按照顺序执行。所有的数据,几何体(顶点),和像素数据可以放到显示列表中。使用显示列表可以提高性能,尤其在网络模式中,client 和 server 是不同的计算机。显示列表是 server 状态的一部分,它们驻留在 server中, 因此避免通过网络重复发送这些数据, 从而降低网络开销。 4.2 顶点操作 Vertex operation
对于顶点数据,接下来的处理步骤是"顶点操作":将顶点转换为图元。对于有些类型的顶点数据(如空间坐标),使用 4*4 的浮点型矩阵对齐进行变换。三维空间坐标被投影到屏幕。
如果启用了高级特性,这个阶段需要完成的工作将更多。如果使用了纹理映射,将可能生成纹理坐标,并对其进行变换。如果光照功能被启用,将执行光照计算:根据变换后的顶点、面法线和其他关照信息计算颜色值。 4.3 图元装配 primitive assembly
图元装配的一个主要内容就是裁剪,它的任务是消除位于半空间(half-space)之外的那部分几 何图元,这个半空间是由一个平面所定义的。点裁剪就是简单地接受或拒绝顶点,直线或多边形裁剪 则可能需要添加额外的顶点,具体取决于直线或多边形是如何进行裁剪的。 在有些情况下,接下来需要执行一个叫做透视除法(perspective division)的步骤。它使远处的 物体看起来比近处的物体更小一些。接下来所进行的是视口(viewport)和深度(z坐标)操作。如 果启用了剔除功能(culling)并且该图元是一个多边形,那么它就有可能被剔除测试所拒绝。根据多边形模式,多边形可能画成点的形式或者直线的形式。
这个阶段产生的结果就是完整的几何图元,也就是根据相关的颜色、深度(有时还有纹理坐标值 以及和光栅化处理有关的一些指导信息)进行了变换和裁剪的顶点。 4.4 像素操作 pixel operation
首先将系统内存中的像素数据进行拆封:从某种格式转换为合适数目的分量。接下来对数据进行缩放,偏移和像素映射。然后将得到的数据进行截取,并将其写入纹理内存后发送给光栅化操作进行处理。
如果是从帧缓存中读取像素数据,则对其进行像素转移(缩放、偏移、映射和截取)操作。然后将其封装为合适格式,并存储到系统内存的数组中。
有一些特殊的像素复制操作,可以用于将数据从帧缓存中复制到帧缓存的其他地方后纹理内存中。数据被写入到纹理内存后帧缓存之前,只经过一遍像素转移操作。 4.5 纹理内存 texture memory
纹理图像被加载到纹理内存中,等待被映射到几何多边形对象上。 4.6 光栅化 Rasterization
光栅化是将几何数据和像素数据转换为片元(fragment).一个片元对应帧缓冲区中一个像素, 包含了颜色,深度,线宽,点宽和反走样信息。如果设置了 GL_FILL 模式,多边形区域内的像素点会被填充。 4.7 片元操作 Fragment Operation
将片元写入帧缓存之前,会执行一系列的操作,其中的每一步操作都可以启用和禁用。
第一个操作是纹理生成,从纹理内存中选取一个纹理对象,然后应用到对应片元上。然后执行雾计算。之后进行一系列的测试:裁剪测试 -> Alpha 测试 -> 模板测试 -> 深度测试,如果未通过某项测试,后续的测试将不再执行。再之后,执行混色,抖动,逻辑运算和屏蔽。最后处理后的片元被绘制到合适的缓存中,成为像素。 5 OpenGL 图元
一切复杂的物体都可以分解为细小的三角形或四边形。看游戏中的3D人物,去除纹理贴图之后,就是一个个的顶点连成的线面组成。OpenGL 提供了一些基本的图元,包括点、线、三角形、四边形、多边形等等, 而绘制图元是利用 glBegin() 和 glEnd() 来进行。如我们绘制几个点:
glBegin(GL_POINTS); glVertex3f (0.0f, 0.0f, 0.0f); glVertex3f (1.0f, 0.0f, 0.0f); glVertex3f (1.0f, 1.0f, 0.0f); glEnd(); 6 刷新缓冲
如同我们在操作文件流的时候,我们通过 fwrite 并不能及时的回馈到文件中, 而是写入到了缓冲区中,当缓冲区满的时候才将之写入文件, 我们可以手动通过 fflush 来将缓冲区内容刷新到文件中去。在 OpenGL 中类似,OpenGL 的命令并不能及时执行, 所有的命令先储存在缓冲区中,(网络缓冲区或是显卡加速缓冲区),当缓冲区满的时候才会发送给GPU(server)去执行。 glFlush() 函数可以将缓冲区命令全部送到GPU, 然后不管GPU那边有没有将命令全部执行完,就立即返回。而 glFinish() 和 glFlush() 的功能一样,清空缓冲区,发送给 server, 但是会等待 server 执行完毕后返回给应用程序。区别大似 Windows 消息处理中的 PostMessage 和 SendMessage . Date: 2010-07-01 21:47:39 HTML generated by org-mode 6.33x in emacs 23