opengl - OpenGL 只会更新最后一个顶点数组对象
问题描述
我正在编写一些生成一些 VAO 的代码,然后在更新物理时调用以更新 VAO 内的顶点,然后调用以重绘这些对象。
我的代码的问题是 UpdateScene 只更新了最后一个 VAO。以下两个函数创建缓冲区。
void BuildBuffers(std::vector<demolish::Object>& objects)
{
VAO = new UINT[objects.size()];
glGenVertexArrays(objects.size(),VAO);
int counter = 0;
for(auto& o:objects)
{
if(o.getIsSphere())
{
BuildSphereBuffer(o.getRad(),o.getLocation(),counter);
counter++;
}
else
{
}
}
}
void BuildSphereBuffer(float radius,std::array<iREAL,3> position,int counter)
{
GeometryGenerator::MeshData meshObj;
geoGenObjects.push_back(meshObj);
geoGen.CreateSphere(radius,30,30,meshObj,position);
VAOIndexCounts.push_back(meshObj.Indices.size());
glGenBuffers(2,BUFFERS);
glBindVertexArray(VAO[counter]);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER,BUFFERS[0]);
glBufferData(GL_ARRAY_BUFFER,
meshObj.Vertices.size()*sizeof(GLfloat)*11,
&meshObj.Vertices.front(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, BUFFERS[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
meshObj.Indices.size() * sizeof(UINT),
&meshObj.Indices.front(), GL_STATIC_DRAW);
glVertexPointer(3, GL_FLOAT,sizeof(GLfloat)*11, 0);
glNormalPointer(GL_FLOAT,sizeof(GLfloat)*11,(GLvoid*)(3*sizeof(GLfloat)));
}
然后以下函数在调用时更新缓冲区。
void UpdateScene(float dt, std::vector<demolish::Object>& objects)
{
float x = radius*sinf(phi)*cosf(theta);
float z = radius*sinf(phi)*sinf(theta);
float y = radius*cosf(phi);
AV4FLOAT position(x,y,z,1.0);
AV4FLOAT target(0.0,0.0,0.0,0.0);
AV4FLOAT up(0.0,1.0,0.0,0.0);
viewModelMatrix = formViewModelMatrix(position,target,up);
for(int i=0;i<objects.size();i++)
{
geoGen.CreateSphere(objects[i].getRad(),
30,
30,
geoGenObjects[i],
objects[i].getLocation());
VAOIndexCounts[i] = geoGenObjects[i].Indices.size();
glBindVertexArray(VAO[i]);
glBufferSubData(GL_ARRAY_BUFFER,
0,
geoGenObjects[i].Vertices.size()*sizeof(GLfloat)*11,
&geoGenObjects[i].Vertices.front());
}
RedrawTheWindow();
}
这段代码的问题是它没有更新所有的缓冲区,只有“最后一个”。例如,如果对象的大小为 3,那么即使所有三个对象的位置都发生了变化,也只有最后一个缓冲区会使用新顶点进行更新。
我已将其范围缩小到 OpenGL,但我不确定我做错了什么。
解决方案
绑定顶点数组对象不会绑定任何数组缓冲区对象。
如果要更改数组缓冲区的内容,则必须绑定数组缓冲区:
GLuint VBO = .....; // VBO which corresponds to VAO[i]
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferSubData(
GL_ARRAY_BUFFER, 0,
geoGenObjects[i].Vertices.size()*sizeof(GLfloat)*11,
&geoGenObjects[i].Vertices.front());
请注意,对于每个属性,顶点数组对象可能引用不同的数组缓冲区对象。那么应该绑定哪一个呢?
从 OpenGL 4.5 开始,您也可以通过直接状态访问版本来执行此操作。
见glNamedBufferSubData
:
glNamedBufferSubData (
VBO, 0,
geoGenObjects[i].Vertices.size()*sizeof(GLfloat)*11,
&geoGenObjects[i].Vertices.front());
如果绑定了顶点数组对象,则可以glGetVertexAttribIuiv
使用参数查询绑定到绑定点的命名数组缓冲区对象GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
:
例如:
glBindVertexArray(VAO[i]);
GLuint VBO;
glGetVertexAttribIuiv(0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &VBO);
推荐阅读
- android - 从 Oracle 过程运行 Powershell 命令
- c# - 在 mvc 4 中实现搜索
- azure - 在订阅下看不到访问控制 (IAM)
- mifos - Fineract 无法在 mac Mojave 中启动
- c++ - 在类定义中使用声明
- awk - awk:生成 icalendar 文件。如何打印一些连续的行?
- python - img src 在 Django 中无法使用 Bootstrap Carousel
- css - UI5:单击按钮后更改列表项的样式
- python - 使用 executemany() 加载 CSV 的 Python cx_Oracle 给出“未找到必需的参数‘参数’(位置 2)”
- sql-server - SQL Server 子查询返回超过 1 个值。这是不允许的