OpenGL与OpenGL ES 2.0 - OpenGL应用程序是否可以轻松移植?

44

我正在开发一个游戏框架,并且是OpenGL的新手。大多数书籍似乎没有很清晰地回答这个问题,我想在我的台式电脑上使用OpenGL进行开发,但在OpenGL ES 2.0环境中执行代码。那么我的问题就有两个:

  1. 如果我针对台式机的OpenGL开发我的框架,是否可以在不修改的情况下在OpenGL ES 2.0环境中运行?
  2. 如果不能,那么是否有好的模拟器可用,无论是PC还是Mac;是否有一种脚本可以将我的OpenGL代码转换为OpenGL ES代码,或者标记哪些内容无法工作?
5个回答

41

距离我上一次进行任何ES工作已经有大约三年时间了,因此我可能已经过时或者只是记错了一些东西。

  1. 不,针对桌面的OpenGL并不等同于针对OpenGL ES,因为ES是一个子集。ES不实现立即模式函数(glBegin()/glEnd(), glVertex*(), ...),而是使用顶点数组作为将数据传入渲染管线的主要方式。

    另外,这还取决于你要针对哪个配置文件:至少在Lite配置文件中,ES不需要实现浮点数函数,而是使用固定点函数;可以将其视为32位整数,其中前16位表示小数点前的数字,后面16位表示小数点后的数字。

    换句话说,即使是简单的代码如果使用浮点数可能也无法移植(你需要用调用gl*x()函数来替换对gl*f()函数的调用)。

    可以看一下在Trolltech's example中如何解决这个问题(特别是qtwidget.cpp文件;这是Qt的例子,但还是可以参考一下)。你会看到他们使用了这个调用:

    q_glClearColor(f2vt(0.1f), f2vt(0.1f), f2vt(0.2f), f2vt(1.0f));

    这是为了替换对glClearColorf()函数的调用。此外,他们使用宏f2vt()——表示将浮点数转换为正确的数据类型。

  2. 三年前我为一家公司开发一些小演示时,使用了PowerVR的SDK取得了成功。该SDK适用于Windows下的Visual C++;我没有在Linux下试过(因为我是在公司电脑上工作)。


  3. 最近我的ES经验有所更新。(2011年6月7日)

    • 现今的平台可能不再使用Lite profile,因此您可能不必担心固定小数点问题
    • 当将桌面代码移植到移动端(例如iOS)时,您主要需要完成以下内容:
      • 使用顶点数组替换glBegin()/glEnd()等函数
      • 使用类似glClearColorf()的函数替换一些调用glClearColor()的函数
      • 重写窗口和输入系统
      • 如果针对OpenGL ES 2.0以获取着色器功能,则您现在必须使用着色器完全替换内置行为的固定管线 - 至少是重新实现固定管线的基本部分。
    • 非常重要:除非您的移动系统没有内存限制,否则您真的需要考虑使用纹理压缩来处理图形芯片。例如,在iOS设备上,您将上传PVRTC压缩数据到芯片上。

2/ http://www.imgtec.com/PowerVR/insider/sdkdownloads/ 哪个档案适用于Linux平台?我相信我们可以在GLES实现的基础上模拟glBegin。 - RzR
@rzr:模拟glBegin()肯定是可行的,但可能不是一个好主意。您可能希望重新构建代码。在该网站上,您需要下载OpenGL ES 1.1或OpenGL ES 2.0的“PC模拟器”存档。 - Ivan Vučica
首要目标是确保源代码兼容性,不必考虑性能,只需构建传统应用程序... - RzR

4

在新设备中使用的OpenGL ES 2.0中,旧的固定管线已经消失,因此您需要提供自己的顶点着色器和片元着色器。这意味着您需要自己进行任何阴影计算等操作,这些操作可能相当复杂,但是您可以在GLSL教程中找到现有的实现。

尽管如此,由于GLES是桌面OpenGL的子集,因此可以在两个平台上运行相同的程序。


3
这是一个非常好的答案,可能会导致最有效的方法(避免重构,在编写代码时就使用VBOs可编程化)。 - Engineer
1
ES2不是桌面GL的严格子集,而ES3是。 - Bartek Banachewicz

4

我知道有两个相关桌面和ES之间提供GL翻译的项目:

  • glshim: 重要的固定管线支持1.x,基本的ES 2.x支持。

  • Regal: 可以将任何内容转化为ES 2.x。


我最近也发现了Regal,它看起来非常不错。 - Bartek Banachewicz
我发现使用Regal很痛苦,不过:( - lunixbochs

3
据我了解,OpenGL ES是OpenGL的一个子集。如果您避免使用即时模式(immediate mode)的内容,比如glBegin()和glEnd(),那么应该就没问题了。虽然我最近几个月没有怎么使用OpenGL,但当我使用ES 1.0时,只要不用glBegin/glEnd,我从标准OpenGL中学到的所有代码都能正常运行。
我知道iPhone模拟器可以运行OpenGL ES代码,但Android模拟器是否支持我就不确定了。
这里有一个Windows仿真器的链接: Windows emulator.

Android SDK模拟器肯定可以运行OpenGL ES代码,取决于您的虚拟设备支持的API版本。但比真实设备慢得多。 - davenpcj
此外,Android模拟器只能处理OpenGL ES 1.x。如果输入OpenGL ES 2.0代码,则会抛出异常。必须在支持2.0的设备上进行测试。这可能会在几周内随着Ice Cream Sandwich的推出而改变,但我不会指望它:开发人员的态度是,在设备上测试更简单,因此更新模拟器并不重要。 - Matt J.

0

选项3)您可以使用Qt这样的库来处理您的OpenGL代码,使用它们内置的包装函数。这为您提供了使用一个代码库(或最小化不同的代码库)来针对OpenGL构建几乎任何平台的选项。您不需要为想要支持的每个不同平台进行端口移植。Qt甚至可以根据您使用的函数选择OpenGL上下文。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接