Undo drawing in Paint Application

时光怂恿深爱的人放手 提交于 2019-12-24 10:35:52

问题


I am making a paint application using OpenGl framework and I'm stuck at UNDO/REDO option.. The code I implemented is like this:

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

 }

This code is not efficient and it has so many faults..Have a look at images before and After Undo.

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

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

So i want to Save image in buffer every time user's Touch ends and call previous image on UNDO..Can anyone help me how to Store image in buffer and retrieve back on UNDO?? I tried to find its sample code but could not find..

Thanks..


回答1:


Ok. I am posting answer to my own Question as so many people seem to refer this question.

There is an application named TouchPainter and its source code is available. It contains drawing, color blending, Undo/Redo (Amazing..!!), Save/Open drawings..

Note : It may require very deep level knowledge of Objective C and design pattern (I still do not know what design pattern is. But I found it so I am sharing..). The whole application's source code is explained in this book "Apress.Pro Objective-C Design Patterns for iOS".

I hope it will be helpful to you.. :) Good luck..




回答2:


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



回答3:


use the nsundomanager, that is the best way to undo



来源:https://stackoverflow.com/questions/6689600/undo-drawing-in-paint-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!