2010-11-05 7 views
0

J'ai une question générale sur la façon dont CAOpenGLLayer fonctionne sous Mac OS X. Est-il possible d'attirer OpenGL dans un lieu autre que dans la méthode -[CAOpenGLLayer drawInCGLContext:] de CAOpenGLLayer?rendu en OpenGL en utilisant CAOpenGLLayer

Je suis en utilisant le code exemple d'Apple CALayerEssentials et juste déplacé le code qui dessine un rectangle drawInCGLContext-redrawGLContent. La méthode redrawGLContent est appelée chaque fois que l'utilisateur clique sur un bouton de la fenêtre OpenGL.
Lorsque le code de dessin est dans drawInCGLContext, il dessine comme prévu, mais lorsque je déplace le code sous redrawGLContent, rien n'est dessiné à la fenêtre OpenGL. J'essaie de comprendre comment ça fonctionne.

-(IBAction)redrawGLContent:(id)sender 
{ 

// This part wass added, but does not draw the rectangle 

    float timeInterval=0; 
    GLfloat rotate = timeInterval * 60.0; // 60 degrees per second! 
    glClear(GL_COLOR_BUFFER_BIT); 
    glMatrixMode(GL_MODELVIEW); 
    glPushMatrix(); 
    glRotatef(rotate, 0.0, 0.0, 1.0); 
    glBegin(GL_QUADS); 
     glColor3f(1.0, 0.0, 0.0); 
     glVertex2f(-0.5, -0.5); 
     glVertex2f(-0.5, 0.5); 
     glVertex2f(0.5, 0.5); 
     glVertex2f(0.5, -0.5); 
    glEnd(); 
    glPopMatrix(); 
// up to here 

    // Just tell the layer to display itself and it will redraw 
    [hostCAOpenGLLayer.layer setNeedsDisplay]; 
} 

-(void)drawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp 
{ 

    // Set the current context to the one given to us. 
    CGLSetCurrentContext(glContext); 


/* This part was removed. When code is here the quad is displayed 

    GLfloat rotate = timeInterval * 60.0; // 60 degrees per second! 
    glClear(GL_COLOR_BUFFER_BIT); 
    glMatrixMode(GL_MODELVIEW); 
    glPushMatrix(); 
    glRotatef(rotate, 0.0, 0.0, 1.0); 
    glBegin(GL_QUADS); 
     glColor3f(1.0, 0.0, 0.0); 
     glVertex2f(-0.5, -0.5); 
     glVertex2f(-0.5, 0.5); 
     glVertex2f(0.5, 0.5); 
     glVertex2f(0.5, -0.5); 
    glEnd(); 
    glPopMatrix(); 
*/  
    // Call super to finalize the drawing. By default all it does is call glFlush(). 
    [super drawInCGLContext:glContext pixelFormat:pixelFormat forLayerTime:timeInterval displayTime:timeStamp]; 
} 
+0

Je remarque que vous n'appelez pas CGLSetCurrentContext dans votre implémentation de redrawGLContent. Êtes-vous sûr que le contexte actuel lors de l'appel est le même que celui passé à drawInCGLContext? – BinaryStar

Répondre

1

Je sais que cette question a été posée il y a un certain temps, mais je pensais y répondre de toute façon pour le bénéfice des autres. Il n'y a rien de pire que de tomber sur une question sur Stack Overflow qui décrit exactement votre problème, mais pour lequel il n'y a pas de réponse ;-)

Je pense que BinaryStar a frappé le clou ici. Votre problème est que vous n'avez pas de contexte GL valide dans lequel dessiner. Lorsque le système appelle drawInCGLContext:pixelFormat:forLayerTime:displayTime:, il vous donne un contexte prêt à être utilisé par votre code.

Par exemple, la fenêtre actuelle aura été définie sur ce contexte afin que vous puissiez dessiner dans vos couches bounds. Au moment où vous appelez votre code personnalisé, vous n'avez aucune garantie que ce contexte a été configuré correctement ou qu'il s'agit même du contexte actuel.

Je pense que l'approche correcte ici serait de définir la propriété asynchrone de CAOpenGLLayer à NO. Ensuite, à partir de votre code de manipulation de bouton, appelez setNeedsDisplay sur le calque.