Objective c 撤消使用不同颜色的笔划

Objective c 撤消使用不同颜色的笔划,objective-c,opengl-es,Objective C,Opengl Es,我正在处理一个基本iOS绘画应用程序的撤销功能。当我只使用一种颜色绘制笔划时,正常的撤消没有问题,但是当我使用不同的颜色时,总是使用最后一种笔划颜色渲染所有笔划 为了实现这一点,我将包含点数组和笔划颜色的自定义对象存储在撤消数组中,最后在移除最后一个对象并清除屏幕后再次绘制 这是密码 - (void)undo { static GLfloat* vertexBuffer = NULL; static NSUInteger vertexMax = 64; NSUInteger

我正在处理一个基本iOS绘画应用程序的撤销功能。当我只使用一种颜色绘制笔划时,正常的撤消没有问题,但是当我使用不同的颜色时,总是使用最后一种笔划颜色渲染所有笔划

为了实现这一点,我将包含点数组和笔划颜色的自定义对象存储在撤消数组中,最后在移除最后一个对象并清除屏幕后再次绘制

这是密码

- (void)undo { 
static GLfloat*     vertexBuffer = NULL;
static NSUInteger   vertexMax = 64;
NSUInteger          vertexCount = 0, count, i; 
CGFloat oldRed = self.red;
CGFloat oldGreen = self.green;
CGFloat oldBlue = self.blue;

if (self.undoBuffer.count > 0)
{
    TEUndoStroke *undoStroke = [self.undoBuffer lastObject];
    if (!self.redoBuffer)
        self.redoBuffer = [NSMutableArray array];
    [self.redoBuffer addObject:undoStroke];

    [self.undoBuffer removeLastObject];

    [EAGLContext setCurrentContext:context];
    glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);

    for (TEUndoStroke *_stroke in self.undoBuffer)
    {
        //Aplicamos el color que tenia
        NSLog(@"R: %f G: %f B: %f", _stroke.red, _stroke.green, _stroke.blue);
        [self setBrushColorWithRed:_stroke.red green:_stroke.green blue:_stroke.blue];

        for (int k = 1; k < _stroke.arrayStrokes.count; k++)
        {
            CGPoint start = [[_stroke.arrayStrokes objectAtIndex:k-1] CGPointValue];
            CGPoint end = [[_stroke.arrayStrokes objectAtIndex:k] CGPointValue];

            glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);

            // Convert locations from Points to Pixels
            CGFloat scale = self.contentScaleFactor;
            start.x *= scale;
            start.y *= scale;
            end.x *= scale;
            end.y *= scale;

            // Allocate vertex array buffer
            if(vertexBuffer == NULL)
                vertexBuffer = malloc(vertexMax * 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 == vertexMax) {
                    vertexMax = 2 * vertexMax;
                    vertexBuffer = realloc(vertexBuffer, vertexMax * 2 * sizeof(GLfloat));
                }

                vertexBuffer[2 * vertexCount + 0] = start.x + (end.x - start.x) * ((GLfloat)i / (GLfloat)count);
                vertexBuffer[2 * vertexCount + 1] = start.y + (end.y - start.y) * ((GLfloat)i / (GLfloat)count);
                vertexCount += 1;
            }

        }

    }

    //Render everithing at last to avoid blinking.

    glEnableVertexAttribArray(ATTRIB_VERTEX);
    glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, 0);

    // Draw
    glUseProgram(program[PROGRAM_POINT].id);
    glDrawArrays(GL_POINTS, 0, vertexCount);

    // Load data to the Vertex Buffer Object
    glBindBuffer(GL_ARRAY_BUFFER, vboId);
    glBufferData(GL_ARRAY_BUFFER, vertexCount*2*sizeof(GLfloat), vertexBuffer, GL_DYNAMIC_DRAW);

    // Display the buffer
    glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER];

}

[self setBrushColorWithRed:oldRed green:oldGreen blue:oldBlue];
}
例如,如果我画三个字母:

红色的R 绿色的G B是蓝色的


我按下撤销按钮,字母“B”消失了,但R和G都是绿色的。

最后我发现了问题。似乎变量声明应该在绘制线内逐点进行

这就是密码

- (void)undo
{
    if (self.undoBuffer.count > 0)
    {
    TEUndoStroke *undoStroke = [self.undoBuffer lastObject];
    if (!self.redoBuffer)
        self.redoBuffer = [NSMutableArray array];
    [self.redoBuffer addObject:undoStroke];

    [self.undoBuffer removeLastObject];

    [EAGLContext setCurrentContext:context];
    glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);

    for (TEUndoStroke *_stroke in self.undoBuffer)
    {
        for (int k = 1; k < _stroke.arrayStrokes.count; k++)
        {
            CGPoint start = [[_stroke.arrayStrokes objectAtIndex:k-1] CGPointValue];
            CGPoint end = [[_stroke.arrayStrokes objectAtIndex:k] CGPointValue];

            static GLfloat*     vertexBuffer = NULL;
            static NSUInteger   vertexMax = 64;
            NSUInteger          vertexCount = 0,
            count,
            i;

            [EAGLContext setCurrentContext:context];
            glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);

            // Convert locations from Points to Pixels
            CGFloat scale = self.contentScaleFactor;
            start.x *= scale;
            start.y *= scale;
            end.x *= scale;
            end.y *= scale;

            // Allocate vertex array buffer
            if(vertexBuffer == NULL)
                vertexBuffer = malloc(vertexMax * 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 == vertexMax) {
                    vertexMax = 2 * vertexMax;
                    vertexBuffer = realloc(vertexBuffer, vertexMax * 2 * sizeof(GLfloat));
                }

                vertexBuffer[2 * vertexCount + 0] = start.x + (end.x - start.x) * ((GLfloat)i / (GLfloat)count);
                vertexBuffer[2 * vertexCount + 1] = start.y + (end.y - start.y) * ((GLfloat)i / (GLfloat)count);
                vertexCount += 1;
            }

            CGFloat _strokeColor[4];

            _strokeColor[0] = _stroke.red * kBrushOpacity;
            _strokeColor[1] = _stroke.green * kBrushOpacity;
            _strokeColor[2] = _stroke.blue * kBrushOpacity;
            _strokeColor[3] = kBrushOpacity;

            if (initialized) {
                glUseProgram(program[PROGRAM_POINT].id);
                glUniform4fv(program[PROGRAM_POINT].uniform[UNIFORM_VERTEX_COLOR], 1, _strokeColor);
            }

            // Load data to the Vertex Buffer Object
            glBindBuffer(GL_ARRAY_BUFFER, vboId);
            glBufferData(GL_ARRAY_BUFFER, vertexCount*2*sizeof(GLfloat), vertexBuffer, GL_DYNAMIC_DRAW);

            glEnableVertexAttribArray(ATTRIB_VERTEX);
            glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, 0);

            // Draw
            glUseProgram(program[PROGRAM_POINT].id);
            glDrawArrays(GL_POINTS, 0, vertexCount);

        }

    }

    // Display the buffer
    glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER];

}
-(无效)撤消
{
如果(self.undoBuffer.count>0)
{
TEUndoStroke*undoStroke=[self.undoBuffer lastObject];
if(!self.redoBuffer)
self.redoBuffer=[NSMutableArray];
[self.redoBuffer addObject:undoStroke];
[self.undobffer removeLastObject];
[EagleContext setCurrentContext:context];
glBindFramebuffer(GL_FRAMEBUFFER,viewFramebuffer);
glClearColor(1.0,1.0,1.0,0.0);
glClear(GLU颜色缓冲位);
用于(TEUNDOSTROW*(自缓冲区中的U笔划)
{
对于(int k=1;k<_stroke.arrayStrokes.count;k++)
{
CGPoint start=[[u stroke.arrayStrokes objectAtIndex:k-1]CGPointValue];
CGPoint end=[[u stroke.arrayStrokes objectAtIndex:k]CGPointValue];
静态GLfloat*vertexBuffer=NULL;
静态整数vertexMax=64;
NSU整数vertexCount=0,
计数
我
[EagleContext setCurrentContext:context];
glBindFramebuffer(GL_FRAMEBUFFER,viewFramebuffer);
//将位置从点转换为像素
CGFloat scale=self.contentScaleFactor;
start.x*=刻度;
start.y*=刻度;
end.x*=刻度;
结束。y*=刻度;
//分配顶点数组缓冲区
if(vertexBuffer==NULL)
vertexBuffer=malloc(vertexMax*2*sizeof(GLfloat));
//向缓冲区添加点,以便每X像素有一个绘图点
计数=最大值(ceilf(sqrtf((end.x-start.x)*(end.x-start.x)+(end.y-start.y)*(end.y-start.y))/kBrushPixelStep),1);
对于(i=0;i

}

你的问题令人困惑。你想把所有的东西都漆成一种颜色吗?还是所有东西都是同一颜色的事实是你的问题?请澄清你的问题,并提出具体问题。问题是,所有东西都重新涂上了相同的颜色,即最后一笔的颜色。
- (void)undo
{
    if (self.undoBuffer.count > 0)
    {
    TEUndoStroke *undoStroke = [self.undoBuffer lastObject];
    if (!self.redoBuffer)
        self.redoBuffer = [NSMutableArray array];
    [self.redoBuffer addObject:undoStroke];

    [self.undoBuffer removeLastObject];

    [EAGLContext setCurrentContext:context];
    glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);

    for (TEUndoStroke *_stroke in self.undoBuffer)
    {
        for (int k = 1; k < _stroke.arrayStrokes.count; k++)
        {
            CGPoint start = [[_stroke.arrayStrokes objectAtIndex:k-1] CGPointValue];
            CGPoint end = [[_stroke.arrayStrokes objectAtIndex:k] CGPointValue];

            static GLfloat*     vertexBuffer = NULL;
            static NSUInteger   vertexMax = 64;
            NSUInteger          vertexCount = 0,
            count,
            i;

            [EAGLContext setCurrentContext:context];
            glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);

            // Convert locations from Points to Pixels
            CGFloat scale = self.contentScaleFactor;
            start.x *= scale;
            start.y *= scale;
            end.x *= scale;
            end.y *= scale;

            // Allocate vertex array buffer
            if(vertexBuffer == NULL)
                vertexBuffer = malloc(vertexMax * 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 == vertexMax) {
                    vertexMax = 2 * vertexMax;
                    vertexBuffer = realloc(vertexBuffer, vertexMax * 2 * sizeof(GLfloat));
                }

                vertexBuffer[2 * vertexCount + 0] = start.x + (end.x - start.x) * ((GLfloat)i / (GLfloat)count);
                vertexBuffer[2 * vertexCount + 1] = start.y + (end.y - start.y) * ((GLfloat)i / (GLfloat)count);
                vertexCount += 1;
            }

            CGFloat _strokeColor[4];

            _strokeColor[0] = _stroke.red * kBrushOpacity;
            _strokeColor[1] = _stroke.green * kBrushOpacity;
            _strokeColor[2] = _stroke.blue * kBrushOpacity;
            _strokeColor[3] = kBrushOpacity;

            if (initialized) {
                glUseProgram(program[PROGRAM_POINT].id);
                glUniform4fv(program[PROGRAM_POINT].uniform[UNIFORM_VERTEX_COLOR], 1, _strokeColor);
            }

            // Load data to the Vertex Buffer Object
            glBindBuffer(GL_ARRAY_BUFFER, vboId);
            glBufferData(GL_ARRAY_BUFFER, vertexCount*2*sizeof(GLfloat), vertexBuffer, GL_DYNAMIC_DRAW);

            glEnableVertexAttribArray(ATTRIB_VERTEX);
            glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, 0);

            // Draw
            glUseProgram(program[PROGRAM_POINT].id);
            glDrawArrays(GL_POINTS, 0, vertexCount);

        }

    }

    // Display the buffer
    glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER];

}