(Also asked on the Apple Developer forums)
I am new to OpenGL, so be kind :). I seem to have a rendering issue with OpenGL. My app is supposed to draw a line as the user traces his finger across the screen. So, touchesMoved calls the draw function below and passes a NSMutableArray currentStroke which contains point data.
The issue I am having is that the last triangle drawn for each line (each line ends with touchesEnded) flickers. I think it has to do with the render buffer... If I call the draw function twice from touchesEnded, the flickering goes away. I just think that is a very, very jimmy-rigged solution. Anyone have an idea of what could cause the flickering and a 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);
}