包装Open API以在编译时检测错误

时间:2013-11-24 10:16:41

标签: c++ opengl

在OpenGL中,你可以浪费很多时间(特别是):

    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // OK
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINES); // WRONG but compiles
    glPolygonMode(GL_LINE, GL_FRONT_AND_BACK); // WRONG but compiles

查找此类错误可能需要一些时间。

我想要的是什么:

  1. 用C ++包装C API;
  2. 强制执行强参数检查以在编译时检测此类错误;
  3. 当我们知道一切正常时(例如,在RELEASE模式下),提供一种轻松“删除”C ++包装器以使用普通OpenGL C API的方法。
  4. 我尝试了什么:

    1. 使用宏函数包装OpenGL调用,添加一些前缀,如MY_
    2. 使用宏函数包装OpenGL函数参数,添加类似MY _ ## type :: MY _ ## name的前缀,以便将OpenGL“global”定义转换为本地枚举;
    3. 定义等效函数和枚举。
    4. 我得到了什么:

      #ifdef _DEBUG
      #define TRFUNC(func) MY_##func
      #define TRPARAM(type, name) MY_##type::MY_##name
      
      enum MY_FACE{MY_GL_FRONT_AND_BACK};
      enum MY_MODE{MY_GL_POINT, MY_GL_LINE, MY_GL_FILL};
      
      static GLenum tr(MY_FACE face)
      {
          if (face == MY_FACE::MY_GL_FRONT_AND_BACK)
              return GL_FRONT_AND_BACK;
      }
      
      static GLenum tr(MY_MODE mode)
      {
          if (mode == MY_MODE::MY_GL_FILL)
              return GL_FILL;
          if (mode == MY_MODE::MY_GL_LINE)
              return GL_LINE;
          if (mode == MY_MODE::MY_GL_POINT)
              return GL_POINT;
      }
      
      // Prefix name because functions names are #defined so will be replaced by preprocessor
      static void MY_glPolygonMode(MY_FACE face, MY_MODE mode)
      {
          glPolygonMode(tr(face), tr(mode));
      }
      #else
      #define TRFUNC(func) func
      #define TRPARAM(type, name) name
      #endif
      

      电话就像:

      TRFUNC(glPolygonMode)(TRPARAM(FACE, GL_FRONT_AND_BACK), TRPARAM(MODE, GL_LINE)); // OK
      TRFUNC(glPolygonMode)(TRPARAM(FACE, GL_FRONT_AND_BACK), TRPARAM(MODE, GL_LINES)); // error C2838: 'MY_GL_LINES' : illegal qualified name
      TRFUNC(glPolygonMode)(TRPARAM(MODE, GL_LINE), TRPARAM(FACE, GL_FRONT_AND_BACK)); // error C2664: 'void MY_glPolygonMode(MY_FACE,MY_MODE)' : cannot convert argument 1 from 'MY_MODE' to 'MY_FACE'
      

      这只是“原型解决方案”,用于测试它是否有效以及可能的情况。

      我想要的是什么:

      1. 找到该特定问题的一些现有源代码/库(在编译时检测OpenGL错误);
      2. 如果没有,找到一个更清洁的解决方案,因为我觉得我的工作,并不优雅。
      3. 我不想要的东西:

        1. C ++包装器将OpenGL C API“隐藏”到一些面向对象的设计中。我希望有1对1的映射;
        2. 即使在“停用”时仍然存在的解决方案。我真的希望最终的代码是纯OpenGL而不需要任何额外的包装函数;

0 个答案:

没有答案