【问题标题】:c++ Having multiple graphics optionsc ++具有多个图形选项
【发布时间】:2010-09-08 19:30:38
【问题描述】:

目前我的应用程序仅使用 Direct3D9 进行图形处理,但未来我计划将其扩展到 D3D10 和可能的 OpenGL。问题是我怎样才能以整洁的方式做到这一点?

目前我的代码中有各种Render方法

void Render(boost::function<void()> &Call)
{
    D3dDevice->BeginScene();
    Call();
    D3dDevice->EndScene();
    D3dDevice->Present(0,0,0,0);
}

然后传递的函数取决于确切的状态,例如 MainMenu->Render、Loading->Render 等。然后这些将经常调用其​​他对象的方法。

void RenderGame()
{
    for(entity::iterator it = entity::instances.begin();it != entity::instance.end(); ++it)
        (*it)->Render();
    UI->Render();
}

还有一个从 entity::Base 派生的示例类

class Sprite: public Base
{
    IDirect3DTexture9 *Tex;
    Point2 Pos;
    Size2 Size;
public:
    Sprite(IDirect3DTexture9  *Tex, const Point2 &Pos, const Size2 &Size);
    virtual void Render();
};

然后,每种方法都会根据更详细的设置(例如是否支持像素着色器)来处理如何最好地渲染。

问题是我真的不确定如何扩展它以便能够使用其中一种可能有些不同的(D3D v OpenGL)渲染模式......

【问题讨论】:

    标签: c++ opengl graphics direct3d


    【解决方案1】:

    定义一个足以满足您应用程序的图形输出需求的接口。然后为你想要支持的每个渲染器实现这个接口。

    class IRenderer {
      public:
        virtual ~IRenderer() {}
        virtual void RenderModel(CModel* model) = 0;
        virtual void DrawScreenQuad(int x1, int y1, int x2, int y2) = 0;
        // ...etc...
    };
    
    class COpenGLRenderer : public IRenderer {
      public:
        virtual void RenderModel(CModel* model) {
          // render model using OpenGL
        }
        virtual void DrawScreenQuad(int x1, int y1, int x2, int y2) {
          // draw screen aligned quad using OpenGL
        }
    };
    
    class CDirect3DRenderer : public IRenderer {
      // similar, but render using Direct3D
    };
    

    不过,正确设计和维护这些界面可能非常具有挑战性。

    如果您还使用渲染驱动程序相关对象(如纹理)进行操作,您可以使用工厂模式让单独的渲染器各自创建自己的实现,例如ITexture 在 IRenderer 中使用工厂方法:

    class IRenderer {
      //...
        virtual ITexture* CreateTexture(const char* filename) = 0;
      //...
    };
    
    class COpenGLRenderer : public IRenderer {
      //...
        virtual ITexture* CreateTexture(const char* filename) {
          // COpenGLTexture is the OpenGL specific ITexture implementation
          return new COpenGLTexture(filename);
        }
      //...
    };
    

    看看现有的(3d)引擎不是一个想法吗?根据我的经验,设计这种界面真的会分散你真正想要做的事情:)

    【讨论】:

    • 因为我已经有了 d3d9 的东西来满足我所需要的一切,我只想选择扩展到其他 API。由于我已经有了封装大多数 d3d 内容(例如 Texture、Sprite、Mesh)的类,我可以重载这些内容,让实际对象具有 API 独立的内容。
    【解决方案2】:

    我想说,如果您想要一个真正完整的答案,请查看Ogre3D 的源代码。他们有D3DOpenGL 后端。看:http://www.ogre3d.org 基本上,他们的 API 迫使您以 D3D 方式工作,创建缓冲区对象并用数据填充它们,然后在这些缓冲区上发出绘图调用。无论如何,这就是硬件喜欢它的方式,所以这不是一个糟糕的方式。

    然后,一旦您了解他们是如何做事的,您不妨继续使用它,而不必重新实现它已经提供的所有功能。 :-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多