c ++有多个图形选项 [英] c++ Having multiple graphics options

查看:150
本文介绍了c ++有多个图形选项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我的应用程序只使用Direct3D9的图形,但是在将来我打算扩展到D3D10和可能的OpenGL。



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

  void Render(boost :: function< void()>& Call)
{
D3dDevice-> BeginScene
Call();
D3dDevice-> EndScene();
D3dDevice->存在(0,0,0,0);然后,函数传递的具体状态取决于具体的状态,例如MainMenu-> Render,这个函数可以通过下面的函数来完成:
}


$ b <载入 - > Render等。然后这些将调用其他对象的方法。

  void RenderGame()
{
for(entity :: iterator it = entity :: instances.begin(); it!= entity :: instance.end(); ++ it)
(* it) - & ();
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();
};



每个方法都会考虑更详细的设置(例如是否支持像素着色器)

问题是我真的不知道如何扩展这个能够使用一个,什么可能有些diffrent(D3D v OpenGL)渲染模式...

解决方案

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

  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){
//使用OpenGL渲染模型
}
virtual void DrawScreenQuad(int x1,int y1,int x2,int y2){
//使用OpenGL绘制屏幕对齐的四边形
}
};

class CDirect3DRenderer:public IRenderer {
//类似,但是使用Direct3D
}渲染;

正确设计和维护这些接口可能非常具有挑战性。



如果你也使用渲染驱动程序依赖的对象,如纹理,你可以使用工厂模式让独立的渲染器每个创建自己的实现例如在IRenderer中使用工厂方法的ITexture:

  class IRenderer {
// ...
virtual ITexture * CreateTexture(const char * filename)= 0;
// ...
};

class COpenGLRenderer:public IRenderer {
// ...
virtual ITexture * CreateTexture(const char * filename){
// COpenGLTexture是OpenGL的implementation
return new COpenGLTexture(filename);
}
// ...
};

是不是想看看现有的在我的经验中,设计这种界面真的分散了你真正想做的:)


Currently my app uses just Direct3D9 for graphics, however in the future I' m planning to extend this to D3D10 and possibly OpenGL. The question is how can I do this in a tidy way?

At present there are various Render methods in my code

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

The function passed then depends on the exact state, eg MainMenu->Render, Loading->Render, etc. These will then oftern call the methods of other objects.

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

And a sample class derived from 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(); };

Each method then takes care of how best to render given the more detailed settings (eg are pixel shaders supported or not).

The problem is I'm really not sure how to extend this to be able to use one of, what may be somewhat diffrent (D3D v OpenGL) render modes...

解决方案

Define an interface that is sufficient for your application's graphic output demands. Then implement this interface for every renderer you want to support.

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
};

Properly designing and maintaining these interfaces can be very challenging though.

In case you also operate with render driver dependent objects like textures, you can use a factory pattern to have the separate renderers each create their own implementation of e.g. ITexture using a factory method in 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);
    }
  //...
};

Isn't it an idea to look at existing (3d) engines though? In my experience designing this kind of interfaces really distracts from what you actually want to make :)

这篇关于c ++有多个图形选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆