原文 地址
现代OpenGL的介绍。第1章:图形流水线
更新于2010年4月5日17:12:05 PDT
目录 | 第2章 ”
OpenGL已经有很长时间了,从互联网上阅读所有积累的文档层面,并不总是清楚哪些部分是历史性的,哪些部分在现代图形硬件上仍然有用和支持。现在是关于OpenGL介绍的时间,介绍今天仍然相关的部分。
更新:加入Reddit讨论。
什么是OpenGL?
维基百科给出了OpenGL的目的和历史的很好的概述,但是我将在此给出一个快速的总结。在现代形式中,OpenGL是用于与可编程GPU进行接口的跨平台库,用于渲染实时3D图形。它的使用在游戏,CAD和数据可视化应用中很常见。它始于90年代初作为SGI专有的GL(“图形库”)的跨平台标准化,将图形硬件驱动到高端工作站。几年后,GLQuake和3dfx的Voodoo图形加速器将3D加速器推向主流,OpenGL成为微软“ 专有的Direct 3d库,用于控制消费者PC中的图形加速器。近年来,Khronos集团已经对OpenGL标准进行了管理,更新了它,以支持现代可编程GPU的功能,将其推向OpenGL ES和WebGL的移动和在线领域,并通过弃用过时的OpenGL 3将其简化杂乱的图书馆早期版本的功能。
另一个最近的发展是采用通用GPU(GPGPU)库,包括nVidia的CUDA和Khronos的OpenCL。这些图书馆通过增加数据并行特征来实现C的方言,允许将GPU用于一般计算,而无需在OpenGL的面向图形框架内工作。然而,这些GPGPU框架并不取代OpenGL; 由于它们的主要目的不是图形编程,它们仅提供对GPU计算单元的访问,忽略其图形特定的硬件。然而,它们可以作为OpenGL的附件。CUDA和OpenCL都可以与OpenGL共享GPU内存的缓冲区,并在GPGPU程序和图形管道之间传递数据。GPGPU将超出这些条款的范围; 一世'
对于这些教程,我要假设你已经是一个程序员,而且你知道C,但是你以前不一定看过OpenGL或完成图形编程。至少知道一些基本代数和几何将有很多帮助。我将介绍OpenGL 2.0,并避免讨论在OpenGL 3或OpenGL ES中不推荐使用或删除的API功能。如果我写了足够的章节,我可以在介绍OpenGL 3和4的一些新特性之后,除了OpenGL中,我将使用两个辅助库:GLUT(总帐实用工具包),它提供窗口系统和OpenGL之间的跨平台接口,和GLEW(总帐扩展牧马人),从而简化处理不同OpenGL版本及其扩展。
我在哪里可以获得OpenGL,GLUT和GLEW?
在MacOS X,Windows和大多数Linux发行版上,OpenGL以某种形式或其他形式标准化。如果要遵循这些教程,您需要确保OpenGL实现至少支持版本2.0。MacOS X的OpenGL实现始终支持OpenGL 2.0,至少在软件中,如果显卡驱动程序不提供它。在Windows上,您依赖于显卡驱动程序来提供OpenGL 2或更高版本。您可以使用RealTech的免费OpenGL扩展查看器来查看驱动程序支持的OpenGL版本。nVidia和AMD的OpenGL驱动程序至少在过去四年发布的所有视频卡上都支持OpenGL 2.0。英特尔车载显卡和旧显卡的用户不太幸运。对于后台,Mesa提供了一个开放源代码,
Mesa也是Linux上最常见的OpenGL实现,它还可以与X服务器一起使用“直接渲染界面”(DRI)驱动程序将OpenGL与图形硬件进行接口。您可以通过从xterm 运行glxinfo命令来查看您的特定DRI驱动程序是否支持OpenGL 2.0 。如果您的硬件不支持OpenGL 2.0,则可以禁用该驱动程序以退回到Mesa的软件实现。nVidia还为针对自己的GPU的Linux提供了自己的专有OpenGL实现; 这个实现应该在任何最近的nVidia卡上提供OpenGL 2.0或更高版本。
要安装GLUT和GLEW,请在其各自的站点上查找二进制包。MacOS X预装了GLUT。大多数Linux发行版都通过其封装系统提供GLUT和GLEW,但对于GLUT,您可能需要启用您的发行版的可选“非免费”软件包存储库,因为其许可证技术上不是开源的。如果你是一个这样的事情,那么有一个开源的GLUT克隆叫做OpenGLUT。
如果你是一个经验丰富的C程序员,你应该可以安装这些库,让他们在你的开发环境中工作,没有任何麻烦。但是,在我们用任何代码弄脏我们的手之前,我将要讨论一些大图概念。在第一章中,我将解释一个渲染作业的图形流水线和数据流。在下一章中,我们将编写一个简单的“hello world”程序,将图像文件的内容绘制到屏幕上,显示管道如何投入使用。
图形管道

自从3d的实时早期以来,三角形一直是绘画场景的画笔。虽然现代GPU可以执行各种闪光效果来掩盖这个肮脏的秘密,但在所有阴影下,三角形仍然是它们工作的媒介。OpenGL实现的图形管道反映了这一点:主机程序使用顶点数组填充OpenGL管理的内存缓冲区; 这些顶点投影到屏幕空间中,组装成三角形,并被光栅化成像素大小的片段; 最后,将片段分配给颜色值并绘制到帧缓冲区。现代GPU通过将“项目进入屏幕空间”和“分配颜色值”阶段委托给称为着色器的可上传程序来获得灵活性。让'
顶点和元素数组
渲染作业通过一组一个或多个顶点缓冲区开始其流水线,其中填充有顶点属性数组。这些属性用作顶点着色器的输入。常见的顶点属性包括顶点在3d空间中的位置以及将顶点映射到一个或多个纹理上的采样点的一组或多组纹理坐标。向渲染作业提供数据的顶点缓冲器集合统称为顶点数组。当渲染作业被提交时,我们提供一个附加元素数组,一个索引数组到顶点数组,以选择哪些顶点被馈送到管道中。
统一的状态和纹理
渲染作业也具有统一的状态,它为流水线的每个可编程阶段的着色器提供一组共享的只读值。这允许着色器程序采用在顶点或片段之间不变的参数。均匀状态包括可以由着色器采样的一维,二维或三维数组的纹理。顾名思义,纹理通常用于将纹理图像映射到表面上。它们也可以用作预先计算的函数的查找表或用作各种效果的数据集。
顶点着色器
GPU通过从顶点数组中读取每个选定的顶点并将其运行通过顶点着色器开始,该顶点着色器将一组顶点属性作为输入并输出一组称为变化值的属性,这些属性被赋予光栅化器。至少,顶点着色器会在屏幕空间中计算顶点的投影位置。顶点着色器还可以生成其他变化的输出,例如颜色或纹理坐标,以使光栅化器跨越连接顶点的三角形的表面进行混合。
三角组合
然后,GPU将投影的顶点连接成三角形。它通过以元素数组指定的顺序获取顶点,并将它们分组为三组。顶点可以以几种不同的方式分组:
- 以每三个元素为独立三角形
- 制作一个三角形条,重新使用每个三角形的最后两个顶点作为下一个的前两个顶点
- 制作一个三角形风扇,将第一个元素连接到每个后续的元素对
该图显示了三种不同模式的行为。条纹和风扇在元件阵列之后,在元件阵列之后,每个三角形只需要一个新的索引,在单元格数组中交换独立三角形的灵活性以获得额外的内存效率。
光栅化
所述光栅化需要的每个三角形,夹子,并丢弃在屏幕之外的部分,并且其余的可以看见的部分分解成像素大小的片段。如上所述,顶点着色器的变化输出也在每个三角形的光栅化表面内插,为每个片段分配一个平滑的值梯度。例如,如果顶点着色器为每个顶点分配一个颜色值,则光栅化器将在像素化表面中混合这些颜色,如图所示。
片段着色器
生成的片段然后通过另一个称为片段着色器的程序。片段着色器接收由顶点着色器输出的变化值,并由光栅化器插值作为输入。它输出颜色和深度值,然后绘制到帧缓冲区。通用片段着色器操作包括纹理映射和照明。由于片段着色器为每个绘制的像素独立运行,因此它可以执行最复杂的特殊效果; 然而,它也是图形流水线中性能最为敏感的部分。
帧缓冲区,测试和混合
一帧缓存是渲染作业的输出的最终目的地。除了默认的framebuffer之外,OpenGL还可以让您绘制到屏幕上,大多数现代化的OpenGL实现让您可以将framebuffer对象绘制到屏幕外的renderbuffer或纹理中。那些纹理然后可以用作其他渲染作业的输入。帧缓冲区不仅仅是一个2d图像; 除了一个或多个颜色缓冲器之外,帧缓冲器可以具有深度缓冲器和/或模板缓冲器,两者都可以在它们被绘制到帧缓冲器之前过滤片段:深度测试从已经绘制的对象后面的对象丢弃碎片,并且模板测试使用绘制到模板缓冲区中的形状来限制帧缓冲区的可绘制部分,“渲染”渲染作业。在这两个手套中存活的片段的颜色值与其覆盖的颜色值混合,最后的颜色,深度和模板值被绘制到相应的缓冲区中。
结论
这是从顶点缓冲区到帧缓冲区的过程,当您在OpenGL中进行单个“绘制”调用时,您的数据将会进行处理。渲染场景通常涉及多个绘图作业,切换纹理,其他统一状态或遍历之间的着色器,并使用framebuffer的深度和模板缓冲区组合每个遍的结果。现在我们已经介绍了3D渲染的一般数据流,我们可以编写一个简单的程序来看看OpenGL如何使它们都发生。在本教程的整个过程中,我很乐意收到您的意见 -如果您帮助您,或者任何事情没有任何意义,请通知我。