我会尽量保持简短:我在 iPhone 上使用 OpenGL ES 2.0,并且正在利用顶点缓冲区对象一次在屏幕上渲染许多形状。
一系列从零向上的索引用于GL_ELEMENT_ARRAY_BUFFER
,它们存储在:
GLushort *ixData;
每个形状都有一个顶点数。创建新形状时,总顶点计数“vxCount”用于为 ixData 重新分配内存:
NSLog(@"allocating ixData for %i shapes, %i vertices",shapes.size(),vxCount);
ixData = (GLushort*)realloc(ixData, vxCount*sizeof(GLushort));
当然,ixData 也有一个初始的 malloc。
每个形状都有 6 个顶点属性(2 个位置,4 个颜色),这些都是GLfloat
. 每个形状总共有 24 个顶点。vector<Shape>
由于代码是 C++ ,因此形状存储在 a中。该值vxCount
是通过将此形状向量的大小乘以每个形状的顶点数(即shapes.size()*24
)来计算的。
每个形状的位置每帧都会改变,所以我在每次渲染调用 glDrawElements 之前重新提交缓冲区数据:
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glBufferData(GL_ARRAY_BUFFER, vxDataSize, vxData, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
NSLog(@"render vxcount is %i",vxCount);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, ixDataSize, ixData, GL_STATIC_DRAW); //*
该应用程序适用于包括 508 在内的任意数量的形状。但是,当我尝试添加第 509 个形状时,我得到一个EXC_BAD_ACCESS
索引缓冲区数据;相关行在上面的代码中带有星号。
上面代码中的 NSLog 打印输出如下所示。如您所见,最新分配的顶点计数与提交原始索引时的计数一致。
...
2011-08-31 20:35:59.438 nibfree [26409:707] 为 503 个形状、12072 个顶点分配 ixData
2011-08-31 20:35:59.441 nibfree [26409:707] 为 504 个形状、12096 个顶点分配 ixData
2011-08-31 20:35:59.444 nibfree [26409:707] 为 505 个形状、12120 个顶点分配 ixData
2011-08-31 20:35:59.448 nibfree [26409:707] 为 506 个形状、12144 个顶点分配 ixData
2011-08-31 20:35:59.451 nibfree [26409:707] 为 507 个形状、12168 个顶点分配 ixData
2011-08-31 20:35:59.454 nibfree [26409:707] 为 508 个形状、12192 个顶点分配 ixData
2011-08-31 20:35:59.457 nibfree [26409:707] 为 509 个形状、12216 个顶点分配 ixData
2011-08-31 20:35:59.746 nibfree [26409:707] 渲染 vxcount 为 12216
大约 12k 个顶点对设备来说应该没有问题,并且索引数据的类型GLushort
意味着 0-65535 顶点索引应该是可能的。
我真的被难住了,有人能猜出哪里出了问题吗?我是否超出了某些特定于 iPhone 的顶点/索引缓冲区限制?
更新
为了增加洞察力,我将形状大小从 24 verts 减半到 12 verts。然后我又试了一次,达到了1536 shapes, 18432 vertices
. 如果我尝试添加 1537 个形状,每个形状有 12 个顶点,那么它会像以前一样崩溃,带有EXC_BAD_ACCESS
.
该最新测试表明 vxData/ixData 存储不是问题,顶点或顶点索引的数量也没有限制。可能的形状数量增加了大约 3 倍 - 这是否表明它是我遇到的 GL_TRIANGLES 渲染怪癖?或者可能是对 realloc 的滥用?我真的不确定为什么会出现问题:(
更新 2
另一组发现模式的数字:300 个顶点最多有 61 个形状,62 个导致崩溃。在 62 处有 vxcount 18300,最后一个 ixData 索引 18299 符合预期。