PDA

View Full Version : [OpenGL] My quest for glowy lines



WILL
15-05-2010, 07:15 PM
(Click on thumbnails below to get a full sized view of the thumbnail images shown)
I'm on a mission of sorts and that mission is glowy lines! 8)

Here is a screenshot from a Geography wars clone that uses the effect I'm trying to get.

http://www.pascalgamedevelopment.com/forum/index.php?action=dlattach;topic=6265.0;attach=188

I think I'm close, but I'm not quite there yet. Here is a screenshot of what I've got so far...

http://www.pascalgamedevelopment.com/forum/index.php?action=dlattach;topic=6265.0;attach=190

The core of my lines need to be white-er and the glow fade out a bit more. Then I'll have the visual appeal that I'm looking for. Now that you know what I'm trying to achieve, I'll explain what I'm doing in OpenGL.

My approach is as follows...

I'm using a small 32x32 (32-bit + alpha channel) texture to represent a glowy pixel. I'm then drawing that pixel, scaled down to size, for each point on the line I am drawing. Here is my exact texture I use.


http://www.pascalgamedevelopment.com/forum/index.php?action=dlattach;topic=6265.0;attach=191

Here is my code for the function...


procedure DrawGlowLine(X1, Y1, X2, Y2: Integer; ColorR, ColorG, ColorB: GLfloat; GlowTexture: TTexture);
var
dx, dy, sdx, sdy, x, y, px, py : Integer;
procedure DrawDot;
begin
DrawTintedParticle(px, py, 0,
0.8, 0.075, // scale, alpha
0, 32, ColorR, ColorG, ColorB, GlowTexture);
DrawTintedParticle(px, py, 0,
0.3, 0.3, // scale, alpha
0, 32, ColorR, ColorG, ColorB, GlowTexture);
DrawTintedParticle(px, py, 0,
0.125, 0.9, // scale, alpha
0, 32, (ColorR+2)/3, (ColorG+2)/3, (ColorB+2)/3, GlowTexture);
end;
begin
dx := X2 - X1;
dy := Y2 - Y1;
if (dx < 0) then sdx := -1 else sdx := 1;
if (dy < 0) then sdy := -1 else sdy := 1;
dx := sdx * dx + 1;
dy := sdy * dy + 1;
x := 0;
y := 0;
px := x1;
py := y1;
if (dx >= dy) then
begin
for x := 0 to dx - 1 do
begin
DrawDot;

y := y + dy;
if (y >= dx) then
begin
y := y - dx;
py := py + sdy;
end;
px := px + sdx;
end;
end
else
begin
for y := 0 to dy - 1 do
begin
DrawDot;

x := x + dx;
if (x >= dy) then
begin
x := x - dy;
px := px + sdx;
end;
py := py + sdy;
end;
end;
end;

Not very complicated, just a line drawing function substituting the pixel for the small glow texture. I draw the texture 3 times.

1) big colored fade for that glow effect
2) for more solid coloring
3) the core where it's a bit whiter to give it that neon-type effect

Now this effect as I've represented it, is not that bad, but it has 2 main flaws.

1) It's SLOW... If I drew many things on the screen, it would slow down my game on older hardware. In fact drawing these few lines even slowed down my simple tron clone running, on-screen, in the background.

2) Resizability; if I wanted to make the lines thicker, or even draw a shape that had was thicker than a single 'pixel' wide (ie my tron/snake guys you see one screen), it might not look as decent as it does my lines because of my raw calculations for scale and alpha + color scaling. (the part where I add 2 and divide by 3 to bias the color towards white)

Any ideas on how I can capture the original effect better? I'm willing to abandon the while DrawGlowLine procedure if there is a better, easier, faster approach.

paul_nicholls
16-05-2010, 01:19 AM
It is a bit hard to see the effect you want as I can't see ANY graphics in your post except for the smiley! LOL

cheers,
Paul

User137
16-05-2010, 03:12 PM
An Error Has Occurred!
It seems that you are not allowed to download or view attachments on this board.
So i can't see any of your images ::)

But from code i assume that you are drawing little dots along the line. Faster method would be drawing 3 quads. You can still use 1 texture of a circular glow where border areas are completely black and center white, and then draw middle, start and end quads. To make it even faster you can do it triangle_strip from start to end.

You can draw it twice, first along Dist/Y and second along Dist/X so from front they cross like + sign.

WILL
16-05-2010, 06:03 PM
Sorry guys, thought this feature actually was working. ???

Well here are the images linked directly instead of uploaded...

A Grid Wars screenshot...

http://topshmups.files.wordpress.com/2008/09/grid3.jpg

My attempt screenshot...

http://www.pascalgamer.com/will/images/scraps/glowing-lines-01-clip.png

Re: User137: How would your approach look? I'd likely have different looking ends would I not? And... How would I do this with a triangle_strip? Would that not look distorted as well?

Also, what kind of texture should I be working with? I mean while I was working away with my current tiny 32x32 textures I noticed that the more translucent I had it, the easier it was to make a faded line, but then I'd lose much of the solidity I had at the center core of my line. Is there some trick to getting the 'ideal' glow texture for this?

WILL
16-05-2010, 08:48 PM
Ok I think I just found a means to do the effect I'd like without too much lag. Have a look at this link guys: http://prideout.net/archive/bloom/index.php#Sneaky

The technique I'm interested in here is the "Sneaky Bloom" effect as done in the sneaky.c source. I think this may be a lot faster and cleaner than my "glowy pixel" approach.

User137
17-05-2010, 12:27 PM
http://i42.tinypic.com/jrd64x.jpg
Any questions? :)

You can make greatly different looking lines by changing the texture, i just showed the idea with help of Gimp and Paint. Mid section texture S-coordinates are 0.5.

For your lines you could use a texture that has bright center and outer circle more rapidly fading into black, would look more like glow.

paul_nicholls
17-05-2010, 09:29 PM
http://i42.tinypic.com/jrd64x.jpg
Any questions? :)

You can make greatly different looking lines by changing the texture, i just showed the idea with help of Gimp and Paint. Mid section texture S-coordinates are 0.5.

For your lines you could use a texture that has bright center and outer circle more rapidly fading into black, would look more like glow.


that looks nice :)

cheers,
Paul

WILL
19-05-2010, 07:57 AM
That does look pretty good. However I believe that as much as I can go that far with it, it will still fall short on one aspect. What if I want to make a larger object glow such as a filled rectangle or elliptical? I think that once I get to that point I'd be stuck, so I'm going to try another approach now.

The below is what I'd like to do...

http://prideout.net/archive/bloom/sneaky.png

I realize that I'd have to draw part of my scene to a couple of buffer surfaces then combine them to the existing screen, but in the end the cost of the effect would likely be cheaper this way.

The technique is here at this link: http://prideout.net/archive/bloom/index.php#Sneaky It's in C and may use something like GLUT so I'm a but at a disadvantage. How do I perform the type of blurring in OpenGL that they are doing? I've not been able to find(via google) any easy to understand list of functions or techniques other than alluded to terms and suggestions. I know what they are saying to do, I just don't know what functions will do the trick.

chronozphere
19-05-2010, 09:25 AM
Yeah.. I suggest you use shaders for this, if you want good performance. Take a look at the bloom-effect and perhaps blur. :)

You probably need to render your geometry multiple times, like you said. Be aware that everything will be glowing (unless you add some geometry after applying the effect). :)
Especially the fonts shouldn't be too shiny because that makes them difficult to read.

User137
19-05-2010, 02:55 PM
In the game you referred to, all glowy squares and objects were actually just simple textures which had the glow already made with a graphics program. No real effects were used in the game itself.

Would the shader solution work if you need some objects glow and some not?

WILL
19-05-2010, 04:01 PM
Well from what I can tell I would be able to render directly to a buffer which I can then make my set of textures that will be combined after to create the bloom effect. Kind of like how the picture above shows. I believe it's saying that I'd use an FBO to prevent making this process too slow. I guess if I'm using a buffer for what I want to glow I could easily draw what will be normal under the bloomed stuff (direct to screen), then do my bloomed stuff (to the FBO then onto screen) and on top of that I could put my interface things such as text and whatnot. (again direct to screen as per normal)

Not sure if I'm just making this up or dreaming, but this is what I'm hoping the referenced technique will allow. My trouble is the functions I need to use to make each of this happen. First the FBO stuff (creation and setting it as what GL will draw to), doing the Gaussian blur, then taking the FBO and applying it to my screen. I've been looking up this effect in some of the official references for OpenGL. In fact I just ordered the 4th Edition of the OpenGL Buperbible (blue book).

arthurprs
21-05-2010, 04:02 PM
WILL, you may find something useful here http://www.pascalgamedevelopment.com/forum/index.php?topic=5454.15

WILL
22-05-2010, 12:13 AM
Hey thats awesome, I'm going to have to check it out. If I'm not mistaken it was not just lines, but quads as well no?

paul_nicholls
22-05-2010, 06:22 AM
Not sure if this will help, but this site seems pretty neat:

http://homepage.mac.com/arekkusu/bugs/invariance/TexAA.html

cheers,
Paul

Andreaz
23-05-2010, 09:36 AM
If you want the blur on all objects and can target some kindof recent hardware, then render the whole scene to a texture, and then do a GLSL blur on the resulting texture.

http://www.gamerendering.com/2008/10/11/gaussian-blur-filter-shader/

That would probably end up with what you need.