opengl 在glfwSwapBuffers()中发生访问冲突

yc0p9oo0  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(522)

我正在使用版本4.6制作OpenGL程序,但是当我编写纹理代码并运行程序时,glfwSwapBuffers()中发生了以下错误:在Project1.exe中的0x00007FFCCD631970(nvoglv64.dll)处引发了异常:数据类型:阅读位置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);
}

纹理. 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

如何解决此问题?

s3fp2yjn

s3fp2yjn1#

索引缓冲区(ELEMENT_ARRAY_BUFFER)绑定存储在顶点数组对象中。当调用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);

与索引缓冲区不同,顶点缓冲区绑定(ARRAY_BUFFER)是一个全局状态。
VAO状态向量中所述的每个属性可以指不同的ARRAY_BUFFER。当调用glVertexAttribPointer时,当前绑定到目标ARRAY_BUFFER的缓冲器与指定的属性索引相关联,并且对象的ID存储在当前绑定的VAO的状态向量中。因此,调用glBindBuffer(GL_ARRAY_BUFFER, 0);没有问题

相关问题