执行位置0x0000000000000000时发生访问冲突.OpenGL与GLAD和GLFW



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

#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

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

GLAD是一个库,它定义了使用OpenGL所需的所有函数,而不必自己计算。

例如,当我们调用GLAD函数glClear时,我们实际上是在从gl上下文中调用一个名为glad_glClear的函数。当进行这个调用时,GLAD会查找当前的gl上下文,以便影响正确的窗口,比如说。出现这个问题的原因是GLAD总是会使用上下文,即使它找不到上下文。

当这种情况发生时,会在内存中的这个位置(0x0000000000000000(进行调用,并且由于它不是GL上下文(它只是一个NULL指针(,因此会引发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时解决了这个问题,但它不包括在这个项目中,所以这对我来说不起作用。

最新更新