解决方案:我之前设置了所有纹理一次,而不是每一帧,我为 GLKBaseEffect 做了同样的事情并修复了它!:D
好的,我非常需要解决这个问题的帮助,因为它会导致很多问题。
我正在创建一个游戏引擎,所以基本上是它的物理渲染和游戏循环等。每当我在模拟器上运行这个应用程序时,它运行平稳快速,基本上没问题。但是,当我在我的 iPhone 3GS 上部署该应用程序(越狱以将其用于开发)时,它运行非常缓慢。该实体移动得非常慢,而且它的动作非常不平稳,不平滑。它有点向前跳跃。
我正在使用 GLKViewController 来绘制和更新游戏。
我发现如果我减少屏幕上的实体并且不为其图像设置动画,平滑度会提高,但是移动实体仍然非常缓慢,这不是解决方案,因为我不能只玩一个游戏里面的对象……</p>
有谁知道我怎样才能让它在我的 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
这是 rwEngine 类代码:
#import "RWEngine.h"
@implementation RWEngine
TestWorld * world;
-(RWEngine *) ignition
{
//Game Loop Tick Set to ~60 fps
world = [[TestWorld alloc] load];
return self;
}
-(void)update
{
[[self getActiveWorld] update];
}
-(void)draw
{
[[self getActiveWorld] draw];
}
-(NSMutableArray *) getWorlds
{
}
-(World *) getActiveWorld
{
return world;
}
@end
绘图路径为 ViewController>Engine>World>Room>Entity
这是实体绘制方法:
-(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);
}