I have two series of N points I want to graph in two different colors. I can't find anything that explicitly states the best way to go about this simple task when using MFC CDC and CPen objects, and as bunch of CDC::MoveTo/CDC::LineTo calls.
It seems each device context can only have one pen object selected at a time, so am I best to select a pen, draw one line, select another pen, draw the other line... or run through my data once, somehow swapping between pens at each point (either continually selecting each pen, or changing the pen color somehow).
I think your best bet would be to do as you said and draw the first series of N points with the first pen, then select the second pen and draw the second series of N points.
There's no way to change a pen color once you've created it. However you did miss one option, which is to draw all segments of a given color with a pen of that color, then switch pens and draw all segments of the other color. That option may not deliver identical results as the overlap of two segments will depend on which is drawn first.
As unpleasant as it may seem, I think your best option is to switch pens for each new color and go through the points in order.
Related
I want to detect that the sprite has encountered a color in pygame, which function should I use to achieve this function.
Though it is possible to get the color at any point in the surface that you want to check against using get_at() (docs here). You would need to find the new area that your sprite covered that it did not cover last time and check every pixel in that, and if other things were moving around you would have to check if your sprite now overlapped with any of those area and check that. Or you could decide that was too complicated and just run through every pixel under your sprites location (without you sprite drawn yet) and check for that color.
It is possible, but would likely not be very fast.
An alternative is if you know where those colors are you can mark those areas using rects, circles, sprites or masks (see here and here) that you can check against. That is usually much faster. These do not have to be drawn and so would be invisible. They would just be used to mark areas for the collision check.
If you do not know exactly where the colors are in the background or the other images, you can create masks based on the colors in them using pygame.mask.from_surface() or pygame.mask.from_threshold() (docs here and here).
So i have this spritesheet here:
And as seen on the left, you have to “add” the individual sprite parts, how do i do this?
I imagine there's a dedicated color (looks like pink) that should be treated not as a color but as transparency. So, you draw the first one without drawing any pixels that are pink (that is, leaving the background as is), then you draw the second one on top of it in a similar fashion, then the third and so on.
Background
Using gluTess to build a triangle list in Direct3D9 from a GDI+ DrawString(..) path:
A pixel shader (v3.0) is then used to fill in the shape. When painting with opaque values, everything looks fine:
The problem
At certain font sizes, if the color has an alpha component (ie Argb #55FFFFFF) we begin to see these nasty tessellation artifacts where triangles may overlap ever so slightly:
At larger font sizes the problem is sometimes not present:
Using Intel's excellent GPA Frame Analyzer Pixel History tool, we can see in areas where the artifacts occur, the pixel has been "touched" 3 times from the single Erg.
I'm trying to figure out how I can stop my pixel shader from touching the same pixel more than once.
Other solutions relating to overdraw prevention seem to be all about zbuffer strategies, however this problem is more to do with painting of a single 2D triangle list within a single pixel shader pass.
I'm at a bit of a loss trying to come up with a solution on this one. I was hoping that HLSL might have some sort of "touch each pixel only once" flag, but I've been unable to find anything like that. The closest I've found was to set the BLENDOP to MAX instead of ADD. But the output is not correct when blending over other colors in the scene.
I also have SRCBLEND = ONE, DSTBLEND = INVSRCALPHA. The only combination of flags which produce correct output (albeit with overdraw artifacts.)
I have played with SEPARATEALPHABLENDENABLE in the GPA frame analyzer, which sounded like almost exactly what I need here -- set blending to MAX but only on the "alpha" channel, however from what I can determine, that setting (and corresponding BLENDOPALPHA) affects nothing at all.
One final thing I thought of was to bake text as opaque onto a texture, and then repaint that texture into the scene with the appropriate alpha value applied, however this doesn't actually work in this project because I also support gradient brushes, where stop values may contain alpha, meaning either the artifacts would still be seen, or the final output just plain wrong if we stripped the alpha away from the stop values prior to baking to a texture. Also the whole endeavor would be hideously expensive.
Any hints or pointers would be appreciated. Thanks for reading.
The problem you're seeing shouldn't happen.
If two of your triangles are overlapping it's because you've placed the vertices in such a way that when the adjacent triangles are drawn, they overlap. What's probably happening is that these two adjacent triangles share two vertices, but each triangle has its own copy of each vertex that's been calculated to be in a very, very slightly different position.
The solution to the problem isn't to try and make the pixel shader touch the pixel only once it's to use an index buffer (if you aren't already) and have the shared vertices between each triangle actually share the same vertex and not use one that's ever-so-slightly not in the same place as the one used by the adjacent triangle.
If you aren't in control of the tessellation algorithm being used you may have to run a pass over the vertex buffer after its been generated to detect and merge vertices that are within some very small tolerance of one another. Even without an index buffer, a naive solution would be this:
For each vertex in the vertex buffer, compare its position to every other vertex in the rest of the vertex buffer.
If two vertices are within some small tolerance of another, replace the second vertex's position with the position of the one you are comparing it against.
This should have the effect of pairing up the positions of two vertices if they are close enough that you deem them to be the same.
You now shouldn't have any problem with overlapping triangles. In everyday rendering two triangles share edges with each other all the time and you won't ever get the effect where they appear to every-so-slightly overlap. The hardware guarantees that a sample point is either on one side of the line or the other, but never both at the same time, no matter how close the point is to the line (even if it's mathematically on the line, it still fails on one side or the other).
I have a prototype of a simple drawing application. When the user drags a finger across the screen, I record the points along the way and draw a series of lines between them. In other words, a drawing is a list of “paths” and each path is a list of points to connect. This is easy, it works and it’s efficient.
The problem is I’d like to implement an eraser tool. In a regular bitmap editor the eraser simply erases pixels, but in my drawing there are no pixels to erase – all pixels are created dynamically by stroking the paths. I could do a simple eraser by “drawing” using the background colour, overlaying the already painted paths. But I’d like to draw on a textured background, so that’s a no-go.
How would you do this? (Short of the obvious solution of representing the drawing as a bitmap where the eraser is simple.)
You can't implement an eraser in the traditional sense; what you describe with recording the paths and drawing them dynamically is vector graphics. The concept of an eraser comes from raster graphics (a bitmap, basically). With vector graphics, the user generally selects an item or an area of items to delete.
If you really wanted to do this, you'd basically have to do collision detection between all of the paths in your graphic and the rectangle (or whatever shape) of the eraser. When contact occurs, you'd have to cut the colliding graphic object on either side of the eraser by using the slope of the line(s) in contact with the eraser and the point of intersection.
You could probably find the intersections of your existing paths and the deleted area, split the existing paths up, and create new points at the intersections (which would become start/end points of the newly split paths).
I could do a simple eraser by
“drawing” using the background colour,
overlaying the already painted paths.
But I’d like to draw on a textured
background, so that’s a no-go.
Can't you do an "eraser by drawing" except you don't use a single color but the whole background as color. I mean, for a given path to erase, you take one by one each pixel and color it with the background color of the same pixel cordinates
Crayon Physics Deluxe is a commercial game that came out recently. Watch the video on the main link to get an idea of what I'm talking about.
It allows you to draw shapes and have them react with proper physics. The goal is to move a ball to a star across the screen using contraptions and shapes you build.
While the game is basically a wrapper for the popular Box2D Physics Engine, it does have one feature that I'm curious about how it is implemented.
Its drawing looks very much like a Crayon. You can see the texture of the crayon and as it draws it varies in thickness and darkness just like an actual crayon drawing would look like.
(source: kloonigames.com)
(source: kloonigames.com)
The background texture is freely available here.
What kind of algorithm would be used to render those lines in a way that looks like a Crayon? Is it a simple texture applied with a random thickness and darkness or is there something more going on?
I remember reading (a long time ago) a short description of an algorithm to do so:
for the general form of the line, you split the segment in two at a random point, and move this point slightly away from it's position (the variation depending on the distance of the point to the extremity). Repeat recursively/randomly. In this way, you lines are not "perfect" (straight line)
for a given segment you can "overshoot" a little bit, by extending one extremity or the other (or both). In this way, you don't have perfect joints. If i remember well, the best was to extends the original extremities, but you can do this for the sub-segment if you want to visibly split them.
draw the lines with pattern/stamp
there was also the (already mentioned) possibility to drawn with different starting and ending opacity (to mimic the tendency to release the pen at the end of drawing)
You can use a different size for the stamp on the beginning and the end of the line (also to mimic the tendency to release the pen at the end of drawing). For the same effect, you can also draw the line twice, with a small variation for one of the extremity (be careful with the alpha in this case, as the line will be drawn twice)
Last, for a given line, you can do the previous modifications several times (ie draw the line twice, with different variations) : human tend to repeat a line if they make some mistakes.
Regards
If you blow the image up you can see a repeating stamp-pattern .. there's probably a small assortment that it uses as it moves from a to b - might even rotate them ..
The wavering of the line can't be all that difficult to do. Divide into a bunch of random segments, pick positions slightly away from the direct route and draw splines.
Here's a paper that uses a lot of math to simulate the deposition of wax on paper using a model of friction. But I think your best bet is to just use a repeating pattern, as another reader mentioned, and vary the opacity according to pressure.
For the imperfect line drawing parts, I have a blog entry describing how to do it using bezier curves.
You can base darkness on speed. That's just measuring the distance traveled by the cursor between this frame and the last frame (remember Pythagorean theorem) and then when you go to draw that line segment on screen, adjust the alpha (opacity) according to the distance you measured.
There is a paper available called Mimicking Hand Drawn Pencil Lines which covers a bit of what you are after. Although it doesn't present a very detailed view of the algorithm, the authors do cover the basics of the steps that they used.
This paper includes high level descriptions of how they generated the lines, as well as how they generated the textures for the lines, and they get results which are similar to what you want.
This article on rendering chart series to look like XKCD comics has an algorithm for perturbing lines which may be relevant. It doesn't cover calculating the texture of a crayon drawn line, but it does offer an approach to making a straight line look imperfect in a human-like way.
Example output:
I believe the easiest way would simply be to use a texture with random darkness (some gradients, maybe) throughout, and set size randomly.