2010-08-26 2 views
0

(Также на форумах разработчиков Apple)Проблема с OpenGL-рендером

У меня, похоже, проблема с рендерингом с OpenGL. Мое приложение должно нарисовать линию, когда пользователь прослеживает свой палец по экрану. Таким образом, touchMMoved вызывает функцию draw ниже и передает NSMutableArray currentStroke, который содержит данные точки.

Проблема, с которой я сталкиваюсь, заключается в том, что последний треугольник, нарисованный для каждой строки (каждая строка заканчивается на touchesEnded) мерцает. Я думаю, что это связано с буфером рендеринга ... Если я дважды вызову функцию draw из touchEnded, мерцание исчезнет. Я просто думаю, что это очень, очень смелое решение. У кого-нибудь есть представление о том, что может вызвать мерцание и решение?

- (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); 

} 

ответ

0

Должен был опубликовать это, когда я понял, но лучше поздно, чем никогда. Установив kEAGLDrawablePropertyRetainedBacking в true, он перестает мерцать. Приложение также мерцало, когда я только что использовал glClear() один раз (ему пришлось использовать его дважды), но установка сохраненного свойства фона также исправила это. Я все еще не совсем уверен, почему произошло мерцание. Очевидно, это проблема с двойным буфером, поскольку она мелькнула на каждом другом фрейме.

1

Непосредственно связано с вопросом, но вы загружаете изображение каждый раз, когда рисуете, не так ли? (или, может быть, нет, но я озадачен синтаксисом object-c). Если вы это сделаете, это не очень хорошо. Особенно initWithData: texData и glTexImage2D должны выполняться только один раз, вне draw().

Для мерцания это обычно проблема с двойной буферизацией, но на iPhone это всегда двойной буфер.

Я думаю, что вы должны называть glBindRenderbufferOES перед действительными вызовами вызова.

+0

О, я переместил это в метод draw для проверки ошибок предыдущего и забыл его переместить. Я волновался, что это проблема текстуры. Загрузка изображения происходит до начала начальной страницы. Я попытался бросить glBindRenderbufferOES перед вызовами, и он ничего не сделал ... – Beaker

1

О, я так понял.

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

так вы получите доступ [число currentStroke] -1 +1 -> вне границ для (INT I = 0; я < ([currentStroke число] -2); я ++) и убедитесь, что счетчик> 2 ...

+0

А, хорошая находка! ... но не исправил это – Beaker

Смежные вопросы