在GLPaint中使用画笔擦除

时间:2010-10-29 03:40:49

标签: iphone

作为修改GLPaint的一部分,我正在尝试添加擦除功能,用户可以选择橡皮擦按钮并像绘画一样擦除绘制的区域。

我正在尝试在"renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end"方法中使用条件语句,以便我可以检查笔画是用于绘画还是擦除。

对于擦除,我不知道如何使用“start”和“end”参数进行擦除。是否有像glClear()这样的OpenGL方法调用接受这两个参数并擦除?

任何指针都会非常有用。谢谢。

4 个答案:

答案 0 :(得分:10)

Erase using brush in GLPaint一样,您可以重复使用

- (void)renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end 

具有以下条件的方法:

if (isEraserBrushType) {
    glBlendFunc(GL_ONE, GL_ZERO);
    glColor4f(0, 0, 0, 0.0);
} else {
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    [self setBrushColorWithRed:brushColourRed green:brushColourGreen blue:brushColourBlue];
}
代码上方

// Render the vertex array
glVertexPointer(2, GL_FLOAT, 0, eraseBuffer);
glDrawArrays(GL_POINTS, 0, vertexCount);

注意,你需要实现isEraserBrushType,并以某种方式存储brushColourRed,brushColourGreen和brushColourBlue。

答案 1 :(得分:4)

我想我可以解决这个问题,虽然不是很好。

您可以像这样创建“renderLineFromPoint”的新功能副本;

- (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;
    }
    //}
    //glEnable(GL_BLEND);   //   打开混合
        //glDisable(GL_DEPTH_TEST);   //   关闭深度测试
        //glBlendFunc(GL_SRC_ALPHA,   GL_ONE);   //   基于源象素alpha通道值的半透明混合函数 

        //You need set the mixed-mode
    glBlendFunc(GL_ONE, GL_ZERO);
        //the erase brush color  is transparent.
    glColor4f(0, 0, 0, 0.0);

    // 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);
}

我的英语很差。你能理解我说的话吗? 希望这些可以帮助你。

答案 2 :(得分:1)

我试图使用接受的答案,但它会以方形图案擦除,而我想用自己的画笔擦除。相反,我使用了不同的混合功能。

if (self.isErasing) {
    glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
    [self setBrushColorWithRed:0 green:0 blue:0];
} else {
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}

这种方法的工作方式是将传入的(源)颜色乘以以完全消失,这意味着您实际上不会绘制任何新内容。然后目标颜色设置为(1 - 源Alpha)。因此,无论画笔具有颜色,目标都具有 no 颜色。

答案 3 :(得分:-2)

另一个想法,如果你认为你的视图的背景是纯黑色,你可以简单地调用[self setBrushColorWithRed:0.0 green:0.0 blue:0.0]然后调用renderPoint:ToPint: - 这将绘制为黑色(并且用户可能认为他实际上正在擦除。