我有一個構建在OpenGL ES 2.0之上的動畫背景層,我使用GLKView作爲圖形容器,並使用GLKViewController作爲控制器。對於繪圖我使用GLKBaseEffect。OpenGL ES 2.0:如何提高繪製精靈的幀率?
我引入了一個sprite類,它可以將png文件加載爲紋理,操縱sprite(SRT)和一些其他屬性,如alpha混合等等。
我想知道如何優化我的程序,因爲在顯示50個sprites(全部具有相同的紋理/ png文件!)時,我的iPhone 4S的幀率下降到大約25 FPS,尺寸爲128x128像素每。
在下面的章節中,我列出了程序的重要部分。目前,我爲每個幀的50個精靈中的每一個調用glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)
(目標幀速率爲60);這相當於每秒3000個呼叫。
那可能是瓶頸嗎?我怎麼能優化這個?
這是我如何初始化精靈陣列(GLKViewController.m):
- (void)initParticles {
if(sprites==nil) {
sprites = [NSMutableArray array];
for (int i=0; i<50; i++) {
Sprite* sprite = [[Sprite alloc] initWithFile:@"bubble" extension:@"png" effect:effect];
// configure some sprite properties [abbreviated]
[sprites addObject:sprite];
}
}
}
這是渲染功能(GLKViewController.m):
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
glClearColor(0.0, 0.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
// render the bubbles
for (Sprite* sprite in sprites) {
[sprite render];
}
}
下面是一些重要部件精靈類(Sprite.m):
- (id)initWithFile:(NSString *)filename extension:(NSString*)extension effect:(GLKBaseEffect *)effect {
if(self = [self init]) {
self.effect = effect;
NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], GLKTextureLoaderOriginBottomLeft, nil];
NSError* error = nil;
NSString *path = [[NSBundle mainBundle] pathForResource:filename ofType:nil];
self.textureInfo = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error];
if (self.textureInfo == nil) {
NSLog(@"Error loading file: %@", [error localizedDescription]);
return nil;
}
TexturedQuad newQuad;
newQuad.bl.geometryVertex = GLKVector2Make(0, 0);
newQuad.br.geometryVertex = GLKVector2Make(self.textureInfo.width, 0);
newQuad.tl.geometryVertex = GLKVector2Make(0, self.textureInfo.height);
newQuad.tr.geometryVertex = GLKVector2Make(self.textureInfo.width, self.textureInfo.height);
newQuad.bl.textureVertex = GLKVector2Make(0, 0);
newQuad.br.textureVertex = GLKVector2Make(1, 0);
newQuad.tl.textureVertex = GLKVector2Make(0, 1);
newQuad.tr.textureVertex = GLKVector2Make(1, 1);
self.quad = newQuad;
}
return self;
}
- (void)render {
[self applyBaseEffect];
long offset = (long)&_quad;
glEnableVertexAttribArray(GLKVertexAttribPosition);
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void*) (offset + offsetof(TexturedVertex, geometryVertex)));
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void*) (offset + offsetof(TexturedVertex, textureVertex)));
glBlendColor(1.0, 1.0, 1.0, self.alpha);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableVertexAttribArray(GLKVertexAttribPosition);
glDisableVertexAttribArray(GLKVertexAttribTexCoord0);
}
- (void)applyBaseEffect {
self.effect.texture2d0.name = self.textureInfo.name;
self.effect.texture2d0.envMode = GLKTextureEnvModeModulate;
self.effect.texture2d0.target = GLKTextureTarget2D;
self.effect.texture2d0.enabled = GL_TRUE;
self.effect.useConstantColor = GL_TRUE;
self.effect.constantColor = GLKVector4Make(self.tint.r*self.alpha, self.tint.g*self.alpha, self.tint.b*self.alpha, self.alpha);
self.effect.transform.modelviewMatrix = GLKMatrix4Multiply(GLKMatrix4Identity, [self modelMatrix]);
[self.effect prepareToDraw];
}
- (GLKMatrix4)modelMatrix {
GLKMatrix4 modelMatrix = GLKMatrix4Identity;
modelMatrix = GLKMatrix4Translate(modelMatrix, self.position.x, self.position.y, 0);
modelMatrix = GLKMatrix4Rotate(modelMatrix, self.rotation, 0, 0, 1);
modelMatrix = GLKMatrix4Scale(modelMatrix, self.scale, self.scale, 0);
modelMatrix = GLKMatrix4Translate(modelMatrix, -self.normalSize.width/2, -self.normalSize.height/2, 0);
return modelMatrix;
}
編輯-1:這裏有一些性能指標(似乎是GPU結合的)
EDIT-2:當我添加了view.drawableMultisample
線無論哪個線的我用(無/ 4X從25提高到45在我的iPhone 4S幀速率)。奇怪 - 我的渲染代碼似乎沒有受到MSAA的影響,恰恰相反。
GLKView *view = (GLKView*)self.view;
view.context = context;
view.drawableMultisample = GLKViewDrawableMultisampleNone;
//view.drawableMultisample = GLKViewDrawableMultisample4x;
有精靈相同的特徵(頂點,紋理等)? – xcesco
是的,它們都是一樣的(一些氣泡從底部移動到頂部)。我只用'effect.transform.modelviewMatrix'來操作它們。 – salocinx
爲了知道您的應用是CPU還是GPU綁定,您需要首先進行配置。請檢查[this](https://developer.apple.com/library/ios/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/ToolsOverview/ToolsOverview.html),然後從XCode運行您的應用程序並在此處添加結果的屏幕截圖。我希望看到「利用率」和「幀時間」的值 –