Opengl到opengl│es翻译器和opengl│es仿真器的制作方法

文档序号:6558399阅读:243来源:国知局
专利名称:Opengl到opengl│es翻译器和opengl│es仿真器的制作方法
技术领域
本发明涉及使用OpenGL|ES图形标准用于移动设备(比如G4M类型的设备)的三维(3D)应用开发,具体地说,涉及用来允许在OpenGL|ES实现之上的OpenGL应用的运行的翻译器。
背景技术
3D图形标准OpenGL常用于在个人计算机(PC)环境中的图形绘制。图形标准OpenGL|ES是把移动设备、比如移动电话和其它手机作为目标的OpenGL标准的清淡版本。尽管建立了OpenGL|ES标准,但存在一个问题即OpenGL|ES标准太新了以致在市场中基于该标准的3D应用非常少。但是,确实存在相当大数量的用OpenGL为个人计算机编写的遗留应用。直到更适合的基于OpenGL|ES标准的应用在市场上出现,消费者想要在他们的移动设备上有机会运行许多基于OpenGL标准的应用。然而,在OpenGL和OpenGL|ES之间的区别阻止这发生到任何消费者满意的程度,特别是对图形密集应用、比如3D游戏而言更是如此。
在所有的基本OpenGL API(应用编程接口,有时称作命令)中,在OpenGL|ES中仅仅保留了约10%没有变化。在OpenGL|ES中保留了约50%的OpenGL API有微小变化,比如允许较少、不同或新的参数。剩余的基本OpenGL API在OpenGL|ES中根本不支持。关于基于OpenGL的应用和OpenGL|ES绘制引擎实现,对于OpenGL|ES完全支持的第一类的API,由OpenGL应用发送的相关命令能直接发送到OpenGL|ES图形绘制实现。然而,对于受限支持的OpenGL命令,例如其中仅仅支持受限的参数,以及对于根本不被支持的OpenGL命令,需要一些翻译工作以便能够在OpenGL|ES实现上正确地运行应用。
Dylogic提供了被称作“DOGLESS”的翻译器程序,它把OpenGL调用翻译到OpenGL|ES并且把它们转发到底层的OpenGL|ES实现DLL。见http//sourceforge.net/projects/dogless。为了在OpenGL|ES实现上运行OpenGL应用,Dylogic的翻译器截取在OpenGL|ES中不支持的运行时OpenGL命令,并且试图通过使用支持的命令翻译这些命令。在图1的流程图中描绘了这种功能性。使用这种解决方案,一些OpenGL应用和游戏,包括类似Quake 2的图形密集游戏,能够在OpenGL|ES实现上正确地运行。
然而,图1的Dylogic翻译器是概念证据产品并且仅仅翻译非常少量的OpenGL API。而且,与将在下文中更详细地讨论的一样,一些这些翻译是游戏相关的。例如,众所周知Dylogic翻译器对游戏Quake 2工作较好,但对于其它游戏却不好。
为了提交多边形的顶点数据(坐标、颜色、法线……)以便绘制,OpenGL支持两种方式a)“立即方式”,其中在两个GL命令之间逐个顶点地发送数据glBegin/glEnd范例(如图5所示的示例);或b)为每个数据类型使用顶点数组。然而,在OpenGL|ES中,仅仅支持顶点数组方法。因为在单个命令中发送所有的图元数据,所以顶点数组更为有效。Dylogic翻译器工具几乎专门集中在glBegin/glEnd范例的翻译上。这示出在图2中。
Dylogic翻译器解决方案把glBegin/glEnd范例翻译到顶点数组如下在glBegin命令中,通过使用命令glEnableClientState(其启用所有的用于颜色、法线顶点、纹理坐标的数组)激活所有的顶点数组。这完成了复杂图元到三角形的转换。然后通过汇编在命令glVertex、glColor、glTexCoord和glNormal中指定的数据来准备用于顶点数组的数据。随后,使用glEnd命令,把顶点数组传递到实现和使用APIglDrawArray来绘制对象。
从Dylogic翻译器解决方案的回顾能容易地注意到有若干理由表明翻译工作太过简单了。首先,给定应用的需要(颜色、法线、纹理坐标),Dylogic解决方案启用用于顶点坐标、颜色、法线和纹理坐标的所有客户顶点数据数组指针以及把相关的数组传递到绘制引擎。这意味着在解决方案中使用无用的命令和数据,它会导致资源的浪费和性能的戏剧性丢失。其次,在Dylogic解决方案中,在glEnd命令中没有记录和恢复数组状态。这会出现存储器问题。第三,Dylogic解决方案没有考虑多个纹理。
本领域技术人员会认识到OpenGL规范定义了可选的API,也被称作“扩展”,它由图形公司提出并且有时在规范中作为核心添加包括进来。大部分的最近流行的游戏使用这些扩展的一部分。遗憾的是,Dylogic翻译器解决方案根本不处理这些扩展。
总之,Dylogic翻译器解决方案是不完整的解决方案,充其量只是非最佳的能够在顺应OpenGL|ES实现之上运行基本上所有(如果不是所有)的OpenGL应用。因此现有技术中需要这样的翻译器解决方案。

发明内容
根据本发明的实施例,在OpenGL和OpenGL|ES之间的翻译过程包括存储可能由在翻译期间使用的OpenGL|ES函数改变的全局GL状态;通过用OpenGL|ES命令代替OpenGL命令来翻译以得到OpenGL API;为OpenGL|ES实现传递OpenGL|ES API;以及恢复以前存储的全局GL状态。
根据本发明的另一实施例,把在OpenGL中使用glTexGen命令的自动纹理坐标生成翻译到OpenGL|ES的方法包括在命令glTexGen的翻译之前存储纹理坐标数组状态和数据;使用在命令glTexGen中提供的信息,决定应该翻译哪一个纹理坐标元素(s,t,r,q)和应该实现哪一个翻译算法;实现选择的翻译算法以便计算纹理坐标元素(s,t,r,q);存储生成的纹理坐标数据;把含有存储的纹理坐标数据的glEnableClientState和glTexCoordPointer命令传递到OpenGL|ES实现;以及恢复前面存储的纹理坐标数组状态和数据。
根据本发明的再一实施例,把在OpenGL中使用glTexGen命令的自动纹理坐标生成翻译到OpenGL|ES的方法包括截取包括指向顶点属性数据数组的指针的OpenGL glVertexPointer(或glVertex)、glNormalPointer(或glNormal)函数的调用;保存用于顶点坐标和法线数据的参数值;以及响应glTexGen命令,为每个顶点执行一个过程。该过程包括在目系中使用模型图矩阵计算顶点坐标;计算球面纹理坐标(s,t);激活纹理坐标数组;以及把指针数组发送到OpenGL。
用于把在OpenGL中画出几何对象的glBegin/glEnd范例翻译成在OpenGL|ES中画出几何对象的顶点数组的过程包括存储GL状态和数组数据;把在OpenGL中的复杂图元四边形和多边形转换成在OpenGL|ES中画出的较小块的三角形;关于三角形为颜色、法线和纹理坐标准备必需的数组数据;在OpenGL|ES中根据数组数据作为对象绘制三角形;以及恢复以前存储的GL状态和数组数据。
根据又一实施例,为了由OpenGL|ES支持用于翻译存储了一组gl命令和绘图命令的OpenGL API显示列表的方法包括截取glNewList调用以便创建显示列表;创建动态gl命令数组以便存储在glNewList和glEndList之间调用的gl命令;以及响应在OpenGL中的glCallList调用而调用显示列表,执行存储在动态gl命令数组中的所有gl命令。
根据又一实施例,用于把指定了三个或更多个纹理的OpenGL图形调用翻译到OpenGL|ES的方法,其中OpenGL|ES支持指定仅仅两个纹理的图形调用,包括使用OpenGL|ES绘制具有由OpenGL图形调用指定的三个或更多的纹理中的两个的几何图;以及,对于每个由OpenGL图形调用指定的额外纹理,把几何图重画成具有根据该额外纹理的纹理。
根据又一实施例,翻译方法包括在运行时间,用为了在OpenGL应用和OpenGL|ES绘制引擎之间执行而定位的可配置层包裹OpenGL应用,其中上述可配置层执行OpenGL ApI和扩展的应用无关翻译以便由OpenGL|ES绘制引擎支持。


通过参考附图可得到对本发明更完整的理解,其中图1是说明现有技术的OpenGL到OpenGL|ES翻译器的流程图;图2示出支持glBegin/glEnd范例的翻译的图1现有技术翻译器的操作;图3是根据本发明的实施例的OpenGL|ES翻译器和仿真器系统的框图;图4描绘了由图3的翻译器模块执行的翻译的过程;图5说明OpenGL中用于glBegin/glEnd范例的典型代码段示例;图6说明状态存储步骤的示例;图7说明根据本发明的实施例的glBegin/glEnd范例的翻译的过程;图8说明复杂图元到三角形的变换的过程;图9说明用于颜色、法线和纹理坐标的数组数据的准备的过程;图10A和10B说明传递数据数组模块的操作;图11A和11B说明在对象绘制之后恢复状态和数据的过程;图12是说明纹理生成的实现步骤的流程图;图13是说明数组元素的实现步骤的流程图;图14是说明球面映射的实现步骤的流程图;图15是说明显示列表的实现步骤的流程图;图16是说明多纹理生成的实现步骤的流程图。
具体实施例方式
为了解决现有技术的缺陷,本发明的实施例在运行时间用在应用和OpenGL|ES绘制引擎之间的小可配置层包裹OpenGL应用。该层执行与大多数常用的OpenGL API和扩展的优化的游戏无关翻译。使用该解决方案,在OpenGL|ES中的视觉性能应提供与天然的OpenGL图形系统相似的结果或至少具有非常好的近似。
在附图中以及结合本发明的实施例的说明使用以下符号ArrV 用于存储顶点元素的位置数据的二维数据数组,大小为m×4;ArrC 用于存储顶点元素的颜色数据的二维数据数组,大小为m×4;ArrN 用于存储顶点元素的法线数据的二维数据数组,大小为m×3;ArrT0用于存储顶点元素的第一层纹理坐标数据的二维数据数组,大小为m×2;ArrT1用于存储顶点元素的第二层纹理坐标数据的二维数据数组,大小为m×2;normalStateEnable 布尔型,代表是否启用法线数组;colorStateEnable布尔型,代表是否启用颜色数组;tex0StateEnable 布尔型,代表是否启用纹理单元0的纹理坐标数组;tex1StateEnable 布尔型,代表是否启用纹理单元1的纹理坐标数组;colorEnable 布尔型,代表在glBegin/glEnd块内是否发送颜色数据;normalEnable布尔型,代表在glBegin/glEnd块内是否发送法线数据;texEnable 布尔型,代表在glBegin/glEnd块内是否发送纹理坐标数据;
multiTexEnable布尔型,代表当前是否使用多纹理。
现在参考图3,其中示出根据本发明的实施例的OpenGL|ES翻译器和仿真器系统100的框图。翻译器模块102接收配置信息和GL命令并且把在OpenGL|ES中不支持的OpenGL API翻译到所支持的API。所翻译的API被传递到OpenGL|ES实现模块(绘制器)104。系统100还包括仿真器模块106。上述仿真器模块106能从外部或从翻译器模块102的输出接收OpenGL|ES命令。OpenGL实现模块(绘制器)108接收来自仿真器模块106的输出,从而允许OpenGL|ES API在OpenGL实现上被仿真。
现在参考图4,它描绘了由翻译器模块102执行的翻译过程。将认识到OpenGL是一个状态机。因而,一些API可改变一些GL状态并因此影响绘制结果。因此,在发送任何OpenGL|ES命令之前,翻译器模块102首先存储110全局GL状态,该全局GL状态可由在翻译期间使用的OpenGL|ES函数改变。然后,通过为那些原来在OpenGL实现中实现的算法实现使用OpenGL|ES命令的算法来翻译112OpenGL API。然后,为OpenGL|ES实现传递114新的OpenGL|ESAPI。最后,为了与OpenGL应用的继续执行一致,恢复116以前存储110的状态。
通过参考说明该翻译机制的细节的以下示例,可以得到对翻译器102的操作的更好理解。
1.glBegin/glEnd范例的翻译在OpenGL中,使用glBegin/glEnd范例来绘出几何对象是常用的方法。在图5中示出了用于glBegin/glEnd范例的典型的代码段示例,其中以用于每个顶点的具体数据(颜色、法线、纹理坐标)画出了四边形。然而,在OpenGL|ES中根本不支持使用glBegin/glEnd范例来绘制对象。如果应用被编写成利用glBegin/glEnd范例,需要在把命令传递到OpenGL|ES流水线之前把glBegin/glEnd块翻译成顶点数组。该翻译由翻译器102/112来执行。
在OpenGL|ES中支持的顶点数组命令(比如glEnableClientState,glVertexArrayPointer,glColorPointer)用来在从OpenGL的glBegin/glEnd范例翻译之后绘制对象。这些顶点数组命令将需要改变一些GL状态和数组数据(可能对于翻译之后的继续应用执行不利)。因此,在翻译112之前存储110这些状态和数据。图6示出了状态存储110步骤的一个示例。如图6所述,colorStateEnable,normalStateEnable,tex0StateEnable和tex1StateEnable被用来记录当前的数组状态。图6直接阐明了状态存储步骤。响应glEnableClientState调用,解决了颜色、法线和纹理坐标状态存储处理。
图示的顺序仅仅是示范性的。首先,关于颜色处理300,过程测试302是否启用颜色数组。如果否,则过程转到法线处理304。如果是这样,则在步骤306把colorStateEnable变量设置为TRUE以及在步骤308启用颜色客户状态。用于存储110的过程则可返回310到应用。在法线处理304中,过程测试312是否启用法线数组。如果否,则过程转到纹理坐标处理314。如果是这样,则在步骤316把normalStateEnable变量设置为TRUE以及在步骤318启用法线客户状态。于是存储110的过程可返回310到应用。最后,在纹理坐标处理314中,过程测试322是否启用法线数组。如果否,则用于存储110的过程可返回310到应用。如果是这样,则过程测试324层0是否纹理激活。如果是,则在步骤326把tex0StateEnable变量设置为TRUE以及在步骤328启用纹理坐标客户状态。如果在步骤324为否,则过程测试334层1是否纹理激活。如果是,则在步骤336把tex1StateEnable变量设置为TRUE以及在步骤328启用纹理坐标客户状态。如果在测试334为否,则用于存储110的过程可返回310到应用。
在存储110状态和数据之后,如图7所示,能实现glBegin/glEnd范例的翻译(由翻译器112进行)。在模块120“glBegin(mode)”,复杂图元被转换成三角形。由模块120“glBegin(mode)”执行的该转换的细节示出在图8中。在OpenGL|ES中不支持复杂图元类型,比如四边形和多边形。因此,如果由“mode”指示四边形和多边形,这些图元需要被“分解”成用于在OpenGL|ES中画出的较小的三角形块。图8说明glBegin“mode”的参数是如何基于OpenGL四边形和多边形标识改变的。如所示,响应glBegin(mode)调用350,在转换模块120,在步骤352关于“mode”是否是GL_QUAD_STRIP进行测试。如果是这样,则在步骤354中把OpenGL方式标志GL_QUAD_STRIP改变到GL_TRIANGLE_STRIP,并且过程返回356。如果在测试352为否,则过程紧接着在步骤358测试关于“mode”是否为GL_QUADS。如果是这样,则在步骤360把OpenGL方式标志GL_QUADS改变为GL_TRIANGLES,并且过程返回356。如果在测试358为否,则过程接着在步骤362测试关于“mode”是否为GL_POLYGON。如果是这样,则在步骤364把OpenGL标志GL_POLYGON改变为GL_TRIANGLE_FAN,并且过程返回356。这样,基于四边形和多边形的OpenGL复杂图元被转换成用于在OpenGL|ES中绘图所支持的三角形。
再次参考图7,在转换120(详细示出在图8中)之后,翻译112使用准备模块122。在模块122中,准备用于颜色、法线和纹理坐标的数组数据以防应用使用它们。在图9中详细说明准备活动。从命令glVertex、glColor、glNormal和glTexcoord收集这些数组数据以及相应地存储在数组ArrV、ArrC、ArrN、ArrT0中。如果使用多纹理,则从命令glMultiTexCoord收集第二层纹理坐标数组数据并且存储在数组ArrT1中。例如,准备模块122响应以下一个或多个函数的调用glMultTexCoord函数370、glTexCoord函数372、glNormal函数374和glColor函数376。响应它们,为了确保使用适当的数据数组,对应地与调用370-376相比,在步骤380-386把texEnable、normalEnable和colorEnable的状态设置为TRUE。这有助于帮助确保了仅仅把有用的命令传递到OpenGL|ES实现。于是,准备了适当的数据数组。对于多个纹理,响应glMultTexCoord函数370调用,与上文讨论的一样,在步骤390准备数据数组ArrT0和ArrT1。对于单个纹理,响应glTexCoord函数372调用,与上文讨论的一样,在步骤392准备数据数组ArrT0。对于法线,响应glNormal函数374调用,与上文讨论的一样,在步骤394准备数据数组ArrN。最后,对于颜色,响应glColor函数376调用,与上文讨论的一样,在步骤396准备数据数组ArrC。
在步骤122中的准备之后,执行模块124“glEnd”(图7)的翻译过程。模块124包括三个模块传递数据数组模块126;绘制对象模块128;以及恢复数据和状态模块130。在过程126中,启用所有的有用数组状态并且把有用数组数据传递到实现。在图10A和10B中详细解释了传递数据数组模块126的操作。
关于颜色处理400,在步骤402关于colorEnable是否为TRUE进行测试。如果是这样,则在步骤404关于colorStateEnable是否为TRUE进行测试。如果是这样,则在步骤406传递颜色数组ArrC(图9,步骤396)。如果在步骤404为否,则在步骤408启用颜色客户状态,并且在步骤406传递颜色数组ArrC(图9,步骤396)。如果在步骤402为否,则在步骤410关于colorStateEnable是否为TRUE进行测试。如果是这样,则在步骤412禁用颜色客户状态。如果在步骤410为否,或在步骤406或412之后,则用于颜色的过程终止414,以及传递数据数组模块126的操作继续。
关于法线处理420,在步骤422关于normalEnable是否为TRUE进行测试。如果是这样,则在步骤424关于normalStateEnable是否为TRUE进行测试。如果是这样,则在步骤426传递法线数组ArrN(图9,步骤394)。如果在步骤424为否,则在步骤428启用法线客户状态,并且在步骤426传递法线数组ArrN(图9,步骤394)。如果在步骤422为否,则在步骤430关于normalStateEnable是否为TRUE进行测试。如果是这样,则在步骤432禁用法线客户状态。如果在步骤430为否,或在步骤426或432之后,则用于颜色的过程终止434,以及传递数据数组模块126的操作继续。
关于纹理处理440,在步骤442关于textEnable是否为TRUE进行测试。如果是这样,则在步骤444关于tex0StateEnable是否为TRUE进行测试。如果是这样,则在步骤446传递纹理坐标数组ArrT0(图9,步骤392)。如果在步骤444为否,则在步骤448启用纹理坐标客户状态,并且在步骤426传递纹理坐标数组ArrT0(图9,步骤392)。如果在步骤442为否,则在步骤450关于tex0StateEnable是否为TRUE进行测试。如果是这样,则在步骤452禁用纹理坐标客户状态。如果在步骤450为否,或在步骤446或452之后,则用于纹理的过程终止454,以及传递数据数组模块126的操作继续。
关于多纹理处理460,在步骤462关于textEnable是否为TRUE进行测试。如果是这样,则在步骤463关于multitextEnable是否为TRUE进行测试。如果是这样,则在步骤464关于tex1StateEnable是否为TRUE进行测试。如果是这样,则在步骤466传递纹理坐标数组ArrT1(图9,步骤390)。如果在步骤464为否,则在步骤468启用纹理坐标客户状态,并且在步骤466传递纹理坐标数组ArrT1(图9,步骤390)。如果在步骤463为否,则在步骤470关于tex1StateEnable是否为TRUE进行测试。如果是这样,则在步骤472禁用纹理坐标客户状态。如果在步骤470为否,或在步骤462为否,或在步骤466或472之后,则用于纹理的过程终止474,以及传递数据数组模块126的操作继续。
为了更完整地理解由模块126执行的过程,作为示例考虑该模块是如何传递颜色信息的(见颜色处理400)。假定在模块122(图7)中由应用调用命令glColor。如果是这样,则状态变量“colorEnable”被设置为TRUE(见图9)。在该例中,应把命令glEnableClientState(GL_COLOR_ARRAY)传递到实现。为了避免传递多余的命令,最好检查状态变量colorStateEnable是否也为TRUE(在图6中记录了该状态变量)。在图7中,如果该状态是TRUE,则不需要发送命令glEnableClientState(GL_COLOR_ARRAY),因为它已经在估算glBegin/glEnd范例之前被发送。如果我们改为假定在模块122中应用没有调用命令glColor,在这种情况下,状态变量“colorEnable”被设置为FALSE,则不需要把命令glEnableClientState(GL_COLOR_ARRAY)传递到实现。然而,如果记录的状态变量colorStateEnable为TRUE,则应使用命令glDisableClientState(GL_COLOR_ARRAY)来防止指定用于其它对象的颜色信息影响glBegin/glEnd范例的绘制结果。
与涉及法线和纹理坐标的其它信息相关的过程420、440和/或460(如图10所示)通常共享与刚提供的颜色信息示例相同的翻译步骤。
再次参考图7,在所有有用的数组状态和数据被启用和传递到实现(模块126)之后,就要使用命令glDrawArray或glDrawElements绘制对象。该任务由绘制对象模块128来执行。
在绘制对象之后,应通过恢复数据和状态模块130来恢复状态和数据。在图11A和11B中详细解释了模块130的操作。
关于颜色处理500,在步骤502关于colorEnable是否为TRUE进行测试。如果是这样,则在步骤504关于colorStateEnable是否为TRUE进行测试。如果是这样,则在步骤506恢复用于颜色数组ArrC的数据。如果在步骤504为否,则在步骤508禁用颜色客户状态,并且在步骤506恢复颜色数组ArrC。如果在步骤502为否,则在步骤510关于colorStateEnable是否为TRUE进行测试。如果是这样,则在步骤512启用颜色客户状态。如果在步骤510为否,或在步骤506或512之后,则用于颜色的过程终止514,以及恢复模块130的操作继续。
关于法线处理520,在步骤522关于normalEnable是否为TRUE进行测试。如果是这样,则在步骤524关于normalStateEnable是否为TRUE进行测试。如果是这样,则在步骤526恢复用于法线数组ArrN的数据。如果在步骤524为否,则在步骤528禁用法线客户状态,并且在步骤526恢复用于法线数组ArrN的数据。如果在步骤522为否,则在步骤530关于normalStateEnable是否为TRUE进行测试。如果是这样,则在步骤532启用法线客户状态。如果在步骤530为否,或在步骤526或532之后,则用于法线的过程终止534,以及恢复模块130的操作继续。
关于纹理处理540,在步骤542关于textEnable是否为TRUE进行测试。如果是这样,则在步骤544关于tex0StateEnable是否为TRUE进行测试。如果是这样,则在步骤546恢复用于纹理坐标数组ArrT0的数据。如果在步骤544为否,则在步骤548启用纹理坐标客户状态,并且在步骤526恢复用于纹理坐标数组ArrT0的数据。如果在步骤542为否,则在步骤550关于tex0StateEnable是否为TRUE进行测试。如果是这样,则在步骤552启用纹理坐标客户状态。如果在步骤550为否,或在步骤546或552之后,则用于纹理的过程终止554,以及恢复模块130的操作继续。
关于多纹理处理560,在步骤562关于textEnable是否为TRUE进行测试。如果是这样,则在步骤563关于multitextEnable是否为TRUE进行测试。如果是这样,则在步骤564关于tex1StateEnable是否为TRUE进行测试。如果是这样,则在步骤566恢复用于纹理坐标数组ArrT1的数据。如果在步骤564为否,则在步骤568禁用纹理坐标客户状态,并且在步骤566恢复用于纹理坐标数组ArrT1的数据。如果在步骤563为否,则在步骤570关于tex1StateEnable是否为TRUE进行测试。如果是这样,则在步骤572启用纹理坐标客户状态。如果在步骤570为否,或在步骤562为否,或在步骤566或572之后,则用于纹理的过程终止574,以及恢复模块130的操作继续。
通过作为示例考虑模块130是如何恢复颜色信息的(见颜色处理500),可得到对由该模块执行的过程的更完整理解。因而,关于涉及颜色信息的前一示例,如果状态变量“colorEnable”是TRUE,但存储的状态变量“colorStateEnable”是FALSE,则在该情况中应该使用glDisableClientState(GL_COLOR_ARRAY),以便与glBegin/glEnd范例之前指定的状态保持一致。
与涉及法线和纹理坐标的其它信息相关的过程520、540和/或560(如图11所示)通常共享与刚提供的颜色信息的示例相同的恢复步骤。
2.数组元素为了降低在glBegin/End块内的函数调用开销的数量,对于OpenGL可能利用函数glArrayElement()使用数组用于把顶点属性发送到OpenGL。遗憾的是,因为不支持立即方式,所以函数glArrayElement()不被OpenGL|ES支持。
图13示出了根据本发明的实施例的数组元素翻译的机制。通过调用OpenGL函数glVertexPointer、glNormalPointer、glColorPointer、glTexCoordPointer,应用600必须首先把指向顶点属性数据数组的指针发送602到OpenGL。翻译器604截取这些调用(参考602)并且保存606参数值(包括相关的属性指针的地址)。然后,在glBegin/End块608内,翻译器604用对glVertex、glColor、glNormal和glTexCoord的调用614替换612用于glArrayElement()的每个调用610并且使用前述glBegin/glEnd范例的翻译(见图7)完成翻译。所得到的OpenGL|ES命令616被传递到OpenGL|ES管道618用于执行。
3.自动纹理坐标生成在OpenGL中,能通过命令glTexCoord和纹理坐标数组指定纹理坐标,它也能通过命令glTexGen自动生成。许多现有的OpenGL游戏使用该自动纹理坐标生成机制。然而,在OpenGL|ES中不支持自动纹理生成过程。根据本发明的实施例,提供了一种过程以便在OpenGL|ES中允许支持这些纹理生成算法。
在纹理生成中,OpenGL使用了几个算法,比如球面映射、对象线性、眼睛线性等。因为OpenGL|ES仅仅支持顶点数组,所以纹理坐标数组用来存储由生成算法生成的纹理坐标数据。在图12中示出了一个示范的实现过程。
在步骤200,在glTexGen的翻译之前存储纹理坐标数组状态和数据。更具体地说,按图6示出的方式存储该状态信息。
随后在步骤202,过程决定应当翻译哪一个纹理坐标的元素(s,t,r,q)以及应当实现哪一个算法。使用在命令glTexGen中提供的信息作出决定。在该步骤中,因为可能使用多个纹理施加到一个对象,所以过程还决定需要哪一个纹理对象生成纹理坐标。
在步骤204,过程实现选择的算法并且计算纹理坐标(s,t,r,q)。然后纹理坐标数据存储到纹理坐标数组中。
随后在步骤206,过程把以下两个命令传递到OpenGL|ES实现具有在步骤202中准备的纹理坐标数据的glEnableClientState(GL_TEXTURE_COORD_ARRAY)和glTexCoordPointer。
最后,在步骤208,过程恢复在前面根据步骤200存储的纹理坐标状态和数据。
现在参考图14,对于球面映射的例子,提供了允许在OpenGL|ES中支持纹理生成算法的机制的图解。通过调用OpenGL函数glVertexPointer(或glVertex)、glNormalPointer(或glNormal),应用600必须首先把指向顶点属性数据数组的指针发送622到OpenGL。翻译器604截取这些调用(参考622)并且相应地保存626和628用于顶点坐标和法线数据的参数值。然后,关于glTexGen命令630,翻译器604为每个顶点632执行以下过程。首先,使用模型图矩阵在目系中计算顶点坐标(步骤634)。然后,在步骤636,计算球面纹理坐标(s,t)。最后,在步骤638,激活纹理坐标数组并且指针数组被发送到OpenGL。于是,产生的OpenGL|ES命令640被传递到OpenGL|ES管道618用于执行。
4.显示列表OpenGL API显示列表允许存储一组gl命令和绘图命令。更具体地说,通过OpenGL预先计算和存储了上述这组gl命令和绘图命令。当绘制一个对象几次时,该显示列表API因此允许节省一些计算时间。遗憾的是,OpenGL|ES不支持该API。
现在参考图15,该图描绘了根据本发明的实施例的显示列表的翻译机制。翻译器604不必像典型的OpenGL实现所作的那样致力于预先计算在显示列表中的gl命令。代替地,翻译器604保存具有它们的参数值的命令以便当由glCallList调用显示列表时重新调用它们。翻译的操作如下当应用600调用650 glNewList以便创建显示列表时,翻译器604在内部创建652用来存储658将在glNewList 650和glEndList 654之间调用的gl命令656的gl命令的动态数组(链接表)。它还激活一个内部标记,该标记指定当由应用600调用能被存储658到显示列表的gl命令656时,翻译器604仅把具有每个参数的值的gl命令656存储658到内部gl命令数组(链接表)。后来,每当应用600调用glCallList 660来调用显示列表时,翻译器604将调用(即执行)662存储在相关联的内部gl命令数组(链接表)中的所有gl命令。于是,产生的OpenGL|ES命令670被传递到OpenGL|ES管道618用于执行。响应由应用600进行的OpenGL glDeleteList调用664,翻译器604删除668链接表。
5.多纹理从OpenGL(1.2版)以后,可能使用几个纹理单元把几个纹理施加到相同的多边形上。然而,OpenGL|ES(1.1版)仅支持最多两个纹理单元的使用。本发明的实施例解决其中应用利用不止两个纹理单元的情形,在新的OpenGL商业游戏(如Quake3)中常常就是这种情况。
现在参考图16。假定OpenGL|ES仅支持两个纹理单元。响应指定的两个(最前的)纹理680,根据OpenGL|ES的法线操作,翻译器604将生成致使多边形用两个(最前的)纹理680来绘制的OpenGL|ES命令682。然而,如果在OpenGL中应用600请求纹理的第三层684,则本发明的翻译器604用来重画686用第三层纹理684来加纹理的相同的多边形。相应地由翻译器604发出适当的OpenGL|ES命令682导致重画的多边形被绘制。对在OpenGL中由应用600请求的任何更多的纹理层(直到层n)可重复相同操作。
将认识到存在几百个OpenGL API。在上文中已经提供了在OpenGL|ES环境中能如何使用本发明的概念来支持这样的API的几个示例。在图4中示出了关于任何的OpenGL API可以使用的一般翻译过程(如上文所述)。
与使用Dylogic解决方案翻译的那些API相对比,根据本发明的实施例的翻译器提供了比现有技术更合理和完整的优化结果。比较起来,例如,对于glBegin/glEnd范例的翻译,把两个新的步骤126和130增加到“End”命令翻译124。
使用图4的过程,申请者翻译了约70%的OpenGL API(包括比如显示列表(见上文)的API、自动纹理坐标生成(见上文)、PushAttribt和PopAttribut、光系列、素材系列、支持更多纹理内部格式、支持更多复杂数据类型、支持复杂图元)。将注意到,应用很少使用剩余的30%的OpenGL API。
根据本发明的实施例的翻译器还支持许多扩展,比如arb_multitexture、ext_texture_compression_s3tc、ext_compiled_vertex_array、arb_texture_cube_map等。
根据本发明的实施例的翻译器通过在不同的顺应OpenGL|ES实现之上能成功地运行广范围的现代和复杂的3D openGL游戏证明了它的有效性。在大部分情况中,视觉结果完全或者几乎完全相同,仿佛用真的OpenGL绘制引擎绘制它们一样。对于另外一些,对于玩游戏的人在玩游戏期间几乎察觉不到区别。例如,使用以下游戏成功地测试了翻译器Quake1,Quake2,Quake3、Tread Mark和Returnto Castle Wolfenstein。所有这些游戏使用开始/结束块和多纹理扩展,并且还在OpenGL|ES中正确地运行,没有任何明显的令人注意力分散的人为现象。翻译器还在使用纹理坐标生成和编译的顶点数组扩展的TuxRacer上成功地进行测试,并没有明显的令人注意力分散的人为现象。翻译器还在使用立方映射扩展和多纹理扩展的Doom3上成功地进行测试,并且能在OpenGL|ES实现上以非常有限的区别工作。翻译器还在使用显示列表的No Limits Roller Coaster上成功地进行测试,并且能工作很好。翻译器还在使用PushAttrib、PopAttrib和S3TC压缩的纹理扩展的OglVillage上成功地进行测试,并且基本上完美地工作。
通过这种翻译机制,能支持更多的API和扩展,并且因此在OpenGL|ES实现上能运行更多的游戏和应用。
与现有的Dylogic解决方案相比较,本发明提供了更完整的OpenGL到OpenGL|ES翻译器的解决方案许多更多的OpenGL游戏通过本翻译器能在任何顺应OpenGL|ES实现上工作。因为翻译的机制是游戏无关的,所以本发明的解决方案还是更优化的,并且覆盖了所有最常见的例子。
此外,本发明的解决方案提供了若干优点,比如优点1使用该发明,可能通过把应用发出的命令运行时翻译成OpenGL|ES命令,把用于PC的OpenGL应用立即移植到移动设备。因此,不需要重新编译应用。
优点2通过存在于应用和绘制引擎之间,翻译器能够充当可配置的过滤器,它允许运行时减少要绘制的画面的复杂性。例如,因为在移动设备上的屏幕比PC屏幕小得多,可能考虑按给定百分比减少在模型的网格中绘制的三角形的数量,或者减小纹理的分辨率,并因而减小图形引擎进行的计算数量以节省时间和功率。
优点3OpenGL|ES仿真器对于那些想要为移动电话开发OpenGL|ES应用的人来说是一个强大的工具。的确,既然通常在工作站或PC上开发用于移动设备的应用,OpenGL|ES仿真器允许非常快速和方便的方式来直接在PC上仿真OpenGL|ES绘制,并因而加快调试阶段。
虽然在附图中图解了和在前述详细描述中描述了本发明的方法和装置的优选实施例,但是将理解到本发明不受限于公开的实施例,而能够进行大量的重新布置、修改和代替,而不会背离由所附权利要求所陈述和定义的本发明的精神。
权利要求
1.一种在OpenGL和OpenGL|ES之间的翻译过程,包括存储可能由在翻译期间使用的OpenGL|ES函数改变的全局GL状态;通过用OpenGL|ES命令代替OpenGL命令来翻译以得到OpenGLAPI;为OpenGL|ES实现传递OpenGL|ES API;以及恢复先前存储的所述全局GL状态。
2.一种把在OpenGL中使用glTexGen命令的自动纹理坐标生成翻译到OpenGL|ES的方法,包括在所述命令glTexGen的翻译之前存储纹理坐标数组状态和数据;使用在所述命令glTexGen中提供的信息,决定应翻译哪个纹理坐标元素(s,t,r,q)和应实现哪个翻译算法;实现所选择的翻译算法以计算所述纹理坐标元素(s,t,r,q);存储所生成的纹理坐标数据;把含有所存储的纹理坐标数据的glEnableClientState和glTexCoordPointer命令传递到OpenGL|ES实现;以及恢复先前存储的所述纹理坐标数组状态和数据。
3.如权利要求2所述的方法,其特征在于,决定还包括决定需要哪个纹理对象来生成所述纹理坐标。
4.如权利要求2所述的方法,其特征在于,所述OpenGL|ES实现支持顶点数组。
5.一种把在OpenGL中使用glTexGen命令的自动纹理坐标生成翻译到OpenGL|ES的方法,包括截取包括指向顶点属性数据数组的指针的OpenGLglVertexPointer(或glVertex)、glNormalPointer(或glNormal)函数的调用;保存用于顶点坐标和法线数据的参数值;以及响应所述glTexGen命令,为每个顶点执行以下过程在目系中使用模型图矩阵计算顶点坐标;计算球面纹理坐标(s,t);激活纹理坐标数组;以及把指针数组发送到OpenGL。
6.如权利要求5所述的方法,其特征在于,还包括把含有来自所述纹理坐标数组的数据的glEnableClientState和glTexCoordPointer命令传递到OpenGL|ES实现。
7.如权利要求6所述的方法,其特征在于,所述OpenGL|ES实现支持顶点数组。
8.一种把在OpenGL中画几何对象的glBegin/glEnd范例翻译成在OpenGL|ES中画几何对象的顶点数组的方法,包括存储GL状态和数组数据;把在OpenGL中的复杂图元四边形和多边形转换成要在OpenGL|ES中画出的较小块的三角形;关于三角形准备用于颜色、法线和纹理坐标的必需数组数据;在OpenGL|ES中根据所述数组数据作为对象绘制所述三角形;以及恢复先前存储的GL状态和数组数据。
9.如权利要求8所述的方法,其特征在于,转换复杂图元四边形和多边形包括测试用于OpenGL的方式是否为GL_QUAD_STRIP,并且如果是这样,则把OpenGL GL_QUAD_STRIP方式改为在OpenGL|ES中的GL_TRIANGLE_STRIP方式。
10.如权利要求8所述的方法,其特征在于,转换复杂图元四边形和多边形包括测试用于OpenGL的方式是否为GL_QUADS,并且如果是这样,则把OpenGL GL_QUADS方式改为在OpenGL|ES中的GL_TRIANGLES方式。
11.如权利要求8所述的方法,其特征在于,转换复杂图元四边形和多边形包括测试用于OpenGL的方式是否为GL_POLYGON,并且如果是这样,则把OpenGL GL_POLYGON方式改为在OpenGL|ES中的GL_TRIANGLE_FAN方式。
12.如权利要求8所述的方法,其特征在于,准备包括从OpenGL命令glVertex、glColor、glNormal和glTexCoord收集数组数据。
13.如权利要求8所述的方法,其特征在于,绘制包括使用OpenGL|ES glDrawArray或glDrawElements命令绘制所述三角形。
14.如权利要求8所述的方法,其特征在于,还包括截取指向顶点属性数据数组的OpenGL指针;保存与所截取的指针相关的参数值;以及在所述glBegin/glEnd范例内,用OpenGL|ES支持的对glVertex、glColor、glNormal和glTexCoord的调用来代替用于glArrayElement()的每个OpenGL调用。
15.一种为了被OpenGL|ES支持而翻译存储了一组gl命令和绘图命令的OpenGL API显示列表的方法,包括截取glNewList调用以创建显示列表;创建动态gl命令数组以存储在glNewList和glEndList之间调用的gl命令;以及响应在OpenGL中的glCallList调用以调用所述显示列表,执行存储在所述动态gl命令数组中的所有所述gl命令。
16.如权利要求15所述的方法,其特征在于,创建还包括设置标记,所述标记指定对于每个调用的能存储到所述显示列表中的gl命令,仅把具有参数值的所述gl命令存储到所述动态gl命令数组中。
17.如权利要求15所述的方法,其特征在于,创建保存具有参数值的所述gl命令,以便当由glCallList调用所述显示列表时重新调用它们。
18.如权利要求15所述的方法,其特征在于,还包括响应OpenGLglDeleteList调用,删除所述动态gl命令数组。
19.一种用于把指定了三个或三个以上纹理的OpenGL图形调用翻译到OpenGL|ES的方法,其中OpenGL|ES支持指定仅仅两个纹理的图形调用,包括使用OpenGL|ES绘制具有由所述OpenGL图形调用指定的所述三个或三个以上纹理中的两个的几何图;以及对于每个由所述OpenGL图形调用指定的额外纹理,重画所述几何图以根据该额外纹理加上纹理。
20.一种翻译方法,包括在运行时间,用为了在OpenGL应用和OpenGL|ES绘制引擎之间执行而定位的可配置层包裹所述OpenGL应用,其中所述可配置层执行OpenGL API和扩展的应用无关翻译,以便被所述OpenGL|ES绘制引擎支持。
21.如权利要求20所述的方法,其特征在于,包裹包括存储可能由任何在应用无关翻译期间使用的OpenGL|ES函数改变的全局GL状态;以及然后在OpenGL|ES绘制之后恢复所述全局GL状态,以便与所述OpenGL应用的继续执行保持一致。
22.如权利要求21所述的方法,其特征在于,所述包裹,就所述应用无关翻译而言,还包括用OpenGL|ES命令代替OpenGL命令并且为OpenGL|ES实现传递OpenGL|ES API。
23.如权利要求22所述的方法,其特征在于,代替包括把OpenGL中的复杂图元四边形和多边形转换成用于在OpenGL|ES中绘图的较小块的三角形。
24.如权利要求22所述的方法,其特征在于,替代包括,对于在OpenGL中使用glTexGen命令的自动纹理坐标生成操作,计算纹理坐标元素,存储所生成的纹理坐标数据,以及把含有所存储的纹理坐标数据的glEnableClientState和glTexCoordPointer命令传递到OpenGL|ES实现。
25.如权利要求22所述的方法,其特征在于,代替包括对于在OpenGL中使用glTexGen命令的自动纹理坐标生成操作,对每个顶点执行以下过程在目系中使用模型图矩阵计算顶点坐标;计算球面纹理坐标(s,t);激活纹理坐标数组;以及把指针数组发送到OpenGL。
26.如权利要求22所述的方法,其特征在于,代替包括对于存储一组gl命令和绘图命令的OpenGL API显示列表截取glNewList调用以创建显示列表;创建动态gl命令数组以存储在glNewList和glEndList之间调用的gl命令;以及响应在OpenGL中的glCallList调用以调用所述显示列表,执行存储在所述动态gl命令数组中的所有所述gl命令。
27.如权利要求22所述的方法,其特征在于,代替包括对于指定了三个或三个以上纹理的OpenGL图形调用,其中OpenGL|ES支持指定仅仅两个纹理的图形调用使用OpenGL|ES绘制具有由所述OpenGL图形调用指定的所述三个或三个以上纹理中的两个的几何图;以及对于每个由所述OpenGL图形调用指定的额外纹理,重画所述几何图以根据该额外纹理加上纹理。
全文摘要
由于缺乏基于Open GL│ES标准的3D应用,期望在Open GL│ES移动设备如蜂窝电话上运行基于OpenGL标准的3D应用。为解决此期望,必须能在OpenGL和OpenGL│ES间翻译函数调用。为支持此翻译和以便确保用于OpenGL应用继续执行的正确数据状态,存储可能被翻译期间使用的OpenGL│ES函数改变的全局GL状态。然后通过用适当OpenGL│ES命令代替OpenGL命令实施OpenGL到OpenGL│ES翻译,为OpenGL│ES实现传递OpenGL│ES API。此后,恢复先前保存的全局GL状态,以致执行的翻译不会不利地影响OpenGL配置的应用继续执行。关于若干OpenGL API和一些已知扩展,这种翻译过程支持OpenGL到OpenGL│ES翻译。
文档编号G06T15/00GK101059760SQ200610077518
公开日2007年10月24日 申请日期2006年4月20日 优先权日2006年4月20日
发明者C·夸尔, 李海珍, 陈国基 申请人:意法半导体研发(上海)有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1