How to XOR the colors under a shape? (SDL2) - sdl

I have an artsy side-project that is running slower than I want it to. Basically, I want to draw a bunch of shapes and colors such that they XOR the shapes and colors that I've already drawn. The program makes things like this:
Which is seven black circles XORed onto the screen.
My method is quite slow, for each pixel, I'm looping through each circle to determine if it should be XORed.
I can draw circles with SDL_gfx, but I can't seem to find a drawing mode that XORs. My current thought process is to use a blending mode that will at least tell me if a specific pixel is odd or even. However, creating an SDL_Texture that can be rendered to ( SDL_TEXTUREACCESS_TARGET ) makes it unable to be directly manipulated ( SDL_TEXTUREACCESS_STREAMING ).
The simple question is, how do I apply a black circle such that it XORs the pixels below it?

I don't think there is a way to do this with SDL_Renderer and still have reasonable performance. You would have to do the work in an SDL_Surface and upload it again.
I wrote SDL_gpu to enable modern graphical effects with a similar style to SDL's built-in render API. This particular effect is trivial in GLSL if you've used it much. If you want to avoid custom shaders, this effect is probably possible with the expanded blend mode options that SDL_gpu has.

Related

Is there a blend mode for drawing "visible" lines?

I'm making a paint-like program. I want to allow users to draw rectangles (selections). Presently, I'm painting the rectangle using white lines. However, if they try drawing one over top a white image, the line won't be visible.
Other programs get around this by using "marching ants" or by using a sort of inverted color so that the line is always visible.
What's the easiest way to achieve this effect in OpenGL?
If relevant, I'm using C# w/ OpenTK + WinForms.
OpenGL can do this, too. Look at the various logic operations offered by OpenGL. Using the XOR logic operation, you'll get a nicely contrasting line.
OpenGL glLogicOp reference
You could draw two rectangles, with colors opposite each other, offset by one pixel from each other. Or you could just use the color they're drawing with (WYSIWYG-style). Drawing a white rectangle atop a white image won't change the image, so why should feedback suggest that it does?

Perfect filled triangle rendering algorithm?

Where can I get an algorithm to render filled triangles? Edit3: I cant use OpenGL for rendering it. I need the per-pixel algorithm for this.
My goal is to render a regular polygon from triangles, so if I use this triangle filling algorithm, the edges from each triangle wouldn't overlap (or make gaps between them), because then it would result into rendering errors if I use for example XOR to render the pixels.
Therefore, the render quality should match to OpenGL rendering, so I should be able to define - for example - a circle with N-vertices, and it would render like a circle with any size correctly; so it doesn't use only integer coordinates to render it like some triangle filling algorithms do.
I would need the ability to control the triangle filling myself: I could add my own logic on how each of the individual pixels would be rendered. So I need the bare code behind the rendering, to have full control on it. It should be efficient enough to draw tens of thousands of triangles without waiting more than a second perhaps. (I'm not sure how fast it can be at best, but I hope it wont take more than 10 seconds).
Preferred language would be C++, but I can convert other languages to my needs.
If there are no free algorithms for this, where can I learn to build one myself, and how hard would that actually be? (me=math noob).
I added OpenGL tag since this is somehow related to it.
Edit2: I tried the algo in here: http://joshbeam.com/articles/triangle_rasterization/ But it seems to be slightly broken, here is a circle with 64 triangles rendered with it:
But if you zoom in, you can see the errors:
Explanation: There is 2 pixels overlapping to the other triangle colors, which should not happen! (or transparency or XOR etc effects will produce bad rendering).
It seems like the errors are more visible on smaller circles. This is not acceptable if I want to have a XOR effect for the pixels.
What can I do to fix these, so it will fill it perfectly without overlapped pixels or gaps?
Edit4: I noticed that rendering very small circles isn't very good. I realised this was because the coordinates were indeed converted to integers. How can I treat the coordinates as floats and make it render the circle precisely and perfectly just like in OpenGL ? Here is example how bad the small circles look like:
Notice how perfect the OpenGL render is! THAT is what I want to achieve, without using OpenGL. NOTE: I dont just want to render perfect circle, but any polygon shape.
There's always the half-space method.
OpenGL uses the GPU to perform this job. This is accelerated in hardware and is called rasterization.
As far as i know the hardware implementation is based on the scan-line algorithm.
This used to be done by creating the outline and then filling in the horizontal lines. See this link for more details - http://joshbeam.com/articles/triangle_rasterization/
Edit: I don't think this will produce the lone pixels you are after, there should be a pixel on every line.
Your problem looks a lot like the problem one has when it comes to triangles sharing the very same edge. What is done by triangles sharing an edge is that one triangle is allowed to conquer the space while the other has to leave it blank.
When doing work with a graphic card usually one gets this behavior by applying a drawing order from left to right while also enabling a z-buffer test or testing if the pixel has ever been drawn. So if a pixel with the very same z-value is already set, changing the pixel is not allowed.
In your example with the circles the line of both neighboring circle segments are not exact. You have to check if the edges are calculated differently and why.
Whenever you draw two different shapes and you see something like that you can either fix your model (so they share all the edge vertexes), go for a z-buffer test or a color test.
You can also minimize the effect by drawing edges using a sub-buffer that has a higher resolution and down-sample it. Since this does not effect the whole area it is more cost effective in terms of space and time when compared to down-sampling the whole scene.

OpenGl Rendering Transparent .png with Random White Pixels

I am working on a game with a friend and we are using openGl, glut, devIL, and c++ to render everything. Simply, Most of the .pngs we are using are rendering properly, but there are random pixels that are showing up as white.
These pixels fall into 2 categories. The first are pixels on the edge of the image. These are resulting from the anti-aliasing going on from photoshop's stroke feature (which i am trying to fix). The second is the more mysterious one. When the enemy is standing still, the texture looks fine, but as soon as it jumps a random white line appears on the top of it.
The line on top is of varying solidity (this shot is not the most solid)
It seems like a blending issue, but I am not as familiar with the way openGl handles the transparency (our code for transparency was learned from the other questions on stack overflow though I couldn't find anything on this issue, however). I am hoping something will fix both issues, but am more worried about the second.
Our current setup code:
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
Transparent areas of a bitmap also have a color. If it is 100% transparent, you usually can't see it. Photoshop usually fills white in these areas.
If you are using minifying or magnifying flags that are not GL_NEAREST, then you will have interpolation. If you interpolate in between two pixels, where one is blue and opaque, and the other is white and transparent, then you will get something that is 50% transparent and light-blue. You may also get the same problem with mimaps, as interpolation is used. If you use mipmaps, one solution is to generate them yourself. That way, you can ignore the transparent areas when doing the interpolations. See some good explanations here: http://answers.unity3d.com/questions/10302/messy-alpha-problem-white-around-edges.html
Why are you using png files? You save some disk space, but need to include complex libraries like devil. You don't save any space in the delivery of an application, as most tools that creates delivery packages have very efficient compression. And you don't save any memory on the GPU, which may be the most critical.
This looks like an artifact in your source PNG. Are you sure there are no such light opaque pixels there?
White line appearing on top could be a UV interpolation error from neighbor texture in your texture atlas (or padding if you pad your NPOT textures to POT with white opaque pixels). Thats why usually you need to pad textures with at least one edge pixel in every direction. That won't help with mipmaps though, as Lars said - you might need to use custom mipmap generation or drop it altogether.

Outline / Silhouette rendering with OpenGL

I know there are several techniques to achieve this, but none of them seems sufficient.
Using a sobel / laplace filter doesn't find all the correct edges (and finds unwanted edges), is slow and doesn't give me control over the outline width.
What i have settled on for now is rendering the backside of my objects first with a solid color and a little bigger than the actual objects. The result does look good, but i really want my outlines to have a constant width.
I already tried rendering the backside of my objects with thick wireframe lines. Gives me a constant outline width, but line width is deprecated, produces rendering artifacts and leaves gaps, if the outline abruptly changes direction (like on a cube for example). I have not yet tried using a third rendering pass drawing a point the size of the wireframe lines for each vertex, because of the other problems with this technique.
Any ideas?
edit I even looked at finding the edges myself using a geometry shader, as described in http://prideout.net/blog/?p=54, but it suffers from the same gaps as the wireframe technique.
edit I was able to get rid of the rendering artifacts with the wireframe technique by disabling the GL_DEPTH_TEST while drawing the outlines. Unfortunately i also lost the outlines on overlapping objects...
My goal is to get the same effect they use on characters in the Dragons Lair 3 game. Does anyone know how they did it?
in case you're after real edge detection, Ive found that you can get pretty good results with a convolution LoG (Laplacian over Gaussian) 5x5 kernel, applied to the depth buffer and blended over the rendered object (possibly with a decent FSAA). You need some tuning in the fragment shader in order to clamp the blended outline, but the results are good. (and its a matter of what you really want, btw)
note that:
1) Laplace filtering and log filtering are different things and produce different results
2) if you apply the convolution on the depth buffer, instead of the rendered image, you end up with totally different results, firthermore, if an outline width conrol is desired, a dilate filter followed by a selective-erode pass can be applied, this way you will end up with a render that closely match a hand drawn sketch made with a marker, and you have fine control over tip size but at the cost of 2 extra pass

How should I do depth independent blending?

I'm working on an OpenGL 3 renderer for a GUI toolkit called Gwen. I nearly have everything working, but I'm having some issues getting everything to blend correctly. I've sorted the triangles by which texture they use and packed them into a VBO, so with the Unit Test, it basically boils down into 3 layers: Filled Rects with no texture, Text, and the windows, buttons, etc that use a skin texture.
The Filled Rects are usually drawn on top of everything else and blended in, but the background behind everything is also a Filled Rect, so I can't count on that. There is a Z-value conflict if you draw them last (ex: the windows have a textured shadow around the edges that turns black because the background fails the depth test) and a blending/z-value conflict if you draw them first (ex: some of the selection highlights get drawn on top of instead of blending like they're supposed to).
I can't count on being able to identify any specific layer except the Filled Rects. The different layers have a mix of z-values, so I can't just draw them in a certain order to make things work. While writing this, I thought of a simple method of drawing the triangles sorted back to front, but it could mean lots of little draw calls, which I'm hoping to avoid. Is there some method that involves some voodoo magic blending that would let me keep my big batches of triangles?
You're drawing a GUI; batching shouldn't be your first priority for the simple fact that a GUI just doesn't do much. A GUI will almost never be your performance bottleneck. This smells of premature optimization; first, get it to work. Then, if it's too slow, make it work faster.
There is no simple mechanism for order-independent transparency. Your best bet is to just render things in the proper Z order.