多个渲染系统

Zay*_*ats 3 c++ directx render system game-engine

在不久的将来的某个时候,我将开始开发游戏引擎.我想要包含的一个功能是拥有多个渲染系统,例如directx 9/10/11和OpenGL.这样,使用此引擎的游戏将能够支持更多玩家,因为如果一个渲染系统不起作用,它将恢复为另一个.

所以我的问题是,我该怎么做呢?我研究了一下,看到Ogre3D使用了这样的东西,但我不知道他们是怎么做到的.我基本上希望能够插入不同的渲染系统并使用相同的代码来运行它.

Nec*_*lis 5

使用C++接口的强大功能!

创建一个抽象,定义渲染系统的接口

class Renderer
{
 //...
    virtual void DrawRect(Color c, Vector2 Pos) = 0;
 //...
}
Run Code Online (Sandbox Code Playgroud)

然后在每个渲染系统中实现它:

class D3DRenderer : Renderer
{
    void DrawRect(Color c, Vector2 Pos);
}
Run Code Online (Sandbox Code Playgroud)

这种方法快速,简单,高效,这就是它在许多游戏引擎中使用的原因.应该注意的是,在构建这样的东西时,它确实需要知道某些API限制(即使是像行主要列和列主要矩阵这样的小东西).


jos*_*mas 5

您可以创建一个接口类,允许您进一步扩展您希望扩展的API.

我在过去做过这个来创建一个DirectX9\11渲染器,我希望很快就能将它扩展到OpenGL.这项任务确实有很多,但很容易解释它的基本工作.不幸的是,我所处的项目是封闭式的,所以如果您对此有任何疑问,请随时提出.

首先,您需要创建一个单独的项目以用作.lib/.dll,我称之为"RenderInterface".这将包含VertexBuffer的,IndexBuffer的,着色器,以及最重要的是,IRenderInterface和IRenderUtility基本接口,这在以后的实施可能持有的项目,如如ID3D11DeviceContext和ID3D11Device.

"RenderInterface"项目中我最重要的两个项目是IRenderInterface和IRenderUtility.这里的想法是让IRenderInterface重要提升,例如创建渲染目标,呈现和初始化API.其中IRenderUtility将执行更常见的操作,例如创建顶点/索引缓冲区,创建着色器和渲染.我在初始化和渲染时更频繁地传递IRenderUtility,并且很少传递IRenderInterface.这是为了防止用户在不需要时进行意外操作.该项目还将包括将在整个代码库中使用的一些常见结构\枚举.

然后我创建了另一个项目,例如D3D11RenderInterface.这个D3D11RenderInterface将具有IRenderInterface,IRenderUtlity,IVertexShader,IVertexBuffer等的实现.

一个过于简单的例子就是

class IRenderUtility
{
public:
    virtual void Draw(unsigned int vertexCount, unsigned int vertexStartOffset) = 0;
};

class D3D11RenderUtility : public IRenderUtility
{
protected:
    ID3D11DeviceContext *mD3D11DeviceContext;
public:
    void Draw(unsigned int vertexCount, unsigned int vertexStartOffset)
    {
        mD3D11DeviceContext->Draw(vertexCount, vertexStartOffset);
    };
};
Run Code Online (Sandbox Code Playgroud)

这可以通过在IRenderUtility :: Draw调用之前调用IRenderUtility来设置VertexBuffer和IVertexBuffer.

然后,在您的应用程序中只需要加载RenderInterface项目和api实现.还有其他方法可以做到这一点,例如整个代码库中的#define'ing代码,但imo,这只是一个混乱.