高版本OpenGL函数适配低版本应用程序的方法、装置及介质与流程

文档序号:31788718发布日期:2022-10-12 15:18阅读:45来源:国知局
高版本opengl函数适配低版本应用程序的方法、装置及介质
技术领域
:1.本发明实施例涉及计算机图形编程
技术领域
:,尤其涉及一种高版本opengl函数适配低版本应用程序的方法、装置及介质。
背景技术
::2.开放图形库或者开放式图形库(opengraphicslibrary,opengl)是用于渲染2d、3d矢量图形的跨语言、跨平台的应用程序编程接口(applicationprogramminginterface,api)。所述应用程序编程接口由近350个不同的函数调用组成,用来从简单的图形比特绘制复杂的三维图像,opengl常用于cad、虚拟实境、科学可视化程序和电子游戏开发,作为独立于操作系统的开放的三维图形的软件开发包,在其基础上开发的应用程序能够简单方便的移植于各种平台。3.随着opengl版本的升级,当前图形开发中使用的opengl版本越来越高,从最初的1.0已经演进到最新的4.6版本。开发方式也从最初的纯c/c++编程转变为c/c++混合着色器shader编程。在opengl3.3版本后,opengl图形管线已由固定管线转变为可编程管线。固定管线编程方式相对比较简单,可编程管线编程复杂很多,但是后者可以实现前者实现不了的一些渲染效果,而且在性能上相对前者也有一定提升。但是目前基于opengl开发的应用程序规模相当庞大,小部分使用的是opengl3.3以后的高版本开发的,大部分使用的还是opengl3.3之前版本开发的,因此对于在opengl3.3之前版本开发的应用程序,无法在仅支持opengl3.3及之后的环境上运行。如果在使用opengl3.3之后版本的接口上重写目标应用程序,需要修改大量的低版本opengl应用程序源码,并且若有很多低版本opengl应用程序源码,但是修改方式又不能通用的情况下,不能批量处理,则需要对低版本opengl应用程序源码一一单独处理,费时费力并且适配效率低下。技术实现要素:4.有鉴于此,本发明实施例期望提供一种高版本opengl函数适配低版本应用程序的方法,通过使用高版本opengl函数模拟opengl3.3之前被摒弃的低版本opengl函数的方式,能够支持所有基于低版本opengl开发的应用程序可以在高版本opengl平台运行,并且不需要在高版本opengl中重写接口以及修改大量的低版本opengl应用程序源码,从而节省开发时间,提高开发效率。5.本发明实施例的技术方案是这样实现的:第一方面,本发明实施例提供了一种高版本opengl函数适配低版本应用程序的方法,包括:在应用程序启动前预加载动态库文件;其中,所述动态库文件包括由高版本opengl函数模拟所得到的在高版本opengl函数中已被摒弃的低版本opengl函数;在所述应用程序运行过程中,相应于被执行的opengl函数在高版本opengl函数库中不存在,则调用所述动态库文件中所模拟的且与所述被执行的opengl函数同名的低版本opengl函数;相应于所述被执行的opengl函数在所述高版本opengl函数库中存在,则直接调用高版本opengl函数库中与所述被执行的opengl函数同名的opengl函数。6.第二方面,本发明实施例提供了一种高版本opengl函数适配低版本应用程序的装置,所述装置包括:预加载部分、第一调用部分和第二调用部分;其中,所述预加载部分,经配置为在应用程序启动前预加载动态库文件;其中,所述动态库文件包括由高版本opengl函数模拟所得到的在高版本opengl函数中已被摒弃的低版本opengl函数;所述第一调用部分,经配置为在所述应用程序运行过程中,相应于被执行的opengl函数在高版本opengl函数库中不存在,则调用所述动态库文件中所模拟的且与所述被执行的opengl函数同名的低版本opengl函数;所述第二调用部分,经配置为相应于所述被执行的opengl函数在所述高版本opengl函数库中存在,则直接调用高版本opengl函数库中与所述被执行的opengl函数同名的opengl函数。7.第三方面,本发明实施例提供了一种计算设备,所述计算设备包括:通信接口,存储器和处理器;各个组件通过总线系统耦合在一起;其中,所述通信接口,用于在与其他外部网元之间进行收发信息过程中,信号的接收和发送;所述存储器,用于存储能够在所述处理器上运行的计算机程序;所述处理器,用于在运行所述计算机程序时,执行第一方面所述高版本opengl函数适配低版本应用程序的方法的步骤。8.第四方面,本发明实施例提供一种计算机存储介质,所述计算机存储介质存储有高版本opengl函数适配低版本应用程序的程序,所述程序被至少一个处理器执行时实现第一方面所述高版本opengl函数适配低版本应用程序的方法的步骤。9.本发明实施例提供了一种高版本opengl函数适配低版本应用程序的方法;通过增加一个动态库文件,使得每个在高版本opengl函数库中被摒弃的低版本opengl函数都通过高版本opengl函数进行模拟实现,从而在应用程序运行至需要执行被摒弃的低版本opengl函数时,调用动态库文件中的同名函数完成执行,无需对应用程序源码中的被摒弃的低版本opengl函数进行改写,并且当动态库文件加载完成后可使得本地的高版本opengl函数库能够适配运行各种由低版本opengl函数所产生的应用程序,节省了开发时间,提高了应用程序的开发效率和兼容性。附图说明10.图1为本发明实施例提供的计算机系统组成示意图。11.图2为说明图1中的cpu、gpu和存储器的实例实施方案的框图。12.图3为本发明实施例提供的固定管线流程示意图。13.图4为本发明实施例提供的可编程管线流程示意图。14.图5为本发明实施例提供的一种高版本opengl函数适配低版本应用程序的方法流程示意图。15.图6为本发明实施例提供的一种详细的应用程序调度流程示意图。16.图7为本发明实施例提供的一种高版本opengl函数适配低版本应用程序的装置组成示意图。17.图8为本发明实施例提供的另一种高版本opengl函数适配低版本应用程序的装置组成示意图。具体实施方式18.下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述。19.参见图1,其示出了能够实现本发明实施例技术方案的计算机系统组成100,需注意,图示的系统是可能的系统的仅一个示例,并且可根据需要在各种系统中的任一系统中实现本发明的实施方案。该计算机系统组成100具体可以为任意类型的计算装置,包括且不限于台式计算机、服务器、工作站、膝上计算机、基于计算机的仿真器、无线装置、移动或蜂窝电话(包含所谓的智能电话)、个人数字助理(pda)、视频游戏控制台(包含视频显示器、移动视频游戏装置、移动视频会议单元)、膝上型计算机、桌上型计算机、电视机顶盒、平板计算装置、电子书阅读器、固定或移动媒体播放器等。如图1所示,计算机系统组成100可以包括中央处理器(centralprocessingunit,cpu)10、图形处理器(graphicprocessingunit,gpu)20、存储器30,还包括显示处理器40、显示器41以及通信接口50。显示处理器40可为与gpu20相同的集成电路(integratedcircuit,ic)的部分,也可在包含gpu20的一或多个ic的外部,或可形成于在包含gpu20的ic外部的ic中。20.具体来说,cpu10可包括控制计算机系统组成100运算的通用或专用处理器,其经配置以处理供执行的计算机程序的指令。用户可经由通信接口50与耦合到计算机系统组成100的另一输入装置(未图示)例如:轨迹球、键盘、鼠标、麦克风、触摸垫、触摸屏以及其他类型的装置将输入提供给计算机系统组成100中的cpu10,以使得cpu10执行一或多个软件应用程序的指令。在cpu10上执行的应用程序可包括图形用户接口(graphicuserinterface,gui)应用程序、操作系统、便携式制图应用程序、用于工程或艺术应用的计算机辅助设计程序、视频游戏应用程序、文字处理器应用程序、电子邮件应用程序、电子表格应用程序、媒体播放器应用程序或使用2d、3d图形的渲染应用程序等,本发明实施例以执行图形渲染应用程序为例。此外,cpu10上执行的渲染应用程序可包含一或多个图形渲染指令(也可以理解为待渲染的画面帧中包含一或多个所述图形),所述图形渲染指令可符合图形应用程序编程接口(applicationprogramminginterface,api),例如,开放式图形库api(openglapi)、开放式图形库嵌入系统(opengles)api、direct3dapi、x3dapi、rendermanapi、webglapi、开放式计算语言(opencltm)、renderscript或任何其它异构计算api,或任何其它公用或专有标准图形或计算api,本发明下面的描述中将以openglapi为例进行说明。21.gpu20可经配置以执行图形运算,从而将一或多个图形图元渲染到显示器41进行展示。可以理解为,cpu10通过控制gpu驱动程序14,将opengl定义的图形渲染指令翻译为gpu20可读的图形渲染命令,然后gpu20根据收到的一或多个图形渲染命令,包括但不限于图形命令和图形数据(例如绘制命令、状态信息、图元信息、纹理信息等),以使得gpu20执行所述图形渲染命令中的一些或者全部,从而将一或多个图形图元进行渲染并在显示器41上展示出来。存储器30,经配置用于存储能够在cpu10上运行的应用程序指令、gpu20执行需要的图形数据以及其运行结果数据。例如,gpu20可将完全形成的图像存储在存储器30中。存储器30可包含一或多个易失性或非易失性存储器或存储装置,例如,随机存取存储器(ram)、静态ram(sram)、动态ram(dram)、可擦除可编程rom(eprom)、电可擦除可编程rom(eeprom)、快闪存储器、磁性数据媒体或光学存储媒体。显示处理器40可从存储器30检索图像且输出使显示器41的像素照亮以显示所述图像的值。显示器41可为计算机系统100的显示器,其显示由gpu20产生的图形图像内容。显示器41可为液晶显示器(lcd)、有机发光二极管显示器(oled)、阴极射线管(crt)显示器、等离子显示器或另一类型的显示装置。22.结合图1所示,图2进一步阐述计算机系统组成100中的关键部件cpu10、gpu20和存储器30的实施方案的框图200,如图2所示,本发明实施例的实施方案的框图200主要包括但不限于cpu10、gpu20、存储器30及其对应内部构成。其中,cpu10包含应用程序11、openglapi13、gpu驱动程序14,其中openglapi13和gpu驱动程序14两者中的每一个,可以为一或多个应用程序服务,在一些示例中,openglapi13和gpu驱动程序14可实施为cpu10的硬件单元,而gpu驱动程序14可以将cpu10的一或多个图形渲染指令编译成gpu20可执行的应用程序命令。gpu20内部结构包括但不限于图形存储器21、处理器集群22、纹理内存23。在本发明实施例中,图形存储器21可为gpu20的一部分。因此,gpu20可在不使用总线的情况下从图形存储器21读取数据且将数据写入到图形存储器21。换句话说,gpu20可使用本地存储装置而不是芯片外存储器在本地处理数据,此类图形存储器21可被称作芯片上存储器。这允许gpu20通过消除gpu20经由总线读取和写入数据的需要来以更高效的方式操作,其中经由总线操作可经历繁重的总线业务。在一些示例中,gpu20可不包含单独的存储器,而是经由总线利用外置的存储器30。图形存储器21的类型参见前述存储器30的类型,此处不再赘述。处理器集群22,用于执行图形处理管线,以便对图形渲染命令进行解码,并对图形处理管线进行配置以执行图形渲染命令中所指定的操作。纹理内存23是指用于存放纹理的内存。在渲染过程中,gpu的内存,也可称之为显存,可能被分配为很多不同的用途,比如作为顶点缓存、索引缓存、纹理缓存、模板缓存等,那么纹理内存23就是指纹理缓存。存储器30可包含输出缓冲器31和系统存储器32。其中,输出缓冲器31可为系统存储器32的部分或可与系统存储器32分离。输出缓冲器31可存储经渲染图像数据,例如像素数据,其具体存储的数据为每个像素的红色、绿色、蓝色、α(rgba)分量,其中“rgb”分量对应于色彩值,并且“a”分量对应于目的地α值(例如,用于图像合成的不透明度值)。其还可被称为帧缓冲器(framebuffer)或显存,用于预览所述画面帧的渲染效果,也可以理解为预览所述画面帧的渲染效果可以通过framebuffer机制实现,帧缓冲器是内核空间中的一种驱动程序接口,它本身不具备任何运算数据的能力,中间不会对数据做处理,但其需要真的显卡驱动的支持。23.基于现有技术中opengl的应用程序调用方式,cpu10通过应用程序11经由图形openglapi13向gpu驱动程序14发出指令,gpu驱动程序14可调配指定供gpu20执行的一或多个运算以便渲染图元的一或多个命令,以用于将一或多个图形图元渲染到可显示的图形图像中。当gpu20接收到来自cpu10的图形渲染命令时,gpu20可使用处理器集群22执行图形处理管线,以便对命令进行解码,并对图形处理管线进行配置以执行图形渲染命令中所指定的操作。具体来说,gpu20在实现或运行应用程序的过程中,需要借助于图形渲染管线以实现对图形的渲染操作,而图形渲染管线包括固定管线300和可编程管线400,分别如图3和图4所示,图形渲染管线属于一种通过级联形成的逻辑结构,各级也可称为各渲染阶段。一般分为顶点处理、图元装配、光栅化、片段着色以及测试与混合五个步骤,具体每个步骤对应的模块及操作详见图3和图4。对比图3和图4所示的图形渲染管线示意图,可知固定管线和可编程管线的区别在于,可编程管线增加了可编程的着色器shader,如图4中圆角框所示的顶点处理器和片元处理器,其中,顶点处理器也可称之为顶点着色器,片元处理器也可称之为片段着色器。用户需要在应用程序中编写这两个模块对应的代码。24.需要说明的是,对于opengl中存在的应用程序program和着色器shader的关系为,program相当于当前渲染管线所使用的应用程序,是shader的容器,可以挂载多个shader;而每个shader相当于一个应用程序部分,用来替代固定渲染管线的可编辑应用程序。对着色器shader的处理流程为,首先需要对shader脚本进行编译,然后将编译好的shader挂载到program上,在opengl的渲染中使用program来使shader生效。也就是说,shader是专门用来实现不同渲染工序的应用程序,通过shader可以自定义gpu的shader渲染算法,以使得gpu根据所述shader渲染算法处理所述图形数据中的每一个顶点以及每一个像素点,从而将该画面帧渲染到显示器。另外,由于固定管线的应用程序运行在低版本opengl平台,可编程管线的应用程序运行在高版本opengl平台,但是在固定管线中没有具备编程能力的模块,而且其运行的应用程序的部分低版本opengl函数在高版本opengl函数库中已不存在,因此在高版本opengl中对于在固定管线中基于低版本opengl开发的应用程序将无法运行。如果在高版本opengl的接口重写低版本opengl应用程序源码,需要修改大量的低版本opengl应用程序源码,并且若有很多应用程序源码修改方式不能通用,不能批量处理时,则需要对应用程序源码一一单独处理,费时费力。25.基于上述内容的阐述,本发明实施例期望在应用程序执行前,将低版本opengl函数在高版本opengl中进行模拟,并封装成动态库文件。其中所述动态库文件在其他一些示例中,也可被称之为“动态链接库”或“动态链接文件”等,从而使得在应用程序执行至低版本opengl函数时,通过调用动态库文件中由高版本opengl函数模拟的与被执行的低版本opengl函数的同名函数,以完成对低版本opengl函数的执行,从而无需对应用程序源码中的低版本opengl函数进行重写,节省了开发时间,提高了开发效率。基于此,参见图5,其示出了本发明实施例提供的一种高版本opengl函数适配低版本应用程序的方法,该方法包括:s501:在应用程序启动前预加载动态库文件;其中,所述动态库文件包括由高版本opengl函数模拟所得到的在高版本opengl函数中已被摒弃的低版本opengl函数;s502:在所述应用程序运行过程中,相应于被执行的opengl函数在高版本opengl函数库中不存在,则调用所述动态库文件中所模拟的且与所述被执行的opengl函数同名的低版本opengl函数;s503:相应于所述被执行的opengl函数在所述高版本opengl函数库中存在,则直接调用高版本opengl函数库中与所述被执行的opengl函数同名的opengl函数。26.在一些示例中,结合图2,动态库文件具体可以表现为图2中虚线框所示的动态库模块12,高版本opengl函数库则可以表现为图2中的openglapi13;那么在图5所示的技术方案中,s502所示的步骤参见图2中应用程序11与动态库模块12之间的虚线箭头,s503所示的步骤参见图2中应用程序11与openglapi13之间的实线箭头。27.根据上述方案的描述,本发明实施例通过增加一个动态库文件,使得每个在高版本opengl函数库中被摒弃的低版本opengl函数都通过高版本opengl函数进行模拟实现,从而在应用程序运行至需要执行被摒弃的低版本opengl函数时,调用动态库文件中的同名函数完成执行,无需对应用程序源码中的被摒弃的低版本opengl函数进行改写,并且当动态库文件加载完成后可使得本地的高版本opengl函数库能够适配运行各种由低版本opengl函数所产生的应用程序,节省了开发时间,提高了应用程序的开发效率和兼容性。28.对于图5所示的技术方案,动态库文件中所包括的低版本opengl函数可以通过对应用程序进行预执行的方式进行收集,在一些示例中,所述方法还包括:根据应用程序与本地的高版本opengl函数库筛选获得需要由高版本opengl函数模拟的低版本opengl函数列表;利用高版本opengl函数库中的函数,对所述函数列表中的每个低版本opengl函数进行模拟,并将模拟得到的低版本opengl函数封装为动态库文件。29.对于上述示例,具体来说,所述根据应用程序与本地的高版本opengl函数库筛选获得需要由高版本opengl函数模拟的低版本opengl函数列表,包括:对比应用程序与高版本opengl函数库中的函数,将处于应用程序中且高版本opengl函数库中不存在的低版本opengl函数添加至所述函数列表;或者,预先执行应用程序以通过图形api接口调用高版本opengl函数库,将报错信息中的低版本opengl函数添加至所述函数列表。30.对于上述具体示例,详细来说,由于opengl是一个关于图形api的详述规范,规定了很多函数和其参数返回类型以及要实现的行为和管线操作。基于opengl开发的应用程序使用到的函数在opengl函数库文件中都有对应的原型。举例来说,基于低版本opengl开发的应用程序中的函数包括glbegin函数、glend函数以及glvertex3f函数,这些函数在其对应的低版本opengl函数库中都有对应的代码和相关的数据;假定高版本opengl函数库的版本为4.6,以glbegin函数为例,由于glbegin函数属于低版本opengl函数,不会在高版本opengl函数库中出现,可选地,将应用程序中的函数与高版本opengl函数库中的函数进行比较,就会发现glbegin函数不存在于高版本opengl函数库中,也就是说,glbegin函数即是需要由高版本opengl模拟的函数,并添加至需要由高版本opengl函数模拟的低版本opengl函数列表。可选地,通过图形api接口调用高版本opengl函数库的方式预执行应用程序的过程中,由于glbegin函数属于低版本opengl,不会在高版本opengl函数库中出现,因此在预执行过程中会产生报错信息以指示glbegin函数在高版本opengl函数库中出现,同样也能够说明glbegin函数即是需要由高版本opengl函数模拟的,并添加至需要由高版本opengl函数模拟的低版本opengl函数列表。31.对于图5所示的技术方案,在一些示例中,对于所述利用高版本opengl函数库中的函数,对所述函数列表中的每个低版本opengl函数进行模拟,并将模拟得到的低版本opengl函数封装为动态库文件,包括:使用高版本opengl函数模拟低版本opengl函数前引入默认的顶点着色器和片段着色器的shader以及其对应的输入、输出参数;根据opengl函数所定义的功能,利用高版本opengl函数库中的一或多个函数,对所述函数列表中的每个低版本opengl函数进行模拟并使用全局上下文记录模拟过程中高版本opengl函数所使用的函数信息;所述函数信息至少包括:函数调用次序、函数调用参数次序;将使用高版本opengl函数模拟完成的低版本opengl函数列表封装为动态库文件。32.具体实施过程,详细来说,需要由高版本opengl函数模拟的低版本opengl函数列表中通常包括绘制基本几何图元的函数、矩阵操作及几何变换函数、状态设置函数以及光照、材质、颜色类型的函数等类型。其中,绘制基本几何图元的函数包括glvertex3f、glbegin、glend、glnorma3f、glvertexpointer;矩阵操作及几何变换函数包括glmatrixmode、glloadmatrixf、glpushmatrix、glpopmatrix、gltranslatef、glrotatef、glscalef;状态设置函数例如glenable;光照、材质、颜色类型的函数例如gllightfv、glmaterialfv、glcolor3f、glcolorpointer等。由于在opengl3.3之后的版本,图形渲染管线已由固定管线转变为可编程管线,可编程管线中增加了顶点着色器和片段着色器,因此在高版本opengl中需要输出对这两个模块的代码并且基于顶点着色器和片段着色器的功能,使用低版本opengl开发的应用程序中的部分函数已被摒弃,所以在高版本opengl模拟函数过程中需要引入默认的顶点和片段的shader,其必须的输入和输出信息为:顶点着色器相关的变量或参数有顶点的位置及颜色position、color、视图矩阵及投影矩阵的变量modelview_matrix、projection_matrix、是否开启光照变量enable_light、光源相关的变量light_position、light_ambient、light_diffuse、light_specular、材质相关的变量material_ambient、material_diffuse、material_specular以及片段着色器的变量fragcolor。33.需要说明的是,在一些示例中,根据opengl函数所定义的功能,单个低版本opengl函数需要使用多个高版本opengl函数来模拟完成,两者是一对多的关系。所述在高版本opengl中模拟的低版本opengl函数和前述引入的默认的顶点和片段的shader的输入和输出信息没有任何直接关系,当在高版本opengl模拟过程中函数调用参数(或称之为函数调用变量)有缺失或者参数变更以及在高版本opengl中引入了着色器程序等情况时,会引入一个全局上下文,例如opengl适配器上下文,用于记录在高版本opengl模拟过程中函数调用次序、函数调用参数次序、高版本opengl引入的模拟着色器程序、顶点缓冲对象vbo(vertexbufferobject)、顶点数组对象vao(vertexarrayobject)等相关数据。在高版本opengl中模拟的低版本opengl函数可以引用到所述opengl适配器上下文中的多个参数,具体执行过程中会按照参数的调用次序依次执行。使用高版本opengl函数完成所有需要模拟的低版本opengl函数列表后统一封装为动态库文件,以便后续的执行调用。34.高版本opengl函数模拟低版本opengl函数的过程,需要在opengl适配器上下文中定义需要的参数,此部分参数可以对应前述引入的默认的顶点和片段的shader的输入和输出信息,opengl适配器上下文中定义的参数代码实现如下所示:structglcontext{public:gluintprogram;matrixtypecurrentmatrix=project_matrix;uint32_tprojectmatrixuniform;uint32_tmodeviewmatrixuniform;vmath::mat4currentmatrixdata;vmath::vec4currentcolor;std::vector《vertex》vertexes;vmath::vec4lightposition,lightambient,lightdiffuse,lightspecular;vmath::vec4materialambient[2],materialdiffuse[2],materialspecular[2];boolenablelight;}结合图5所示的技术方案,本发明以绘制基本几何图元的函数glbegin、glend为实施例,根据函数定义的功能,阐述使用高版本opengl函数模拟低版本opengl函数的操作过程。其他需要模拟的低版本opengl函数的模拟方法及具体代码实现与此类似,不再详细赘述。[0035]实施例一:glbegin函数是在高版本opengl函数库已不存在的函数,仅存在于低版本opengl函数库中,其在低版本opengl中的原型是glbegin(glenummode),其中mode是要绘制图元的类型,可以是绘制点gl_points、绘制线段gl_lines、绘制首尾相连线gl_line_loop、绘制三角形gl_triangles、绘制四边形gl_quads等。在高版本opengl中模拟此函数需要完成如下步骤:1.glbegin函数内记录传入的mode类型;2.使用适配器中默认的渲染程序(program);3.更新当前渲染的着色器模型矩阵、投影矩阵的数据并写入渲染程序;4.创建当前glbegin渲染对象并设置其图元类型为传入的mode。在本发明实施例中,glbegin函数在高版本opengl中实现模拟,具体实现的示例性代码如下:void_glbegin(uint32_tflag){gluseprogram(glcontext.program);gluniformmatrix4fv(glcontext.projection_matrix_uniform,1,gl_true,&glcontext.projection_matrix[0][0]);gluniformmatrix4fv(glcontext.model_matrix_uniform,1,gl_true,&glcontext.model_matrix[0][0]);glcontext.vertexdrawmode=flag;}参考在低版本opengl中glbegin函数的代码实现,即可称之为glbegin函数的源码,在低版本opengl实现glbegin函数的代码如下所示:voidglapientry_mesa_begin(glenummode){get_current_context(ctx);structvbo_context*vbo=vbo_context(ctx);structvbo_exec_context*exec=&vbo-》exec;inti;//检查之前是否调用过glbegin且未调用glendif(_mesa_inside_begin_end(ctx)){_mesa_error(ctx,gl_invalid_operation,"glbegin");return;}if(ctx-》newstate)_mesa_update_state(ctx);//判断输入参数mode的合法性glenumerror=_mesa_valid_prim_mode(ctx,mode);if(error!=gl_no_error){_mesa_error(ctx,error,"glbegin");return;}if(exec-》vtx.vertex_size&&!exec-》vtx.attr[vbo_attrib_pos].size){vbo_exec_flushvertices_internal(exec,flush_stored_vertices);//当前绘制图元+1i=exec-》vtx.prim_count++;exec-》vtx.mode[i]=mode;exec-》vtx.draw[i].start=exec-》vtx.vert_count;exec-》vtx.markers[i].begin=1;ctx-》driver.currentexecprimitive=mode;//标记当前调用函数为glbegin已结束ctx-》exec=ctx-》beginend;}if(ctx-》glthread.enabled){ctx-》currentserverdispatch=ctx-》exec;}elseif(ctx-》currentclientdispatch==ctx-》outsidebeginend){ctx-》currentclientdispatch=ctx-》exec;_glapi_set_dispatch(ctx-》currentclientdispatch);}else{assert(ctx-》currentclientdispatch==ctx-》save);}}对比glbegin函数在高版本opengl中模拟的代码实现和在低版本opengl中的源码实现,可知两种代码实现方式均是基于glbegin函数定义的功能,但在高版本opengl中glbegin函数是基于高版本opengl函数库模拟出来的同名函数,而在低版本opengl中glbegin函数是通过调用驱动内部opengl上下文来实现的,因此两者在glbegin函数的代码实现方式上没有可对比性,在高版本opengl中模拟低版本opengl函数的过程中也不需要参考和修改glbegin函数的源码,即可实现glbegin函数的功能。[0036]实施例二:glend函数是在高版本opengl函数库中已不存在的函数,仅存在于低版本opengl函数库中,其原型是glend,此函数的出现意味着一次绘制的结束并且glend函数与glbegin函数相匹配,可以理解为,出现一个glbegin意味着后面就需要一个对应的glend。在高版本opengl中模拟glend函数,则需要做以下工作:1.创建一个vbo对象(vbo对象仅高版本opengl存在),例如命名为vbo;2.绑定vbo对象;3.加载顶点数据对象到vbo;4.指定vbo数据布局中0号位置是一个三元float的数据并激活,布局中0号位置即为顶点位置;5.指定vbo数据布局中1号位置是一个四元float的数据并激活,布局中1号位置即为顶点颜色位置;6.指定vbo数据布局中2号位置是一个三元float的数据并激活,布局中2号位置即为法线信息;7.调用gldrawaray函数绘制;8.调用gldeletebuffers清理绑定的vbo。在高版本opengl中模拟glend函数具体实现的示例性代码如下:void_glend(){gluintvbo;//创建一个对象vboglgenbuffers(1,&vbo);//给vbo分配显存空间glbindbuffer(gl_array_buffer,vbo);//绑定类型为gl_array_buffer的vbo对象//加载顶点数据对象到vboglbufferdata(gl_array_buffer,glcontext.vertexdata.size()*sizeof(vertex),glcontext.vertexdata.data(),gl_static_draw);//指定vbo数据布局中0号位置是一个三元float的数据并激活,0号位置即为顶点位置glvertexattribpointer(0,3,gl_float,gl_true,0,nullptr);glenablevertexattribarray(0);//指定vbo数据布局中1号位置是一个四元float的数据并激活,1号位置即为顶点颜色位置glvertexattribpointer(1,4,gl_float,gl_true,0,(void*)(3*sizeof(float)));glenablevertexattribarray(1);//指定vbo数据布局中2号位置是一个三元float的数据并激活,2号位置即为法线信息glvertexattribpointer(2,3,gl_float,gl_true,0,(void*)(7*sizeof(float)));glenablevertexattribarray(2);//调用gldrawaray函数绘制gldrawarrays(glcontext.vertexdrawmode,0,glcontext.vertexdata.size());//调用gldeletebuffers清理绑定的vbogldeletebuffers(1,&vbo);}以实施例一和实施例二所示出的关于glbegin和glend函数通过高版本opengl函数进行模拟实现的示例,可以利用高版本opengl函数库中的函数模拟完成低版本opengl函数列表中的每个低版本opengl函数,并将完成模拟后的所有低版本opengl函数封装为动态库文件,在高版本opengl应用程序执行至所述低版本opengl中的glbegin和glend函数时,优先执行动态库文件中已模拟过的同名函数。[0037]对于图5所示的技术方案,在一些示例中,动态库文件在被调用之前需要被指定为预加载库,因此,所述在应用程序启动前预加载动态库文件,包括:在应用程序启动前采用ld_preload方式预加载所述动态库文件;或者,在应用程序启动前采用elfplthook方式预加载所述动态库文件;或者,在应用程序启动前采用mhook方式预加载所述动态库文件。[0038]对于上述示例,具体来说,上述三种方式均可称之为hook方式,所述hook直译就是“钩子”的意思,是指截获进程对某个api函数的调用,使得api的执行流程转向实现的代码片段,从而实现所需要的功能,所述功能可以是监控、修复系统漏洞,也可以是劫持或者其他恶意行为。关于ld_preload是适用于linux系统的一个环境变量,它可以影响应用程序的运行时的链接,它允许调试或者开发人员自定义在应用程序运行前优先加载的动态链接库。这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数。通过这个环境变量,调试或者开发人员可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数库。因此,可以以此功能在无需源码的基础上来使用更好的函数,还可以向已开发完成的应用程序注入特定的目的其他程序,例如调试所需的程序;关于elfplthook方式,其最常用的实现机制是got/plthook,got/plthook主要是通过修改可执行和链接格式(executableandlinkingformat,elf)文件结构中的全局偏移表(globaloffsettable,got)和程序链接表(procedurelinktable,plt)段的地址来实现的。elf文件格式除了作为可执行文件,还可以作为共享库格式,也就是我们常见的so(sharedobject)文件(.so)、object文件(.o)、coredumps文件等,got/plthook主要用于实现替换某个so文件的外部调用,其适用于linux系列平台;关于mhook方式,mhook采用的是hook住其它进程中的套接字socket接收和发送方法,所以要写成动态链接库,用于windows系列平台。[0039]本发明实施例以采用ld_preload方式预加载所述动态库文件为例,具体实施方式为,例如上述的低版本opengl中的glbegin函数,其在高版本opengl中模拟完成后封装的动态库文件假定命名为mygl.so,高版本opengl的函数库命名为gl.so,可以在linux命令行输入如下命令进行加载动态库文件mygl.so:exportld_preload="./mygl.so"对于图5所示的技术方案,在一些示例中,对于s502所述的在所述应用程序运行过程中,相应于被执行的opengl函数在高版本opengl函数库中不存在,则调用所述动态库文件中所模拟的且与所述被执行的opengl函数同名的低版本opengl函数,在具体实施过程中,仍然结合上述作为示例的glbegin函数为例,结合前述采用ld_preload方式预加载所述动态库文件的实施方式,假定在高版本opengl上要执行的应用程序命名为myapp,可以在linux命令行输入如下命令调用要执行的应用程序myapp:./myapp应用程序myapp执行过程中,当执行到glbegin函数时,如图6所示,首先判断在高版本opengl函数库中是否存在glbegin函数,若不存在,则调用动态库mygl.so中模拟的低版本opengl的同名glbegin函数而不是高版本opengl函数库gl.so中的函数。对于动态库文件mygl.so来说,在高版本opengl中模拟glbegin函数的过程中需要通过调用高版本opengl函数库gl.so中的函数来模拟完成,因此动态库文件mygl.so需要连接到高版本opengl函数库gl.so。[0040]对于图5所示的技术方案,在一些示例中,对于s503所述相应于所述被执行的opengl函数在所述高版本opengl函数库中存在,则直接调用高版本opengl函数库中与所述被执行的opengl函数同名的opengl函数,在具体实施过程中,仍参见图6,具体来说,如果应用程序myapp要执行的opengl函数在高版本opengl函数库gl.so中存在,则直接调用其对应的高版本opengl函数库gl.so中的函数。[0041]基于前述技术方案相同的发明构思,参见图7,其示出了本发明实施例提供的一种高版本opengl适配低版本应用程序的装置700,所述装置700包括:预加载部分701、第一调用部分702和第二调用部分703;其中,所述预加载部分701,经配置为在应用程序启动前预加载动态库文件;其中,所述动态库文件包括由高版本opengl函数模拟所得到的在高版本opengl函数中已被摒弃的低版本opengl函数;所述第一调用部分702,经配置为在所述应用程序运行过程中,相应于被执行的opengl函数在高版本opengl函数库中不存在,则调用所述动态库文件中所模拟的且与所述被执行的opengl函数同名的低版本opengl函数;所述第二调用部分703,经配置为相应于所述被执行的opengl函数在所述高版本opengl函数库中存在,则直接调用高版本opengl函数库中与所述被执行的opengl函数同名的opengl函数。[0042]在一些示例中,参见图8,所述装置700还包括:筛选部分704和模拟部分705;其中,所述筛选部分704,经配置为根据应用程序与本地的高版本opengl函数库筛选获得需要由高版本opengl函数模拟的低版本opengl函数列表;所述模拟部分705,经配置为利用高版本opengl函数库中的函数,对所述函数列表中的每个低版本opengl函数进行模拟,并将模拟得到的低版本opengl函数封装为动态库文件。[0043]在一些示例中,所述筛选部分704,经配置为:对比应用程序与高版本opengl函数库中的函数,将处于应用程序中且高版本opengl函数库中不存在的低版本opengl函数添加至所述函数列表;或者,预先执行应用程序以通过图形api接口调用高版本opengl函数库,将报错信息中的低版本opengl函数添加至所述函数列表。[0044]在一些示例中,所述模拟部分705,经配置为:使用高版本opengl函数模拟低版本opengl函数前引入默认的顶点着色器和片段着色器的shader以及其对应的输入、输出参数;根据opengl函数所定义的功能,利用高版本opengl函数库中的一个或多个函数,对所述函数列表中的每个低版本opengl函数进行模拟并使用全局上下文记录模拟过程中高版本opengl函数所使用的函数信息;所述函数信息至少包括:函数调用次序、函数调用参数次序;将使用高版本opengl函数模拟完成的低版本opengl函数列表封装为动态库文件。[0045]在一些示例中,所述预加载部分701,经配置为:在应用程序启动前采用ld_preload方式预加载所述动态库文件;或者,在应用程序启动前采用elfplthook方式预加载所述动态库文件;或者,在应用程序启动前采用mhook方式预加载所述动态库文件。[0046]可以理解地,在本实施例中,“部分”可以是部分电路、部分处理器、部分程序或软件等等,当然也可以是单元,还可以是模块也可以是非模块化的。[0047]另外,在本实施例中的各组成部分可以集成在一个处理单元中,也可以是各个单元单独物理存在,也可以两个或两个以上单元集成在一个单元中。上述集成的单元既可以采用硬件的形式实现,也可以采用软件功能模块的形式实现。[0048]所述集成的单元如果以软件功能模块的形式实现并非作为独立的产品进行销售或使用时,可以存储在一个计算机可读取存储介质中,基于这样的理解,本实施例的技术方案本质上或者说对现有技术做出贡献的部分或者该技术方案的全部或部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质中,包括若干指令用以使得一台计算机设备(可以是个人计算机,服务器,或者网络设备等)或processor(处理器)执行本实施例所述方法的全部或部分步骤。而前述的存储介质包括:u盘、移动硬盘、只读存储器(readonlymemory,rom)、随机存取存储器(randomaccessmemory,ram)、磁碟或者光盘等各种可以存储应用程序代码的介质。[0049]因此,本实施例提供了一种计算机存储介质,所述计算机存储介质存储有高版本opengl函数适配低版本应用程序的程序,所述应用程序被至少一个处理器执行时实现上述技术方案中所述高版本opengl函数模拟低版本应用程序方法的步骤。[0050]可以理解地,上述高版本opengl适配低版本应用程序的装置700的示例性技术方案,与前述高版本opengl适配低版本应用程序的方法的技术方案属于同一构思,因此,上述对于高版本opengl适配低版本应用程序的装置700的技术方案未详细描述的细节内容,均可以参见前述高版本opengl适配低版本应用程序的方法的技术方案的描述。本发明实施例对此不做赘述。[0051]以上所述,仅为本发明的具体实施方式,但本发明的保护范围并不局限于此,任何熟悉本
技术领域
:的技术人员在本发明揭露的技术范围内,可轻易想到变化或替换,都应涵盖在本发明的保护范围之内。因此,本发明的保护范围应以所述权利要求的保护范围为准。当前第1页12当前第1页12
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1