GLFW 加载函数

GLFW load functions

来自 Opengl 维基:

There are two phases of OpenGL initialization. The first phase is the creation of an OpenGL context; the second phase is to load all of the necessary functions to use OpenGL.

This boilerplate work is done with various OpenGL loading libraries;

所以我下载了 GLFW 并编译了库中的演示测试。但是发现框架将 windows 创建和上下文创建合并为一个函数调用 createWindow,其中它首先创建一个 window 和一个上下文,然后加载一些扩展函数通过 initWGLExtensions.

所以上下文现在已经设置好了,没有加载任何其他 gl 函数。简单的演示然后开始一个消息循环来绘制。

int main(void)
{
    GLFWwindow* window;

    glfwSetErrorCallback(error_callback);

    if (!glfwInit())
        exit(EXIT_FAILURE);

    window = glfwCreateWindow(640, 480, "Simple example", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }

    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);

    glfwSetKeyCallback(window, key_callback);

    while (!glfwWindowShouldClose(window))
    {
        float ratio;
        int width, height;

        glfwGetFramebufferSize(window, &width, &height);
        ratio = width / (float) height;

        glViewport(0, 0, width, height);
        glClear(GL_COLOR_BUFFER_BIT);

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f);
        glMatrixMode(GL_MODELVIEW);

        glLoadIdentity();
        glRotatef((float) glfwGetTime() * 50.f, 0.f, 0.f, 1.f);

        glBegin(GL_TRIANGLES);
        glColor3f(1.f, 0.f, 0.f);
        glVertex3f(-0.6f, -0.4f, 0.f);
        glColor3f(0.f, 1.f, 0.f);
        glVertex3f(0.6f, -0.4f, 0.f);
        glColor3f(0.f, 0.f, 1.f);
        glVertex3f(0.f, 0.6f, 0.f);
        glEnd();

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glfwDestroyWindow(window);

    glfwTerminate();
    exit(EXIT_SUCCESS);
}

所以所有的渲染命令功能都是即时的?它实际上在 GL.h 中声明。因此,由于框架没有从驱动程序中加载这些功能。这些函数驻留在什么地方?[提问]

并且GLFW加载的所有函数都像

src\wgl_context.h(39):typedef PROC (WINAPI * WGLGETPROCADDRESS_T)(LPCSTR);
src\wgl_context.h(44):#define _glfw_wglGetProcAddress _glfw.wgl.opengl32.GetProcAddress
src\wgl_context.h(89):        WGLGETPROCADDRESS_T GetProcAddress;
src\wgl_context.c(42):        _glfw_wglGetProcAddress("wglGetExtensionsStringEXT");
src\wgl_context.c(44):        _glfw_wglGetProcAddress("wglGetExtensionsStringARB");
src\wgl_context.c(48):        _glfw_wglGetProcAddress("wglCreateContextAttribsARB");
src\wgl_context.c(52):        _glfw_wglGetProcAddress("wglSwapIntervalEXT");
src\wgl_context.c(56):        _glfw_wglGetProcAddress("wglGetPixelFormatAttribivARB");
src\wgl_context.c(289):    _glfw.wgl.opengl32.GetProcAddress = (WGLGETPROCADDRESS_T)
src\wgl_context.c(290):        GetProcAddress(_glfw.wgl.opengl32.instance, "wglGetProcAddress");
src\wgl_context.c(659):    const GLFWglproc proc = (GLFWglproc) _glfw_wglGetProcAddress(procname);

这是否意味着我不需要加载任何其他 GL 函数?[[问题]] 只是有点混淆 GL 工作流程。

更新

找出那些链接到 opengl32.lib 的 gl 函数调用。这是什么意思?我使用 windows10 默认的 1.1 gl 实现?所以,我真的不需要从 nvoglv32.dll​ 实际驱动程序中导出这些函数,而是在 opengl32.lib?

中使用静态链接函数

OpenGL wiki 中的措辞有点不吉利。细节有点复杂。 OpenGL 环境有 3 个方面:

  • 操作系统ABI(应用程序二进制接口)契约
  • OpenGL 上下文
  • window系统集成

从历史上看,OpenGL 与 OS 集成的方式是一种粗略的 hack,只有一个设计不佳的界面:由于 OpenGL 是一个 API 设计用于与图形驱动程序对话,因此它不是某种驱动程序您可以安装第 3 方库。它的某一组接口必须由操作系统提供。这些具体是哪些接口,在ABI contract里面都有写。当然,每个 OS 都有自己的合同,甚至可能会在不同版本之间发生变化。

为了支持更新版本的 OpenGL,定义了所谓的 "extension mechanism",通过它可以加载 ABI 契约之外的函数。作为 ABI 合约一部分的功能也可能会或**可能不会*通过此机制提供,因此请不要依赖该假设。

在 Windows(从 Win-NT-4 和 Win-95B 开始)中,ABI 契约保证,程序将总是找到一个符合 OpenGL-1.1 的实施。为了简单起见,OpenGL-1.1 入口点直接由接口存根库公开(opengl32.dll,符号 table 可通过 opengl32.lib 获得),仅此而已。设备驱动程序然后 附加 到存根库,其 OpenGL 实现结束,与硬件对话。对于所有 OpenGL 上下文,OpenGL-1.1 存根是不变的,即它们对于所有上下文都是相同的。扩展功能 OTOH 特定于每个上下文。因此,对于创建的每个 OpenGL 上下文,扩展函数指针必须单独加载,并在调用时与活动上下文正确匹配。这也意味着,您首先必须创建一个上下文(并使其处于活动状态),然后才能尝试加载其扩展功能。

在X11/GLX环境中(例如Linux、*BSDs、Solaris)情况如下:ABI契约指定if OpenGL是可用,那么 至少 OpenGL-1.2 的函数 必须 由 OpenGL 实现 共享对象导出。这是特别要注意的!在 Windows 上有一些供应商中立的存根,在 X11/GLX 上 libGL.so 您的程序动态加载 实现。此外,libGL.so 可能会导出更多的符号,可能涵盖所有支持的 OpenGL 功能。作为一名程序员,你不应该依赖这个。同样在 GLX 中,断言所有入口点都是上下文不变的,即您可以加载它们一次并在所有上下文中重复使用。

在 MacOS-X 上,您可以通过框架获取 OpenGL。 ABI 合同是每个 OS 版本,因此程序可用的 OpenGL 函数完全由特定的 OS 版本决定。有一个扩展机制,但几乎没有任何作用;仅导出了几个 Apple 特定的扩展,因此甚至不用在 Apple 的 OS 上使用它。