代码之家  ›  专栏  ›  技术社区  ›  Justin Meiners

如何设计OpenGL DirectX“抽象层”

  •  6
  • Justin Meiners  · 技术社区  · 14 年前

    我在读关于创建图形“抽象层”的书,以方便在图形平台之间切换。不幸的是,我没能找到关于这个主题的很多细节。这样的抽象在函数级是可以实现的吗?

    void pushMatrix(){
      if (directx){
         // do directx function
    
      }else if (opengl){
         // do opengl function
      }
    
    }
    

    是这样的吗?有更好的办法吗?有没有人能给我举一些例子来做这个或者更多的例子代码?

    4 回复  |  直到 9 年前
        1
  •  8
  •   Calvin1602    14 年前

    通常要做的是有一个到“通用”渲染器的接口:

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

    每个库有一个实现:

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

        2
  •  5
  •   Alexander Rafferty    14 年前

    是的,就是这样。通过抽象您使用的图形API,您就可以将它从程序员需要担心的事情中移除。这类似于GDI抽象要写入的设备的方式,例如程序员不必担心它。

    这比简单地检查API,然后调用适当的函数要困难得多。这两个API(DirectX和OpenGL)是非常不同的,将它们抽象成一个单一的接口并不容易,特别是如果您想涵盖大部分功能的话。

    假设OpenGL要求您先调用函数A,然后调用函数B来实现某些事情,但DX要求您先调用函数B,然后调用函数A。为了适应这种情况,您需要执行类似的操作:

    void functionA(...) {
      if (OpenGL) {
        glFuncA();
      } else {
        //store parameters
      }
    }
    
    void functionB(...) {
      if (OpenGL) {
        glFuncB();
      } else {
        dxFuncB();
        dxFuncA( saved params );
      }
    }
    

    这不是一个很好的例子,但它表明了原则。为非常大和不同的API创建一个抽象需要花费大量的精力,比包装每个函数要花更多的精力。

        3
  •  4
  •   Mikayla Hutchinson    14 年前

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

    我建议你看看跨平台的图形引擎,比如Ogre3d。

        4
  •  3
  •   Doug65536    13 年前

    if (this_platform) { do_this(); } else { do_that(); } 很快就会把程序搞得一团糟。

    虽然一开始你会认为实现一个场景绘图系统会增加很多开销。实际上,通过使用场景图来管理状态更改(通过避免状态更改(更改纹理、更改明暗器等)并以更优化的顺序绘制场景,我的渲染引擎大大提高了速度。像实例化这样的东西被优雅地集成到一个场景绘图系统中,可以给你带来很大的加速,同时也可以清除代码中所有以API为中心的混乱,并将主程序逻辑中的“它做什么”和“它怎么做”分开。