如何设计OpenGL DirectX“抽象层”

时间:2010-09-12 23:01:36

标签: opengl opengl-es directx abstraction

我正在阅读有关创建图形“抽象层”的信息,以便在图形平台之间切换。不幸的是,我无法找到关于这个主题的更多细节。这种抽象是否可以在功能级别上实现?

void pushMatrix(){
  if (directx){
     // do directx function

  }else if (opengl){
     // do opengl function
  }

}

这是如何运作的?有没有更好的办法?有人能指出一些做这个或更多示例代码的事情的例子吗?

4 个答案:

答案 0 :(得分:7)

通常做的是拥有“通用”渲染器的接口:

class RendererInterface{
    virtual DrawMesh() = 0;
    virtual SwapBuffers() = 0;
    /// etc
}

每个lib都有一个实现:

class OpenGLRenderer : public RendererInterface{
    virtual DrawMesh(){... }
    ....
}

但这个概念与亚历山大的答案相同。

答案 1 :(得分:4)

是的,这就是它的工作原理。通过抽象您使用的图形API,您将从程序员需要担心的内容中删除它。这类似于GDI抽象写入设备的方式,例如程序员不必担心它。

从这个意义上说,你的功能库与上面的类似,就像HDC一样。它是这种抽象的接口。

然后对API进行简单检查会更加困难,然后调用相应的函数。这两个API(DirectX和OpenGL)非常不同,将它们抽象为单个界面并不容易,特别是如果您想要覆盖大部分功能。

你需要更多的抽象,然后简单地制作通用函数。您需要创建更复杂的结构。

假设OpenGL要求你调用函数A,然后函数B才能使某些事情发生,但DX要求你调用func B,然后调用函数A.为了适应这个,你需要做类似的事情:< / p>

void functionA(...) {
  if (OpenGL) {
    glFuncA();
  } else {
    //store parameters
  }
}

void functionB(...) {
  if (OpenGL) {
    glFuncB();
  } else {
    dxFuncB();
    dxFuncA( saved params );
  }
}

这不是一个很好的例子,但它证明了校长。为非常大的和不同的API创建抽象需要经过深思熟虑,并且需要更多的努力来包装每个函数。

答案 2 :(得分:3)

这将导致混乱和低效。我将通过场景图抽象,即具有“场景”的广义高级表示。然后,该场景将由“渲染器”实例渲染,该实例可以使用OpenGL或Direct3D实现。

我建议你看一下像Ogre3d这样的跨平台图形引擎。

答案 3 :(得分:2)

我同意mhutch 100%。通过重构你的渲染器来专注于它正在做的事情,而不是如何做到这一点,你将做出更清洁的设计。

围绕API设计太近,或者更糟糕的是,使用if (this_platform) { do_this(); } else { do_that(); }乱丢代码会很快造成程序的大量混乱。

我的建议是通过你的应用程序并找出它做了什么的列表,尽量不要注意如何。你的项目可能要迟到了,我不知道你的具体情况,但是(恕我直言)从API调用乱码噩梦重构它到足以抽象它的东西将改善你的最终结果。

虽然最初想到,你可能会认为实现一个场景图形系统会增加一大堆开销。实际上,我通过使用场景图来管理状态更改,通过避免状态更改(更改纹理,更改着色器等)以及以更优化的顺序绘制场景,使用渲染引擎获得了大幅加速。像实例化这样的东西优雅地集成到场景图形系统中,可以为您提供主要的加速,以及清除代码中所有以API为中心的混乱,并将“它的作用”与主体中的“它如何做”分开程序逻辑。