OpenGLESCommon/Common-Lite规范OpenGLES基本知识OpenGLES(以后简写为“GL”)仅关心如何在帧缓存(framebuffer)中渲染(渲染后的值将保存到帧缓存中)。它不支持其他的外围设备与图形硬件关联,例如鼠标和键盘。编程人员必须通过其他的途径获取用户操作,例如KhronosOpenKODEAPI。GL在一定数量的可选模式下绘制原始对象。每个原始对象可以是一个点,线段或者一个三角形。每种模式可以独立的改变。每个设置之间不相互影响(虽然一些模式可能最终影响帧缓存中的最后结果)。模式被设置,原始对象被定义,其他GL操作通过在函数或者程序中调用。原始对象是一组被定义好的数据结构,包含一个或者多个顶点。一个顶点定义了一个点,或一个边的结束点,或者一个三角形的2条边相交的顶点。数据(包括位置坐标,颜色,规格化,纹理坐标)保存在一个顶点中,每个顶点按照顺序,以相同方式,独立的被处理。唯一例外的是,如果一组顶点必须在一个指定的矩形区域内被裁减,这个操作将导致,一些顶点可能被修改,一些新顶点可能被创建。裁减的类型依赖于这组顶点数据代表的描绘类型。命令永远按照顺序执行,虽然可能命令的实现会有不确定的延时。比如,一个原始对象在必须在任何子序列影响帧缓存之前绘制。它也意味着查询和像素读取操作返回的状态时,之前的所有的GL命令执行完毕。通常,GL命令必须在其他子序列在造成任何影响之前完成。在GL中,数据绑定发生在调用的时候。这意味着命令执行时,使用的数据会被解释。即使命令要求一个指向数据的指针,这些数据当调用的时候即被解释,任何子序列的对数据的改变都不会产生影响(除非后继的操作中使用了同样的指针)。GL提供对3D,2D图形的基本操作。包括特定的矩阵变换,光照方程系数,抗锯齿,像素更新操作。它不提供复杂几何元素的描述或者建模。另一种对这种解决方案的描述是GL提供一些途径去描述如何渲染复杂的几何对象,而不直接描述此类复杂的对象。GL命令是按照客户端-服务器模式去解释的。也就是说,程序(客户端)运行命令,这些命令在服务器端解释并且执行。一个服务器可能保持一定数量的GLcontext对象。每个对象都是对当前GL状态的封装。一个客户端可能选择连接任何这些context对象中的任何一个。当程序不连接任何一个context时,运行GL命令会导致未定义的行为。GL命令的通过窗口系统最大限度的控制帧缓存,窗口系统决定GL在给定的时间内可以访问帧缓存中的哪些点,它还负责与GL交流点的数据结构。因此,没有任何GL命令去定义帧缓存或者初始化GL。同样,在CRT或者LCD上帧缓存的显示内容(包括某些技术进行的单独帧缓存值变换,例如gamma纠错)是不被定位到GL中。帧缓存构造发生在GL的外部,同窗口系统相关联。GL的初始化发生在窗口系统为GL分配一个窗口时。EGLAPI定义了一个简便的途径创建GLcontexts和窗口,该窗口可用于连接不同平台的窗口系统。GL被设计成运行可以运行在一系列图形平台上,并提高图形显示的效果和性能。为了适应多样性,某些GL操作使用理想行为代替了实行行为,因为背叛这种设想是允许的,也规定了一个实现必须遵守的规则使其接近理想的行为。在GL中,这个允许的变化指2个完全不同的GL的实现可以出现像素到像素的不一致,即便相同的输入,或者相同帧缓存配置下。最后,命令的名字,常数和类型都是用GL作前缀(可以为gl,GL_,GL),这样可以减少与其他包出现姓名冲突。在以后的文档中,前缀可能被省略。数值计算GL操作中必须进行一些数值运算。Commonprofile下,通常使用浮点数计算,浮点数的范围将在后面的“浮点计算”中有精确的定义。Commonliteprofile下,通常使用定点数计算,顶点数的范围将在后面的“定点运算”中做更精确的定义,但是也它也可以使用浮点数来计算。浮点计算我们不规定浮点数是如何表现的,它们的操作是如何执行的。我们简单的要求数字浮点部分包含足够的比特位和足够大的指数位,所有单独浮点操作结果都精确到1/105。浮点数用来表示位置和规格化坐标时,最重要的是至少精确到232。表示颜色或者纹理坐标,最少精确到210。其他浮点数至少精确到232。x.0=0.x=01.x=x.1=xx+0=0+x00=1大部分单精度浮点格式需要满足这些要求。任何浮点数作为GL命令的输入是合法的,如果提供一个浮点数是未定义的,但是必须保证不会导致GL中断或者结束。在IEEE计算中,例如,对GL命令输入一个负零或者一个未规格化数会产生可预知的结果,而提供NaN或者无穷大会产生未定义的结果。如果x的值不是一个浮点数,以上一致性的规定不需要保持。定点数计算内部计算可以即可以使用定点计算,也可以使用浮点计算。定点计算必须精确在±2-15。定点数表示位置或者规格化坐标必须精确到215;表示颜色或者纹理坐标必须精确到210。其他定点值必须精确到215。x.0=0.x=01.x=x.1=x;x+0=0+x=x00=1定点数可能导致上溢出或者下溢出,计算的结果是未被定义的,但是不能导致GL中断或者终止。通常要求以下的限制对所有的实现都必须被遵守,无论使用浮点数还是定点数计算。32比特位按照16.16划分,16表示分数,16表示整数位。如果一个顶点使用16.16表示,模型视图和映射矩阵用16.16表示,视野空间和规格化设备坐标空间的点用16.16表示(计算过程中的表达式可以使用充足的动态范围),然后变换管线必须计算视野空间和规格化设备坐标空间的点是有理由的精确(例如:溢出是不被接受的)。一些计算需要除法。因为某些原因(包括矢量规格化中隐含的除法),除零会导致一个未定义的结果,但是不能导致GL中断或者终止。GL状态GL拥有相当多的状态。这份文档列举了每个状态变量,并且描述了如何改变这些变量。为了方便讨论,状态变量根据功能被归类。虽然GL操作在帧缓存中执行,但是帧缓存不属于GL状态。虽然GL的实现可能依赖于硬件,该规范不依赖于任何特别实现GL的硬件,因此我们关注于图形卡与GL精确通信后的状态。GL命令语法GL命令是函数或者程序。各种不同的命令组执行着同样的操作,但是区别于提供不同的参数。为了方便的提供这种变化,我们采纳一种标记法来描述命令和他们的参数。GL命令是按照下面的格式来命名的,依赖于4个特别的字母。第一个字母指示必须提供给命令的参数的数量,第二个字母指示参数的类型:8比特位的整数,32比特位的整数,32比特位的顶点数,或者单精度的浮点数。最后一个字母,如果是v,它指示命令需要一个指针参数,该参数指向一个数组(一个向量),而不是一系列的单独参数。以下是2个例子:voidColor4f(floatr,floatg,floatb,floata);和voidGetFloatv(enumvalue,float*data);这些例子显示了ANSIC对这些命令的申明,通常一个命令的申明使用如下格式:rtypeName{∈1234}{∈ixfubui}{∈v}([args,]Targ1,:::,TargN[,args]);rtype表示函数返回值,{}包括了一系列的字母或者字母对,它们是多选一的关系。∈不表示字母。括号中的参数([args,]和[,args])表示是可选的。从第arg1到argN个参数的类型都是T,T的代表的具体意义在Table2.1中描述(如果是表中不存在的字母,可能这个参数的类型已经被明确了的)。如果最后一个字母不是v,N可能是1,2,3,4(如果这里没有数字,参数的数目一定是明确的)。LetterCorrespondingGLTypeiintxfixedffloatububyteuiuintTable2.1:CorrespondenceofcommandsuffixletterstoGLargumenttypes.RefertoTable2.2fordefinitionsoftheGLtypes.如果最后一个字母是v,此时只有参数arg1,它是一个含有N个指定类型值的数组,最后,我们指明一个无符号类型使用u做前缀(因此,unsignedint被缩写成uint)。例如,voidNormal3{xf}(Tag);代表2个声明voidNormal3f(floatarg1,floatarg2,floatarg3);voidNormal3x(fixedarg1,fixedarg2,fixedarg3);fixed类型的参数是Table2.2中13种类型中的一个,或者指向其中某种类型。GL类型到特定语言数据类型的映射是语言绑定声明的一部分,它可能与平台相关,各种不同数据类型的实际和正式参数的类型转换或者类型提升,都依赖于语言绑定的平台。例如,C语言包括自动转换在整型和浮点数据类型,但是不包括int和fixed,或者float到fixedGL数据类型的转换,因为fixed得数据类型不是一个清晰地内置类型。无论何种语言绑定,enum类型可以不做任何缩放转化成定点类型,整型可以通过与216相乘,转化成定点数据类型。GLTypeMinimumBitWidthDescriptionboolean1Booleanbyte8Signedbinaryintegerubyte8Unsignedbinaryintegershort16Signed2’scomplementbinaryintegerushort16Unsignedbinaryintegerint32Signed2’scomplementbinaryintegeuint32Unsignedbinaryintegerfixed32Signed2’scomplement16.16scaledintegerclampx3216.16scaledintegerclampedto[0,1]sizei32Non-negativebinaryintegersizeenum32EnumeratedbinaryintegervalueintptrptrbitsSigned2’scomplementbinaryintegersizeiptrptrbitsNon-negativebinaryintegersizebitfield32Bitfieldfloat32Floating-pointvalueclampf32Floating-pointvalueclampedto[0,1]Table2.2:GL数据类型。GL类型不是C类型。因此,例如GL类型int为GLint,它并非一定等同与c语言类型int。一个实现可能使用比表中指出的数字还要多的比特位去表示一个GL类型。纠正超过最小范围的整型值是不必要的。然而ptrbits是一个指针类型必须的比特位数。换句话说,类型intptr和sizeiptr必须足够大,可以保存任何地址。基础GL操作图例2.1显示了一个GL的大纲图表。GL命令从左边输入。一些命令用于几何图形的绘制,另一些用于控制不同场景中的对象。第一类场景操作是针对原始几何对象:点、线段和三角形。它们使用顶点来描述。在这个场景中,顶点被转换和限制,原始对象被裁减成一个视图的容量,为下一个场景做准备—栅格化。栅格化构建了一系列的帧缓存地址和值,使用二维描述点、线段、或者三角形。每个片段的创建是为下个场景提供源。在他们最终改变到帧缓存中之前,每个场景作为独立的片段运行。这些操作包括有条件的更新到帧缓存(该操作基于正在到来和先前保存深度值(影响深度缓存)),混合正在到来的片段颜色和先前保存的颜色,遮照和其他的对片段的逻辑操作。值可能从帧缓存中被读回,或者复制帧缓存的一部分到另一个帧缓存中去,这些传输可能包含某种类型的编解码。这种分类意味着仅仅使用作为一个工具去描述GL,而不能严格定义GL是如何实现的,我们在这里规定的只是组织各种GL的操作。GL报错GL仅能探测到所有被考虑到的错误的一个子集,这是因为很多情况下,错误的检查与一个错误-自由程序的实现相违背。命令:enumGetError(void);用于获得错误信息,每个可以