Problem with al_draw_filled_circle()
Francis Langlais

I'm trying to use al_draw_filled_circle() to draw a shield around a robot but every time I use it, my game crash. I managed to use it once in a test I made just to make myself comfortable with the function but when I try it in my game it doesn't work.

Here is how I use it :

#SelectExpand
1 robot = al_load_bitmap("ressources//images//basic_robot.bmp"); 2 al_convert_mask_to_alpha(robot, al_map_rgb(255, 0, 255)); 3 shield = al_create_bitmap(SHIELD_R, SHIELD_R); 4 al_set_target_bitmap(shield); 5 al_draw_filled_circle(SHIELD_R - 5, SHIELD_R - 5, SHIELD_R / 2, al_map_rgb(255, 0, 255)); 6 character = al_create_bitmap(SHIELD_R, SHIELD_R); 7 al_set_target_bitmap(character); 8 al_draw_tinted_bitmap(shield, al_map_rgba_f(1*alpha, 1*alpha, 1*alpha, alpha), 0, 0, 0); 9 al_draw_bitmap(robot, SHIELD_R / 2 - al_get_bitmap_width(robot) / 2, SHIELD_R / 2 - al_get_bitmap_height(robot) / 2, 0);

The way I want to do it is to draw the shield on the character bitmap then draw the robot over it so the whole robot is visible. In this code my game crash and I use al_clear_to_color(al_map_rgb(255, 0, 255); instead everything is fine except I have a square instead of a circle.

I don't have the code where the function is working with me at the moment but I will update this post tomorrow as soon as I get it.

Edgar Reynaldo

Did you call al_init_primitives_addon()?

Elias

Paths can be separated with / instead of // btw.

Francis Langlais

@Edgar Reynaldo
Yes I did

@Elias
I thought so but when I use / it's not working so to be safe I use //.

Here is the code when al_draw_filled_circle() work :

  character = al_create_bitmap(SQUARE, SQUARE);
  al_set_target_bitmap(character);
  al_clear_to_color(al_map_rgb(0, 0, 255));
  al_draw_filled_circle(SQUARE / 2, SQUARE / 2, SQUARE / 2, al_map_rgb(255, 0, 255));
  al_convert_mask_to_alpha(character, al_map_rgb(0, 0, 255));

Here I was trying to use al_convert_mask_to_alpha() so I know I'm filling my bitmap and creating a alpha for nothing.
I can post the full code if you guys think it can help you understand better.

RPG Hacker

I thought so but when I use / it's not working so to be safe I use //.

Maybe you're confusing / with \? \ wouldn't work because \ starts an escape sequence. \\ will work on Windows as path seperator. / should work on all systems, though.

Francis Langlais

So to comeback to my initial question about al_draw_filled_circle, here is the code that is bugging me right now.

#SelectExpand
1void DrawSensorBitmaps(t_LL listOfRobots) { 2 double startAngle, endAngle, oppositeAngle, radians, radiansL1, radiansL2; 3 int j, x, y, x1, x2, y1, y2, range; 4 int xMin, yMin, left, top; 5 ROBOT *robot; 6 7 al_init_primitives_addon(); 8 9 ForeachLL_M(listOfRobots, robot) 10 { 11 for (j = 0; j < MAX_SENSORS; j++) 12 switch (robot->sensorArray[j].type) { 13 case SENSOR_RADAR: 14 //The algorithm for drawing the radar bitmap is: 15 //1: Clear the bitmap to transparent. 16 //2: Draw a colored circle to the radar range. 17 //3: Draw lines in transparency bounding the arc on either side 18 //4: Directly opposite to the arc, 10 pixels out, fill the remainder 19 // of the circle with the transparent color. 20 //5: Now the job is to copy just the sensor graphic to the bitmap 21 // associated with the radar. 22 //6: Find the three x,y points that define the arc and find the min 23 // and max each of x/y. 24 //7: Min/max doesn't work if the arc is pointing with its curve left/ 25 // right or up/down because the curve is further away than any of 26 // the defining arc points. To compensate, do a test to see if the 27 // round part of the arc is left/right or up/down, and if so, 28 // bound the box so the arc fits. 29 //8: Pick x/y points for the final image for where the sensor should 30 // be drawn. Sadly, although there is math behind it, due to 31 // rounding of odd pixels, the value had to be adjusted with +1 32 // with no proof...just empirical tests. 33 al_set_target_bitmap(sensorPic); 34 al_clear_to_color( 35 al_map_rgb(COLOR_TRANS_RED, COLOR_TRANS_GREEN, 36 COLOR_TRANS_BLUE)); //1 37 38 range = robot->sensorArray[j].range * PX_PER_CM; 39 40 startAngle = -robot->sensorArray[j].angle + robot->heading; 41 endAngle = startAngle - robot->sensorArray[j].width; 42 oppositeAngle = startAngle - robot->sensorArray[j].width / 2 43 + 180; 44 al_set_target_bitmap(sensorPic); 45 al_draw_filled_circle(al_get_bitmap_width(sensorPic) / 2, //*************************************************** 46 al_get_bitmap_height(sensorPic) / 2, //2 47 range, robot->color); 48 49 radiansL1 = startAngle * DEG_PER_RAD; 50 x1 = RADAR_WRKIMG_PX / 2 * cos(radiansL1); 51 y1 = RADAR_WRKIMG_PX / 2 * sin(radiansL1); 52 al_set_target_bitmap(sensorPic); //3a 53 al_draw_line(al_get_bitmap_width(sensorPic) / 2, 54 al_get_bitmap_height(sensorPic) / 2, 55 al_get_bitmap_width(sensorPic) / 2 + x1, 56 al_get_bitmap_height(sensorPic) / 2 - y1, 57 al_map_rgb(COLOR_TRANS_RED, COLOR_TRANS_GREEN, 58 COLOR_TRANS_BLUE), 1); 59 radiansL2 = endAngle * DEG_PER_RAD; 60 x2 = RADAR_WRKIMG_PX / 2 * cos(radiansL2); 61 y2 = RADAR_WRKIMG_PX / 2 * sin(radiansL2); 62 al_set_target_bitmap(sensorPic); 63 al_draw_line(al_get_bitmap_width(sensorPic) / 2, 64 al_get_bitmap_height(sensorPic) / 2, //3b 65 al_get_bitmap_width(sensorPic) / 2 + x2, 66 al_get_bitmap_height(sensorPic) / 2 - y2, 67 al_map_rgb(COLOR_TRANS_RED, COLOR_TRANS_GREEN, 68 COLOR_TRANS_BLUE), 1); 69 70 radians = oppositeAngle * DEG_PER_RAD; 71 x = 10 * cos(radians); 72 y = 10 * sin(radians); 73 floodfill(sensorPic, al_get_bitmap_width(sensorPic) / 2 + x, //4 74 al_get_bitmap_height(sensorPic) / 2 - y, al_map_rgb(COLOR_TRANS_RED, COLOR_TRANS_GREEN, 75 COLOR_TRANS_BLUE)); 76 77 //OK, now the *big* bitmap is drawn. Now we just have to take the 78 //section we need and copy it to the radar sensor's bitmap. //5 79 x1 = RADAR_WRKIMG_PX / 2 + range * cos(radiansL1); //6 80 y1 = RADAR_WRKIMG_PX / 2 - range * sin(radiansL1); 81 x2 = RADAR_WRKIMG_PX / 2 + range * cos(radiansL2); 82 y2 = RADAR_WRKIMG_PX / 2 - range * sin(radiansL2); 83 84 xMin = al_get_bitmap_width(sensorPic) / 2; //6 85 if (x1 < xMin) 86 xMin = x1; 87 if (x2 < xMin) 88 xMin = x2; 89 90 yMin = al_get_bitmap_height(sensorPic) / 2; //6 91 if (y1 < yMin) 92 yMin = y1; 93 if (y2 < yMin) 94 yMin = y2; 95 96 while (startAngle < 0) //Due to earlier calc, 97 startAngle += 360; //startAngle could be -ve. 98 99 if (startAngle > 180 && startAngle < 225) //7 100 left = 1; 101 else 102 left = xMin + 1; 103 104 if (startAngle > 90 && startAngle < 135) //7 105 top = 1; 106 else 107 top = yMin + 1; 108 109 al_set_target_bitmap(robot->sensorArray[j].image); 110 al_draw_bitmap_region(sensorPic, left, top, RADAR_IMAGE_PX, 111 RADAR_IMAGE_PX, 0, 0, 0); 112 113 robot->sensorArray[j].drawX = RADAR_IMAGE_PX - left + 1; 114 ; //8 115 robot->sensorArray[j].drawY = RADAR_IMAGE_PX - top + 1; 116 117 break; 118 case SENSOR_RANGE: 119 break; 120 case SENSOR_NONE: 121 default: 122 break; 123 } 124 } 125}

I have put al_init_primitives_addon(); on line 7 in the function just to be sure it is initialised before using it (it is initialised earlier but just to be sure).

Also, sensorPic is initialised and the bitmap is created like this:

static ALLEGRO_BITMAP *sensorPic;
sensorPic = al_create_bitmap(RADAR_WRKIMG_PX, RADAR_WRKIMG_PX);

Note : static ALLEGRO_BITMAP *sensorPic; is a global for this file. I don't know if this is the right way of doing things but since it's not my code I left it like this.

The part that crash my program is at line 45 to 47. When commented the program run but if that part is in the code the program crashes. I do use al_draw_filled_circle at other place in my code and it works perfectly but this one can't seems to work.

I tried to draw a circle bigger than the bitmap on an other program and it work. Also drawing the circle with the centre outside of the bitmap works fine too. I tried using hard value instead of al_get_bitmap_width and al_get_bitmap_height but the result is the same.

I honestly have no idea why this doesn't work. If you guys need, I can give you the whole code.

Thread #615547. Printed from Allegro.cc