2011-04-29 3 views
1

Je lance un nouveau projet opengles depuis xcode 4 et je supprime toutes les références et appels ES2 (je veux utiliser le code draw ES1). Mon exemple de projet fonctionne très bien sur iphone 4 mais ne fonctionne pas sur iphone 3g et ipod 2ème génération. Hre est mon code modifié:Xcode 4 Modèle OpenGL ES 1.1

EAGLView.m

#import <QuartzCore/QuartzCore.h> 

#import "EAGLView.h" 

@interface EAGLView (PrivateMethods) 
- (void)createFramebuffer; 
- (void)deleteFramebuffer; 
@end 

@implementation EAGLView 

@synthesize context; 

// You must implement this method 
+ (Class)layerClass 
{ 
    return [CAEAGLLayer class]; 
} 

//The EAGL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:. 
- (id)initWithCoder:(NSCoder*)coder 
{ 
    self = [super initWithCoder:coder]; 
    if (self) { 
     CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; 

     eaglLayer.opaque = TRUE; 
     eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: 
             [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, 
             kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, 
             nil]; 
    } 

    return self; 
} 

- (void)dealloc 
{ 
    [self deleteFramebuffer];  
    [context release]; 

    [super dealloc]; 
} 

- (void)setContext:(EAGLContext *)newContext 
{ 
    if (context != newContext) { 
     [self deleteFramebuffer]; 

     [context release]; 
     context = [newContext retain]; 

     [EAGLContext setCurrentContext:nil]; 
    } 
} 

- (void)createFramebuffer 
{ 
    if (context && !defaultFramebuffer) { 
     [EAGLContext setCurrentContext:context]; 

     // Create default framebuffer object. 
     glGenFramebuffersOES(1, &defaultFramebuffer); 
     glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer); 

     // Create color render buffer and allocate backing store. 
     glGenRenderbuffersOES(1, &colorRenderbuffer); 
     glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer); 
     [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer *)self.layer]; 
     glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &framebufferWidth); 
     glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &framebufferHeight); 

     glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer); 

     if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) 
      NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); 
    } 
} 

- (void)deleteFramebuffer 
{ 
    if (context) { 
     [EAGLContext setCurrentContext:context]; 

     if (defaultFramebuffer) { 
      glDeleteFramebuffersOES(1, &defaultFramebuffer); 
      defaultFramebuffer = 0; 
     } 

     if (colorRenderbuffer) { 
      glDeleteRenderbuffersOES(1, &colorRenderbuffer); 
      colorRenderbuffer = 0; 
     } 
    } 
} 

- (void)setFramebuffer 
{ 
    if (context) { 
     [EAGLContext setCurrentContext:context]; 

     if (!defaultFramebuffer) 
      [self createFramebuffer]; 

     glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer); 

     glViewport(0, 0, framebufferWidth, framebufferHeight); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glOrthof(0, framebufferWidth, framebufferHeight, 0, 0, 1); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 


    } 
} 

- (BOOL)presentFramebuffer 
{ 
    BOOL success = FALSE; 

    if (context) { 
     [EAGLContext setCurrentContext:context]; 

     glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer); 

     success = [context presentRenderbuffer:GL_RENDERBUFFER_OES]; 
    } 

    return success; 
} 

- (void)layoutSubviews 
{ 
    // The framebuffer will be re-created at the beginning of the next setFramebuffer method call. 
    [self deleteFramebuffer]; 
} 

@end 

testViewController.m

#import "testAppDelegate.h" 
#import "testViewController.h" 
#import "EAGLView.h" 

// Uniform index. 
enum { 
    UNIFORM_TRANSLATE, 
    NUM_UNIFORMS 
}; 
GLint uniforms[NUM_UNIFORMS]; 

// Attribute index. 
enum { 
    ATTRIB_VERTEX, 
    ATTRIB_COLOR, 
    NUM_ATTRIBUTES 
}; 
@interface testViewController() 
@property (nonatomic, retain) EAGLContext *context; 
@property (nonatomic, assign) CADisplayLink *displayLink; 
@end 
@implementation PyrotexniViewController 
@synthesize animating, context, displayLink; 

- (void)awakeFromNib 
{ 
    EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; 



    if (!aContext) 
     NSLog(@"Failed to create ES context"); 
    else if (![EAGLContext setCurrentContext:aContext]) 
     NSLog(@"Failed to set ES context current"); 

    self.context = aContext; 
    [aContext release]; 

    [(EAGLView *)self.view setContext:context]; 
    [(EAGLView *)self.view setFramebuffer]; 
    animating = FALSE; 
    animationFrameInterval = 1; 
    self.displayLink = nil; 

- (void)dealloc 
{ 
    // Tear down context. 
    if ([EAGLContext currentContext] == context) 
     [EAGLContext setCurrentContext:nil]; 

    [context release]; 
    [EAGLView dealloc]; 
    [self stopAnimation]; 

    [super dealloc]; 

} 

- (NSInteger)animationFrameInterval 
{ 
    return animationFrameInterval; 
} 

- (void)setAnimationFrameInterval:(NSInteger)frameInterval 
{ 

    if (frameInterval >= 1) { 
     animationFrameInterval = frameInterval; 

     if (animating) { 
      [self stopAnimation]; 
      [self startAnimation]; 
     } 
    } 
} 

- (void)startAnimation 
{ 
    if (!animating) { 
     CADisplayLink *aDisplayLink = [[UIScreen mainScreen] displayLinkWithTarget:self selector:@selector(drawFrame)]; 
     [aDisplayLink setFrameInterval:animationFrameInterval]; 
     [aDisplayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
     self.displayLink = aDisplayLink; 

     animating = TRUE; 
    } 
} 

- (void)stopAnimation 
{ 

    if (animating) { 
     [self.displayLink invalidate]; 
     self.displayLink = nil; 
     animating = FALSE; 

    } 
} 

- (void)drawFrame 
{ 

    [(EAGLView *)self.view setFramebuffer]; 

    ......draw code here..... 




    [(EAGLView *)self.view presentFramebuffer]; 
} 

basé sur ce schéma de projet censé fonctionner sur OpenGLES 1.1 appareils, mais ne fonctionne pas (ce code ne fonctionne que sur iphone4)! qu'est-ce qui ne va pas ici? Aidez-moi, s'il vous plaît. Merci.

+0

quelles erreurs obtenez-vous? – Bastian

+0

la couleur de l'écran d'arrière-plan est violet sur 3g et ipod 2e gén .. – Dorald

+0

Quelle est la taille de la texture de l'arrière-plan? Je pense que la taille maximale sur ces appareils est 1024x1024 – Bastian

Répondre

1

Un problème est que CADisplayLink n'existe pas dans les versions IOS antérieures à 3.1. Vous pouvez détecter que dans awakeFromNib comme ceci:

NSString *reqSysVer = @"3.1"; 
NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; 
if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending) 
    mDisplayLinkSupported = TRUE;  

puis à DebuterAnimation vous pouvez le faire

if (mDisplayLinkSupported) 
    { 
     // CADisplayLink is API new to iPhone SDK 3.1. Compiling against earlier versions will result in a warning, but can be dismissed 
     // if the system version runtime check for CADisplayLink exists in -initWithCoder:. The runtime check ensures this code will 
     // not be called in system versions earlier than 3.1. 

     mDisplayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(drawView:)]; 
     [mDisplayLink setFrameInterval:1]; 
     [mDisplayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
    } 
    else 
     mAnimationTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)(1.0/60.0) target:self selector:@selector(drawView:) userInfo:nil repeats:TRUE]; 

et stopAnimation faire quelque chose comme ceci:

if (mAnimating) 
{ 
    if (mDisplayLinkSupported) 
    { 
     [mDisplayLink invalidate]; 
     mDisplayLink = nil; 
    } 
    else 
    { 
     [mAnimationTimer invalidate]; 
     mAnimationTimer = nil; 
    } 

    mAnimating = FALSE; 
} 

Vous devez également Faites en sorte que la signature de drawFrame ressemble à ceci afin de pouvoir gérer les messages AnimationTimer.

- (void) drawFrame:(id)sender 

Quoi qu'il en soit, ce code n'utilise pas tous les mêmes noms de variables que vous aviez depuis que je viens recopié de mon code, mais vous obtenez l'essentiel. Incidemment, ce code a été dérivé d'un modèle XCode plus ancien qui prenait en compte les anciennes versions d'IOS qui ne supportaient pas les liens d'affichage.

+0

Ceci est un point valide, mais vous trouverez à peine 3.0 périphériques là-bas aujourd'hui. Tous les anciens périphériques ont reçu la mise à jour 3.1.3 et CADisplayLink est pris en charge depuis la version 3.0. Si c'était le problème, il n'y aurait pas d'écran rose, l'application ne démarre pas du tout. Je ne pense pas que soutenir 3.0 n'a aucun sens de nos jours. – Bastian

+0

Non, CADisplayLink était le premier disponible dans la version 3.1. Et vous seriez surpris du nombre de personnes qui utilisent encore iOS 3.0. Si vous pouvez le supporter avec un peu d'effort: allez-y! – JustSid

+0

Oh ouais, bon point sur l'écran rose. Je n'ai pas vu cette friandise avant que j'aie fini de poster! –

1

Le problème réside probablement dans les fichiers de vue. vous devez le définir par défaut sur GLES 1 au lieu de GLES 2 par défaut dans la plupart des cas. il aura probablement quelque chose comme

 if ((self = [super initWithCoder:coder])) 
    { 
     // Get the layer 
     CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; 

     eaglLayer.opaque = TRUE; 
     eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: 
            [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; 

    renderer = [[ES2Renderer alloc] init]; 

    if (!renderer) 
    { 
     renderer = [[ES1Renderer alloc] init]; 

     if (!renderer) 
     { 
      [self release]; 
      return nil; 
     } 
    } 

Il suffit de modifier ES2Renderer et ES1Renderer. Il est dit que tout cela fonctionne pour créer l'EALayer et ensuite définir ES2 comme valeur par défaut et si ES2 ne peut pas être chargé, alors vous utilisez ES1

Questions connexes