Я пытаюсь сделать простое приложение для рисования на основе Apple GLPaint. Чтобы нарисовать линию, GLPaint рисует массив точек с текстурой кисти. При включенном смешивании в OpenGL каждая точка этой строки с альфа-каналом меньше 1 смешивается с предыдущими. Я хочу этого избежать. Например, вы устанавливаете красный цвет для кисти и альфа на 0,5, рисуете линию, и вся линия одноцветная - красная с альфа 0,5, без самопересечений ... Я не могу объяснить, ясно, но я надеюсь, что вы меня понял))
Итак, первый вопрос: как я могу это сделать?
Я решил нарисовать текущую линию текстуры без смешивания, а затем наложить поверх текущего изображения. Код такой:
- (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"
}
Второй вопрос: этот код рисует только текстуру кисти в центре экрана, что я делаю не так?