撤消绘画应用程序中的绘图

我正在使用OpenGl框架进行绘制应用程序,我被卡在UNDO / REDO选项..我实现的代码是这样的:

-(void)undo_called { artbrushAppDelegate *app=(artbrushAppDelegate *)[[UIApplication sharedApplication]delegate]; mbrushscale=app.brushscale; brushimage=app.brush_image; Erase=YES; [self playRayundo]; } -(void)playRayundo { artbrushAppDelegate *app=(artbrushAppDelegate *)[[UIApplication sharedApplication]delegate]; glColor4f(app.r1g, app.b1g, app.g1g, 0); NSLog(@"%f",app.r1g); if(undo != NULL) { for(int l = 0; l < [undo count]; l++) { //replays my writRay -1 because of location point for(int p = 0; p < [[undo objectAtIndex:l]count]-1; p ++) { [self drawErase:[[[undo objectAtIndex:l]objectAtIndex:p]CGPointValue] toPoint:[[[undo objectAtIndex:l]objectAtIndex:p + 1]CGPointValue]]; } } } Erase=NO; glColor4f(app.rg, app.bg, app.gg, kBrushOpacity); } -(void) drawErase:(CGPoint)start toPoint:(CGPoint)end { static GLfloat* eraseBuffer = NULL; static NSUInteger eraseMax = 64; NSUInteger vertexCount = 0, count, i; [EAGLContext setCurrentContext:context]; glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); // Convert locations from Points to Pixels CGFloat scale = 1.0;//self.contentScaleFactor; start.x *= scale; start.y *= scale; end.x *= scale; end.y *= scale; // Allocate vertex array buffer if(eraseBuffer == NULL) eraseBuffer = malloc(eraseMax * 2 * sizeof(GLfloat)); // Add points to the buffer so there are drawing points every X pixels count = MAX(ceilf(sqrtf((end.x - start.x) * (end.x - start.x) + (end.y - start.y) * (end.y - start.y)) / kBrushPixelStep), 1); for(i = 0; i < count; ++i) { if(vertexCount == eraseMax) { eraseMax = 2 * eraseMax; eraseBuffer = realloc(eraseBuffer, eraseMax * 2 * sizeof(GLfloat)); } eraseBuffer[2 * vertexCount + 0] = start.x + (end.x - start.x) * ((GLfloat)i / (GLfloat)count); eraseBuffer[2 * vertexCount + 1] = start.y + (end.y - start.y) * ((GLfloat)i / (GLfloat)count); vertexCount += 1; } [self ChangebrushPic:brushimage]; //the erase brush color is transparent. glEnable(GL_POINT_SPRITE_OES); glTexEnvf(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE); glPointSize(64/mbrushscale); // Render the vertex array glVertexPointer(2, GL_FLOAT, 0, eraseBuffer); glDrawArrays(GL_POINTS, 0, vertexCount); // Display the buffer glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); [context presentRenderbuffer:GL_RENDERBUFFER_OES]; // at last restore the mixed-mode glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } 

这个代码效率不高,而且有太多的错误。看看图像之前和之后的撤销。

之前: http : //imageshack.us/photo/my-images/577/screenshot20110714at121.png/

之后: http : //imageshack.us/photo/my-images/200/screenshot20110714at121.png/

所以我想每次用户的触摸结束时,将图像保存在缓冲区中,并调用UNDO上的前一个图像。任何人都可以帮助我如何将图像存储在缓冲区中,并恢复在UNDO? 我试图find它的示例代码,但无法find..

谢谢..

好。 我发布了自己的问题的答案,因为很多人似乎都提到这个问题。

有一个名为TouchPainter的应用程序,它的源代码是可用的。 它包含绘图,颜色混合,撤消/重做(惊人.. !!),保存/打开图纸..

注意:这可能需要对目标Cdevise模式有非常深入的了解(我仍然不知道devise模式是什么,但是我发现它是我共享的)。 整个应用程序的源代码在本书“iOS的Apress.Pro Objective-Cdevise模式”中进行了解释

我希望这会对你有所帮助.. :)祝你好运..

  Hope this may be help u.. This code for UIBezierPath Drawing. -(void)undoButtonClicked { if([pathArray count]>0){ UIBezierPath *_path = [pathArray lastObject]; [bufferArray addObject:_path]; [bufferColorArray addObject:[PathColorArray lastObject]]; [pathArray removeLastObject]; [PathColorArray removeLastObject]; [bufferDrawType addObject:[pathDrawType lastObject]]; [pathDrawType removeLastObject]; [bufferDrawOpacity addObject:[pathDrawOpacity lastObject]]; [pathDrawOpacity removeLastObject]; [bufferDrawLineWidth addObject:[pathDrawLineWidth lastObject]]; [pathDrawLineWidth removeLastObject]; [self setNeedsDisplay]; } } -(void)redoButtonClicked { if([bufferArray count]>0){ UIBezierPath *_path = [bufferArray lastObject]; [pathArray addObject:_path]; [bufferArray removeLastObject]; [PathColorArray addObject:[bufferColorArray lastObject]]; [bufferColorArray removeLastObject]; [pathDrawType addObject:[bufferDrawType lastObject]]; [bufferDrawType removeLastObject]; [pathDrawOpacity addObject:[bufferDrawOpacity lastObject]]; [bufferDrawOpacity removeLastObject]; [pathDrawLineWidth addObject:[bufferDrawLineWidth lastObject]]; [bufferDrawLineWidth removeLastObject]; [self setNeedsDisplay]; } } 

使用nsundomanager,这是撤消的最好方法