How can I draw with [UIColor clearColor] in OpenGL ES 1.1? I want to create eraser tool...
You can create a masked image. There are many ways to do this and here is what worked for me:
I created an image that has a black circle and all the rest is transparent. I create a texture from this image and draw it as a simple textured square but using this blend func:
glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
Do not forget to enable blend and after the draw call is done restore your blend func (or disable the blend if you don't use it anywhere else)
Related
I am trying to add basic pressure sensitivity to a drawing app.
I am running into an issue when I try to draw strokes, where the opacity depends on the pressure - the point of overlap of the line segments blends the two lines, which creates darker spots:
This is my code:
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineWidth(context, path.thickness);
CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);
for (Segment *segment in segments) {
CGContextMoveToPoint(context, segment.start.x, segment.start.y);
CGContextAddLineToPoint(context, segment.end.x, segment.end.y);
CGContextSetAlpha(context, segment.alpha);
CGContextStrokePath(context);
}
I want avoid the circles where the line caps meet, but still be able to have transparency over the background.
I have experimented with the context blend modes, but nothing is completely satisfactory - kCGBlendModeDestinationAtop gave me smooth lines, but there is an artifact at the very end of the line and I lose blending with the background.
The banding is not an issue.
In case anyone has the same problem, the way I solved it was to draw the line segments into CGLayer (Core Graphics layer - not Core Animation layer and not Core Graphics Transparency layer).
I set the CGLayer context blend mode to DestinationAtop and then rendered the CGLayer in my real CGContext with normal blending.
Worked like a charm.
Can anyone suggest why my low opacity painting does this weird blending, while the SketchBookX app does it perfect?
In both images attached the vertical strokes on the left are done at full opacity, the strokes on the right are done at low opacity. The top image is mine and as you can see the strokes on the right at low opacity turn a orange-red color and don't blend/mesh with the full opacity strokes. But the SketchBookX app blends perfectly and maintains the same color.
I'm using glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA) and have tried many variations with no luck, so I'm starting to think there are other things that are giving me this problem.
Do I need to handle this problem in the fragment shader? I currently have this,gl_FragColor = color * rotatedTexture; I'm using PNGs for brush textures.
UPDATE: Im getting the same results without using a texture. gl_FragColor = color;
I want it to be like mixing ink, not like mixing light :)
Using OpenGL ES 2.0 on iOS 4.
I have an OpenGL view that inherits from UIView. It is in front of a UIImageView that provides a background.
I have a .png image with transparency that I am using for an OpenGL texture.
The problem I am having is the transparency of the image in the OpenGL view shows through to the image in the UIImageView background. I would like to show content in the OpenGL view that is behind the elements with the transparent texture.
The underneath OpenGL texture is being rendered, but any portion that has the transparent texture on top does not show the underneath OpenGL texture. It shows the UIImageView background.
What do I need to do so that the transparency will show content in the OpenGL view that is behind the transparent content?
EDIT:
I restructured the index array so all elements with transparent textures come at the end and should be rendered after all opaque elements when I call glDrawElements.
Still having the problem with the transparency.
I set up some data so that I have 4 vertices and 6 indices for 2 triangles to draw a square with the opaque texture.
There are also 4 vertices and 6 indices for 2 triangles to draw a square with the transparent texture which come after the other entries in the vertex/index arrays. The transparent element coordinates render it in front of the opaque element.
I can see the transparent element, and I can also see the edges of the opaque element sticking out from behind.
However, instead of showing the opaque element which lies immediately behind the transparent element, the transparency goes right through and shows the background of the view behind the OpenGL view.
Opaque yellow square:
Transparent test image:
The transparent image covers the opaque image but the transparency shows the background not the opaque image behind:
Did you try using some blending? Something like this:
//draw your background scene here
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//draw your foreground scene here
glDisable(GL_BLEND);
-----------------EDIT on comment----------------
So you want to do the blending in fragment shader:
vec4 color1 = texture2D(backgroundTexture, ...);
vec4 color2 = colorYouGetFromSecondaryTextureOrSomeOtherElement;
vec4 outputColor = color1*(1.0-color2.a) + color2*(color2.a);
outputColor.a = 1.0; //or some function of color1.a and color2.a
gl_FragColor = outputColor;
-----------------EDIT 2-------------------------
Also considering your results I would say that you forgot something in your pipeline. You probably use 2 or more textures but only your second is binded resulting in the fragment snippet I posted to be all black but your foreground.. Are you using "active texture"? Something like this:
- (void)bindFirstTexture {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_1D, firstTextureID);
}
- (void)bindSecondTexture {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, secondTextureID);
}
You need such binding in both, before creating and before drawing multiple textures.
I want to draw map overlay with blend mode. But this code just draw white overlay without any blend mode. What I'm doing wrong?
- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
{
UIGraphicsPushContext(context);
CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextSetBlendMode(context, kCGBlendModeSaturation);
CGContextFillRect(context, [self rectForMapRect:mapRect]);
UIGraphicsPopContext();
}
Here is result that I want. I make it in Photoshop with three layers:
original google map.
black layer with saturation blend mode.
white layer with exclusion blend mode.
I would recommend to design your own maps with openstreetmap and a wms server or with a service like mapbox and than add this custom map as overlay.
Here is an example on how to add other maps as overlays: https://github.com/mtigas/iOS-MapLayerDemo
I guess you cannot acces the real mapview context directly. So probably you have to take a "screenshot" of the map and draw it again in your context. After that you can apply your effects of course.
I'm usin GLPaint to paint inside an UIView, but not I want to using an erasing brush.
I know that the code to have a erase brush is:
glBlendFunc(GL_ONE, GL_ZERO);
glColor4f(0, 0, 0, 0.0);
but if I put in my UIView an imageView I want to delete it also...is it possible?
There are several possible ways to do this, but here's what I would try first. Inside your PaintingView, draw a textured quad with the image textured onto it. Then draw a textured quad over that with your paint strokes on it. Set the blending mode to the normal over mode (glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);). Then wherever the source alpha is 0, you'll see the textured quad with the image through it.