Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » [A5] al_draw_rectangle bug? rectangle is drawn by 1 pixel off.

Credits go to Elias and SiegeLord for helping out!
This thread is locked; no one can reply to it. rss feed Print
 1   2 
[A5] al_draw_rectangle bug? rectangle is drawn by 1 pixel off.
Matthew Leverton
Supreme Loser
January 1999
avatar

I created macros for myself: algui_draw_hline(), etc.

But I'm not sure that they really belong in Allegro.

Neil Walker
Member #210
April 2000
avatar

This is harder than trying to understand the IE6 box model ;)

Is all this complication due to the way opengl renders or something?

Neil.
MAME Cabinet Blog / AXL LIBRARY (a games framework) / AXL Documentation and Tutorial

wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie

Matthew Leverton
Supreme Loser
January 1999
avatar

Read Mark's article. It's supposed to clear this up.

Neil Roy
Member #2,229
April 2002
avatar

I have to agree with axilmar on this. Having some sort of toggle would be nice. Selecting what type of system you wish to use.

Although writing your own would be no big deal I guess. I may write a few of my own functions for pixel co-ordinates. I haven't used A5 that much yet, just getting started, there is a function to plot a pixel right? So I could use that and create my own for lines, circles etc.

---
“I love you too.” - last words of Wanda Roy

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I would also like to see compatibility functions for 2D drawing. Simple wrappers for the new al_draw calls that mimic the behaviour of A4's drawing functions. Once my GUI library is ready to be ported to A5, I would have to write them anyway, as that would be much simpler than replacing all the drawing function calls.

Neil Roy
Member #2,229
April 2002
avatar

Just created a nice line drawing function. It's pretty fast if anyone wants to use it. :)

I looked up Bresenham's line algorithm online and adopted what I found. I plan on adding more to this for circles (using similar algorithm's as I find 'em).

There's nothing here specifying a particular bitmap or screen to draw on yet.

A5_PixelDraw.h...

#SelectExpand
1#ifndef _A5_PixelDraw_h_ 2#define _A5_PixelDraw_h_ 3 4extern void a5_line(int start_x, int start_y, int dest_x, int dest_y, ALLEGRO_COLOR colour); 5 6#endif

A5_PixelDraw.cpp...

#SelectExpand
1#include <cstdlib> // abs() 2#include <allegro5/allegro.h> 3#include "A5_PixelDraw.h" 4 5 6void a5_line(int start_x, int start_y, int dest_x, int dest_y, ALLEGRO_COLOR colour) 7{ 8 // Bresenham's line algorithm 9 int x0 = start_x; 10 int x1 = dest_x; 11 int y0 = start_y; 12 int y1 = dest_y; 13 int sx, sy, err, e2; 14 15 int dx = abs(x1-x0); 16 int dy = abs(y1-y0); 17 18 if(x0 < x1) sx = 1; else sx = -1; 19 if(y0 < y1) sy = 1; else sy = -1; 20 err = dx-dy; 21 22 while(x0 != x1 and y0 != y1) { 23 al_put_pixel(x0, y0, colour); 24 e2 = 2*err; 25 if(e2 > -dy) { 26 err -= dy; 27 x0 += sx; 28 } 29 if(e2 < dx) { 30 err += dx; 31 y0 += sy; 32 } 33 } 34 35 return; 36}

---
“I love you too.” - last words of Wanda Roy

Mark Oates
Member #1,146
March 2001
avatar

Neil Roy said:

I haven't used A5 that much yet, just getting started, there is a function to plot a pixel right? So I could use that and create my own for lines, circles etc.

Just be sure to lock your bitmap first before drawing the pixels, then unlock it when you're done (drawing the pixels). Otherwise you'll get a really slow render.

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

Neil Roy
Member #2,229
April 2002
avatar

Oh yeah!! I forgot about that, thanks Mark. I'll modify my function. I had that in mind before I started on this function and got so wrapped up in making it that I forgot about locking the bitmap! ;D.

Hmmm, I don't require a bitmap in my function... I s'pose I should so I can lock it?

It runs REALLY fast, at least in a simple test I done as is.

---
“I love you too.” - last words of Wanda Roy

Matthew Leverton
Supreme Loser
January 1999
avatar

Either lock the target bitmap or tell the programmer to do it before calling any of the functions.

Mark Oates
Member #1,146
March 2001
avatar

You're always drawing to a bitmap. If you haven't explicitly defined a bitmap then it will be the ALLEGRO_BITMAP* you can get from al_get_backbuffer().

Either lock the target bitmap or tell the programmer to do it before calling any of the functions.

Yes, that.

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

Neil Roy
Member #2,229
April 2002
avatar

I overloaded the function so that you can pass a bitmap, display or nothing. If you pass a display or bitmap, it will lock it. If you pass nothing, you have to lock it. I like this. Should be fun to do up some more. ;)

deleted old code

Edit: Fixed. The above code now has both a working line and rect function, all overloaded and working properly. When I tried the functions normally, without locking any bitmaps or displays, it still drew so many lines that my screen was almost solid colour from them after only a few seconds.

---
“I love you too.” - last words of Wanda Roy

axilmar
Member #1,204
April 2001

While such an add-on does not technically belong to the Allegro library itself, I think it would be very helpful if it is in the core distribution, and I don't think it would be such a great effort. A couple of days, perhaps, for a veteran Allegro developer.

SiegeLord
Member #7,827
October 2006
avatar

Why not copy the functions from Allegro 4, if the goal is to emulate the behaviour of Allegro 4... Also, there is no overloading in C.

And thirdly, anyone advocating a mode switch please provide a floating point versions of both line drawing and circle drawing functions. I literally spent months trying to get them working, and failed. Separate functions are fine as long as they take integer coordinates though.

Another thing to check is if it is any faster to draw these things using ALLEGRO_PRIM_POINTS.

EDIT: Also, all rectangular shapes (rectangles and horizontal + vertical lines) should be implemented using al_draw calls. There's way too much FUD about the current al_draw functions.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Elias
Member #358
May 2000

Wouldn't it be faster to just do all rendering to a memory bitmap instead? The A5 software line resterizer with width set to 0 is likely close to how A4 lines look anyway. Something like:

al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
screen = al_create_bitmap(320, 200);
al_set_target_bitmap(screen);
...
yay, i can use software rasterization for everything
...

And then at the end of each frame just draw that bitmap. It means there wouldn't be any locking or texture up and down loading. You'd even have direct pixel access to the screen, just like in A4.

--
"Either help out or stop whining" - Evert

Neil Roy
Member #2,229
April 2002
avatar

I just created those on the fly as I read this topic actually. I have no desire to redo all the Allegro 4 functions. I'll probably create a few useful functions for myself. Using C++ for a change because I do like overloading for this type of thing.

I may just rename them so they can be interchanged with A4 functions. Would make porting some of my own stuff easier. I may try my hand at wrapping them around the A5 line() functions etc... <shrug> gives me something to do. ;)

Edit: after more thinking, I may just redo these in C and leave the locking etc... up to the user. Would make my life easier. ;)

Okay, I redone them in 'C'. There are 3 functions that all take a bitmap perimeter, they all lock the bitmap and draw very fast. For example, I tested the a5_rectfill() from 10,10 - 790-590 and it was instant, at least on my machine. To draw to the display and not a bitmap, you simply get the bitmap from the backbuffer with ALLEGRO_BITMAP *bitmap = al_get_backbuffer(display);. This seems to be a nice compromise and matches the Allegro 4 functions. I don't think I have the skill to duplicate Allegro 4 functions, but I can make some simple drawing functions to plot pixels like A4 did.

A5_PixeDraw.h#SelectExpand
1#ifndef _A5_PixelDraw_h_ 2#define _A5_PixelDraw_h_ 3 4#ifdef __cplusplus 5 extern "C" { 6#endif 7 8extern void a5_line(ALLEGRO_BITMAP *bitmap, int start_x, int start_y, int dest_x, int dest_y, ALLEGRO_COLOR colour); 9extern void a5_rect(ALLEGRO_BITMAP *bitmap, int start_x, int start_y, int dest_x, int dest_y, ALLEGRO_COLOR colour); 10extern void a5_rectfill(ALLEGRO_BITMAP *bitmap, int start_x, int start_y, int dest_x, int dest_y, ALLEGRO_COLOR colour); 11 12#ifdef __cplusplus 13 } 14#endif 15 16#endif /*_A5_PixelDraw_h_ */

A5_PixeDraw.c#SelectExpand
1#include <stdlib.h> /* abs() */ 2#include <allegro5/allegro.h> 3#include "A5_PixelDraw.h" 4 5 6void a5_line(ALLEGRO_BITMAP *bitmap, int start_x, int start_y, int dest_x, int dest_y, ALLEGRO_COLOR colour) 7{ 8 /* Bresenham's line algorithm */ 9 int x0 = start_x; 10 int x1 = dest_x; 11 int y0 = start_y; 12 int y1 = dest_y; 13 int sx, sy, err, e2; 14 int dx = abs(x1-x0); 15 int dy = abs(y1-y0); 16 int x,y; 17 18 if(x0 < x1) sx = 1; else sx = -1; 19 if(y0 < y1) sy = 1; else sy = -1; 20 err = dx-dy; 21 22 al_lock_bitmap(bitmap, al_get_bitmap_format(bitmap), ALLEGRO_LOCK_WRITEONLY); 23 al_set_target_bitmap(bitmap); 24 25 if (x0 == x1) { 26 for (y=y0; y!=y1; y+=sy) al_put_pixel(x0, y, colour); 27 al_put_pixel(x1, y1, colour); 28 al_unlock_bitmap(bitmap); 29 return; 30 } 31 if (y0 == y1) { 32 for (x=x0; x!=x1; x+=sx) al_put_pixel(x, y0, colour); 33 al_put_pixel(x1, y1, colour); 34 al_unlock_bitmap(bitmap); 35 return; 36 } 37 38 while(x0 != x1 && y0 != y1) { 39 al_put_pixel(x0, y0, colour); 40 e2 = 2*err; 41 if(e2 > -dy) { 42 err -= dy; 43 x0 += sx; 44 } 45 if(e2 < dx) { 46 err += dx; 47 y0 += sy; 48 } 49 } 50 al_unlock_bitmap(bitmap); 51 52 return; 53} 54 55/***************************************/ 56 57void a5_rect(ALLEGRO_BITMAP *bitmap, int start_x, int start_y, int dest_x, int dest_y, ALLEGRO_COLOR colour) 58{ 59 if (start_x==dest_x || start_y==dest_y) { 60 a5_line(bitmap, start_x, start_y, dest_x, dest_y, colour); 61 return; 62 } 63 64 int sx, sy, dx, dy; 65 if (start_x < dest_x) { 66 sx = start_x; 67 dx = dest_x; 68 } 69 else { 70 sx = dest_x; 71 dx = start_x; 72 } 73 74 if (start_y < dest_y) { 75 sy = start_y; 76 dy = dest_y; 77 } 78 else { 79 sy = dest_y; 80 dy = start_y; 81 } 82 83 a5_line(bitmap, sx, sy, dx, sy, colour); 84 a5_line(bitmap, dx, sy, dx, dy, colour); 85 a5_line(bitmap, dx, dy, sx, dy, colour); 86 a5_line(bitmap, sx, dy, sx, sy, colour); 87 88 return; 89} 90 91/***************************************/ 92 93void a5_rectfill(ALLEGRO_BITMAP *bitmap, int start_x, int start_y, int dest_x, int dest_y, ALLEGRO_COLOR colour) 94{ 95 int temp, y; 96 97 /* if start x is greater than destination x, swap them. */ 98 if (start_x > dest_x) { 99 temp = start_x; 100 start_x = dest_x; 101 dest_x = temp; 102 } 103 104 /* if start y is greater than destination y, swap them. */ 105 if (start_y > dest_y) { 106 temp = start_y; 107 start_y = dest_y; 108 dest_y = temp; 109 } 110 111 if (start_x==dest_x || start_y==dest_y) { 112 a5_line(bitmap, start_x, start_y, dest_x, dest_y, colour); 113 return; 114 } 115 116 for (y=start_y; y<dest_y; y++) { 117 a5_line(bitmap, start_x, y, dest_x, y, colour); 118 } 119 120 return; 121}

---
“I love you too.” - last words of Wanda Roy

 1   2 


Go to: