c++ - 如何在 C++ 字体库中支持不同的 OpenGL 版本/扩展

标签 c++ opengl

我打算重写一个小的 C++ OpenGL 字体库,我之前使用过 FreeType 2,因为我最近发现了更新的 OpenGL 版本的变化。我的代码 使用立即模式和一些函数调用我很确定现在已经弃用了,例如 glLineStipple.

我非常希望支持一系列 OpenGL 版本,这样代码 使用例如可能时使用 VBO,如果没有其他可用的,则返回立即模式 等等。我不确定如何去做。 Afaik,你不能编译 时间检查,因为您需要在运行时创建有效的 OpenGL 上下文。到目前为止,我已经 提出以下建议(从其他线程/站点获得灵感):

  • 使用 GLEW 在绘图函数中进行运行时检查并检查函数 支持(例如 glLineStipple)

  • 使用一些可以在编译时指定的#define 和其他预处理器指令 是时候编译适用于不同 OpenGL 版本的不同版本了

  • 编译支持不同 OpenGL 版本的不同版本,并将每个版本作为 单独下载

  • 使用检查 OpenGL 版本的脚本 (Python/Perl) 发布库 系统(如果可能/可靠)并对源进行适当的修改 所以它适合用户的 OpenGL 版本

  • 仅针对较新的 OpenGL 版本并放弃对以下任何内容的支持

无论如何我可能会使用 GLEW 来轻松加载扩展。

跟进: 根据您非常有帮助的回答,我尝试根据我的旧代码编写几行,这是一个片段(未测试/完成)。我在配置 header 中声明了适当的函数指针,然后在初始化库时,我尝试获取正确的函数指针。如果 VBO 失败(指针为空),我将返回到显示列表(在 3.0 中已弃用),然后最后返回到顶点数组。我应该(也许?)还检查可用的 ARB 扩展,如果 fx。 VBO 加载失败或者工作量太大?这是一个可靠的方法吗?欢迎评论:)

#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
    #define OFL_WINDOWS
    // other stuff...
    #ifndef OFL_USES_GLEW
        // Check which extensions are supported
    #else
        // Declare vertex buffer object extension function pointers
        PFNGLGENBUFFERSPROC          glGenBuffers          = NULL;
        PFNGLBINDBUFFERPROC          glBindBuffer          = NULL;
        PFNGLBUFFERDATAPROC          glBufferData          = NULL;
        PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = NULL;
        PFNGLDELETEBUFFERSPROC       glDeleteBuffers       = NULL;
        PFNGLMULTIDRAWELEMENTSPROC   glMultiDrawElements   = NULL;
        PFNGLBUFFERSUBDATAPROC       glBufferSubData       = NULL;
        PFNGLMAPBUFFERPROC           glMapBuffer           = NULL;
        PFNGLUNMAPBUFFERPROC         glUnmapBuffer         = NULL;
    #endif
#elif some_other_system

初始化函数:

#ifdef OFL_WINDOWS
    bool loaded = true;

    // Attempt to load vertex buffer obejct extensions
    loaded = ((glGenBuffers          = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glGenBuffers"))                   != NULL && loaded);
    loaded = ((glBindBuffer          = (PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer"))                   != NULL && loaded);
    loaded = ((glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)wglGetProcAddress("glVertexAttribPointer")) != NULL && loaded);
    loaded = ((glDeleteBuffers       = (PFNGLDELETEBUFFERSPROC)wglGetProcAddress("glDeleteBuffers"))             != NULL && loaded);
    loaded = ((glMultiDrawElements   = (PFNGLMULTIDRAWELEMENTSPROC)wglGetProcAddress("glMultiDrawElements"))     != NULL && loaded);
    loaded = ((glBufferSubData       = (PFNGLBUFFERSUBDATAPROC)wglGetProcAddress("glBufferSubData"))             != NULL && loaded);
    loaded = ((glMapBuffer           = (PFNGLMAPBUFFERPROC)wglGetProcAddress("glMapBuffer"))                     != NULL && loaded);
    loaded = ((glUnmapBuffer         = (PFNGLUNMAPBUFFERPROC)wglGetProcAddress("glUnmapBuffer"))                 != NULL && loaded);

     if (!loaded)
        std::cout << "OFL: Current OpenGL context does not support vertex buffer objects" << std::endl;
    else {
        #define OFL_USES_VBOS
        std::cout << "OFL: Loaded vertex buffer object extensions successfully"
        return true;
    }

    if (glMajorVersion => 3.f) {
        std::cout << "OFL: Using vertex arrays" << std::endl;
        #define OFL_USES_VERTEX_ARRAYS
    } else {
        // Display lists were deprecated in 3.0 (although still available through ARB extensions)
        std::cout << "OFL: Using display lists"
        #define OFL_USES_DISPLAY_LISTS
    }
#elif some_other_system

最佳答案

首先,你会很安全地使用它,因为到处都支持它:重写你的字体渲染器以使用顶点数组。从 VA 到 VBO 只是一小步,但是到处都支持 VA。您只需要一小组扩展功能;也许手动加载是有意义的,而不是依赖于 GLEW。静态链接它是巨大的矫枉过正。

然后将调用放入包装函数中,您可以通过函数指针引用它,以便您可以那样切换渲染路径。例如,添加一个函数“stipple_it”左右,它在内部调用 glLineStipple 或为其构建和设置适当的片段着色器。

glVertexPointer 与 glVertexAttribPointer 类似。

关于c++ - 如何在 C++ 字体库中支持不同的 OpenGL 版本/扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10798880/

相关文章:

c++ - 如何在 Qt Creator 中设置 “set a breakpoint in malloc_error_break to debug”?

c++ - OpenGL 属性偏移量未按预期工作

c++ - 给出一个对象指针作为参数

c++ - llvm:在函数返回之前生成清理析构函数

c++ - const int 定义的变量是在编译时确定的吗?

java - 在 OpenGL 中重用纹理和顶点

c++ - 好的 Linux/Ubuntu OpenGL 教程?

multithreading - 从线程内执行 OpenGL 绘图

c - 我的 open gl 无法正常工作?

c++ - 一个程序会分配多少栈内存