Я использую MacMini '11 с AMD Radeon HD 6630M.Я рисую сетку, используя структуру массивов, и все хорошо: 60 кадров в секунду (используя CVDisplayLink).Я использую шейдер со встроенными атрибутами.Жизнь хороша.Я переключаюсь на использование массива структур (с чередованием), потому что я понимаю, что это предпочтительнее для «современных» графических процессоров.Атрибуты определены в шейдере.Сетка нарисована красиво.Но когда я делаю это, частота кадров падает примерно на 33% (до 40 кадров в секунду).И есть несколько копий этих звонков.Используя инструменты: Time Profiler, я получаю следующие сравнения:
Using structure of arrays (60 fps)
Running Time Self Symbol Name
3.0ms 0.0% 3.0 0x21b76c4 ATIRadeonX3000GLDriver
2.0ms 0.0% 0.0 gldUpdateDispatch ATIRadeonX3000GLDriver
2.0ms 0.0% 0.0 gleDoDrawDispatchCore GLEngine
2.0ms 0.0% 0.0 glDrawElements_ACC_Exec GLEngine
2.0ms 0.0% 0.0 glDrawElements libGL.dylib
2.0ms 0.0% 0.0 -[Mesh draw] me
Using array of structures (40 fps)
Running Time Self Symbol Name
393.0ms 7.4% 393.0 0x86f6695 ?
393.0ms 7.4% 0.0 gleDrawArraysOrElements_ExecCore GLEngine
393.0ms 7.4% 0.0 glDrawElements_IMM_Exec GLEngine
393.0ms 7.4% 0.0 glDrawElements libGL.dylib
393.0ms 7.4% 0.0 -[Mesh draw] me
Похоже, libGL принимает решение идти в разных направлениях, а массив структур выглядит так, как будто драйвер X3000 не вызывается,Это выполняется в программном эмуляторе Apple?Должен ли я просто остаться со структурой массивов?Кто-нибудь видел что-нибудь подобное?
Код для атрибутов взят из примера Apple и используется во всем моем приложении (по крайней мере, в 10 других областях), при этом производительность не снижается в этих областях.Это из медленной версии.Как я уже упоминал, я использую встроенные атрибуты в быстрой версии, поскольку данные не чередуются.Рендеринг точный, только медленный.
Я надеюсь, что это то, что вы ищете:
// Step 5 - Bind each of the vertex shader's attributes to the programs
[self.meshShader addAttribute:@"inPosition"];
[self.meshShader addAttribute:@"inNormal"];
[self.meshShader addAttribute:@"inTexCoord"];
// Step 6 - Link the program
if([[self meshShader] linkShader] == 0){
self.posAttribute = [meshShader attributeIndex:@"inPosition"];
self.normAttribute = [meshShader attributeIndex:@"inNormal"];
self.texCoordAttribute = [meshShader attributeIndex:@"inTexCoord"];
...
- (void) addAttribute:(NSString *)attributeName
{
if ([attributes containsObject:attributeName] == NO){
[attributes addObject:attributeName];
glBindAttribLocation(program, [attributes indexOfObject:attributeName],
[attributeName UTF8String]);
}
}
Обновление: После дальнейшего изучения: 1) Я использую загрузчик modelObj dhpoWare (модифицированный) итак как он использует чередующийся массив структур, он также действует как мой массив структур с точки зрения производительности - просто не такой уж хит.Возможно, я неправильно интерпретирую инструменты.Код modelObj вызывает glDrawElements_IMM_Exec, он также окольным путем вызывает gleDoDrawDispatchCore.Я не уверен, что он просто накапливает несколько вызовов в glDrawElements_IMM_Exec, а затем уничтожает их через gleDoDrawDispatchCore.Не знаю.2) Я думаю, что у Instruments есть проблемы, поскольку он показывает, что GLEngine вызывает один из моих неиспользуемых внутренних методов объекта 3ds, который не имеет внешних хуков.Я дважды проверил, установив там точку останова XCode, и она никогда не сработала.Я больше не делаю 3DS.
Думаю, я продолжу осматриваться и, возможно, наткнусь на ответ.Если бы кто-то дал мне мнение о том, стоит ли использовать массив структур, это будет оценено.
РЕШЕНИЕ: Я добавил VBO в начало этого процесса, и все хорошо.Оригинальный код взят из Руководства OpenGL ES 2.0, и добавление VBO решает мою проблему.Частота кадров 60, 1 мс звонит водителю.Вот код:
glGenVertexArrays(1, &vaoName);
glBindVertexArray(vaoName);
// new - create VBO
glGenBuffers(1, &vboName);
glBindBuffer(GL_ARRAY_BUFFER, vboName);
// Allocate and load position data into the VBO
glBufferData(GL_ARRAY_BUFFER, sizeof(struct vertexAttribs) * self.numVertices,
vertexAttribData, GL_STATIC_DRAW);
// end of new
NSUInteger vtxStride = sizeof(struct vertexAttribs);
//GLfloat *vtxBuf = (GLfloat *)vertexAttribData; // no longer use this
GLfloat *vtxBuf = (GLfloat *)NULL; // use this instead
glEnableVertexAttribArray(self.posAttribute);
glVertexAttribPointer(self.posAttribute, VERTEX_POS_SIZE, GL_FLOAT, GL_FALSE,
vtxStride, vtxBuf);
vtxBuf += VERTEX_POS_SIZE;
glEnableVertexAttribArray(self.normAttribute);
glVertexAttribPointer(self.normAttribute, VERTEX_NORM_SIZE, GL_FLOAT, GL_FALSE,
vtxStride, vtxBuf);
vtxBuf += VERTEX_NORM_SIZE;
glEnableVertexAttribArray(self.texCoordAttribute);
glVertexAttribPointer(self.texCoordAttribute, VERTEX_TEX_SIZE, GL_FLOAT, GL_FALSE,
vtxStride, vtxBuf);
...