王志科 Coder, Designer, Manager

Ogre 2.1 FAQ

2016-08-02
王志科
 

2.1 版是否稳定?

它是稳定的,它很少崩溃与泄露 (和其他稳定版差不多)
虽然仍在开发中,可能需要你花上 10 到 20 分钟来调整你的代码,但是不会有重大的变化了。
目前 Ogre 2.1 的主要问题是 WIKI 和 插件的不足而不是 Ogre 2.1 的稳定性,虽然社区用户进行了一些插件的移植工作但还无法评估它们的质量(不是说他们质量差)

如果你还是不相信 Ogre 2.1 可以稳定的支持高质量的项目,那么可以参考下面的内容:

有否参考手册?

有的,你在这里可以找到 Docs/2.0/Ogre 2.0 Porting Manual DRAFT.odt。 我们建议使用 OpenOffice 或 LibreOffice 查看, 如果你喜欢使用 PDF 阅读器也可以导出为 PDF 进行阅读,微软 WORD 软件会出现一些排版的问题。

有样例代码或例子程序吗?

有的! 你只需要在 CMake 中选中 OGRE_BUILD_SAMPLES2 (请注意,不是 OGRE_BUILD_SAMPLES 选项,这个选项最终将被移除)。
如果这些例子无法编译,可能是你没有提供 SDL2 依赖库, 还有一些例子使用了 RapidJSON,如果你克隆了 ogredeps 你就都有了。
注意:你必须克隆依赖项的代码仓库,下载的 ZIP 包是无法正常工作的, ZIP 包里没有 SDL2,因为 SDL2 是一个子代码仓库的连接(使用 git submodel 命令才能下载下来)

所有例子在 %OgreRoot%/Samples/2.0 目录下面( 虽然目录名是 “2.0”, 但却是 “2.1” 的例子 )

编译例子时发生错误,和 “SampleBrowser” 有关

SampleBrowser 是 1.x 的例子,不是 2.X 的例子,请参考上一个章节。

2.1 与 1.x 有多大区别?有哪些期待的变化?

大部分的变更已经涵盖在手册里面了,不过下面是一个快速总结:

  • 原有的内容放到了 v1 命名空间中,如果发现编译错误你只需要增加 “v1”,例如 Entity * myEntity 修改为 v1::Entity *myEntity;
  • Item 取代了 Entity ,因为她更快也更容易使用,不过并不支持 Entity 的全部内容(例如:支持面部表情的姿势动画),对于移植来说 Entity 仍然是有用的。
  • 有了新的材质系统 HLMS(High Level Material System)
  • 原有的材质系统不推荐使用,除非很少的实体使用(因为缓慢而笨拙)或者需要进行后处理(这是它们最有用的地方)
  • 纹理最大程度的保持兼容
  • HlmsTextureManager 管理了 HLMS 的纹理,但是不要被他欺骗了,它只是巧妙的通过 TextureManager 进行纹理管理(为了提升 HLMS 的渲染速度),如非必要你可以不用管他。
  • 新版本中通过合成器进行渲染,它不再是进行后处理的可选组件,而是 Ogre 渲染场景整个工作流中的一部分。
  • 默认的 ParticleFX 仍然可以正常工作
  • 数学类 (Vector3, Matrix4, Quaternion) 最大程度保持相同

我如何开始编写 Ogre 应用程序?

我对 Ogre 2.1 的线程支持感到困惑

对于线程支持有老的代码也有新的代码

原来的线程代码可以使用,它需要第三方依赖项(BOOST,POCO,TBB 等),是用来支持后台加载,在我看来这是一个很差的功能因此我不推荐使用它,之所以保留下来是因为一些用户比较成功的使用了它们(虽然不是我们期望的方式)。
新的线程代码总是启用的,因为直接使用系统的同步原语,不需要在 CMake 总切换任何选项,这些代码用来并行更新场景图、AABB 计算、视锥体裁剪、LOD 选取、灯光裁剪和新版本的骨骼动画。 你可以通过 Root::createSceneManager( ) 告诉 Ogre 创建多少个线程(至少要有一个线程)工作线程是针对 SceneManager 的,如果创建了 2 个含 4 个线程的 SceneManager,Ogre 将创建 8 个线程,值得注意的是,在同一时刻有四个线程在工作,另外四个线程处于休眠状态,因为更新 SceneManager 仍然是串行的。

我需要 Boost 库吗?

不需要 除非你要用老的线程功能,否则完全不需要,可以参考上一节

有好几个 “2.1” 分支,我应该选那个?

有两个稳定的分支: 2.1 和 2.1-pso
2.1-pso 分支增加了 “Pipeline State Object” 模型,这是为了支持 Metal、DX12 和 Vulkan,同时也提升了性能和代码可阅读性。另外还增加了对 Compute Shaders 的支持。

该分支还没有合并到 2.1 分支中有两个原因:

  • 一些社区提供的第三方库(CEGUI, Gorilla) 无法工作因为他们不能绑定着色器, 我们还没有提供一个工具使这个过程变得容易。
  • 2.1-pso 不像 2.1 在实际的工作中被详细彻底的测试。

任何其他 2.1 开头的分支都是不稳定的,并且不要使用

支持 Android 吗?

参见 支持 GLES 吗?

支持 GLES 吗?

计划修复当前无法使用的 GLES2 渲染系统, 将支持 GLES2 和 GLES3. 支持 GLES2 是因为兼容性,虽然其 API 设计是过时的但考虑到要兼容上百万的安卓设备,所以重点是兼容性和稳定性而不是高性能 (仍然要比 Ogre 1.x 快很多)。或许还有一些我们无法预测的局限性。
至于 GLES3, 它应该更容易运行高性能的移动应用。

支持 WebGL 吗?

一旦 GLES2 就绪,WebGL 的支持就是小菜一碟了,因为它们 99% 是相同的。

支持 D3D9 吗?

目前没有支持 D3D9 的计划,或许有人会重写从而支持它,我们将为 Ogre 2.1 实现 GLES2 , 再说了很多团队都不高兴使用 D3D9 了,只有 Assaf 依然关注和维护它. 只要 GLES2 还没有准备好,我们将保留 D3D9 的代码, 尽管不能保证可用性和稳定性甚至可以编译通过。

支持 D3D11 Level 9.x 吗?

这不是一个优先处理的内容,通过 GLES2 支持或许更加容易一些,它并不能很好的映射到 GLES2 或者 D3D9,如果 Level 9.2 == Shader Model 2.x, level 9.3 == Shader Model 3.0 事情就变得简单了, 但不幸的是他们混合在一起就是最大的灾难了.
所以真的希望不需要支持 Level 9.x

支持 iOS 吗?


对于老的 iOS 设备, 使用 GLES 渲染系统. 对于新的 iOS 设备, 我们正在开发 Metal 渲染系统.

支持 OS X 吗?


当 Metal 渲染系统完成后, OS X 将被很好的支持. 对于老的不支持 Metal 的 Macs 机器, Ogre 所支持的 GLES3 就是他们最后的希望了.
在这项工作完成之前我们都不知道它能否很好的工作。

支持 Vulkan/D3D12 吗?

这些 API 在开发计划中,实际上 PSO (Pipeline State Object) 就和此有关,并且合成器已经能够处理 Texture/RenderTarget/UAV 和依赖的资源, 这样很容易实现这些 APIs.

不过这些不是短期开发目标,除了异步着色器, 大多数新 API 的好处是减少 CPU 开销而不是 GPU。 然而 Ogre 2.1 对 GPU 是很大的负担 Vulkan 比 D3D12 优先级高是因为只有很少的的功能是 D3D12 具有而 D3D11 没有的, 同时也是因为 Vulkan 是在安卓上实现高性能图形的唯一的办法(a void no version of GLES is filling). 不过还好的是支持 Vulkan 的 Android 设备还比较少,即使在 2016 年有安卓设备制造和销售,但他么仍然是使用的 GLES2 和 KitKat.
短期内我们仍然聚焦在 D3D11 和 OpenGL 上以及扩展在移动设备上的支持(GLES & Metal),我们的设计策略是等到 Vulkan 和 D3D12 容易适配的时候进行开发。

我创建了多个 RenderWindows and I’m having severe graphical glitches or I get many GL_INVALID_OPERATION errors

如何使用 Double 精度? 编译时有错误

我们还没有正式的对双精度提供维护,但是它能工作 (mostly?).在你使用双精度之前,非常有可能你要解决的问题根本不是因为精度引起的,你需要学习如何透过 SceneManager::setRelativeOrigin 使用 Camera-relative rendering / Relative Origin .
另外请参考

如果你真的需要双精度浮点,那么这么做:

启用 OGRE_CONFIG_DOUBLE
禁用 OGRE_SIMD_NEON
禁用 OGRE_SIMD_SSE2

NEON 支持在 Android 设备上是可选的,但 Ogre 是在编译时选择是否支持 NEON,我如何在运行时动态选择?

Ogre 不支持在运行时进行切换,支持运行时切换将导致很多复杂的问题 (虚函数指针,同步信号等), 同时引入运行时切换的开销和使用 SIMD 提高效率的初衷是相违背的。 在桌面上解决该问题的方式是提供多个版本的 EXE,根据检测系统是否支持 SSE 来启动对应的 EXE,在安卓上也可以这样做。 在安卓上不需要建立一个进程,而是库和 Java 程序,在 java 程序中加载库并执行库中定义的入口函数,这个进程不是自动的,Java 进程首先要使用 NDK 加载库,代码和下面的类似:

System.loadLibrary("hello-jni");

在你加载库的时候,Java 代码修改为下面的样子

if( supportsNeon )
    System.loadLibrary("hello-jni-neon");
else
    System.loadLibrary("hello-jni");

当然这样导致你需要编译两边你的代码,并且在部署时需要两倍的磁盘空间,桌面程序也有相同的问题。

编译 RTSS(Run Time Shader System)时发生错误

RTSS 在 2.1 中已经被废弃, HLMS(高级材质系统)替换了 RTSS 并成为 OGRE 的一部分,它更快、更稳定也更容易使用。

关于 HLMS 的 C++ 实现

要使 PBS 材质工作,你需要:

  • 连接或包含 OgreHlmsPbs 的 C++ 代码到你的工程中;
  • “Samples/Media/Hlms/Common” 和 “Samples/Media/Hlms/Pbs” 目录下的模板文件,当你实例化 HlmsPbs 时需要明确告知这些文件的位置;
  • 重要的一点:不要把这两个目录下的文件放到一个目录中;

要使 Unlit 材质工作,你需要:

  • 连接或包含 OgreHlmsUnlit 的 C++ 代码到你的工程中;
  • “Samples/Media/Hlms/Common” 和 “Samples/Media/Hlms/Unlit” 目录下的模板文件,当你实例化 HlmsUnlit 时需要明确告知这些文件的位置;
  • 重要的一点:不要把这两个目录下的文件放到一个目录中;

你可以实现自己的 HLMS ,不过我们已经实现了一个默认的。
写 PbsMobile 和 UnlitMobile 的时候他们还不能 100% 工作,因为只是为 GLES2 写的。

我添加了一个 Point/Spot 光源,但是它不起作用

首先确认使用了 PBS 材质,Unlit 材质对光照无明显反应
其次 point 或 spot 灯光不投下阴影, PBS 默认不会使用它,因此需要使用更高级的技术来处理。你可以开启 Forward3D 来使它正常工作,建议看看 Forward3D 例子的代码。

我创建了一个 PBS 自定义几何体,但是它看起来是黑白的

请确认材质是有效的
请确认 MESH 有法线并且法线正确,如果没有法线使用 PBS 将导致无法进行光照处理

我如何编程生产一个 Mesh

如果是 v1 对象,和之前一样。
如果是 v2 对象,参考 DynamicGeometry 和 CustomRenderable 例子。

后记

读完这篇 FAQ 后,一些问题有了答案,另外一些也有了方向,很好的文章 我没有严格按照原文翻译,一些地方是我的理解,可能不是很准确,请见谅。


下一篇 Ogre 2.0 Changes

正文目录