glfwSwapBuffers() 中发生访问冲突

Access violation occurred in glfwSwapBuffers()

我正在使用4.6版本制作OpenGL程序,但是当我编写纹理代码和运行程序时,在glfwSwapBuffers()中出现了以下错误: 在 Project1.exe 中的 0x00007FFCCD631970 (nvoglv64.dll) 抛出异常:0xC0000005:访问冲突读取位置 0x0000000000000000.

这是我的代码:

#include"shader.h"
#include"texture.h"

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

int main(){
    
    if (glfwInit() == GLFW_FALSE) {
        std::cout << "Failed to initialize GLFW" << std::endl;
        return -1;
    }

    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    GLFWwindow* window = glfwCreateWindow(1280, 800, "What a TD", nullptr, nullptr);
    if (window == nullptr) {
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);

    if (gladLoadGL() != 1) {
        std::cout << "Failed to load GLAD" << std::endl;
        return -1;
    }

    glViewport(0, 0, 1280, 800);

    GLfloat vertices[] = {
        -0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
        -0.5f, 0.5f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
        0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
        0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f
    };

    GLuint indices[] = {
        0, 1, 2,
        2, 3, 0
    };

    GLuint vbo, vao, ebo;

    glGenVertexArrays(1, &vao);
    glGenBuffers(1, &vbo);
    glGenBuffers(1, &ebo);
    
    glBindVertexArray(vao);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(6 * sizeof(GLfloat)));
    
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
    
    texture tex0("planks.png", 0);
    
    shader Shader("default.vs", "default.fs");
    
    //main loop
    while (!glfwWindowShouldClose(window))
    {
        glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        Shader.use();
        tex0.active();
        glBindVertexArray(vao);
        glDrawElements(GL_TRIANGLES, sizeof(indices) / sizeof(GLuint), GL_UNSIGNED_INT, 0);

        glfwSwapBuffers(window); // Access violation
        glfwPollEvents();
    }
    ...
}

顶点着色器:

#version 460 core

layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;

out vec3 Color;
out vec2 texCoord;

void main() {
    gl_Position = vec4(aPos, 1.0f);
    Color = aColor;
    texCoord = aTexCoord;
}

片段着色器:

#version 460 core

in vec3 Color;
in vec2 texCoord;

out vec4 fragColor;

uniform sampler2D tex0;

void main() {
    fragColor = texture(tex0, texCoord);
}

texture.h :

#ifndef GL_TEXTURE_H
#define GL_TEXTURE_H

#include<glad/glad.h>
#include<GLFW/glfw3.h>
#include<stb/stb_image.h> //STB_IMAGE_IMPLEMENTATION defined in other file

#include<iostream>

class texture {
private:
    GLuint ID;
    GLuint unit;
public:
    texture(const char* image, GLuint unit)  {
        stbi_set_flip_vertically_on_load(true);

        this->unit = unit;

        glGenTextures(1, &ID);
        glActiveTexture(GL_TEXTURE0 + unit);
        glBindTexture(GL_TEXTURE_2D, ID);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        int width, height, channels;
        unsigned char* data = stbi_load(image, &width, &height, &channels, 0);
        if (data) {
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
        }
        else {
            std::cout << image << " : " << "Failed to load image" << std::endl;
        }
    
        glGenerateMipmap(GL_TEXTURE_2D);
    
        stbi_image_free(data);
        glBindTexture(GL_TEXTURE_2D, 0);
    }

    void active() {
        glActiveTexture(GL_TEXTURE0 + unit);
        glBindTexture(GL_TEXTURE_2D, ID);
    }
};

#endif

我该如何解决这个问题?

Index Buffer (ELEMENT_ARRAY_BUFFER) binding is stored within the Vertex Array Object。当调用 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO) 时,元素缓冲区对象 ID 存储在当前绑定的顶点数组对象中。
在绑定 VAO 时调用 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 会破坏该绑定,并且索引缓冲区不再绑定到 VAO。去掉这行代码,你根本不需要它。

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);

不同于 Index Buffer, the Vertex Buffer 绑定 (ARRAY_BUFFER) 是一个全局状态。
VAOs 状态向量中声明的每个属性可能引用不同的 ARRAY_BUFFER。当调用 glVertexAttribPointer 时,当前绑定到目标 ARRAY_BUFFER 的缓冲区与指定的属性索引相关联,对象的 ID 存储在当前绑定的 VAO 的状态向量中。因此调用glBindBuffer(GL_ARRAY_BUFFER, 0);

没有问题