(也在Apple Developer论坛上提问)
我似乎有OpenGL的渲染问题。当用户在屏幕上追踪他的手指时,我的应用程序应绘制一条线。因此,touchesMoved调用下面的draw函数并传递包含点数据的NSMutableArray currentStroke。
我遇到的问题是为每一行绘制的最后一个三角形(每行以touchesEnded结尾)闪烁。我认为它与渲染缓冲区有关...如果我从touchesEnded调用两次draw函数,则闪烁消失。我只是认为这是一个非常非常严格的解决方案。任何人都知道什么可能导致闪烁和解决方案?
- (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 :(得分:1)
与问题没有直接关系,但是每次画画都会加载图片,不是吗? (或者可能不是,但我对Objective-c的语法感到困惑)如果你这样做,那不是一件好事。特别是initWithData:texData和glTexImage2D只能在draw()之外完成一次。
对于闪烁,它通常是双缓冲问题,但在iPhone上它始终是双缓冲区。
我认为你应该在实际的绘制调用之前调用glBindRenderbufferOES。
答案 1 :(得分:1)
for (int i=0; i<([currentStroke count]-1); i++)
vertices[2] = [[currentStroke objectAtIndex:i+1] CGPointValue].x;
所以你访问[currentStroke count] -1 + 1 - &gt;出界 for(int i = 0; i&lt;([currentStroke count] -2); i ++),并确保计数&gt; 2 ...
答案 2 :(得分:0)
当我想出来时应该发布这个,但迟到总比没有好。通过将kEAGLDrawablePropertyRetainedBacking设置为true,它会停止闪烁。当我刚刚使用glClear()一次(必须使用它两次)时,应用程序也闪烁,但设置保留的背景属性也固定了这一点。我还不完全确定闪烁发生的原因。这显然是一个双重缓冲问题,因为它在每一个框架上都闪烁着。