iPhone-iPhone设备上的GLKit绘制方法太慢
解决方案:我之前设置了所有纹理一次,而不是每个帧,我对GLKBaseEffect也做了同样的设置,这就解决了问题!:DiPhone-iPhone设备上的GLKit绘制方法太慢,iphone,objective-c,xcode,glkit,Iphone,Objective C,Xcode,Glkit,解决方案:我之前设置了所有纹理一次,而不是每个帧,我对GLKBaseEffect也做了同样的设置,这就解决了问题!:D 好的,我真的需要帮助解决这个问题,因为它引起了很多问题 我正在创建一个游戏引擎,所以基本上它的物理渲染和游戏循环等。 每当我在模拟器上运行这个应用程序时,它运行平稳、快速,基本上很好。 然而,当我在iPhone3GS上部署应用程序时(越狱使用它进行开发),它运行得非常慢。实体的移动速度非常慢,而且它的运动非常急促,不平稳。它有点向前跳 我正在使用GLKViewControll
好的,我真的需要帮助解决这个问题,因为它引起了很多问题 我正在创建一个游戏引擎,所以基本上它的物理渲染和游戏循环等。 每当我在模拟器上运行这个应用程序时,它运行平稳、快速,基本上很好。 然而,当我在iPhone3GS上部署应用程序时(越狱使用它进行开发),它运行得非常慢。实体的移动速度非常慢,而且它的运动非常急促,不平稳。它有点向前跳 我正在使用GLKViewController绘制和更新游戏 我发现,如果我减少屏幕上的实体,并且不设置它们的图像动画,平滑度会提高,但移动实体仍然非常缓慢,这不是解决方案,因为我不能让一个游戏中只有一个对象 有人知道我怎样才能让它在iPhone上以同样的速度平稳运行吗? 请帮忙,过去两天我一直在努力解决这个问题(实际上是48小时内最好的部分) vvv所有代码vvv 这是自定义GLKViewController类:
#import "RWViewController.h"
#import <QuartzCore/QuartzCore.h>
@interface RWViewController()
@property (strong, nonatomic) EAGLContext *context;
@end
@implementation RWViewController
@synthesize context = _context;
@synthesize rwEngine;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
if(!self.context)
NSLog(@"Failed To Create ES Context");
GLKView *view = (GLKView *) self.view;
self.preferredFramesPerSecond = 60;
view.enableSetNeedsDisplay = true;
view.context = self.context;
[EAGLContext setCurrentContext:self.context];
rwEngine = [[RWEngine alloc] ignition];
}
#pragma mark - GLKViewDelegate
-(void) glkView:(GLKView *)view drawInRect:(CGRect)rect
{
glClearColor(104.0/255.0, 0, 0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
[rwEngine draw];
}
- (void)update {
[rwEngine update];
}
@end
绘图路径为ViewController>引擎>世界>房间>实体
以下是实体绘制方法:
-(void) draw
{
CGPoint drawPoint = (self.room == nil) ? self.location : CGPointMake(self.location.x - self.room.viewPoint.x, self.location.y - self.room.viewPoint.y);
if(isAnimated)
{
SpriteInfo * frame = [[self getAnimation] getCurrentFrame];
[RWImageRenderer renderSprite:frame.imageName position:drawPoint spritePosition:frame.spritePosition spriteDimensions:frame.spriteSize];
}
else if(!isAnimated)
{
SpriteInfo * spriteInfo = [self getSprite];
NSString * imageName = spriteInfo.imageName;
CGSize spriteSize = spriteInfo.spriteSize;
CGPoint spritePosition = spriteInfo.spritePosition;
[RWImageRenderer renderSprite:imageName position:drawPoint spritePosition:spritePosition spriteDimensions:spriteSize];
}
}
这是RWImageRenderer代码:
+(void)renderSprite:(NSString *)filePath position:(CGPoint) position spritePosition:(CGPoint)spriteP spriteDimensions:(CGSize)spriteD
{
[self renderSpriteWithRotation:filePath position:position spritePosition: spriteP spriteDimensions:spriteD rotationOrigin:CGPointMake(0, 0) rotationDegrees:0];
}
+(void)renderSpriteWithRotation:(NSString *)filePath position:(CGPoint) position spritePosition:(CGPoint)spriteP spriteDimensions:(CGSize)spriteD rotationOrigin:(CGPoint) origin rotationDegrees:(int) degrees
{
NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool: YES], GLKTextureLoaderOriginBottomLeft, nil];
NSError * error;
NSString * path = [[NSBundle mainBundle] pathForResource:filePath ofType:nil];
GLKTextureInfo * textureInfo = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error];
NSInteger spriteWidth, spriteHeight;
spriteWidth = (spriteD.width == -1 && spriteD.height == -1) ? textureInfo.width : spriteD.width;
spriteHeight = (spriteD.width == -1 && spriteD.height == -1) ? textureInfo.height : spriteD.height;
GLKBaseEffect* effect = [[GLKBaseEffect alloc] init];
effect.transform.projectionMatrix = GLKMatrix4MakeOrtho(0, 480, 320, 0, -1024, 1024);
if(textureInfo == nil)
{
NSLog(@"Error Loading image: %@", [error localizedDescription]);
return;
}
float spriteX = spriteP.x / textureInfo.width;
float spriteY = spriteP.y / textureInfo.height;
float textureWidth = ((float)spriteWidth) / textureInfo.width;
float textureHeight = ((float)spriteHeight) / textureInfo.height;
VertexQuad quad;
if(degrees != 0)
{
quad.tl.positionVertex = [self rotatePoint:CGPointMake(position.x, position.y) origin:origin angleofRotation:degrees];
quad.tr.positionVertex = [self rotatePoint:CGPointMake(position.x+spriteWidth, position.y) origin:origin angleofRotation:degrees];
quad.bl.positionVertex = [self rotatePoint:CGPointMake(position.x, position.y + spriteHeight) origin:origin angleofRotation:degrees];
quad.br.positionVertex = [self rotatePoint:CGPointMake(position.x+spriteWidth, position.y + spriteHeight) origin:origin angleofRotation:degrees];
//quad.tr.positionVertex = CGPointMake(position.x+spriteWidth, position.y);
//quad.bl.positionVertex = CGPointMake(position.x, position.y + spriteHeight);
//quad.br.positionVertex = CGPointMake(position.x+spriteWidth, position.y + spriteHeight);
}
else if(degrees == 0)
{
quad.tl.positionVertex = CGPointMake(position.x, position.y);
quad.tr.positionVertex = CGPointMake(position.x+spriteWidth, position.y);
quad.bl.positionVertex = CGPointMake(position.x, position.y + spriteHeight);
quad.br.positionVertex = CGPointMake(position.x+spriteWidth, position.y + spriteHeight);
}
quad.tl.textureVertex = CGPointMake(spriteX, 1 - spriteY);
quad.tr.textureVertex = CGPointMake(spriteX + textureWidth, 1 - spriteY);
quad.bl.textureVertex = CGPointMake(spriteX, 1 - spriteY - textureHeight);
quad.br.textureVertex = CGPointMake(spriteX + textureWidth, 1 - spriteY - textureHeight);
effect.texture2d0.name = textureInfo.name;
effect.texture2d0.enabled = YES;
[effect prepareToDraw];
glEnableVertexAttribArray(GLKVertexAttribPosition);
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
long offset = (long)&quad;
glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImageVertex), (void *) (offset + offsetof(ImageVertex, positionVertex)));
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(ImageVertex), (void *) (offset + offsetof(ImageVertex, textureVertex)));
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
您应该只加载一次纹理,然后在绘制时使用对GLKTextureInfo的引用。每次抽签都打这条线肯定会扼杀你的表现:
GLKTextureInfo * textureInfo = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error];
没有那么多的修正,但你应该在iPhone4和iPhone5上试试。如果他们工作顺利,你可以忽略这个问题,因为3GS在市场上的份额很小。另外,需要注意的是,模拟器与您的计算机一样强大,与手机处理器的功率没有任何关系。谢谢,它帮助您加载。我之前设置了所有的纹理,但它仍然非常慢,所以我想了一下还有什么可以调用一次,而不是每一帧,我尝试了GLKBaseEffect,效果非常好,所以我选择了你的答案,因为你让我进入了正确的思维模式:DGlad它很有帮助:)我一定在你的代码中错过了这一点,只初始化一次GLKBaseEffect也是有意义的。尽管如此,我还是希望它的影响远远小于GLKTextureLoader
GLKTextureInfo * textureInfo = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error];