OpenGL VBO数据似乎已损坏

OpenGL VBO data seems to get corrupted

本文关键字:已损坏 数据 VBO OpenGL      更新时间:2023-10-16

我已经将顶点、颜色、法线和纹理坐标上传到一个与 VO 关联的 VBO 中。 我还有一个与存储索引的同一 VAO 关联的 EBO。 我还使用 SDL 和 OpenGL 3.3(核心配置文件上下文,使用 SDL 设置(。

起初,我的模型似乎渲染得很好。 然后大约 8 秒后,看起来数据已损坏。

这是一个视频: https://youtu.be/eEiH3EFTPFk

每一帧我都在从OpenGL中提取数据(使用glGetNamedBufferSubData(并与它应该是什么进行比较,一切似乎都检查出来了。

有谁知道这里会发生什么? 我很欣赏你们可能提供的任何见解。

这是我用于加载模型数据的代码:

struct Vbo
{
    GLuint id;
};
struct Ebo
{
    GLuint id;
    GLenum mode;
    GLsizei count;
    GLenum type;
};
struct Vao
{
    GLuint id;
    Vbo vbo[4];
    Ebo ebo;
};
// ...
MeshId GraphicsEngine::createStaticMesh(
    std::vector<glm::vec3> vertices,
    std::vector<glm::detail::uint32> indices,
    std::vector<glm::vec4> colors,
    std::vector<glm::vec3> normals,
    std::vector<glm::vec2> textureCoordinates
)
{
    Vao vao;
    glGenVertexArrays(1, &vao.id);
    glGenBuffers(1, &vao.vbo[0].id);
    glGenBuffers(1, &vao.ebo.id);
    auto size = vertices.size() * sizeof(glm::vec3);
    size += colors.size() * sizeof(glm::vec4);
    size += normals.size() * sizeof(glm::vec3);
    size += textureCoordinates.size() * sizeof(glm::vec2);
    glBindVertexArray(vao.id);
    glBindBuffer(GL_ARRAY_BUFFER, vao.vbo[0].id);
    glBufferData(GL_ARRAY_BUFFER, size, nullptr, GL_STATIC_DRAW);
    auto offset = 0;
    glBufferSubData(GL_ARRAY_BUFFER, offset, vertices.size() * sizeof(glm::vec3), &vertices[0]);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);
    offset += vertices.size() * sizeof(glm::vec3);
    glBufferSubData(GL_ARRAY_BUFFER, offset, colors.size() * sizeof(glm::vec4), &colors[0]);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(offset));
    glEnableVertexAttribArray(1);
    offset += colors.size() * sizeof(glm::vec4);
    glBufferSubData(GL_ARRAY_BUFFER, offset, normals.size() * sizeof(glm::vec3), &normals[0]);
    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(offset));
    glEnableVertexAttribArray(2);
    offset += normals.size() * sizeof(glm::vec3);
    glBufferSubData(GL_ARRAY_BUFFER, offset, textureCoordinates.size() * sizeof(glm::vec2), &textureCoordinates[0]);
    glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(offset));
    glEnableVertexAttribArray(3);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao.ebo.id);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(glm::detail::uint32), &indices[0], GL_STATIC_DRAW); 
    glBindVertexArray(0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    vao.ebo.count = indices.size();
    vao.ebo.mode = GL_TRIANGLES;
    vao.ebo.type =  GL_UNSIGNED_INT;
    vertexArrayObjects_.push_back(vao);
    auto index = vertexArrayObjects_.size() - 1;
    return MeshId(index);
}

这是我进行渲染的代码:

// Setup camera
const glm::quat temp = glm::conjugate(camera_.orientation);
view_ = glm::mat4_cast(temp);
view_ = glm::translate(view_, glm::vec3(-camera_.position.x, -camera_.position.y, -camera_.position.z));
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shaderProgram_);
const int modelMatrixLocation = glGetUniformLocation(shaderProgram_, "modelMatrix");
const int pvmMatrixLocation = glGetUniformLocation(shaderProgram_, "pvmMatrix");
const int normalMatrixLocation = glGetUniformLocation(shaderProgram_, "normalMatrix");
glm::detail::uint32 i = 0;  
for ( const auto& r : renderables_ )
{
    const auto& graphicsData = graphicsData_[i];
    glm::mat4 newModel = glm::translate(model_, graphicsData.position);
    newModel = newModel * glm::mat4_cast( graphicsData.orientation );
    newModel = glm::scale(newModel, graphicsData.scale);
    // Send uniform variable values to the shader       
    const glm::mat4 pvmMatrix(projection_ * view_ * newModel);
    glUniformMatrix4fv(pvmMatrixLocation, 1, GL_FALSE, &pvmMatrix[0][0]);
    glm::mat3 normalMatrix = glm::inverse(glm::transpose(glm::mat3(view_ * newModel)));
    glUniformMatrix3fv(normalMatrixLocation, 1, GL_FALSE, &normalMatrix[0][0]);
    glUniformMatrix4fv(modelMatrixLocation, 1, GL_FALSE, &newModel[0][0]);
    glBindTexture(GL_TEXTURE_2D, r.texture.id);
    glBindVertexArray(r.vao.id);
    glDrawElements(r.vao.ebo.mode, r.vao.ebo.count, r.vao.ebo.type, 0);
    glBindVertexArray(0);
    i++;
}

片段着色器:

#version 330 core
in vec4 ourColor;
in vec2 texCoord;
out vec4 color;
uniform sampler2D ourTexture;
void main()
{
    color = texture(ourTexture, texCoord);
}

顶点着色器:

#version 330 core
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
uniform mat4 pvmMatrix;
uniform mat3 normalMatrix;
layout (location = 0) in vec3 position;
layout (location = 1) in vec4 color;
layout (location = 2) in vec3 normal;
layout (location = 3) in vec2 textureCoordinate;
out vec4 ourColor;
out vec2 texCoord;
void main()
{
    //gl_Position = vec4(position, 1.0);
    gl_Position = pvmMatrix * vec4(position, 1.0);
    ourColor = color;
    texCoord = textureCoordinate;
}

根据@MichaelNastenkos评论,我在渲染代码之前添加了glEnable(GL_DEPTH_TEST);,它似乎可以修复它。