2

我现在正在为我们的引擎编写 Direct3D 渲染器。

这就是问题所在:
在 OpenGL 中,我可以轻松地调用glClearColor()clear。
在 Direct3D 中,我需要使用g_pd3dDevicejust to callClearRenderTargetView()来清除。

我们引擎的设计是这样的:

class Renderer
{
    // ...
}

class Direct3dWin32 : public Renderer
{
    private ID3D10Device* g_pd3dDevice;
}

class OpenGLWin32 : public Renderer
{
    // Nothing, I can call a function easily without relying on something
}

当我的ShaderManager班级想要编译着色器时,问题就出现了。我需要使用上课的g_pd3dDevice那个。Direct3dWin32

我的问题是,解决这个问题的最佳方法是什么?我正在考虑全局变量、单例类,或者只是在函数中传递类。

4

3 回答 3

3

首先,我不禁注意到g_pd3dDevice,它不是一个全局的。它是一个类成员指针,指向设备的 COM 接口 ID3D10Device*,在这里它不是全局的,也不应该是全局的。

并尽可能简单地回答您的问题(因为它似乎是一个初学者引擎/框架设计问题),提供访问器方法,该方法返回一个指向工作设备的指针,可以从该设备进一步传递,需要使用它。

一个符合楼上小“规范”的简单示例:

class Direct3DWin32 : public Renderer
{
      ID3D10Device* pD3DDevice;
  public:
      ID3D10Device* getD3DDevice();

}

现在,当您需要它时,您可以在从 Direct3DWin32 实例获取它时通过函数传递它。引擎设计远不止于此,我个人不建议将其作为一条路径,但这是另一个时代的故事,也许是一系列书籍。

笔记!

你可以像这样定义基本的东西,但是如果你真的想把多渲染路径设计到一个适当的水平,你将不得不引入多态性,增加一个很好的抽象层次。然后,您可以简单地定义一个统一的渲染接口,无论当前使用的是 DirectX 还是 OpenGL 渲染路径,都将做正确的事情,实例化一个派生类并将其地址提供给指向其抽象基类的指针,该抽象基类包含指定的接口一切符合。然后,您可以忽略 API 的底层选择。

希望这可以解决您当前的问题。此外,再次避开全局变量。和快乐的编码。

于 2012-06-27T17:04:44.383 回答
1

您可能会使用双重调度的变体(又名访问者模式):

class ShaderManager
{
public:
   void compileShader(Renderer* r, Shader* s) { r->compileShader(this, s); }
   void compileD3DShader(ID3D10Device* device, Shader*s);
   void compileGLShader(Shader* s);
};

class Renderer
{
public:
   virtual void compileShader(ShaderManager* m, Shader* s) = 0;
};

class Direct3dWin32 : public Renderer
{
private:
   ID3D10Device* m_device;
public:
   virtual void compileShader(ShaderManager* m, Shader* s)
   {
      m->compileD3DShader(m_device, s);
   }      
}

class OpenGLWin32 : public Renderer
{
public:
   virtual void compileShader(ShaderManager* m, Shader* s)
   {
      m->compileGLShader(s);
   }
}

(我不是“吸气剂”的忠实粉丝。)

于 2012-06-27T17:16:13.503 回答
0

您应该为要传递给另一个类的变量提供访问器方法。

例如,在 Direct3dWin32 中,您可以:

ID3d10Device* get_gpd3Device()
{
    return g_pd3Device;
}

然后,您可以将其传递给 OpenGLWin32:

void useDevice (ID3d10Device* aDevice)
{
// do work
}

使用这两个类的应用程序将负责弥合差距:

OpenGLWin32 openGL;
openGL.useDevice(direct3d.get_gpd3device());
于 2012-06-27T16:57:13.027 回答