Adventure Game Studio | Forums

AGS Support => Modules & Plugins => Topic started by: Kweepa on 12 Jan 2010, 08:43

Title: MODULE: DrawAntialiased v1.1
Post by: Kweepa on 12 Jan 2010, 08:43
(http://www.kweepa.org/step/ags/tech/AntialiasedLine.png)

Allows you to draw antialiased lines and circles onto a drawing surface, like so:
Code: [Select]
DrawingSurface *surf = Room.GetDrawingSurfaceForBackground();
surf.DrawAntialiasedLine(x1, y1, x2, y2, transparency);
surf.DrawAntialiasedCircle(x, y, radius, transparency);
surf.DrawAntialiasedFilledCircle(x, y, radius, transparency);
surf.Release();

Demo in here:
http://www.kweepa.org/step/ags/tech/RopeTest.zip (900k)

Download here:
http://www.kweepa.org/step/ags/tech/DrawAntialiased.zip (2k)

For AGS 3.x.
Note: requires a 16 or 32 bit game and a 16 or 32 bit surface (for example, when drawing to the background, you must have imported a 16 or 32 bit image as the background). If you don't do this, the lines and circles will look blocky and the game will run slowly.

Enjoy!
Steve

Version History:
v1.1 Name change; added circles; extended DrawingSurface
v1.0 Lines only
Title: Re: MODULE: AntialiasedLine v1.0
Post by: SSH on 12 Jan 2010, 09:09
Pretty cool, but why does Roger have a rope coming out of THERE exactly?  :=
Title: Re: MODULE: AntialiasedLine v1.0
Post by: Layabout on 12 Jan 2010, 09:50
Wow, the rope test is really really impressive. I saw the rope 'demo' in the other thread, but combined with AA, it's superb.

Just a quick question, would it be possible to use the rope in the example to be affected by 'systems' such as wind. It would be cool to have it simulate power lines in a room without having to worry about animating something so tedious. (I know it's a bit off topic, but hey!)
Title: Re: MODULE: AntialiasedLine v1.0
Post by: ThreeOhFour on 12 Jan 2010, 10:29
Holy crap Steve!

That's the most bestest thing I ever saw  :o :D
Title: Re: MODULE: AntialiasedLine v1.0
Post by: GarageGothic on 12 Jan 2010, 13:25
Very nice work. I'll have to take a closer look at the rope physics script later today - I was wanting to integrate more physics puzzles in my next game but never thought of using rope. I'm guessing I'll have to look into how to model gravity on objects hanging from the end of the rope too.
Title: Re: MODULE: AntialiasedLine v1.0
Post by: monkey0506 on 12 Jan 2010, 16:07
Very nice demo. My question isn't about that though...

Why take a DrawingSurface as a parameter instead of using an extender method like:

Code: [Select]
import void DrawAntiAliasedLine(this DrawingSurface*, int x1, int y1, int x2, int y2, int transparency);

DrawingSurface *surface = Room.GetDrawingSurfaceForBackground();
surface.DrawAntialiasedLine(x1, y1, x2, y2, transparency);
surface.Release();

No technical difference except the fact that it provides automatic parameter validation of the DrawingSurface and prevents the possibility of null pointer references. :=

From an aesthetic viewpoint it would group the function together with the rest of the DrawingSurface functions and make it more streamlined with the built-in code. You already said it's for AGS 3.0+.

But in any case, very nice work, as usual. :=
Title: Re: MODULE: AntialiasedLine v1.0
Post by: Kweepa on 12 Jan 2010, 17:07
Extender what now? :=
Sounds like a good idea. I'll do that.

RE: the rope comments above.
Easy to apply wind. Just like gravity.
Harder to add weights and make it look good. Add stronger force to the end of the rope. Need to shorten the rope to make it less stretchy, and maybe add another (invisible) direct link from the start of the rope to the end to reduce stretching some more. Or do more constraint iterations (but then it gets slow). Perhaps a different physics approach would be better.
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Kweepa on 13 Jan 2010, 01:01
Bump for new version:
:= Name change
:= Added circles and filled circles
:= Changed to extend DrawingSurface, as suggested by the monkey
Title: Re: MODULE: DrawAntialiased v1.1
Post by: abstauber on 13 Jan 2010, 07:58
 :o
Amazing as always!
Great job!
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Danman on 13 Jan 2010, 13:41
Great I have been wanting for something like this to play with. Good work.
Title: Re: MODULE: DrawAntialiased v1.1
Post by: monkey0506 on 13 Jan 2010, 13:58
Hey Steve, I was thinking of using this module for something, but I need the lines to be thicker than 1 pixel. Any possibility you could add an optional thickness parameter like the built-in DrawingSurface.DrawLine function has? :D Thanks!!
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Kweepa on 13 Jan 2010, 18:54
Hmm, not so easy.
As a workaround you could draw the line multiple times with 1px offsets.
Code: [Select]
 float dy = (x2 - x1);
  float dx = (y2 - y1);
  float len = Maths.Sqrt(dx*dx + dy*dy);
  
  if (len > 0.0001)
  {
    dy = dy/len;
    dx = dx/len; // EDIT - FORGOT THIS LINE
    float offset = -0.5*IntToFloat(thickness-1);
    int i = 0;
    while (i < thickness)
    {
      surf.DrawAntialiasedLine(x1 + offset*dx, y1 + offset*dy, x2 + offset*dx, y2 + offset*dy);
      offset = offset + 1.0;
      i++;
    }
  }
Which is obviously pretty slow :(
Title: Re: MODULE: DrawAntialiased v1.1
Post by: GarageGothic on 13 Jan 2010, 19:34
I guess it depends on the effect you want (i.e. should the anti-aliased area also grow or just the width of the opaque pixels). If you just want a thick solid line with soft edges, it should be possible to do the opaque pixels either using DrawLine repeatedly or drawing two triangles (for very wide lines) - and then draw two anti-aliased lines, one on each side of the aliased line.
Title: Re: MODULE: DrawAntialiased v1.1
Post by: tzachs on 24 Feb 2010, 23:27
I had a puzzle with a rope in my game, I originally thought of manually animating the whole thing, but then I remembered this module, and it:
A. Looks much more impressive than what I had planned.
B. Took a lot less time.
C. Saved my life!

So I guess I just wanted to say thanks for this great module!
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Dualnames on 25 Feb 2010, 20:38
D. Also helps with the ladies! ;)
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Ryan Timothy B on 18 May 2010, 05:30
Hey Steve,

Using the rope test demo, is there any chance of being able to remove those AA gaps between the vertices of the rope joints, having it solid?
Like the center pixel always being 100% no matter what.

I've studied the code as much as I can without frying my brain.  It's gotta be the worst thing about using other people's code.
Heck, it even took me an hour just to make it draw on a sprite for an object instead of the background.  Now I can use it anywhere, even above the chosen characters and objects.  Even works with foreground walkbehinds.  Yay!

Edit: It doesn't show up all that badly on the black backgrounds, but really badly on colored backgrounds.  Like this:
(http://www.bryvis.com/entertainment/other/agsf/gapsinrope.png)
(background is totally ripped from some random adventure game)

I understand why it's doing it, it's using floats for the vertices and judging the transparency on the edges by that.  What is the easiest way to make it convert to Int before it calculates the AA?  Obviously the visual of the 'rope' won't be as smooth anymore with ints, but at least it'll be consistent in opacity.

Thanks.

Hmm.. Now that I think about it, having the 33 rope points in int form, it'll still have AA issues between the two points.
So perhaps the only solution would be to increase the AA to 3 pixels wide/high in the areas in needs it based on the point before and after..  Basically how the photoshop line tool works, always with a strong center of the line.
How could I do this?
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Kweepa on 18 May 2010, 15:14
Since it's your birthday, I decided to take a look at this.
The gaps in the rope are more exaggerated because you have rendered the rope to a sprite first, so the alpha channel is on/off rather than smooth, and any pixels that are less than 50% won't render at all.
I'm out of time to look into this further - gotta go to work - but it may be possible to retain the alpha by drawing single pixel images of varying alpha to the sprite rather than a single pixel image of varying transparency.
Take a look at the "plot" function in AntiAliasedLine.asc and try replacing
gSurfaceToDrawOn.DrawImage(y,x,gPixel.Graphic,t);
with
gSurfaceToDrawOn.DrawImage(y,x,gPixel[t/4]);
where gPixel is an array of sprites of varying alpha (you'd need to create these in a paint package and load them in, then set the array up before drawing any lines).

Perhaps someone like monkey can help you further since it's your birthday and all :)
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Ryan Timothy B on 18 May 2010, 17:06
Since it's your birthday, I decided to take a look at this.
That's the only reason I decided to ask last night.  Now get it working!!   ;D

Edit:  I removed the last portion of this post because I've got it working! Yay!  It suddenly hit me, you're drawing the gPixel at different transparencies sometimes in the same X,Y location - like layers.  I kept clearing the X,Y pixel of the sprite to match the background every time it went to draw a pixel.  So that's why they appeared as light AA in those broken connections.

Right on.  Thanks for this awesome module, you're my hero Steve.
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Monsieur OUXX on 06 Jul 2010, 11:16
Steve, may I ask you if you based your implementation on Xiaolin Wu's algorithm?

Do you know if there are algorithms out there that are more "space consuming"* and less "time-consuming"* ?
The more the better.

* as they say in algorithmics dialect


Title: Re: MODULE: DrawAntialiased v1.1
Post by: Kweepa on 07 Jul 2010, 00:37
I did, yes - as it says in the source code :)
I doubt you'd get significant savings from another algorithm. Specifically, I doubt you'd get more than a 50% speedup, without making significant assumptions. If you have some assumptions (for example, start and end are always going to be on exact pixels, maximum line length is X, ...) then for example you could precache some lines and just pick a precached line.
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Monsieur OUXX on 07 Jul 2010, 09:15
I did, yes - as it says in the source code :)

Ah? I've read it and recognized the algorithm but didn't spot the comment. Selective vision! :-)

About the assumptions: Yes, there are definitely some assumptions to make, but I was wondering if some expert had already made them 20 years ago ;-)
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Monsieur OUXX on 07 Jul 2010, 09:41
One last question: Unfortunately, I can't test your line-drawing implementation myself. Did you run some speed tests? How does it compare to AGS' built-in DrawingSurface.DrawLine ? (I know that your one is antialiased and DrawLine is not, but I can compare yours with DrawLine x 3).

Title: Re: MODULE: DrawAntialiased v1.1
Post by: Kweepa on 09 Jul 2010, 01:13
(I know that your one is antialiased and DrawLine is not, but I can compare yours with DrawLine x 3).

x3? That's optimistic! My guess would be x200 - x500, given the amount of interpreted instructions that have to be run.

I put each in a loop (so there's some loop overhead too) drawing random lines between 0 and 64*sqrt(2) long.
Results:
AA 1360 lines/second.
DL 96928 lines/second.
So DrawLine is approximately 70 times faster.
Actually that's a surprisingly good result for DrawAntialiased. Hooray!
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Monsieur OUXX on 09 Jul 2010, 11:32
AA 1360 lines/second.
DL 96928 lines/second.

Woaw, I didn't expect that at all.
The reason why I was considering comparing AA and DLx3 is because I'm thinking of doing a fake AA using 2 grey lines and one white line (total: 3 lines). But considering the results, I could even afford plenty more gray lines...
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Adrian on 20 Jul 2010, 20:18
That's a mighty module!!
Is there any way to control the speed the lines are drawn with?
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Monsieur OUXX on 21 Jul 2010, 09:30
Is there any way to control the speed the lines are drawn with?

Slow it down, you mean? Slow down the drawing of individual lines, so that the player can see the steps of the drawing?
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Adrian on 21 Jul 2010, 10:14
Yes, that's what I mean. To draw an antialiased line from point a to point b step by step, slowly so the user can watch it. Like a track on a map, for example.
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Gilbert on 21 Jul 2010, 10:20
This is just trivial. Something like (untested):
Code: [Select]
int ii=0;
DrawingSurface* blah;
while(ii<=100){
  blah=Room.GetDrawingSurfaceForBackground();
  blah.DrawAntialiasedLine(x1, y1, (x1*(100-ii)+x2*ii)/100, (y1*(100-ii)+y2*ii)/100, 0);
  blah.Release();
  Wait(1)
  ii++;
}
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Adrian on 21 Jul 2010, 13:33
Thanks for replying so quickly!
I tried to implement your code like this:

Code: [Select]
ii=0;
DrawingSurface* blah;
while(ii<=100){
  blah=Room.GetDrawingSurfaceForBackground();
  blah.DrawAntialiasedLine(88.0, 65.0, (88.0*(100-ii)+65.0*ii)/100, (65.0*(100-ii)+15.0*ii)/100, 0);
  blah.Release();
  Wait(1)
  ii++;
}

But I get this message:
Type mismatch: cannot convert 'float' to 'int'

What's wrong?
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Dualnames on 21 Jul 2010, 14:44
Code: [Select]
ii=0;
DrawingSurface* blah;
while(ii<=100){
  blah=Room.GetDrawingSurfaceForBackground();
  blah.DrawAntialiasedLine(88, 65, (88*(100-ii)+65*ii)/100, (65*(100-ii)+15*ii)/100, 0);
  blah.Release();
  Wait(1)
  ii++;
}

You used floats instead of integers
float of zero = 0.0
integer of zero = 0
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Adrian on 21 Jul 2010, 15:37
Sorry, I already tried that. Now it's the other way round:

Type mismatch: cannot convert 'int' to 'float'

I think it's not possible to mix int and float in that progress line.
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Gilbert on 21 Jul 2010, 16:03
Sorry, I missed the declaration part. ii should be an integer (I don't like floating point numbers :P). Original post updated.
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Adrian on 21 Jul 2010, 16:31
Yes, I declared ii as an integer, but it won't do the trick.
I don't like floating point numbers too  :P  But Steve's DrawAntialiasedLine function claims floats.
So it seems like you can't mix floats and ints in one calculation, like (float*(int-int)+float*int)/int for example  :(
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Gilbert on 21 Jul 2010, 18:14
You can, but you need to use those inconvenient FloatToInt() and IntToFloat() functions.

All right. I've downloaded the module and seems that it requires float for the coordinates. :P (As I don't use modules I don't care to download them unnecessary I really need to.)

This may work instead:
Code: [Select]
int ii=0;
DrawingSurface* blah;
while(ii<=100){
  blah=Room.GetDrawingSurfaceForBackground();
  blah.DrawAntialiasedLine(x1, y1, (x1*(100.0-IntToFloat(ii))+x2*ii)/100.0, (y1*(100.0-IntToFloat(ii))+y2*IntToFloat(ii))/100.0, 0);
  blah.Release();
  Wait(1)
  ii++;
}
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Adrian on 21 Jul 2010, 18:41
No, sorry, doesn't work. I'm still getting the same error message.
But never mind. I'm going to do this with rawdrawline, like here:

http://www.adventuregamestudio.co.uk/yabb/index.php?topic=25664.0 (http://www.adventuregamestudio.co.uk/yabb/index.php?topic=25664.0)

It won't be antialiased, but that's ok.

Thank you very much for your time and help!!!
bye
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Kweepa on 21 Jul 2010, 21:38
Don't give up... You are nearly there.
Code: [Select]
float x1 = 100.0;
float y1 = 100.0;
float x2 = 200.0;
float y2 = 200.0;
int ii=0;

DrawingSurface* blah;
DynamicSprite *ds = DynamicSprite.CreateFromBackground();
while(ii<=100)
{
  blah=Room.GetDrawingSurfaceForBackground();
  blah.DrawImage(0, 0, ds.Graphic);
  float t = IntToFloat(ii)/100.0;
  float omt = 1.0 - t;
  blah.DrawAntialiasedLine(x1, y1, omt*x1 + t*x2, omt*y1 + t*y2, 0);
  blah.Release();
  Wait(1);
  ii++;
}
ds.Delete();
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Adrian on 21 Jul 2010, 21:59
Wow, this looks complicated...

"Error: Floating point devide by zero" in DrawAntialiased.asc line 84:

Code: [Select]
(...)

[b]float gradient = dy / dx;[/b]

(...)

Edit:
my coordinates:
x1 = 88; y1 = 65;
x2 = 140; y2 = 15

in a 320x200 room.
Title: Re: MODULE: DrawAntialiased v1.1
Post by: Gilbert on 22 Jul 2010, 01:52
It seems that the module cannot draw just a point then (as the divide by zero case is not isolated out).

Just set ii to 1 initially instead of 0.

Title: Re: MODULE: DrawAntialiased v1.1
Post by: Adrian on 22 Jul 2010, 06:44
YES, THAT'S IT !!! Works perfectly, now!
Thank you very much, I would never have come there by myself!  :D

EDIT:
These antialiased lines look so sexy...!  ;D
Title: Re: MODULE: DrawAntialiased v1.1
Post by: eri0o on 22 Apr 2018, 23:55
Hey.

(https://i.imgur.com/6gJXMNh.gif)

Just adding some modifications in the original, mainly removing the anti-alias for instead using pixel lines.

Rope Test example room (https://drive.google.com/open?id=1D5JAqq9jREEc9iOC_tpP_NNC-xYV4yBN)

Updated, to demonstrate how to use. Now Rope has a GetGraphic() property, that passes the integer that points to the sprite, so you can apply it to an object, an overlay, a GUI or anything.

using Rope.Create(int rope_area_width , int rope_area_height, int rope_thickness = 1, int rope_color = 65535 )

you have to set the area, also you can set the color and the rope thickness.

Rope.scm (https://drive.google.com/open?id=15DQMkr_do2b1cNFD5m79YqUY6pP63tQU) - Rope packaged as a module.

Rope.ash (https://drive.google.com/open?id=1JhS1Rw-KonHS0wV-q3dsZZ8Ug1w5dVoZ) - the .ash file , the header.

Rope.asc (https://drive.google.com/open?id=1LKqyFEHX_qdDCY7sBwpZ45ea_fWAX2eM) - the .asc file if you just want to read.

Maybe this modification is useful for someone.

Chicky asked for help getting it to work on the Discord chat, but if you noticed, I cheated by removing the anti-alias part.
If someone has a better understanding of DrawAntialiasedLine and can make it work in similar fashion with AGS 3.4.1 in an object in the room, it would be useful!