outline
BlitzMax Forums/OpenGL Module/outline
| ||
How would you add an outline to an 2d image in openGL? Lets say that I load the picture shown below and create a quad which uses this as its texture. Is there a way to make an even outline? I tried just upscaling it and drawing it all black, then set the scale to 1 again and draw the image on top, but that doesn't work. |
| ||
this should work:Function DrawImageOutline(img:TImage,x:Float,y:Float,thickness:Int=1) Local r:Int,g:Int,b:Int GetColor(r,g,b) SetColor(0,0,0) For Local dx:Int = -thickness To thickness For Local dy:Int = -thickness To thickness DrawImage(img,x+dx,y+dy) Next Next SetColor(r,g,b) DrawImage(img,x,y) EndFunctionAlthough it isn't OpenGL specific, you can do the same.. |
| ||
The simplest way for an outline is doing it in the graphics application. It will take less performance as well then adding 1+ new quads for a "line". |
| ||
Maybe he's doing an app that can add the outline automatically :) |
| ||
@fredborg, I don't know why I didn't think of that solution, I am sure that I have used similar before. Ofcause it solves the problem, but it would have been nice, if there were a way to do it without having to draw the image so many times. @Dreamora, It can be done in a graphics application, but if its needed for an editor of sorts, where the user manipulates the output directly, then that won't help. I should have mentioned that ofcause. |
| ||
You can `jitter` the drawing. Draw the image four or eight times in black at the same coords except -1,0 then 1,0 then 0,-1 then 0,1 (add these to the normal coords). If you want to do it 8 times, also draw it at -1,-1, -1,1, 1,-1 and 1,1 to cover the diagonals. This will put a 1-pixel border around it. Then draw the regular image on top. |
| ||
@ImaginaryHuman, thats what fredborgs function does, isn't it? @fredborg, thats correct, I need this for my own application and need it to be changeable in realtime. |
| ||
In that case I would suggest implementing a a small little edge detection by running a matrix filter operation. not tested code for it would be ' assuming pix holds the pixmap ' assuming that maskColor holds the ARGB value of the "to cut color" ' assuming borderColor holds the color for the border / outline local pw:int = pixmapwidth(pix) - 1 local ph:int = pixmapheight(pix) - 1 for local x:int = 0 to pw for local y:int = 0 to ph local pixel:int = 0 for local i:int = max(x-radius,0) to min(x+radius, pw) for local j:int = max(y-radius,0) to min(y+radius, ph) pixel :+ readpixel(pix,x+i, y+j) next next pixel :/ int(radius*radius) if( pixel <> maskColor ) writepixel(pix, x, y, borderColor) else writepixel(pix, x, y, maskColor) endif next next this uses a square combination ... you could reduce it to do it only if i + j <= radius so you get a "rounder" shape that collects the data for the outline. There are other, quite optimized algorithms for that, so having a look at those might actually be an idea if it is too slow :) |
| ||
Oh yea, doh, I didn't notice the nested loop. |
| ||
Since your symbol more or less looks like it could be vector art, why not construct it out of triangles, draw it, and then draw a wireframe outline? |
| ||
It was for a bitmap image manipulation effect, the ankh was just something I had lying around that was simple. |