How to use al_draw_soft_line function
Francis Langlais

I'm a beginner in Allegro and in programming in general and I have to port a game from Allegro 4.4 to Allegro 5.0. In the earlier version they use do_line to compare the color of 2 pixel.

What I found on the internet is that al_draw_soft_line do the same thing. The thing is I don't understand how to use this function and I can't find any example to help me on the internet.

So if anyone can help me on that it'll be greatly appreciate.

beoran

This thread has an example on how to use al_draw_soft_line:

https://www.allegro.cc/forums/thread/615415

Basically it's a function that takes the points in between the line that will be traced, user data and 3 callback functions, of which the last is most useful.

Edgar Reynaldo

Here's another code example of how to use al_draw_soft_line :

#SelectExpand
1 2#include "allegro5/allegro.h" 3#include "allegro5/allegro_primitives.h" 4 5ALLEGRO_DISPLAY* display = 0; 6ALLEGRO_BITMAP* buffer = 0; 7 8void FirstFunction(uintptr_t state , int x , int y , ALLEGRO_VERTEX* v1 , ALLEGRO_VERTEX* v2); 9void StepFunction(uintptr_t state , int step); 10void DrawFunction(uintptr_t state , int x , int y); 11 12#include <cstdlib> 13#include <cstdio> 14 15int main(int argc, char** argv) { 16 17 (void)argc; 18 (void)argv; 19 20 if (!al_init()) {return 1;} 21 if (!al_init_primitives_addon()) {return 2;} 22 23 int w = 400; 24 int h = 400; 25 26 display = al_create_display(w,h);// sorry, you need a target bitmap to draw with al_draw_soft_line 27 if (!display) {return 3;} 28 29 buffer = al_create_bitmap(w,h); 30 if (!buffer) {return 4;} 31 al_set_target_bitmap(buffer); 32 al_clear_to_color(al_map_rgba(0,0,255,255)); 33 34 al_set_target_backbuffer(display); 35 al_clear_to_color(al_map_rgba(0,255,0,255)); 36 al_draw_bitmap(buffer , 0 , 0 , 0); 37 al_flip_display(); 38 39 al_set_blender(ALLEGRO_ADD , ALLEGRO_ONE , ALLEGRO_ZERO); 40 41for (unsigned int i = 0 ; i < 10 ; ++i) { 42 ALLEGRO_VERTEX v1; 43 ALLEGRO_VERTEX v2; 44 45 v1.x = (int)((((float)(unsigned)rand())/RAND_MAX)*w); 46 v1.y = (int)((((float)(unsigned)rand())/RAND_MAX)*h); 47 v1.z = 0; 48 v2.x = (int)((((float)(unsigned)rand())/RAND_MAX)*w); 49 v2.y = (int)((((float)(unsigned)rand())/RAND_MAX)*h); 50 v2.z = 0; 51 52 al_set_target_bitmap(buffer); 53 al_draw_soft_line(&v1 , &v2 , (uintptr_t)NULL , FirstFunction , StepFunction , DrawFunction); 54 55} 56al_rest(2.0); 57 58//void al_draw_soft_line(ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, uintptr_t state, 59// void (*first)(uintptr_t, int, int, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*), 60// void (*step)(uintptr_t, int), 61// void (*draw)(uintptr_t, int, int)) 62 return 0; 63} 64 65 66 67void FirstFunction(uintptr_t state , int x , int y , ALLEGRO_VERTEX* v1 , ALLEGRO_VERTEX* v2) { 68 (void)state; 69 (void)x; 70 (void)y; 71 72 printf("Drawing a line from v1 (%f,%f,%f) to v2 (%f,%f,%f)\n" , v1->x , v1->y , v1->z , v2->x , v2->y , v2->z); 73 return; 74} 75 76 77 78void StepFunction(uintptr_t state , int step) { 79 (void)state; 80 (void)step; 81 return; 82} 83 84 85 86void DrawFunction(uintptr_t state , int x , int y) { 87 (void)state; 88 printf("Pixel drawn at %i , %i\n" , x , y); 89 90// al_set_target_bitmap(buffer); 91 al_set_target_bitmap(buffer); 92 al_put_pixel(x,y,al_map_rgba(255,255,255,255)); 93/// al_clear_to_color(al_map_rgba(rand()%255 , rand()%255 , rand()%255 , 255)); 94 95 al_set_target_backbuffer(display); 96 al_draw_bitmap(buffer , 0 , 0 , 0); 97 al_flip_display(); 98 return; 99}

Francis Langlais

Thank you guys, one last question :

The I have read about the uintptr_t type and I was wondering if I could (and if so how) use the uintptr_t state parameter to pass a int array.

As of now my do_line looks like this :
do_line(NULL, robX, robY, sensX, sensY, (int) collidedData, CheckPixel);

and I need the (int) collidedData in my step part. collideData is define as int collideData[5];

so should I use it like this:

al_draw_soft_line(&v1, &v2, (uintptr_t) collideData, First, CheckPixel, Draw);

and then in CheckPixel do (int)collideData?

Or should I Put my CheckPixel function inside my draw?

beoran

"An unsigned integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer"

So yes you can do this, but technically you need to cast the array to void * first, then to uintptr_t, and then back to void * in the callback function. However, normally, it will work with a direct cast to intptr_t.

Edgar Reynaldo

Uhm, what's the need for uintptr_t then? Why not just use void* for the state member?

beoran

The use is that uintptr_t can also be passed an integer. For example, intptr_t and uintptr_t are used when you want a function to be able to take a parameter that is either a pointer or an integer, for more flexibility.

Thread #615463. Printed from Allegro.cc