Я постараюсь быть кратким: я использую OpenGL ES 2.0 на iPhone, и я использую объект буфера вершин для одновременного рендеринга множества фигур на экране.
Для 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 ++. Значение 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] размещение ixData для 503 фигур, 12072 вершин
2011-08-31 20: 35: 59.441 nibfree [26409: 707] выделение ixData для 504 фигур, 12096 вершин
2011-08-31 20: 35: 59.444 nibfree [26409: 707] размещение ixData для 505 форм, 12120 вершин
2011-08-31 20: 35: 59.448 nibfree [26409: 707] размещение ixData для 506 фигур, 12144 вершин
2011-08-31 20: 35: 59.451 nibfree [26409: 707] размещение ixData для 507 фигур, 12168 вершин
2011-08-31 20: 35: 59.454 nibfree [26409: 707] размещение ixData для 508 фигур, 12192 вершин
2011-08-31 20: 35: 59.457 nibfree [26409: 707] размещение ixData для 509 фигур, 12216 вершин
2011-08-31 20: 35: 59.746 nibfree [26409: 707] рендеринг vxcount - 12216
~ 12k вершин не должно быть проблемой для устройства, а тип индексных данных GLushort
означает, что индексы вершин 0-65535 должны быть возможны.
Я действительно в тупике, может ли кто-нибудь предположить, что пошло не так? Я превышаю ограничение буфера вершин / индекса, специфичное для iPhone?
ОБНОВЛЕНИЕ
Чтобы добавить ясности, я уменьшил размер фигуры вдвое с 24 до 12. Затем я попытался снова и достиг предела 1536 shapes, 18432 vertices
. Если я попытаюсь добавить 1537 фигур с 12 вершинами на фигуру, она вылетит, как и раньше, с EXC_BAD_ACCESS
.
Этот последний тест показывает, что хранилище vxData / ixData не является проблемой, и нет ограниченного количества вершин или индексов вершин. Возможное количество форм увеличилось примерно в 3 раза - означает ли это, что я столкнулся с особенностями рендеринга GL_TRIANGLES? А может это неправильное использование перераспределения? Я правда не понимаю, почему это проблема :(
ОБНОВЛЕНИЕ 2
Другой набор чисел для определения паттерна: 300 вершин имеют максимум 61 форму, 62 вызывает сбой. На 62 есть vxcount 18300, последний индекс ixData 18299, как и ожидалось.
ixDataSize
получит неверное значение, превышающееvxCount*sizeof(GLushort)
? - person Tommy   schedule 01.09.2011ixData
находится в диапазоне:for (size_t i=0; i<ixDataLen; i++) assert(ixData[i]<vxCount);
- person Justicle   schedule 01.09.2011