문제

현재 내 앱은 그래픽에 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) 렌더링 모드 중 하나를 사용할 수 있도록 이것을 확장하는 방법을 잘 모르겠습니다...

도움이 되었습니까?

해결책

애플리케이션의 그래픽 출력 요구 사항에 충분한 인터페이스를 정의하십시오.그런 다음 지원하려는 모든 렌더러에 대해 이 인터페이스를 구현하십시오.

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

그러나 이러한 인터페이스를 적절하게 설계하고 유지하는 것은 매우 어려울 수 있습니다.

텍스처와 같은 렌더 드라이버 종속 개체를 사용하여 작업하는 경우 팩토리 패턴을 사용하여 별도의 렌더러가 각각 고유한 구현을 생성하도록 할 수 있습니다.IRenderer에서 팩토리 메소드를 사용하는 ITexture:

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) 엔진을 살펴보는 것은 아이디어 아닌가요?내 경험에 따르면 이런 종류의 인터페이스를 디자인하면 실제로 만들고 싶은 것에서 방해가 됩니다. :)

다른 팁

정말 완전한 답을 원한다면 소스 코드를 살펴보세요. Ogre3D.그들은 둘 다 가지고 있습니다 D3D 그리고 OpenGL 백엔드.보다 : http://www.ogre3d.org기본적으로 API 종류는 D3D 방식으로 작업하고, 버퍼 객체를 생성하고 여기에 데이터를 채운 다음 해당 버퍼에 대해 그리기 호출을 실행하도록 강제합니다.어쨌든 하드웨어가 좋아하는 방식이므로 나쁜 방법은 아닙니다.

그런 다음 그들이 어떻게 일하는지 확인한 후에는 그냥 사용하고 이미 제공되는 모든 것을 다시 구현해야 하는 수고를 덜 수 있습니다.:-)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top