gpt4 book ai didi

c++ - glDrawArrays 调用 mangling 数据之间的 glBufferSubData

转载 作者:太空宇宙 更新时间:2023-11-04 11:45:47 25 4
gpt4 key购买 nike

似乎 glBufferSubData 在我的 glDrawArrays 调用之间覆盖或以某种方式破坏数据。我在 Windows 7 64 位系统中工作,使用适用于我的 Nvidia GeForce GT520M CUDA 1GB 的最新驱动程序。

我有 2 个模型,每个模型都有一个动画。这些模型有 1 个网格,并且该网格存储在同一个 VAO 中。它们各有 1 个动画,用于渲染网格的骨骼变换存储在同一个 VBO 中。

我的工作流程是这样的:

  • 计算模型的骨骼转换矩阵
  • 使用 glBufferSubData 将骨骼转换矩阵加载到 opengl 中,然后绑定(bind)缓冲区
  • 使用 glDrawArrays 渲染模型网格

对于一个模型,这是可行的(至少,大部分 - 有时我会在顶点之间出现奇怪的间隙)。

但是,对于不止一个模型,骨骼转换矩阵数据似乎在对网格的渲染调用之间混淆了。

Single Model Animated Windows
Two Models Animated Windows

我像这样加载我的骨骼转换数据:

void Animation::bind()
{
glBindBuffer(GL_UNIFORM_BUFFER, bufferId_);
glBufferSubData(GL_UNIFORM_BUFFER, 0, currentTransforms_.size() * sizeof(glm::mat4), &currentTransforms_[0]);
bindPoint_ = openGlDevice_->bindBuffer( bufferId_ );
}

然后我像这样渲染我的网格:

void Mesh::render()
{
glBindVertexArray(vaoId_);
glDrawArrays(GL_TRIANGLES, 0, vertices_.size());
glBindVertexArray(0);
}

如果我在调用 render() 之后添加对 glFinish() 的调用,它工作得很好!这似乎向我表明,出于某种原因,一个动画的变换矩阵数据正在“渗入”到下一个动画。

怎么会这样?我的印象是,如果我在该缓冲区正在使用时调用 glBufferSubData(例如,对于 glDrawArrays),它就会阻塞。不是这样吗?

可能值得一提的是,同样的代码在 Linux 中工作得很好。

注:与previous post相关,我删除了。

网格加载代码:

void Mesh::load()
{
LOG_DEBUG( "loading mesh '" + name_ +"' into video memory." );

// create our vao
glGenVertexArrays(1, &vaoId_);
glBindVertexArray(vaoId_);

// create our vbos
glGenBuffers(5, &vboIds_[0]);

glBindBuffer(GL_ARRAY_BUFFER, vboIds_[0]);
glBufferData(GL_ARRAY_BUFFER, vertices_.size() * sizeof(glm::vec3), &vertices_[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER, vboIds_[1]);
glBufferData(GL_ARRAY_BUFFER, textureCoordinates_.size() * sizeof(glm::vec2), &textureCoordinates_[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER, vboIds_[2]);
glBufferData(GL_ARRAY_BUFFER, normals_.size() * sizeof(glm::vec3), &normals_[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER, vboIds_[3]);
glBufferData(GL_ARRAY_BUFFER, colors_.size() * sizeof(glm::vec4), &colors_[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 0, 0);

if (bones_.size() == 0)
{
bones_.resize( vertices_.size() );
for (auto& b : bones_)
{
b.weights = glm::vec4(0.25f);
}
}

glBindBuffer(GL_ARRAY_BUFFER, vboIds_[4]);
glBufferData(GL_ARRAY_BUFFER, bones_.size() * sizeof(VertexBoneData), &bones_[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(4);
glVertexAttribIPointer(4, 4, GL_INT, sizeof(VertexBoneData), (const GLvoid*)0);
glEnableVertexAttribArray(5);
glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(VertexBoneData), (const GLvoid*)(sizeof(glm::ivec4)));

glBindVertexArray(0);
}

动画 UBO 设置:

void Animation::setupAnimationUbo()
{
bufferId_ = openGlDevice_->createBufferObject(GL_UNIFORM_BUFFER, Constants::MAX_NUMBER_OF_BONES_PER_MESH * sizeof(glm::mat4), &currentTransforms_[0]);
}

其中 Constants::MAX_NUMBER_OF_BONES_PER_MESH 设置为 100。

OpenGlDevice中:

GLuint OpenGlDevice::createBufferObject(GLenum target, glmd::uint32 totalSize, const void* dataPointer)
{
GLuint bufferId = 0;
glGenBuffers(1, &bufferId);
glBindBuffer(target, bufferId);

glBufferData(target, totalSize, dataPointer, GL_DYNAMIC_DRAW);
glBindBuffer(target, 0);

bufferIds_.push_back(bufferId);

return bufferId;
}

最佳答案

虽然您可能会考虑尝试 GL_STREAM_DRAW,但这些用法标志对于这种情况大多是正确的。

由于某种原因,您的驱动程序似乎无法隐式同步,因此您可能想尝试一种首先消除同步需求的技术。我会建议 Buffer Orphaning:在发送数据之前调用 glBufferData (...) 并为数据指针设置 NULL。这将允许当前正在使用 UBO 的命令继续使用原始数据存储而不强制同步,因为您将在发送新数据之前分配一个新的数据存储。当前面提到的命令完成时,原始数据存储将被孤立,GL 实现将释放它。

在较新的 OpenGL 实现中,您可以使用 glInvalidateBuffer[Sub]Data (...) 来提示驱动程序执行上面讨论的操作。同样,您可以使用带有适当标志的 glMapBufferRange (...) 来更明确地控制所有这些行为。取消映射将隐式刷新和同步对缓冲区对象的访问,除非另有说明,如果您不想乱用无同步缓冲区更新逻辑,这可能会让您的驱动程序完成它的工作。

我提到的大部分内容都有更详细的讨论 here .

关于c++ - glDrawArrays 调用 mangling 数据之间的 glBufferSubData,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19897461/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com