OpenGL vs OpenGL ES 2.0 - 可以轻松移植 OpenGL 应用程序吗?

Posted

技术标签:

【中文标题】OpenGL vs OpenGL ES 2.0 - 可以轻松移植 OpenGL 应用程序吗?【英文标题】:OpenGL vs OpenGL ES 2.0 - Can an OpenGL Application Be Easily Ported? 【发布时间】:2010-11-13 20:02:58 【问题描述】:

我正在开发各种游戏框架,并且是 OpenGL 的新手。大多数书籍似乎都没有对这个问题给出非常明确的答案,我想在我的桌面上使用 OpenGL 进行开发,但在 OpenGL ES 2.0 环境中执行代码。那么我的问题是双重的:

    如果我将我的框架用于桌面上的 OpenGL,它是否会在 OpenGL ES 2.0 环境中不加修改地运行? 如果没有,那么有没有好的模拟器,PC 或 Mac;是否有我可以运行的脚本将我的 OpenGL 代码转换为 OpenGL ES 代码,或者标记那些不起作用的东西?

【问题讨论】:

【参考方案1】:

自从我上次做任何 ES 工作以来已经过去了大约三年,所以我可能已经过时或者只是记错了一些东西。

    不,针对桌面的 OpenGL 不等于针对 OpenGL ES,因为 ES 是一个子集。 ES 没有实现立即模式函数(glBegin()/glEnd(), glVertex*(), ...)顶点数组是向管道发送内容的主要方式。

    此外,这取决于您所针对的配置文件:至少在 Lite 配置文件中,ES 不需要实现浮点函数。相反,您会得到定点函数;考虑 32 位整数,其中前 16 位表示小数点前的数字,后面的 16 位表示小数点后的数字。

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

    在Trolltech's example(特别是qtwidget.cpp 文件;这是Qt 示例,但仍然...)中查看如何解决此问题。你会看到他们打了这个电话:

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

    这是为了替换对 glClearColorf() 的调用。此外,他们使用宏 f2vt() - 意思是 float 到顶点类型 - 它自动将参数从 float 转换为正确的数据类型。

    三年前,当我为一家公司开发一些小型演示时,我与PowerVR's SDK 合作取得了成功。它适用于 Windows 下的 Visual C++; Linux下没试过(因为我在公司PC上工作所以没必要)。


一个小更新,以反映我最近使用 ES 的经验。 (2011 年 6 月 7 日)

当今的平台可能不使用 Lite 配置文件,因此您可能不必担心定点小数 在将桌面代码移植到移动设备(例如 ios)时,很可能您必须主要执行以下操作,而其他操作不多: 用顶点数组替换glBegin()/glEnd() 用诸如glClearColorf()之类的调用替换一些对诸如glClearColor()之类的函数的调用 重写您的窗口和输入系统 如果以 OpenGL ES 2.0 为目标来获得着色器功能,您现在必须用着色器完全替换固定功能管道的内置行为 - 至少是重新实现固定功能管道的基本行为 非常重要:除非您的移动系统不受内存限制,否则您真的想考虑为您的图形芯片使用纹理压缩;例如,在 iOS 设备上,您会将 PVRTC 压缩数据上传到芯片

【讨论】:

2/ imgtec.com/PowerVR/insider/sdkdownloads 哪个存档用于 linux 平台?我相信我们可以在 GLES 实现之上模拟 glBegin @rzr:模拟 glBegin() 当然是可能的,但可能是个坏主意。相反,您可能想要重组代码。在该站点上,您需要下载 OpenGL ES 1.1 或 OpenGL ES 2.0 的“PC Emulation”存档。 目标是首先确保源代码兼容性,不关心性能,只想构建遗留应用程序... -- rzr.online.fr/q/opengl【参考方案2】:

在新设备使用的 OpenGL ES 2.0 中,您还必须提供自己的顶点和片段着色器,因为旧的固定功能管道已不复存在。这意味着必须自己进行任何着色计算等,这将是相当复杂的事情,但您可以在 GLSL 教程中找到现有的实现。

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

【讨论】:

+1 这是一个非常好的答案,可能会导致最有成效的方法(避免重构,从一开始就将代码编写为可使用 VBO 进行编程)。 ES2 不是桌面 GL 的严格子集,ES3 是。【参考方案3】:

我知道有两个项目可以在桌面和 ES 之间提供 GL 翻译:

glshim:大量固定管道到 1.x 支持,基本 ES 2.x 支持。

Regal:ES 2.x 的任何内容。

【讨论】:

我最近也找到了Regal,看起来还不错。 我发现 Regal 使用起来很痛苦,但是 :(【参考方案4】:

据我了解,OpenGL ES 是 OpenGL 的一个子集。我认为如果你避免使用立即模式的东西,比如 glBegin() 和 glEnd() 你应该没问题。在过去的几个月里,我没有对 OpenGL 做太多事情,但是当我使用 ES 1.0 时,只要我不使用 glBegin/glEnd,我从标准 OpenGL 中学到的所有代码都可以工作。

我知道 iPhone 模拟器运行 OpenGL ES 代码。我不确定android的。

这里是Windows emulator.

【讨论】:

android SDK 模拟器肯定会运行 OpenGL ES 代码,具体取决于您的虚拟设备支持的 API 版本。不过比真实设备慢得多。 此外,Android 模拟器只能处理 OpenGL ES 1.x。如果输入 OpenGL ES 2.0 代码,它会引发异常。这必须在支持 2.0 的设备上进行测试。 Ice Cream Sandwich 可能会在几周内改变这种情况,但我不会指望它:开发人员的态度是无论如何在设备上进行测试更简单,因此更新模拟器并不那么重要。跨度> 【参考方案5】:

选项 3)您可以使用 Qt 之类的库来处理您的 OpenGL 代码,使用它们的内置包装函数。这使您可以选择为 OpenGL 使用一个代码库(或最少不同的代码库)并为您想要的大多数平台构建。您不需要为要支持的每个不同平台移植它。 Qt 甚至可以根据您使用的函数选择 OpenGL 上下文。

【讨论】:

以上是关于OpenGL vs OpenGL ES 2.0 - 可以轻松移植 OpenGL 应用程序吗?的主要内容,如果未能解决你的问题,请参考以下文章

IOS:OpenGL ES 2.0 与 3.0 中动态分支着色器的性能

OPENGL ES 2.0 知识串讲――OPENGL ES 2.0 概括

OPENGL ES 3.1是否比OPENGL ES 2.0慢?

如何在Android上使用OpenGL ES 2.0绘制点

如何在Android上将OpenGL ES 1.0代码转换为OpenGL Es 2.0?

OpenGL ES 2.0 符点精度