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

Cir*_*cía 2 c++ opengl glfw glad

我一直在尝试按照learnopengl.comglfw.org 上的说明创建一个使用 GLAD 和 GLFW 的 OpenGL 窗口。乍一看,根据文档,这足以使窗口正常工作:

#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();
    }

}
Run Code Online (Sandbox Code Playgroud)

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

Exception thrown at 0x0000000000000000 in CPP_Test.exe: 0xC0000005: Access violation executing location
Run Code Online (Sandbox Code Playgroud)

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

Cir*_*cía 6

为什么我收到这个错误?

来自learnopengl.com

因为 OpenGL 实际上只是一个标准/规范,所以由驱动程序制造商将规范实现到特定显卡支持的驱动程序。由于OpenGL驱动有很多不同的版本,其大部分函数的位置在编译时是未知的,需要在运行时查询。然后开发人员的任务是检索他/她需要的函数的位置并将它们存储在函数指针中以供以后使用。

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

glClear例如,当我们调用 GLAD 函数时,实际上是在调用glad_glClear从 gl 上下文中调用的函数。进行此调用时,GLAD 会查找当前的 gl 上下文,以影响正确的窗口,就像说话一样。出现此问题的原因是 GLAD 将始终使用上下文,即使它没有找到。

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


我如何解决它?

解决这个问题非常简单。如果您正在阅读本文,您可能正在使用 GLAD 和 GLFW。GLFW 有一个函数,它允许我们在创建窗口后只需一次调用即可定义上下文:

glfwMakeContextCurrent(GLFWwindow* window);
Run Code Online (Sandbox Code Playgroud)

太好了,现在我们已经设置了上下文,但 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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