Emscripten对OpenGL的支持

Emscripten对OpenGL的支持

翻译:云荒杯倾
本文是Emscripten-WebAssembly专栏系列文章之一,更多文章请查看专栏。
也能够去做者的博客阅读文章。
欢迎加入Wasm和emscripten技术交流群,群聊号码:939206522。html


Emscripten支持三种OpenGL编译模式:git

  • OpenGL ES 2.0/3.0的WebGL子集(默认)----支持OpenGL ES 2.0/3.0中能够直接映射到WebGL 1/2的子集。
  • 模拟OpenGL ES 2.0/3.0----支持一些WebGL中没有的OpenGL ES 2.0/3.0特性。
  • 模拟桌面OpenGL API----支持一些OpenGL 1.X 的特性和命令。

本篇文章介绍一些这几种模式的信息,并告诉你们怎么启用这些模式。github

tip:
咱们强烈推荐你的代码使用OpenGL ES 2.0/3.0的WebGL子集,甚至尽量移植你的代码到这些API上。其余两种模式效率不高,只有你的代码很是依赖这两种模式的API的时候(再不得已而)用。

OpenGL ES 2.0/3.0的WebGL子集

默认下,Emscripten编译代码为OpenGL ES 2.0/3.0的WebGL子集。它是OpenGL ES能够直接映射到WebGL的一些命令。这个子集包括了OpenGL ES 2.0的绝大多数命令,除了客户端数组(client-sede arrays)和一些其余特性,能够在这个地址查看web

为了针对OpenGL ES的WebGL子集编程,要使用GL ES 2.0头文件和GL ES 2.0 API,同时遵照WebGL规范第6章中具体的限制(上个地址)。编程

之因此默认状况下是使用此模式,是由于它能最好匹配浏览器提供的WebGL特性。segmentfault

若是想让编译后的代码建立的是WebGL2上下文,请编译时设置连接标记-s USE_WEBGL2=1。在运行时,指定此标志会在运行时容许(而且默认状况下,除非在上下文建立时指定,才能)建立WebGL 2上下文,但仍有可能建立WebGL 1上下文,所以应用程序能够选择是否须要WebGL 2,或者是否支持回退到WebGL 1。api

模拟OpenGL ES 2.0/3.0

这种编译模式模拟了一些不在WebGL 1规范中的OpenGL ES 2.0/3.0特性。数组

尤为是对OpenGL ES 2.0/3.0的WebGL子集没有包括进来的客户端数组(client-sede arrays)提供了模拟。浏览器

这容许您在没有绑定缓冲区的状况下使用glDrawArrays和glDrawElements等函数,而且Emscripten的GL bindings将自动设置缓冲区(WebGL要求绑定缓冲区)。安全

note:
这种构建模式有一个限制,即客户端索引缓冲区中最大的索引必须小于该缓冲区的总索引数。

要启用OpenGL ES 2.0,请指定选项-s FULL_ES2=1。

要启用OpenGL ES 2.0,请指定选项-s FULL_ES3=1。这就增长了将内存块映射到客户端内存的模拟。标记- s FULL_ES2= 1和- s FULL_ES3= 1是正交的,所以能够指定其中一个或两个同时指定来模拟不一样的特性。

模拟桌面OpenGL API

OpenGL模式支持许多遗留在桌面OpenGL 1.x的特性和命令。(例如“immediate mode”和“glNormalPointer”)。

虽然这部分模拟并无完成,但已有的模拟已经足以使用Emscripten将Sauerbraten 3D游戏(BananaBread项目)和一些其余的代码库移植了。

要启用这种模式,请指定emcc选项-s LEGACY_GL_EMULATION=1。

优化设置

在这种模式下,除了-s LEGACY_GL_EMULATION=1,还有一些额外的flags能够用来调整GL 模拟层的性能表现:

  • -s GL_UNSAFE_OPTS=1 尝试跳过冗余的GL工做和清理。这种优化不安全,因此默认下不启用。
  • -s GL_FFP_ONLY=1 告诉GL仿真层,您的代码将不会使用可编程的管道pipeline/着色器。这容许GL仿真代码在知道安全的状况下执行额外的优化。
  • 将Module.GL_MAX_TEXTURE_IMAGE_UNITS整数添加到模板文件.html,以明确代码使用的纹理单元的最大数。这确保了在检查固定函数管道(FFP)仿真着色器运行时,GL仿真层不会浪费时钟周期迭代未使用的纹理单元。(This ensures that the GL emulation layer does not waste clock cycles iterating over unused texture units when examining which Fixed Function Pipeline (FFP) emulation shader to run.)

若是个人代码依赖一个目前尚不支持的桌面OpenGL特性怎么办?

您能够考虑在Regal桌面OpenGL仿真库中构建代码库,该库旨在支持OpenGL ES 2.0上的桌面OpenGL功能。根据项目的不一样,这可能比Emscripten的GL模拟效果更好或更差。

OpenGL ES 扩展

当移植代码时,应该注意到桌面OpenGL、OpenGL ES和WebGL都有本身的扩展注册表。这意味着,这三者的扩展都不是自动完成的。请参阅WebGL 1.0扩展注册表,以得到已注册扩展的完整列表。

此外,在WebGL中,与桌面或移动OpenGL不一样的是,扩展必须首先在其公开的特性生效以前被激活。若是您使用一个本地的api 如SDL、EGL、GLUT或GLFW来建立您的GL上下文,那么这将自动完成大多数扩展。若是使用HTML5 WebGL上下文建立API,则必须显式地选择是否自动启用WebGL扩展。若是在上下文建立时没有自动启用扩展,那么能够使用HTML5 API函数emscripten_webgl_enable_extension来激活它。调试相关的扩展、草案扩展和供应商-前缀扩展(MOZ_ ,WEBKIT_ )在建立时不会自动启用,但必须始终手动激活。

当从WebGL 1迁移到WebGL 2时,注意一些WebGL 1扩展迁移到为 WebGL 2的核心特性,所以它们的功能再也不被宣传为GL扩展。这并不意味着这些特性应该被丢弃,而是在WebGL 2中能够使用这些特性不须要首先这个测试GL扩展的存在。


Emscripten代码移植系列文章

Emscripten代码移植主题系列文章是emscripten中文站点的一部份内容。
第一个主题介绍代码可移植性与限制
第二个主题介绍Emscripten的运行时环境
第三个主题第一篇文章介绍链接C++和JavaScript
第三个主题第二篇文章介绍embind
第四个主题介绍文件和文件系统
第六个主题介绍Emscripten如何调试代码

相关文章
相关标签/搜索