2010-11-12 22 views
0

j'ai suivi le tutoriel sur cette page:Pourquoi je ne reçois pas un fond gris dans ce programme

http://iphone-3d-programming.labs.oreilly.com/ch01.html

Je suis descendu à la partie où il est dit, « compiler et construire et vous devriez maintenant voir un écran gris uni, Hourra! Cependant, quand j'ai lancé le programme, j'ai juste un écran noir.

Ce sont ce que les fichiers ressemblent:

HelloArrowAppDelegate.h

#import <UIKit/UIKit.h> 
#import "GLView.h" 

@interface HelloArrowAppDelegate : NSObject <UIApplicationDelegate> { 
    UIWindow *m_window; 
    GLView* m_view; 
} 

@end 

HelloArrowAppDelegate.mm

#import "HelloArrowAppDelegate.h" 

@implementation HelloArrowAppDelegate 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  

    // Override point for customization after application launch. 
    CGRect screenBounds = [[UIScreen mainScreen] bounds]; 

    m_window = [[UIWindow alloc] initWithFrame: screenBounds]; 
    m_view = [[GLView alloc] initWithFrame:screenBounds]; 

    [m_window addSubview: m_view]; 
    [m_window makeKeyAndVisible]; 

    return YES; 
} 

- (void)dealloc { 
    [m_view release]; 
    [m_window release]; 
    [super dealloc]; 
} 

@end 

GLView.h

#import <UIKit/UIKit.h> 
#import <OpenGLES/EAGL.h> 
#import <QuartzCore/QuartzCore.h> 
#import <OpenGLES/ES1/gl.h> 
#import <OpenGLES/ES1/glext.h> 

@interface GLView : UIView { 
    EAGLContext* m_context; 
} 

-(void) drawView; 

@end 

GLView.mm

#import "GLView.h" 

@implementation GLView 

- (void) drawView 
{ 
    glClearColor(0.5f, 0.5f, 0.5f, 1); 
    glClear(GL_COLOR_BUFFER_BIT); 

    [m_context presentRenderbuffer:GL_RENDERBUFFER_OES]; 
} 

+ (Class) layerClass 
{ 
    return [CAEAGLLayer class]; 
} 

- (id)initWithFrame:(CGRect)frame { 
    if ((self = [super initWithFrame:frame])) { 
     CAEAGLLayer* eaglLayer = (CAEAGLLayer*) super.layer; 
     eaglLayer.opaque = YES; 

     m_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; 

     if (!m_context || ![EAGLContext setCurrentContext:m_context]) { 
      [self release]; 
      return nil; 
     } 

     // OpenGL Initialization 
     GLuint framebuffer, renderbuffer; 
     glGenFramebuffersOES(1, &framebuffer); 
     glGenFramebuffersOES(1, &renderbuffer); 

     [m_context 
     renderbufferStorage:GL_RENDERBUFFER_OES 
     fromDrawable: eaglLayer]; 

     glFramebufferRenderbufferOES(
            GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, 
            GL_RENDERBUFFER_OES, renderbuffer); 

     glViewport(0, 0, CGRectGetWidth(frame), CGRectGetHeight(frame)); 

     [self drawView]; 
    } 
    return self; 
} 

- (void)dealloc { 
    if ([EAGLContext currentContext] == m_context) { 
     [EAGLContext setCurrentContext:nil]; 
    } 

    [m_context release]; 
    [super dealloc]; 
} 

@end 
+0

Je ne sais pas si cela est un problème, mais il semble étrange que vous dessiniez avant que la vue ne soit attachée à la fenêtre. Que se passe-t-il si vous ajoutez ce qui suit à la fin de l'application: didFinishLaunchingWithOptions: call? '[m_view performSelector: @selector (drawView) withObject: nil afterDelay: 0.0];' –

Répondre

2

Le paramètre initWithFrame est incorrect. Vous voulez générer un framebuffer et un renderbuffer et lier les deux. Au lieu de cela, vous générez deux framebuffers et en ignorez complètement un. Vous devriez également conserver les références (les «rendererbuffer» et «framebuffer» des variables) dans votre classe, car vous devrez les supprimer plus tard, sauf si vous voulez perdre de la mémoire.

Sans fixer la deuxième question, je vous recommande:

- (id)initWithFrame:(CGRect)frame { 
    if ((self = [super initWithFrame:frame])) { 
     CAEAGLLayer* eaglLayer = (CAEAGLLayer*) super.layer; 
       eaglLayer.opaque = YES; 

     m_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; 

       if (!m_context || ![EAGLContext setCurrentContext:m_context]) { 
           [self release]; 
               return nil; 
       } 

     // these should be in the class so that we can release them later, 
     // this will leak resources 
     GLuint framebuffer, renderbuffer; 

     // generate and bind a framebuffer 
     glGenFramebuffersOES(1, &framebuffer); 
     glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer); 

     // generate a colour renderbuffer; this example doesn't seem to want 
     // e.g. a depth buffer, but if it did then you'd generate and add one 
     // of those here also 

     // generate and bind 
     glGenRenderbuffersOES(1, &renderbuffer); 
     glBindRenderbufferOES(GL_RENDERBUFFER_OES, renderbuffer); 

     // get storage from the layer 
     [m_context 
     renderbufferStorage:GL_RENDERBUFFER_OES 
     fromDrawable: eaglLayer]; 

     // link to the framebuffer 
     glFramebufferRenderbufferOES(
                                 GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, 
                                 GL_RENDERBUFFER_OES, renderbuffer); 

     glViewport(0, 0, CGRectGetWidth(frame), CGRectGetHeight(frame)); 

     [self drawView]; 
    } 
    return self; 
} 

Put framebuffer et renderbuffer quelque part vous pouvez obtenir à eux à nouveau au moment pertinent et vous devez également:

- (void)dealloc { 

    if(renderbuffer) glDeleteRenderbuffersOES(1, &renderbuffer); 
    if(framebuffer) glDeleteFramebuffersOES(1, &framebuffer); 

    if ([EAGLContext currentContext] == m_context) { 
       [EAGLContext setCurrentContext:nil]; 
    } 

    [m_context release]; 
    [super dealloc]; 
} 

J'ai testé cela par rapport au code que vous fournissez. Je reçois l'écran gris.Changer l'appel de glClearColor change la couleur de l'écran, donc le contexte GL fonctionne clairement.

0

whithout code qu'il peut être difficile de vous dire lol

votre fenêtre grise vient de

(void) drawView 
{ 
    glClearColor(0.5f, 0.5f, 0.5f, 1); 
    glClear(GL_COLOR_BUFFER_BIT); 

    [m_context presentRenderbuffer:GL_RENDERBUFFER_OES]; 
} 

vérifier que ce qu'on appelle correclty

+0

J'ai vérifié et il est appelé. –

0

La cause la plus probable est que vous avez manqué quelque chose en suivant le tutoriel. Ou ils se sont trompés. Quelle est la plus probable :-)

Donc la prochaine étape est de déboguer et de comprendre ce qui s'est mal passé. Surtout que vous avez probablement manqué une ligne de code qui ajoute des choses à l'affichage. Je regarderais d'abord dans cette section de votre code et le comparerais au tutoriel.

Si cela ne fonctionne pas, je prendrais une copie de votre code comme sauvegarde, puis je commencerais à supprimer les données jusqu'à ce que vous ayez la quantité minimale de code. Ensuite, postez ça ici. Sans code, nous ne pouvons pas vous dire ce qui ne va pas.

+0

J'ai ajouté le code. Je n'ai rien remarqué de manquant. –

0

Je vais essayer d'ajouter ce qui suit à votre code ci-dessus:

- (id)initWithFrame:(CGRect)frame { 
    if ((self = [super initWithFrame:frame])) { 
     CAEAGLLayer* eaglLayer = (CAEAGLLayer*) super.layer; 
     eaglLayer.opaque = YES; 
     eaglLayer.drawableProperties = 
     [NSDictionary dictionaryWithObjectsAndKeys: 
      [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, 
      kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; 


... 
} 

Dans le code, je l'utilise, je définir un drawableProperties mais vous semblez le manquer.

1

J'ai rencontré ce problème et je l'ai corrigé dans mon cas en m'assurant que la classe de calque était implémentée juste après la ligne @implementation.

@implementation GLView 

+ (Class) layerClass 
{ 
    return [CAEAGLLayer class]; 
} 
1

J'ai obtenu le fond gris en se débarrassant de la ligne

m_window = [[UIWindow alloc] initWithFrame: screenBounds]; 

en application: didFinishLaunchingWithOptions: méthode dans le fichier HelloArrowAppDelegate.h