【问题标题】:OpenGL VBO data seems to get corruptedOpenGL VBO 数据似乎已损坏
【发布时间】:2016-05-27 06:06:30
【问题描述】:

我已将顶点、颜色、法线和纹理坐标上传到与 VAO 关联的单个 VBO。我还有一个与存储索引的同一个 VAO 关联的 EBO。我也在使用 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;
}

【问题讨论】:

  • glGetError() 能给你什么吗?
  • 看起来您的状态已损坏,而不是 VBO 数据。尝试在渲染之前启用 GL_DEPTH_TEST。
  • 您的 Depthbuffer 似乎被弄乱了...您能过滤掉您与数据库交互的所有调用并检查它们吗?
  • 谢谢@MichaelNastenko,就是这样!如果您想添加答案,我会接受!我在渲染代码之前添加了glEnable(GL_DEPTH_TEST);,它似乎可以修复它。我最初在设置 OpenGL 上下文后启用了 GL_DEPTH_TEST,但显然这似乎不起作用 - 每次渲染时都需要启用它吗?
  • @Jarrett 好吧,AFAIK 它应该是一致的。你确定你没有在其他地方改变它吗?

标签: c++ opengl opengl-3


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-14
    • 2013-05-23
    • 2020-03-18
    • 1970-01-01
    • 2021-12-10
    • 2013-07-07
    • 1970-01-01
    • 2018-02-24
    相关资源
    最近更新 更多