4

我一直在尝试按照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();
    }

}

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

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

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

4

1 回答 1

9

为什么我会收到此错误?

来自learnopengl.com

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

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

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

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


我如何解决它?

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

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 时解决了它,但它不包含在这个项目中,所以这对我不起作用。

于 2021-05-05T11:34:58.913 回答