0

解决方案:我之前设置了所有纹理一次,而不是每一帧,我为 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);
}
4

1 回答 1

2

您应该只加载一次纹理,然后在绘制时使用对 GLKTextureInfo 的引用。为每次平局调用这条线一定会扼杀你的表现:

GLKTextureInfo * textureInfo = [GLKTextureLoader textureWithContentsOfFile:path         options:options error:&error];
于 2013-03-28T23:35:16.837 回答