c++ - OpenGL VBO 数据似乎已损坏

标签 c++ opengl opengl-3

我已将顶点、颜色、法线和纹理坐标上传到与 VAO 关联的单个 VBO 中。我还有一个 EBO 与存储索引的同一个 VAO 相关联。我也在使用 SDL 和 OpenGL 3.3(Core Profile 上下文,使用 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);,它似乎修复了它。

关于c++ - OpenGL VBO 数据似乎已损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35424467/

相关文章:

c++ 和 portaudio,可怕的扭曲输出

c++ - 如何从 C++ 文件中读取带逗号的数字?

c++ - 将方法参数传递给 googlemock 中的操作

opengl - 如何在 OpenGL 中交互地绘制图元?

c++ - 帧缓冲对象错误?

c++ - N 元谓词评估函数 (count_if)

c++ - OpenGL - 使用两个 GL 程序改变顶点的位置

OpenGL VAO 最佳实践

c++ - OpenGL 视口(viewport)失真

c++ - VAO 与 VBO 和 IBO 的手动绑定(bind)