2014-02-24 4 views
0

기본 iOS 페인팅 앱의 실행 취소 기능을 다루고 있습니다. 한 색상으로 만 선을 페인트 할 때 정상적인 실행 취소에는 아무런 문제가 없습니다. 그러나 다른 색상을 사용하면 항상 모든 선을 마지막 획 색상으로 렌더링합니다.다른 색상의 획 실행 취소

이 작업을 수행하려면 포인트 배열과 획 색상이 포함 된 마지막으로 개체를 제거하고 화면을 지운 후에 마지막으로 다시 페인팅하는 사용자 정의 개체를 실행 취소 배열에 저장합니다. 녹색 B에 붉은 색으로 G를

R : 여기

내가 세 글자를 그리는 경우가 setBrushColorMethod 예를 들어

- (void)setBrushColorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue 
{ 
    self.red = red; 
    self.green = green; 
    self.blue = blue; 

    // Update the brush color 
    brushColor[0] = red * kBrushOpacity; 
    brushColor[1] = green * kBrushOpacity; 
    brushColor[2] = blue * kBrushOpacity; 
    brushColor[3] = kBrushOpacity; 

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

, 인 코드

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

입니다 푸른 색으로

나는 홍보 취소 버튼을 누르면 문자 "B"가 사라지지만 R과 G는 모두 녹색으로 표시됩니다.

+0

귀하의 질문은 혼란 스럽다. 한 가지 색상으로 모든 것을 다시 칠하고 싶습니까? 아니면 모든 것이 같은 색깔 * 문제 *라는 사실입니까? 질문을 명확히하고 구체적으로 물어보십시오. – insys

+0

문제는 모든 것이 동일한 색, 마지막 칠해진 색의 색으로 다시 칠해진다는 것입니다. – Rotten

답변

0

마침내 문제가 발견되었습니다. 변수 선언은 점선으로 그리는 선 안쪽에 있어야합니다.

그건 코드입니다.

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

} 

}