开发者

OpenGL ES 2.0 on iPhone: Unable to Exceed Small Index/Vertex Count

开发者 https://www.devze.com 2023-04-01 12:31 出处:网络
I\'ll try to keep it brief: I\'m using OpenGL ES 2.0 on iPhone, and am utilising a Vertex Buffer Object to render many shapes on-screen at once.

I'll try to keep it brief: I'm using OpenGL ES 2.0 on iPhone, and am utilising a Vertex Buffer Object to render many shapes on-screen at once.

A series of zero-upwards indices are used for GL_ELEMENT_ARRAY_BUFFER, these are stored in:

GLushort *ixData;

Each shape has a vertex count. When a new shape is created, the total vertex count 'vxCount' is used to reallocate memory for ixData:

NSLog(@"allocating ixData for %i shapes, %i vertices",shapes.size(),vxCount);
ixData = (GLushort*)realloc(ixData, vxCount*sizeof(GLushort));

There is of course an initial malloc for ixData too.

Each shape has 6 vertex attributes (2 position, 4 colour) and these are all GLfloat. Each shape has 24 vertices in total. The shapes are stored in a vector<Shape> since the code is C++. The value vxCount is calculated by multiplying the size of this shapes vector by the number of vertices per shape (i.e. shapes.size()*24).

The position of each shape changes every frame so I resubmit the buffer data just before calling glDrawElements on each render:

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); //*

The app works great for any number of shapes up to and including 508. However, when I try to add the 509th shape I get an EXC_BAD_ACCESS for the indices buffer data; relevant line is asterisked in the code above.

The NSLog printouts in the code above are shown below. As you can see the latest allocated vertex count is consistent with the count upon submission of the primitive indices.

...

2011-08-31 20:35:59.438 nibfree[26409:707] allocating ixData for 503 shapes, 12072 vertices

2011-08-31 20:35:59.441 nibfree[26409:707] allocating ixData for 504 shapes, 12096 vertices

2011-08-31 20:35:59.444 nibfree[26409:707] allocating ixData for 505 shapes, 12120 vertices

2011-08-31 20:35:59.448 nibfree[26409:707] allocating ixData for 506 shapes, 12144 vertices

2011-08-31 20:35:59.451 nibfree[26409:707] allocating ixData for 507 shapes, 12168 vertices

2011-08-31 20:35:59.454 nibfree[26409:707] allocating ixData for 508 shapes, 12192 vertices

2011-08-31 20:35:59.457 nibfree[26409:707] allocating ixData for 509 shapes, 12216 vertices

2011-08-31 20:35:59.746 nibfree[26409:707] render vxcount is 1开发者_运维百科2216

~12k vertices should be no problem for the device, and the type of the index data is GLushort meaning 0-65535 vertex indices should be possible.

I'm truly stumped, can anyone surmise what's gone wrong? Am I exceeding some vertex/index buffer limit that's iPhone specific?

UPDATE

To add insight I've halved the shape size from 24 verts to 12 verts. I then tried again, and reached a limit of 1536 shapes, 18432 vertices. If I try adding 1537 shapes with 12 verts per shape then it crashes as before with an EXC_BAD_ACCESS.

This latest test indicates that the vxData/ixData storage is not an issue, nor is there a limiting number of vertices or vertex indices. The possible number of shapes has increased by roughly factor 3 - does this suggest its a GL_TRIANGLES rendering quirk I'm encountering? Or maybe it's a misuse of realloc? I'm really not sure why it's a problem :(

UPDATE 2

Another set of numbers to spot the pattern: 300 verts has max 61 shapes, 62 causes the crash. At 62 there is vxcount 18300, last ixData index 18299 as expected.


The EXC_BAD_ACCESS at upload is likely caused when the GL driver attempts to read memory that your application doesn't own. So it's likely that your ixDataSize has a value larger than vxCount*sizeof(GLushort). Such a problem may have gone undiscovered with smaller buffer sizes because the ixDataSize you're coming up with in those cases doesn't run outside the area given to your application and, because it's larger than the number you actually want, all of the data you go on to use is copied.

0

精彩评论

暂无评论...
验证码 换一张
取 消