萌梦动作编辑器设计支持多渲染器的思想



  • 截止现在,萌梦动作编辑器只能支持OpenGL作为默认的渲染器进行渲染。我在和同行的交流过程中了解到,目前他们也在积极地将自己的软件向新型渲染器vulkan靠拢,对于我们做萌梦动作编辑器这款产品来说,支持vulkan的确会带来很多好处的,比如说咱们目前渲染的过程中还会出现一些卡顿,这个也有可能和OpenGL架构相关。如果换做vulkan,那么指令会得到进一步精简,运行速度可能会更快。但是作为这项研究的第一步,我们必须将现有OpenGL的调用从咱们骨骼动画等业务逻辑中剥离出来。形成独立的模块,这样在不同平台上可以选用不同类型的渲染器以便达到更好的效果。

    此外,萌梦动作编辑器面向的用户群是使用MikuMikuDance、MikuMikuMoving、nanoem等等的喜欢三维动画编辑器的初级用户,我们需要做的是积极地对接这部分的用户,满足他们的需求。而其中有一个点就是他们有较大一部分使用的是MikuMikuEffect,也就是制作渲染特效的插件。这个插件呢,是使用微软的HLSL编写的,而HLSL就需要Direct3D(通常是Direct3D 9),这就要求我们软件需要支持Direct3D进行渲染了。这也是我们此次支持多渲染器的目的之一。

    为了达成目的,我们设计了这样一个结构:我们定义的所有三维对象的基类名称叫做Entity,那么Entity采用了PIMPL设计模式(私有实现设计模式),在私有的实现里,我们将其数据的部分和渲染的部分剥离开来。渲染的部分单独写一个基类。这个基类叫做EntityRenderer,这里只负责搜集Entity实例的个数以及做抽象渲染流程。具体的实现呢,我们采用的是Qt的插件思想,插件里与OpenGL相关的类聚合起来,写成一个插件。具体来说,假设我使用OpenGL要渲染Entity,那么在插件里,我会写这样一个类:

    class OpenGLEntityRenderer: public EntityRenderer, protected QOpenGLFunctions
    {
    public:
        virtual void render( void ) { ... }
    };
    

    这样写的好处显而易见:将OpenGL相关的指令隔离到插件中,渲染模块完全不用依赖任何与OpenGL相关的内容。并且通过C++多态性,依然可以采用OpenGL渲染出和以前一样的渲染效果。

    实际操作中,我们还需要让EntityRenderer继承自Renderer接口来获得更抽象一层的方法,在插件中我们使用分布式抽象工厂方法来让渲染器根据需求获得——即传入具体渲染类名称字符串,即可返回相应的渲染器对象实例。有关分布式工厂方法,如果有需要的话,我会单独抽出时间写一篇长文给大家讲解。

    目前这一套方案已经成功地在我写的一个单元测试案例中得以实现。接下来就是推广之,将以前的渲染器都替换代码隔离并且成可以切换的实现方案。
    😝 😝 😝 😝 😝


 

最近的回复

  • 很棒!求软件,我要摆在我的桌面上。

    阅读更多
  • 这个很有意思 ^_^

    阅读更多
  • 思路:
    1.把官方时钟demo改了,加了秒针,加了壁纸,加了小萝莉
    2.QWindow窗口嵌入到桌面

    0_1533891238039_20180810_164211.gif

    改版

    去掉秒针,把小萝莉正过来,沿着表盘走

    0_1533893719543_20180810_173309.gif

    源代码

    Fork me on Gitee

    阅读更多

关注我们

微博
QQ群











召唤伊斯特瓦尔