2010-08-26 6 views
0

(également demandé sur les forums Apple Developer)Problème de rendu OpenGL

Je semble avoir un problème de rendu avec OpenGL. Mon application est censée tracer une ligne lorsque l'utilisateur trace son doigt sur l'écran. Ainsi, touchesMouvements appelle la fonction dessiner ci-dessous et transmet une requête currentStroke NSMutableArray qui contient des données ponctuelles.

Le problème que je rencontre est que le dernier triangle dessiné pour chaque ligne (chaque ligne se termine avec des touches effacées) scintille. Je pense que cela a à voir avec le tampon de rendu ... Si j'appelle deux fois la fonction draw de touchesEnded, le scintillement disparaît. Je pense juste que c'est une solution très, très jimmy-truquée. Quelqu'un a une idée de ce qui pourrait causer le scintillement et une solution?

- (void)draw { 

glLoadIdentity(); 

//Configuring OpenGL 
glEnable(GL_TEXTURE_2D); 
glEnable(GL_BLEND); 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 



//Texture Loading 
GLuint  texture[1]; 
glGenTextures(1, &texture[0]); 
glBindTexture(GL_TEXTURE_2D, texture[0]); 

//Configuring Image for OpenGL Texture: Switch off mipmap; Set linear scaling 
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 

//Set image to texture 
NSString *path = [[NSBundle mainBundle] pathForResource:@"at2" ofType:@"png"]; 
    NSData *texData = [[NSData alloc] initWithContentsOfFile:path]; 
    UIImage *image = [[UIImage alloc] initWithData:texData]; 
    if (image == nil) 
     NSLog(@"No Image"); 

    GLuint width = CGImageGetWidth(image.CGImage); 
    GLuint height = CGImageGetHeight(image.CGImage); 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    void *imageData = malloc(height * width * 4); 
    CGContextRef context2 = CGBitmapContextCreate(imageData, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedLast |kCGBitmapByteOrder32Big); 
    CGColorSpaceRelease(colorSpace); 
    CGContextClearRect(context2, CGRectMake(0, 0, width, height)); 
    CGContextTranslateCTM(context2, 0, height - height); 
    CGContextDrawImage(context2, CGRectMake(0, 0, width, height), image.CGImage); 

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData); 

    CGContextRelease(context2); 

    free(imageData); 
    [image release]; 
    [texData release]; 

static const GLfloat texCoords[] = { 
     0.0, 1.0, 
     1.0, 1.0, 
     1.0, 0.0, 
     0.0, 0.0 
}; 




glEnableClientState(GL_VERTEX_ARRAY); 
glEnableClientState(GL_NORMAL_ARRAY); 
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

GLfloat vertices[8]; 
GLfloat xadjust; 
GLfloat yadjust; 

//Iterate through points and create triangles 

if ((currentStroke != nil) && ([currentStroke count] > 1)) { 

    for (int i=0; i<([currentStroke count]-1); i++) { 
    vertices[0] = [[currentStroke objectAtIndex:i] CGPointValue].x; 
    vertices[1] = self.frame.size.height - [[currentStroke objectAtIndex:i] CGPointValue].y; 
    vertices[2] = [[currentStroke objectAtIndex:i+1] CGPointValue].x; 
    vertices[3] = self.frame.size.height - [[currentStroke objectAtIndex:i+1] CGPointValue].y; 

    //Minimum width of triangle 
    xadjust = -4; 


    //Minimum height of triangle, increase of y aspect of triangle is short 
    if ((vertices[3]-vertices[1])<1&&(vertices[3]-vertices[1])>=0) { 
     yadjust = 2; 
    } else if ((vertices[3]-vertices[1])>-1&&(vertices[3]-vertices[1])<=0){ 
     yadjust = -3; 
    } else { 
     yadjust = 2; 
    } 

    vertices[4] = [[currentStroke objectAtIndex:i] CGPointValue].x+xadjust; 
    vertices[5] = self.frame.size.height - [[currentStroke objectAtIndex:i] CGPointValue].y+yadjust; 
    vertices[6] = [[currentStroke objectAtIndex:i+1] CGPointValue].x+xadjust; 
    vertices[7] = self.frame.size.height - [[currentStroke objectAtIndex:i+1] CGPointValue].y+yadjust; 

    glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 

    glVertexPointer(2, GL_FLOAT, 0, vertices); 

    glEnableClientState(GL_VERTEX_ARRAY); 

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 


    } 




    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); 
    [context presentRenderbuffer:GL_RENDERBUFFER_OES]; 


    glDisable(GL_BLEND); 
    glDisableClientState(GL_VERTEX_ARRAY); 
    glDisableClientState(GL_NORMAL_ARRAY); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

} 

Répondre

0

J'aurais dû poster ceci quand je l'ai compris, mais mieux vaut tard que jamais. En définissant kEAGLDrawablePropertyRetainedBacking sur true, il a cessé de clignoter. L'application a également clignoté lorsque j'ai simplement utilisé glClear() une fois (je devais l'utiliser deux fois), mais la définition de la propriété d'arrière-plan retenue a également corrigé ce problème. Je ne suis toujours pas tout à fait sûr pourquoi le scintillement est arrivé. Il s'agissait évidemment d'un problème de double tampon car il clignotait sur toutes les autres images.

1

Non directement liée à la question, mais vous chargez l'image à chaque fois que vous dessinez, n'est-ce pas? (ou peut-être pas, mais je suis intrigué par la syntaxe de l'objectif-c) Si vous le faites, ce n'est pas une bonne chose. Particulièrement initWithData: texData et glTexImage2D devraient être faits une seule fois, en dehors de draw(). Pour le scintillement, il s'agit généralement d'un problème de double tampon, mais sur l'iPhone, il s'agit toujours d'un double tampon.

Je pense que vous devriez appeler glBindRenderbufferOES avant les appels de tirage réels, cependant.

+0

Oh, je l'ai déplacé dans la méthode de dessin pour le contrôle d'erreur précédent et j'ai oublié de le déplacer. J'étais inquiet que ce soit un problème de texture au début. Le chargement de l'image a lieu avant la création initiale de la page. J'ai essayé de lancer le glBindRenderbufferOES avant les appels et ça n'a pas l'air de faire quoi que ce soit ... – Beaker

1

oh, je pense que je l'ai eu.

for (int i=0; i<([currentStroke count]-1); i++) 
    vertices[2] = [[currentStroke objectAtIndex:i+1] CGPointValue].x; 

donc vous accès [count currentStroke] -1 +1 -> hors limites for (int i = 0; i < ([currentStroke count] -2); i ++), et assurez-vous que le nombre> 2 ...

+0

Ah, une bonne trouvaille! ... mais ne l'a pas réparé – Beaker