原文链接:http://www.cnblogs.com/vertexshader/articles/2917540.html
OpenGL®作为业界最为广泛使用的2D和3D图形接口标准,应用在成千上万的各式各样的计算机的程序中。从初期的崭露头角,到与Direct3D激烈竞争,后经历黯淡被Khronos接手又发扬光大,已经历经波折发展了20年。由于过去的黯淡,至今甚至仍有人站在错误的时间角度认为它是落后的——它从未停止它前进的步伐,这篇文章就来简述OpenGL的版本历史和发展。
OpenGL 1.0
发布时间: 1992年1月
OpenGL的最早版本OpenGL 1.0由Mark Segal和Kurt Akeley发布于1992年1月。从这之后,OpenGL每隔一段时间都会发布一个新版本的规范,这些规范定义了一些显卡必须支持的新扩展。这就决定了OpenGL的每个版本其实就是由各个扩展组成的,当硬件的驱动全部支持相应的扩展的时候,相应的OpenGL版本就被支持了。
OpenGL 1.1
发布时间:1997年1月
扩展 | 特性增加 |
Vertex arrays | |
Polygon offset | |
Logical operation | |
Internal texture formats, texture proxy, and texture env | |
Copy texture and subtexture from framebuffer | |
Texture object |
时隔5年OpenGL才发布新的版本OpenGL 1.1,而Direct3D的出现(尤其是红色警戒的大卖)使得OpenGL感觉到了压力。顶点数组(Vertex arrays)的出现取代了glVertex*这类立即模式绘图函数,多个数据可以被一个函数调用绘制了,降低了调用函数带来的CPU循环开销;polygon offset解决了z-fighting和stitching的问题;在pre-fragment operation开始支持逻辑操作(logic operation);纹理方面开始支持纹理代理(texture proxy)和纹理环境映射(texture environment),以及从帧缓冲(frameuffer)复制像素至texture或者subtexture;纹理对象(texture object)的出现改变了过去只能使用显示表(display list)来静态地使用纹理的方法,现在纹理和参数(texture parameter)能被改变了。
OpenGL 1.2
发布时间:1998年3月16日
扩展 | 特性 |
Three-dimensional texture | |
BGR or BGRA pixel format | |
Packed pixel formats | |
Normal rescaling | |
Separate specular color | |
Texture coordinate edge clamping | |
Texture LOD control | |
Vertex array draw element range |
这个版本的OpenGL开始支持可以用于体渲染(volume rendering)和体纹理(solid texture)的texture 3D;BGRA和BGA的出现主要是为了兼容某些平台和硬件;包装像素(pack pixel)的出现使得像素可以在不同的对象之间进行像素传输(pixel transfer),这也就是像素缓冲对象(pixel buffer object)的前身;GL_SGIS_texture_edge_clamp扩展的出现将texture coordinate规范在[0,1]这个区间;GL_SGIS_Texture_lod扩展则带来了重要的MipMap技术,可以通过对纹理参数(texture parameter)的控制来完成对MipMap的控制。
OpenGL 1.2.1
发布时间:1998年10月14日
这个版本的OpenGL没有什么重大的改变,但是专门介绍了ARB扩展的概念。ARB扩展是经过OpenGL ARB认证的扩展,这样的扩展将被广泛地实现。
OpenGL 1.3
发布时间:2001年8月14日
扩展 | 特性增加 |
compressed texture format | |
texture cube | |
GL_ARB_multitexture(removed) | multi-texture |
Texture add env mode, texture combine env mode, texture dot3 env mode | |
Texture border clamp | |
transpose matrix |
这个版本开始支持压缩纹理(compressed texture),可以有效地减少存储和带宽的压力,现在广泛的应用于各种对存储大小和带宽敏感的手持设备上;立方体纹理(texture cube)的出现主要用于在天空盒(skybox)、动态反射(dynamic reflection)等技术上;而multisample的出现让OpenGL可以支持纹理和Framebuffer的MSAA抗锯齿技术,代替了过去在光栅化状态(rasterizer state)中趋近无用的抗锯齿设置。
OpenGL 1.4
发布版本:2002年7月24日
扩展 | 特性增加 |
Automatic mipmap generation | |
Blend squaring | |
Depth texture adn shadows | |
Fog coordinate | |
Multi draw arrays | |
Point parameters | |
Secondary color | |
Separate blend functions | |
Stencil warp | |
Texture crossbar env mode | |
Texture mirrored repeat | |
Window raster position |
这个版本开始支持纹理自动生成Mipmap; 以及关于point光栅化的parameter。
OpenGL 1.5
发布时间:2003年7月29日
扩展 | 特性增加 |
Buffer object | |
Occlusion query | |
Shadow functions |
这个版本出现了缓冲对象(buffer object),彻底取代了过去的顶点数组(vertex array)和立即模式,顶点数据可以从客户端内存(client's memory)上传到服务端内存(server's memory)了;同时添加了非常重要的遮挡查询(occlusion query)。
OpenGL 2.0
发布时间:2004年9月7日
扩展 | 特性增加 |
OpenGL Shading Language 1.00 | |
Multiple render targets | |
Non-power-of-two textures | |
Point sprites | |
Separate stencil |
OpenGL终于有了自己的着色语言(shading language),ARB选择了3Dlabs的Dave设计的着色语言成为OpenGL原生的着色语言,同时OpenGL也开始有了顶点着色器(vertex shader)和片元着色器(fragment shader),导致这个阶段的OpenGL出现了固定管线和可编程管线并存的情况;OpenGL的片元着色器输出(fragment shader output)现在也可以输出到帧缓冲(framebuffer)的多个渲染目标(render target)上去了;同时OpenGL的纹理也不再有2^n大小的限制。
OpenGL 2.1
发布时间:2006年7月2日
扩展 | 特性增加 |
Pixel buffer objects | |
sRGB textures |
这个版本增加了像素缓冲对象(pxiel buffer object),用来更快地像素传输(pixel tansfer)的工作,支持将像素从纹理对象(texture object)和帧缓冲对象(framebuffer object)包装到(pack)像素缓冲对象(pixel buffer object),或者从像素缓冲对象解包装到纹理对象和帧缓冲对象,另外像素缓冲对象也可以像普通的缓冲对象(buffer object)一样被映射(map)更新数据,通过DMA的方式更加快地传输纹理;同时支持sRGB格式的纹理对象。
代号Longs Peak和OpenGL 3.0争议
在OpenGL 3.0发布之前,这个版本的代号叫做Longs Peak,包含了很多大量修改OpenGL的工作方式以及根本性改变API的调用方式等内容。2008年8月11日OpenGL 3.0发布,这个版本的OpenGL开始分core profile和compatibility profile,并且Khronos Group希望只支持core profile,这个革新性的规范引起一片哗然,许多厂商明确表示不会接受这个建议,并表示会继续支持许多被划入compatibility profile的扩展,迫于压力compatibility profile被改为是可选的。OpenGL 3.0的出现改变了过去OpenGL一定会向下兼容的特性,在一定程度上简化了API的臃肿以及增加了API的灵活度。
OpenGL 3.0
发布日期:2008年8月11日
扩展 | 特性增加 |
New functions for shading language | |
Framebuffer objects, along with blitting, multisample renderbuffer objects, and packed depth/stencil image formats | |
Framebuffer blit | |
Floating-point color and depth internal formats for textures and render buffers | |
Red-Green texture compression | |
Transform feedback | |
Vertex array objects | |
Conditional rendering | |
Intergral image formats |
这个版本的OpenGL变化非常的大,开始分core profile和compatibility profile,core profile扩展的实现决定了所支持的OpenGL版本。下面列出这个版本之后可能会被弃用的很多特性:
- Application-generated object names
- Color index mode
- Shading language 1.10 and 1.20
- Begin/End primitive specification
- Edge flags
- Fixed function vertex processing
- Client-side vertex arrays
- Rectangles
- Current raster position
- Two-sided color selection
- Non-sprite points
- Wide linee and line strip
- Quadrilateral and polygon primitives
- Sepatate polygon draw mode
- Polygon stripple
- Pixel transger modes and operations
- Pixel drawing
- Bitmaps
- Legacy OpenGL 1.0 pixel formats
- Legacy pixel formats
- Depth texture mode
- Texture wrap mode CLAMP
- Texture borders
- Automatic mipmap generation
- Fixed function fragment processing
- Alpha test
- Accumulation buffers
- Context framebuffer size queries
- Evaluators
- Selection and feedback mode
- Display lists
- Hints
- Attribute stacks
- Unified extension string
这个版本正式把帧缓冲对象(framebuffer object)划入core profile,现在OpenGL也具有离线的帧缓冲了,就像Direct3D的output-merger stage专门管理render target和接收fragment shader的输出;增加了许多GLSL的函数,尤其是texture方面的;帧缓冲对象之间可以互相拷贝像素到持有的不同的render target,是性能上的提升;增加了浮点型和整型的texture和depth的image format;另外也增加了RGTC这个自带的纹理压缩模式;最为重要的增加就是transform feedback,数据可以经过vertex shader和geometry shader之后,又输出回buffer而不经过rasterization以及之后的阶段,在物理和粒子的计算上面非常的有用;增加的vertex array object方便管理buffer object以及vertex attrib pointer和其开启/关闭状态,不必每次在渲染前都要设置一遍了;增加了重要的条件渲染(conditional rendering)。
OpenGL 3.1
发布日期:2009年3月24日
扩展 | 特性增加 |
Instanced rendering | |
Data copying between buffer objects | |
Buffer texture | |
Rectangle texture | |
Uniform buffer object | |
Primitive restart |
有了Instanced rendering,减轻了同类物体绘制所占有的带宽压力;Copy buffer的出现,是让数据在client端进行拷贝,也是一种性能的优化;Buffer texture其实是让buffer object像texture那样被访问,在某些特殊的场合有意想不到的用途;不得不谈的就是uniform buffer object,过去OpenGL上传uniform数据需要靠glUniform*的函数进行上传,而OpenGL每个函数的调用所消耗的CPU循环都非常的大,频繁地调用glUniform*会带来很大的性能问题,而且到后期这些单个的uniform也会被保存至OpenGL管理的default uniform buffer中,现在开放了uniform buffer object,通过map/unmap更新数据,函数调用开销明显地减少。
OpenGL 3.2
发布日期:2009年8月3日
扩展 | 特性增加 |
Geometry shaders, input/output interface block | |
Fence sync objects | |
D3D compatible color vertex component ordering | |
Draw command allowing modification of the base vertex index | |
Seamless cube map filtering | |
Multisampled textures andd texture samplers for specific sample locations | |
Shader fragment coordinate conventions control | |
Provoking vertex control | |
Fragment depth clamping |
这个版本最重磅的支持就是几何着色器(geometry shader), 可以用来生成新的图元类型(点、线和三角形),后期重要的tessellation等技术都会使用到它;还有一个就是Texture正式支持multisample,可以作为render target来进行framebuffer object上的抗锯齿,而不是经过的WGL_ARB_multisample和GLX_ARB_multisample进行窗口的抗锯齿。
OpenGL 3.3
发布日期:2010年3月11日
扩展 | 特性增加 |
Dual-source blending | |
Shader-defined locationfor attributes and fragment shader outputs | |
Simple boolean occlusion query | |
Sampler objects | |
Texture swizzle | |
Timer queries | |
Instanced arrays | |
new texture format for unsigned_10_10_10_2 and new vertex attributes for 2_10_10_10 |
这个版本是shader model 4.0的OpenGL的最终版本,这个版本改变了程序需要查询输入变量(attribute)的location的方式,可以像HLSL指定semantic一样在shader里指定layout,减少了相应API的调用;同时将texture object和sampler state解耦,增加了sampler object,sampler object也可以绑定到ACTIVE_TEXTURE上了。
OpenGL 4.0
发布日期:2010年3月11日
扩展 | 特性增加 |
Tessellation control and evaluation shaders | |
OpenGL Shading Language 4.00 | |
Request minimum number of fragment inputs | |
Individual blend equations for each color output | |
Draw instanced arrays indirect | |
Transform feedback objects and multiple feedback stream output |
这个版本和OpenGL 3.3同时发布,增加了令人兴奋的Tessellation Shader;Shader Language 4.00的subroutine提供了在运行时刻不需要切换着色器或者是重新编译或者使用if判断选择不同功能的方法,降低了切换着色器程序所带来的巨大开销(切换着色器的CPU循环消耗真的非常的惊人);另外GL_ARB_draw_buffers_blend让fragment shader输出的每条buffer都可以完成各自的pre-fragment operaion,而不是像过去那样每条都完成相同的pre-fragment operation;GL_ARB_transform_feedback2和GL_ARB_transform_feedback3提供了transform feedback object,以及transform feedback相关的控制(比如pause之类),也把transform feedback当做一个对象来进行处理。
OpenGL 4.1
发布日期:2010年7月26日
扩展 | 特性增加 |
Pulling missing functionality from OpenGL ES 2.0 into OpenGL | |
Query and load a binary blob for program objects | |
Ability to bind programs individually to programmable stages | |
Multiple viewports for the same rendering surface, or one per surface | |
Documents precision requirements for several FP operaions | |
Provoids 64-bit floating-point component vertex shader inputs |
这个版本把OpenGL ES的一些功能划入core profile的范围,一方面反映出了OpenGL ES巨大的成功;GL_ARB_get_program_binary提供了可以将shader事先编译好序列化进入二进制文件,避免了运行时进行编译的方法;这个版本也提供了64位的浮点型输入变量,提升了数据精度。
OpenGL 4.2
发布日期:2011年8月8日
扩展 | 特性增加 |
Allows instanced rendering with a starting instance value | |
Allows for sub-rectangle selections when transferring compressed texture data | |
Allos querying of the aligment for pointers returned from buffer object mapping operations | |
Allows the user to detect the maximum number of samples possible for a particular image format and texture type | |
Allows querying of the alignment for pointers returned from buffer object mapping operations | |
Allows the setting of Uniform Buffer Object and sampler binding points directly from GLSL, among many other small changes | |
Allows texture objects to have immutable storage, and allocating all mipmap levels and images in one call. The storage becomes immutable, but the contents of the storage are not | |
Allows instanced rendering of data written by transform feedback operations | |
Allows atomically incrementing/decrementing and fetching of buffer object memory locations from shaders | |
Allows shaders to read and write images, with few but difficult restrictions | |
Allows the use of certain advanced compression formats |
这个版本比较好的改动就是现在也支持Compressed pixel format transfer了,而过去这是不允许的;另外提供了immutable texture,可以调用一次API创建texture object而不是像过去一样要频繁地调用API;还有一个就是GL_ARB_texture_compression_bptc,以及compatibility profile的GL_EXT_texture_compression_s3tc,让OpenGL开始支持所有的Block Compression格式。
OpenGL 4.3
发布日期:2012年8月6日
扩展 | 特性增加 |
GLSL multidimensional arrays | |
Clear Buffer Objects to specific values, ala memset | |
Arbitrary Compute Shaders | |
Arbitrary image copying | |
Debug messaging | |
Compatibility with OpenGL ES 3.0 | |
Specifying uniform locations in a shader | |
Rendering to a Framebuffer Object that has no attachments | |
Generalized queries for information about Image Formats | |
Texture, buffer object, and framebuffer invalidation | |
Issuing multiple indirect rendering commands from a single drawing command | |
Improved API for getting info about program object interfaces | |
Buffer object read-write access from shader, via a uniform-block style mechanism | |
Get size of images from GLSL | |
Accessing the stencil values from a depth/stencil texture | |
Layer and viewport indices available from the fragment shader | |
GLSL can detect the available mipmap pyramid of a sampler or image | |
Immutable storage for multisample textures | |
The ability to create a new texture, with a new internal format, that references an existing texture's storage | |
Separation of vertex format from buffer object | |
More robustness of API |
这个版本最重要的增加就是可以用于并行计算的compute shader;GL_ARB_explicit_uniform_location提供了uniform也能在GLSL中像HLSL指定semantic一样指定layout的方法,这个版本的OpenGL的vertex shader input和fragment shader output,以及uniform现在都能在shader中指定layout了;把OpenGL ES 3的某些功能加入了OpenGL core profile;增加了texture view的概念,用来共享已经创建纹理的内容;另外加入的debug messaging帮助程序猿更好的调试OpenGL。
OpenGL 4.4
发布日期:2013年7月23日
扩展 | 特性增加 |
Allows buffer objects to have immutable storage, and allocating all data in one call. | |
Clear texture Objects to specific values. | |
Add more functionality to layout qualifiers in OpenGL Shading Language. | |
Allowing applications to bind or unbind a set of objects in one call. | |
Introduces a mechanism whereby the result of a query object may be retrieved into a buffer object instead of client memory. | |
Extends the set of texture warp mdes to include an additional mode that effectively uses a texture map twice as large as the original image in which the additional half of the new image is a mirror image of the original image. | |
Accept STENCIL_INDEX8 as a texture internal format. | |
New vertex attribute data format. | |
Allows application to write generic compute shader that operate on work groups with arbitrary dimensions. | |
Add "parameter buffer" which is a target allowing buffers to store parameters for certain drawing commands. | |
Allow a implementation to provide a per-texture setting for enabling seamless sampling from cube maps. | |
Add a built-in variable gl_DrawID in OpenGL Shading Language. | |
Add new built-in functions to compute the cmpoite of a set of boolean conditions across a group of shader invocations. |
GL_ARB_muti_bind允许通过一次调用来绑定多个资源,将绑定资源的开销分摊到一个调用上,并且和Direct3D11的接口相互兼容;GL_ARB_enhanced_layout允许uniform block内部指定layout,相当于Direct3D的registry;GL_ARB_buffer_object也提供了单个draw call完成创建buffer object的方法,并且提供presistent-mapped buffer来显著的减少glMapBuffer的调用。
总结
从发展历程上看,OpenGL 1.0~OpenGL 1.5是经典的固定管线时代;OpenGL 2.0~OpenGL 2.1是固定管线和可编程管线并存的时代;OpenGL 3.0~OpenGL 4.x开始是可编程管线崛起的时代。在出现可编程管线的那个时代,OpenGL因为OpenGL ARB的臃肿而一度落后,取而代之的是Khronos Group管理的精简的OpenGL ES流行;最后ARB决定将OpenGL的接力棒交给Khronos Group,在之后的几年内,OpenGL重新焕发了活力,推陈出新至今。另外在移动设备上免授权费用的OpenGL ES的胜利,在一方面上也促进了桌面版的OpenGL重新回到主流地位,现在先进的OpenGL已经受到各个厂家的重视,Nvidia和AMD等显卡制造商都争相发布相关的OpenGL驱动;在游戏开发方面,因为其良好的可移植性,不同的平台、不同的主流引擎都会有OpenGL的实现。
附录
OpenGL 4.4 pipeline
Q&A:
Q:OpenGL已经落伍了,更新的也非常的慢,再努力几年也赶不上技术雄厚的Direct3D。
A:近几年Khronos Group接手OpenGL之后,发展速度迅猛,新版本的OpenGL已经更新到了OpenGL 4.4,其功能略超过Direct3D 11,且被Nvidia和AMD主流显卡全面支持;值得注意的是有96.8%手持设备都只使用桌面OpenGL的子集OpenGL ES作为他们的图形编程接口;许多家用游戏机也使用OpenGL作为其图形的编程接口。OpenGL已经重新回到主流的地位,我想或许你的教科书真的是太老了!
Q:OpenGL的功能会比Direct3D少,且OpenGL的速度不如Direct3D来得快。
A:PC上的OpenGL和Direct3D工作在同样的硬件上,他们的功能是基本一致的,另外你应该看看这个。
Q:从哪里才能下载到OpenGL的SDK?
A:OpenGL并没有SDK,想要启用高级OpenGL都是通过获取相应的函数指针来完成的,当然必须由显卡的驱动支持才行。不过有些库可以帮你完成这类繁琐的工作,比如GLEW。
Q:OpenGL的扩展是什么?
A:OpenGL功能的实现都是靠一个个扩展实现的,如果实现了OpenGL版本规范规定的扩展,那么就是实现了相应的OpenGL扩展。
Q:我如何知道我的设备支持了多少OpenGL扩展以及什么OpenGL扩展?
A:在编程中你可以使用特定的库比如GLEW检测相应的扩展是否被支持;你也可以下载OpenGL Extensions Viewer直观的查看支持的OpenGL的特性和扩展,这个软件也有多个平台的版本。
Q:感觉OpenGL的文档都太不详细了,我在搜索引擎里搜索的结果都很令人失望。
A:详细的OpenGL文档都在其官网里:①OpenGL Registry里面有上百个OpenGL扩展的文档;②OpenGL Reference Page里面有各个函数的使用方法;③OpenGL Reference Card能帮助你宏观地了解OpenGL的所有主要函数;④OpenGL Specification其实是扩展文档的集合,不过也是非常的详细和有用。
Q:什么是Core Profile和Compatibility Profile?
A:在OpenGL的发展历程中,总是兼顾向下兼容的特性,但是到了一定的程度之后,这些旧有的OpenGL API不再适应时代的需要,还有一些扩展并不是驱动一定要实现的扩展,这些被统一划入可选的Compatibility Profile;而由OpenGL规范规定必须支持的扩展,则是Core Profile,想要支持先进的OpenGL,相应的Core Profile扩展必须被实现。
Q:有什么好的入门书籍可以介绍吗?
A:《OpenGL Superbible》和《OpenGL Shading Language Cookbook》以及《OpenGL Insights》都非常的不错。
Q:OpenGL如何进行Debug,DirectX的PIX真的很好用呢。
A:现在支持GLSL和OpenGL跟步调试的只有Nvidia的Nsight,只支持Nvidia的显卡;其他的基本都是track,不支持GLSL的跟步调试,比如AMD的GPUPerfClient以及gDEBugger。还有AMD的GPU ShaderAnalyzer也非常的不错,能看到相应的GLSL汇编代码。
Q:OpenGL有多少引擎支持呢!
A:基本主流的引擎都会在上层抽象一层,然后都有用OpenGL和Direct3D分别实现的模块;绝大部分的主流引擎都留有了OpenGL的实现。
Q:网上很多Tutorias都很老了,Nehe也落伍了,有没有比较好的Tutorias呢?
A:当然有!看看这个。
Q:学OpenGL来钱快不快?
A:建议去新XX学厨师。
后记
在khronos Group接手OpenGL之后,OpenGL的API的进化方向也渐渐地和Direct3D一致了,其深层次原因是因为硬件进化趋势的一致性,在API的使用上OpenGL也渐渐地和Direct3D更加的相似了,在OpenGL 4.4的环境下,基本可以“还原”出和Direct3D 11一样的接口,从Direct3D11移植到OpenGL程序不再是一件难事。