I'm trying to make simple paint application, based on Apple's GLPaint. To draw a line, GLPaint draws an array of points with brush texture. With blending in OpenGL turned on, every point of that line with alpha less than 1 is blended with previous ones. I want to avoid this. For example, you set red color to brush and alpha to 0.5, draw a line and all the line is single-color - red with alpha 0.5, without self crossings... I can't explain clear, but I hope you've understood me))
So, first question is how can I do this?
I've decided to draw current line to texture, without blending, and then put over current image. The code is:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
CGRect bounds = [mainView bounds];
UITouch* touch = [[event touchesForView:mainView] anyObject];
firstTouch = YES; location = [touch locationInView:mainView];
location.y = bounds.size.height - location.y;
// Offscreen buffer
glGenRenderbuffersOES(1, &brushFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER_OES, brushFramebuffer);
glGenRenderbuffers(1, &brushDepthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, brushDepthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rushDepthBuffer);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(status != GL_FRAMEBUFFER_COMPLETE) {
NSLog(@"failed to make complete framebuffer object %x", status);
return;
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
CGRect bounds = [mainView bounds];
UITouch* touch = [[event touchesForView:mainView] anyObject];
if (firstTouch) {
firstTouch = NO;
previousLocation = [touch locationInView:mainView];
previousLocation.y = bounds.size.height - previousLocation.y;
}
else {
location = [touch locationInView:mainView];
location.y = bounds.size.height - location.y;
previousLocation = [touch previousLocationInView:mainView];
previousLocation.y = bounds.size.height - previousLocation.y;
}
[self renderLineFromPoint:previousLocation toPoint:location];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
CGRect bounds = [mainView bounds];
UITouch* touch = [[event touchesForView:mainView] anyObject];
if (firstTouch) {
firstTouch = NO;
previousLocation = [touch previousLocationInView:mainView];
previousLocation.y = bounds.size.height - previousLocation.y;
[self renderLineFromPoint:previousLocation toPoint:location];
}
// getting texture from buffer
glBindTexture(GL_TEXTURE_2D, bufferTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 768, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, bufferTexture, 0);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
// drawing texture to image
CGFloat vertices[] = {backingWidth/2, backingHeight/2};
glVertexPointer(2, GL_FLOAT, 0, vertices);
glDrawArrays(GL_POINTS, 0, 1);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
- (void) renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end {
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, brushFramebuffer);
glBindTexture(GL_TEXTURE_2D, brushTexture);
/// .... then drawing a line from "start" to "end"
}
The second question is: this code draws only draws brush texture to the center of screen, what am I doing wrong?