Drawing with transparency in opengl es 2 - opengl-es

I'm working on a simple drawing application. My line is constructed using polygons and things look good so far. I would like to add a transparency feature and I used glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); for that reason. However, because my polys sometimes overlap, I get the ugly result shown in the picture (multiple layers of transparency). What I would like to get is the figure in the left(no overlapping because there is no transparency), with an overall transparency.
I guess I could do this by keeping the polys from overlaping, but that would be a overkill for this task I think. There should be a way to control them at drawing time, but being a beginner with OpenGL doesn't help.

I'm sorry, but the way transparency works does not allow you to do what you want without manually keeping the polygons from overlapping. The way that transparency works is that it takes the colour of the surface below it, and uses the blending function you specify in order to calculate the final colour of the pixel.
In your program you are drawing multiple polygons with alpha on top of each other. That means that their colours add up, giving the result you see.
I've never actually written a drawing application, but you could perhaps take a look at triangle strips to draw your lines. They allow you to extend the line point by point, and make sure the geometry won't overlap with itself.

Related

Draw the outlines of a 3D model with OpenGL ES

I need to add this classic effect which consist in highlighting a 3D model by stroking the outlines, just like this for example (without the transparent gradiant, just a solid stroke) :
I found a way to do this here which seems pretty simple and easy to implement. The guy is playing with the stencil buffer to compute the model shape, then he's drawing the model using wireframes and the thickness of the lines is doing the job.
This is my problem, the wireframes. I'm using OpenGL ES 2.0, which means I can't use glPolygonMode to change the render mode to GL_LINE.
And I'm stuck here, I can't find any simple alternative way to do it, the most relevant solution i found for the moment is to implement the wireframe rendering myself, which is clearly not the easiest solution. To draw my objects I'm using glDrawElements with GL_TRIANGLES as primitive, I tried to use GL_TRIANGLE_STRIP as primitive but the result is definetely not the right one.
Any idea/trick to bypass the lack of glPolygonMode with OpenGL ES? Thanks in advance.
Drawing Outline or border for a Model in OpenGL ES 2 is not straight forward as the example you have mentioned.
Method 1:
The easiest way is to do it in multiple passes.
Step 1 (Shape Pass): Render only the object and draw it in black using the same camera settings. And draw all other pixels with different color.
Step 2 (Render Pass): This is the usual Render pass, where you actually draw the objects in real color. This every time you a fragment, you have to test the color at the same pixel on the ShapePass image to see if any of the nearby 8 pixels are different in color. If all nearby pixels are of same color, then the fragment does not represent a border, else add some color to draw the border.
Method 2: There are other techniques that can give you similar effects in a single pass. You can draw the same object twice, first time slightly scaled up with a single color, and then with real color.

binary image filter thin continuous line

I have a series of continuous frames which record drawing by pens with real hands.
(Those frames)
What I want to do is reconstruction the drawing strokes.
I want to remove the hand area.
I have thought about its property.
1.The drawing are thin lines.
2.The drawing are continuous.
3.The drawing won't change only if obscured by hands.
So, now I have came up with little idea.
Because I have all the frames already.
For the current frame's black pixel, I will check if afterward frames mostly the pixel is black or not(because sometimes obscured by hands), then I recognize it as drawing strokes.
But the effect isn't good.
I have checked some line detection, edge detection, contour detection but not what I want.
Could you give me some advice or direction?
1.How to extract thin line?
2.How to remove hand area?
Look into the Stroke Width Transform (Stroke Width Transform (SWT) implementation (Java, C#...)). The concept is relatively simple, and the original algorithm has since spun off several variants.
Since you have multiple frames, you could also simply retain any pixels that are present in every frame (starting with the first frame in which a pixel is turned "on"). This might be simpler to implement than the Stroke Width Transform (or related algorithm), but in the long run may not be as robust as you'd like.
The Stroke Width Transform has the advantage of working in natural, complex scenes.

Need line drawing algorithm for simulating natural pencil

I'm writing a drawing program that uses a pressure sensitive table for input. I'd like to be able to simulate the soft pencil effect that many other art programs have (such as Paint Tool SAI, Art Rage). Technique I'm using at the moment is functional, but is missing the cleanness I see in more professional programs.
My algorithm at the moment works like this:
Create a bitmap representing the head of the brush. This is just a transparent bitmap with a black circle drawn on it. The circle has an inner radius that is solid black and an outer radius. The blackness linearly fades from opaque to transparent as you move from the inner to the outer radius.
Capture input events from my tablet. Each point contains an (x, y) coordinate as well as a pressure value
For every point after the first one, draw a line from the previous point to the current one. This is done by drawing (daubing) the brush bitmap several times between the two points. The step size between each daub is chosen so there is an overlap between subsequent daubs.
This works reasonably well, but the result is a line that is somewhat blobby and jagged.
One thing I need to do is somehow smooth out the input points so that the stroke as a whole is smooth.
The other thing I need to do is figure out how to 'drag' the brush head along this path to make the stroke. If the spacing is too far apart, the stroke looks like a line of circles. If too close together, the stroke builds up on itself and becomes very dark. (I tried to fix this by attenuating the brush by the spacing. This does make things more consistent, but stops the stroke from being fully opaque).
Anyhow, I'd expect that there's a lot of research already done on this, if only I knew where to look. Please let me know if there are any better pencil drawing algorithms out there.
Instead of drawing the new circle over what has already been drawn, using the standard blending functions (so that regions of overlap get a higher opacity), you need to keep the maximum opacity so far.
Only after you have built up the complete stroke (as on a white sheet), you can blend it to the existing line art.
The picture illustrates the difference between blending and keeping the maximum opacity.

how to achieve anti-aliasing in perspective mode?

I want to draw some parallel lines. At first I used gl.LINES but the problem was that the rendered line was one pixel wide at any point on the screen, whether it was very close or very far from the camera.
So instead, I rendered thin rectangles:
As you can see, they now get thinner as they get farther from the camera, but now I get all these ugly aliasing artifacts. Is there a "correct" way to do this in OpenGL/WebGL?
There's a couple of ways to tackle this.
(1) As others have mentioned, just run with super or multisampling.
(2) Use a shader. If you are using Es2/WebGL you are doing that already. But instead of outputting a constant color, write a color plus an alpha that determines how close you are to the line. And then enable blending with that alpha.
One very easy way to do this is to just map a texture as an alpha channel on your rectangle.
Alternatively you can draw 2 quads instead of one and compute the distance in the shader. Then map the distance with a ramp function to alpha.
If you're using GLUT, you can try something like this-
glutInitDisplayMode(GLUT_MULTISAMPLE);// along with all the other flags
If you're not using GLUT, then you can find a very helpful topin on the subject here.
Every platform allows you to do multisampling after getting the OpenGL context.

LibGDX - Sprites to texture using FBO

I am working on a simple painting app using LibGDX, and I am having trouble getting it to "paint" properly with the setup I am using. The way I am trying to do this is to draw with sprites, and add these individual sprites into a background texture, using LibGDX's FBO commands, when it is appropriate.
The problem I am having is something relating to blending, in that when the sprites are added to this texture that I am building, any transparent pixels of the sprite that are on top of pixels that have been drawn to previous will be brightened up substantially, which obviously doesn't look very good. The following is what the result looks like, using a circle with a green>red gradient as the "brush". The top row is part of the background texture now, while the bottom one is still in its purely sprite drawn form.
http://i238.photobucket.com/albums/ff307/Muriako/hmm.png
Basically, the transparent areas of each sprite are brightening anything below them, and I need to make them completely transparent. I have messed around with many different blending mode combinations and couldn't find one that was any better. GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA for example did not have this problem, but instead the transparent pixels of each sprite seem to be lowered in alpha and even take on some of the color from the layer below, which seemed even more annoying.
I will be happy to post any code snippets on request, but my code has become a bit of mess since I started trying to fix these problems, so I would rather only put up the necessary bits as necessary.
What order are you drawing the sprites in? Alpha blending only works with respect to pixels already in the target, so you have to draw all alpha-containing things (and everything "behind" them) in Z order to get the right result. I'm using .glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);

Resources