访问冲突执行位置 0x0000000000000000。带有 GLAD 和 GLFW 的 OpenGL

Access violation executing location 0x0000000000000000. OpenGL with GLAD and GLFW

我一直在尝试使用 GLAD 和 GLFW 创建一个 OpenGL window,遵循 learnopengl.com and glfw.org 中的说明。乍一看,根据文档,这足以让 window 工作:

#include <iostream>
#include <glad/glad.h>
#include <GLFW/glfw3.h>

using namespace std;

// framebuffer size callback function
void resize(GLFWwindow* window, int width, int height)
{
    glViewport(0, 0, width, height);
}

void render(GLFWwindow* window) {

    // here we put our rendering code
    
}

void main() {

    int width = 800;
    int height = 600;

    // We initialzie GLFW
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    // Now that it is initialized, we create a window
    GLFWwindow* window = glfwCreateWindow(width, height, "My Title", NULL, NULL);

    // We can set a function to recieve framebuffer size callbacks, but it is optional
    glfwSetFramebufferSizeCallback(window, resize);


    //here we run our window, swapping buffers and all.
    while (!glfwWindowShouldClose(window))
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glClearColor(0.0f, 0.0f, 0.1f, 0.0f);
        render(window);
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

}

假设您的 Visual Studio 环境配置正确,这应该 运行 没有问题。但是,如果我们运行这个项目,就会出现这个错误:

Exception thrown at 0x0000000000000000 in CPP_Test.exe: 0xC0000005: Access violation executing location

在 运行 运行程序之前我们没有出现任何错误,为什么会出现这个错误?

为什么会出现此错误?

来自learnopengl.com

Because OpenGL is only really a standard/specification it is up to the driver manufacturer to implement the specification to a driver that the specific graphics card supports. Since there are many different versions of OpenGL drivers, the location of most of its functions is not known at compile-time and needs to be queried at run-time. It is then the task of the developer to retrieve the location of the functions he/she needs and store them in function pointers for later use.

GLAD 是一个库,它定义了使用 OpenGL 所需的所有函数,而无需我们自己解决。

例如,当我们调用一个 GLAD 函数 glClear 时,我们实际上是从 gl 上下文中调用一个名为 glad_glClear 的函数。进行此调用时,GLAD 会查找当前的 gl 上下文以影响正确的 window,可以说是这样。出现此问题的原因是因为 GLAD 将始终使用上下文,即使找不到上下文也是如此。

发生这种情况时,会在内存中的此位置 (0x0000000000000000) 进行调用,并且由于它不是 GL 上下文,因此会引发 Access violation 异常。


我该如何解决?

解决这个问题很简单。如果您正在阅读本文,您可能正在使用 GLAD 和 GLFW。 GLFW 有一个功能,允许我们在创建 window:

后仅在一次调用中定义上下文
glfwMakeContextCurrent(GLFWwindow* window);

很好,现在我们已经设置了上下文,但 GLAD 还不知道。为此,我们只需在设置上下文后立即使用 gladLoadGL 初始化 GLAD。

我们现在可以再次运行我们的程序了,一切都应该正常。

下面是完整的代码,稍作改动:

#include <iostream>
#include <glad/glad.h>
#include <GLFW/glfw3.h>

using namespace std;

// framebuffer size callback function
void resize(GLFWwindow* window, int width, int height)
{
    glViewport(0, 0, width, height);
}

void render(GLFWwindow* window) {

    // here we put our rendering code
    
}

void main() {

    int width = 800;
    int height = 600;

    // We initialzie GLFW
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    // Now that it is initialized, we create a window
    GLFWwindow* window = glfwCreateWindow(width, height, "My Title", NULL, NULL);

    // We set the context to be our window and then initialize GLAD
    glfwMakeContextCurrent(window);
    gladLoadGL();   

    // We can set a function to recieve framebuffer size callbacks, but it is optional
    glfwSetFramebufferSizeCallback(window, resize);


    //here we run our window, swapping buffers and all.
    while (!glfwWindowShouldClose(window))
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glClearColor(0.0f, 0.0f, 0.1f, 0.0f);
        render(window);
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
}

我自己费了好几个小时才找到这个解决方案,因为每个人都解决了它初始化 GLEW,但它不包含在这个项目中,所以这对我不起作用。