- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
似乎 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), ¤tTransforms_[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), ¤tTransforms_[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/
我正在处理一个个人 Java OpenGL (JOGL) 项目,我正在使用一些具有独立绘制函数和顶点的自定义对象。 public class Cube extends PhysicalObject {
我正在尝试渲染巨大的点云 (~150M),但 OpenGL 只渲染其中的一部分 (~52M)。渲染较小的数据集(glMapBufferRange,这可能会解决 4GB 的限制。 要考虑的另一件事是使用
我正在尝试渲染一个可以扩展到其他对象的四面体。 使用静态数组可以很好地绘制四面体。 但是当我将 OFF 文件读入动态数组时,什么也没有出现。编译时没有出现错误。 GLfloat *tetra_vert
我尝试使用 glDrawArray 和 GL_TRIANGLE_STRIP 渲染纹理网格,但绘制时存在伪影,但在屏幕上分布不均匀。 Screenshot of the problem. 这是我使用的代
伪代码: void draw() { Vertex* vertices = scene.GetVertexArray(); glEnableClientState(...);
我有一个未声明顶点属性的顶点着色器。它根据 UBO、gl_VertexId 和 gl_InstanceID 计算所有需要的值。 我know必须绑定(bind)非零 VAO 才能渲染。 那么,在当前 V
我正在关注一些初学者 OpenGL 教程,并且对这段代码有点困惑: glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject); //Bind GL_ARRAY
我正在尝试在 glDrawArray 上修改程序。如果我只使用glVertex3f一切都很好,如果我使用glDrawArrays`作为相同的顶点值,除了图形之外,我还会得到一些随机线。 与glDraw
我在 python3 中有这段代码,它不能在 Windows 机器上运行,但可以在 Linux 机器上运行。我绘制了一个绿色屏幕和一个红色三角形,但红色三角形仅在我退出时出现。 import pyga
我正在尝试遵循 [this][1] 简单教程,但在到达“glDrawArrays”时出现以下错误: openGLTest.exe 中 0x03D7598E (nvoglv32.dll) 处的未处理异常
我正在使用以下代码在某些指定坐标处绘制一条绿线 GLfloat colors[] = {0,1,0,1, 0,1,0,0.5}; CGPoint v[] = {{p1.x, p1.y},
我使用 vector 来存储顶点和法线数据 vector vertex; vector normal; 例如: normal.push_back(-1); normal.push_back(0); n
我正在尝试做一个简单的 Pong 游戏,但我遇到了一些问题。本质上,我有一个由四个点组成的数组,x 和 y 值表示一个硬编码的球,我需要让那个球正确显示。当我尝试使用 glDrawArray 时,我一
我最近发现 glDrawArrays 在每一帧上分配和释放大量内存。我怀疑它与 openGL 探查器报告的“Shaders compiled outside initialization”问题有关。这
当我尝试使用 glDrawArrays 绘制圆时,它显示四分之一 circle 由代码生成的 VBO 是正确的。顺便说一句,没有 0,0,0 这样的坐标。它似乎只绘制正顶点,但如果我将顶点乘以 -1
我在 openGL 的固定流水线上花了很多时间,最近开始学习可编程流水线。我认识我的画家,着色器类不是问题,因为它们使用固定功能管道的东西。我似乎无法让 glDrawArrays 为我的生活工作。 我
在循环遍历我想在 3D 引擎中渲染的所有对象时,尝试调用时出现错误 glDrawArrays(mesh->primitiveType, 0, mesh->vertexCount); 因为它试图从位置
好的,所以我仍在努力让它发挥作用。我的代码的重要部分是: def __init__(self, vertices, normals, triangles): self.bufferVertic
在通过 lwjgl 学习如何使用 OpenGL 3.2 时,我遵循了 here 上的教程.我一直在方法调用 glDrawArrays 上收到无效操作错误。如果我从教程中复制源代码,甚至会发生此错误。
我有一堆要绘制的多边形数据。我提取了那个绘图代码,现在它看起来像这样 for (int Index = 0; Index < Count; Index++) { glDrawArrays(GL
我是一名优秀的程序员,十分优秀!