Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Al_draw_bitmap_region doesn't update the window

This thread is locked; no one can reply to it. rss feed Print
Al_draw_bitmap_region doesn't update the window
Sphinxs
Member #16,827
March 2018

#SelectExpand
1void Map::build_map () { 2 3 ALLEGRO_BITMAP * wall_map = al_load_bitmap(wall); 4 5 for(int row = 0; row < max_lines; row++) { 6 7 for(int col = 0; col < max_cols; col++) { 8 9 if(this->map_form[row][col] == "#") { 10 al_draw_bitmap_region(wall_map, row, col, width, height, 0, 0, 0); 11 } 12 13 } 14 15 } 16 17 al_flip_display(); 18 19}

How can I update the window, it's not working this way, This method is in a class that I'm included on my main.cpp ( Which has a main display already configured )

Chris Katko
Member #1,881
January 2002
avatar

Don't forget code tags.

void Map::build_map () {
   ALLEGRO_BITMAP * wall_map = al_load_bitmap(wall);
   for(int row = 0; row < max_lines; row++) {
      for(int col = 0; col < max_cols; col++) {
          if(this->map_form[row][col] == "#") {
             al_draw_bitmap_region(wall_map, row, col, width, height, 0, 0, 0);
             }
          }
      }
   al_flip_display();
   }

See the function signature:

void al_draw_bitmap_region(ALLEGRO_BITMAP *bitmap,
   float sx, float sy, float sw, float sh, float dx, float dy, int flags)

So it should probably be:

//from
  al_draw_bitmap_region(wall_map, row, col, width, height, 0, 0, 0);

//to
  al_draw_bitmap_region(wall_map, 0, 0, width, height, row, col, 0);

And are "rows" and "columns" in pixels? or do you need to multiply them by the tile height? Because it looks like you're drawing a map of walls, but each wall is say, index=5, at pixel=5. But it should be index * tile_width to go from map index coordinates to screen coordinates.

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Sphinxs
Member #16,827
March 2018

Sorry, I'm a beginner here. Yeah, I'm on documentation for hours ( I'm slower so ... : [ ). I need to multiply, thanks, it worked but now the entire map it's very small :

{"name":"pZsw6tN.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/e\/de7fef6ff8f1476a4912abd18ebb2259.png","w":391,"h":490,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/e\/de7fef6ff8f1476a4912abd18ebb2259"}pZsw6tN.png

Wall : 30 px

This map should be something like this :

{"name":"oSdecdi.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/b\/0\/b066cd352942738f86dc14c4a04c6ad1.png","w":438,"h":414,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/b\/0\/b066cd352942738f86dc14c4a04c6ad1"}oSdecdi.png

Chris Katko
Member #1,881
January 2002
avatar

Well, first, are you using al_draw_bitmap_region for a specific reason? Because I literally wrote a map drawing code like... last night... (for the umptenth time...) and it doesn't use _region anywhere. In fact, I almost never use the region version.

The simplest version is drawing the entire map (subtract an x and y offset for camera movement) by iterating two for loops, and using al_draw_bitmap. No regions needed.

One step above, is limiting the "overdraw" (drawing outside the screen) by pruning your map lookups to only map indexes that are inside the bounds of the screen.

Are you just trying to do a simple map drawing routine?

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Edgar Reynaldo
Member #8,592
May 2007
avatar

Using the 'region' drawing routine is fine if you know what you're doing, and you don't want to use sub bitmaps, but generally tiling an atlas is what is done.

Like Chris said, you need to draw at dx = col*TILE_WIDTH , dy = row*TILE_HEIGHT, otherwise they will all overlap by one pixel like in your picture.

Chris Katko
Member #1,881
January 2002
avatar

Finally back on my laptop, here's a full example (in D, but it's almost the same as C++ or C#):

#SelectExpand
1//g is a struct holding all my globals 2//g.TILE_D - is tile_width=tile_height = 64 in my running code for the moment 3//g.tile_bmp (etc) - is a bitmap for a single tile like a floor, or wall. 4 5 6class viewport_t 7 { 8 int x,y,w,h; //screen position and width/height 9 float offset_x, offset_y; //camera offset 10 } 11 12class map_t 13 { 14 int [24][24] data; 15 int width; 16 int height; 17 18 void draw(viewport_t v) 19 { 20 //screen caps 21 int start_x = 0 + to!int(v.offset_x/g.TILE_D); 22 int start_y = 0 + to!int(v.offset_y/g.TILE_D); 23 int end_x = (v.w/g.TILE_D)+1 + to!int(v.offset_x/g.TILE_D); 24 int end_y = (v.h/g.TILE_D)+1 + to!int(v.offset_y/g.TILE_D); 25 26 //array boundary caps 27 if(start_x < 0)start_x = 0; 28 if(start_y < 0)start_y = 0; 29 if(start_x > width-1)start_x = width-1; 30 if(start_y > height-1)start_y = height-1; 31 if(end_x < 0)end_x = 0; 32 if(end_y < 0)end_y = 0; 33 if(end_x > width-1)end_x = width-1; 34 if(end_y > height-1)end_y = height-1; 35 36 for(int i = start_x; i <= end_x; i++) //note <= because this is start/end coordinates, not, "width" which would be -1. 37 for(int j = start_y; j <= end_y; j++) 38 { 39 if(data[i][j] == 0) 40 { 41 // empty/space 42 } 43 44 45 if(data[i][j] == 1) 46 { 47 al_draw_bitmap(g.tile_bmp, 48 i*g.TILE_D - v.offset_x + v.x, 49 j*g.TILE_D - v.offset_y + v.y/g.TILE_D, 50 0); 51 } 52 53 if(data[i][j] == 2) 54 { 55 al_draw_bitmap(g.tile2_bmp, 56 i*g.TILE_D - v.offset_x + v.x, 57 j*g.TILE_D - v.offset_y + v.y/g.TILE_D, 58 0); 59 } 60 61 if(data[i][j] == 3) 62 { 63 al_draw_bitmap(g.tile3_bmp, 64 i*g.TILE_D - v.offset_x + v.x, 65 j*g.TILE_D - v.offset_y + v.y/g.TILE_D, 66 0); 67 } 68 69 70 } 71 } 72 73 void tick(){} 74 void load_map(string path) 75 { 76 //removed 77 } 78 void save_map(){} 79 }

This one isn't using a texture atlas, that Edgar mentioned the use for using regions. A texture atlas is a single bitmap with all (or many) of your tiles on it so you draw only the relevant tile. But you can also have individual bitmaps for tiles (which I'm using here).

{"name":"figure1.jpg","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/9\/99f2fe58419e61de1b91f12f028be129.jpg","w":400,"h":400,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/9\/99f2fe58419e61de1b91f12f028be129"}figure1.jpg
A texture atlas

Mine also supports viewports (drawing to less than the full screen, for split-screen multiplayer), and trimming the overdraw by only drawing array indexes that fit inside the screen. I might be able to remove those features if you really need it to see just the drawing portion.

But basically, if you want texture atlas, you just replace the if(data[i][j] = 0/1/2/3) that contain al_draw_bitmap(invidual_bitmap_pointers,...) with al_draw_region with the location of the tile you care about inside the atlas. But because that's an additional "thing" to deal with, I'd get the basic drawing with hand-picked tiles first, before adding the atlas. Cut the amount of failure points so you can debug and get to the source of the issue faster.

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Go to: