2011-07-14 49 views
1

我使用OpenGL框架下準備塗料中的應用,我被困在撤銷/重做選項.. 我實現的代碼是這樣的:撤消在塗料中的應用繪圖

-(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..Can任何先前的圖像幫助我如何存儲圖像緩衝區檢索UNDO?我試圖找到它的示例代碼,但無法找到..

謝謝..

回答

1

確定的最佳途徑。我在我自己的問題中發佈了答案,因爲很多人似乎都提到了這個問題。

有一個名爲的應用程序TouchPainter及其source code可用。它包含了素描,色彩調和,撤銷/重做(驚人的.. !!),保存/打開圖紙..

注:可能需要的目標C設計模式非常深層次的知識(我仍然不知道什麼樣的設計模式,但我發現它,所以我分享..)。整個應用程序的源代碼在本書「適用於iOS的Apress.Pro Objective-C設計模式」中進行了解釋。

我希望這將有助於你.. :)祝你好運..

+0

TouchPainter不是基於OpenGL ES的繪圖應用程序。檢查兩次。 – BigAppleBump

+0

+1 TouchPainter的參考對我很有幫助。謝謝。 – Mustafa

+1

@Mustafa:謝謝..一般來說,它只是一個不好的主意,只是提供了答案中的鏈接,但幾個月後我沒有得到任何正確的答案,並且遇到了這個應用程序示例代碼,所以我想我應該只是發佈鏈接,以便訪問者至少得到正確的方向.. :-)) –

-1

使用nsundomanager,即撤消

+0

你肯定會與OpenGL的工作嗎?我不認爲所以。 –

+2

NSUndoManager並不神奇 - 它可以幫助您管理撤銷狀態,但在您的模型中實際執行撤消操作仍然取決於您。 – duskwuff

+0

有人告訴我使用它的命令模式..該方法是否有用? –

0
 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]; 
      } 
     }