Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Trying to target the same bitmap I's copying from...

This thread is locked; no one can reply to it. rss feed Print
Trying to target the same bitmap I's copying from...
nshade
Member #4,372
February 2004

Ok,so I can't do it, but copying to a temp bitmap isn't working either.

Here is my original code

Blit(int d, int s, int dx, int dy, int sx, int sy, int w, int h)
{
al_set_target_bitmap(bufmap[d]);
al_draw_bitmap_region(bufmap[s], sx, sy, w, h, dx, dy, 0);
al_set_target_bitmap(al_get_backbuffer(DISPLAY));
}

If s and d are the same it crashes.
"Assertion failed: bitmap != dest && bitmap != dest->parent"

Cool cool. looked up the documentation. Says I should use a temp bitmmap.

How about this then...

Blit(int d, int s, int dx, int dy, int sx, int sy, int w, int h)
{
al_set_target_bitmap(tempbuf);
al_draw_bitmap_region(bufmap[s], sx, sy, w, h, dx, dy, 0);
al_set_target_bitmap(bufmap[d]);
al_draw_bitmap_region(tempbuf, sx, sy, w, h, dx, dy, 0);
al_set_target_bitmap(al_get_backbuffer(DISPLAY));
}

Now it crashes when the function is ran twice.
Assertion failed: bitmap != dest && bitmap != dest->parent

should I just be creating/destroying a temp bitmap every time?

EDIT
Nope that just goofed up things even more! Now it's super slow and doesn't blit right at all!

Blit(int d, int s, int dx, int dy, int sx, int sy, int w, int h)
{
  ALLEGRO_BITMAP *altemp = NULL;
    altemp = al_create_bitmap(GameWidth, GameHeight);
    al_set_target_bitmap(altemp);
    al_draw_bitmap_region(bufmap[s], sx, sy, w, h, dx, dy, 0);
    al_set_target_bitmap(bufmap[d]);
    al_draw_bitmap_region(altemp, sx, sy, w, h, dx, dy, 0);
    al_set_target_bitmap(al_get_backbuffer(DISPLAY));
    al_destroy_bitmap(altemp);
}

Elias
Member #358
May 2000

nshade said:

Now it crashes when the function is ran twice.

On which of your al_draw_bitmap_region calls? It sounds like your tempbuf is the same as either bufmap[s] or bufmap[d] - instead try to use a separate bitmap not used for anything else. I would not re-create a new bitmap every time if you can avoid it as it could be slow.

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

nshade
Member #4,372
February 2004

tempbuf is it's own global

ALLEGRO_BITMAP *bufmap[9]; //<! Array of 10 buffers for holding graphics
ALLEGRO_BITMAP *tempbuf = NULL;   //!< Temp Buffer for page flipping

These all are initialized with a al_create_bitmap() later....

Hmm, I used a bigger hammer, and now it works... Kind of.. At can at least get though my title sequence now.

#SelectExpand
1if (d==s) 2 { 3 al_set_target_bitmap(tempbuf); 4 al_draw_bitmap_region(bufmap[s], sx, sy, w, h, dx, dy, 0); 5 al_set_target_bitmap(bufmap[d]); 6 al_draw_bitmap_region(tempbuf, sx, sy, w, h, dx, dy, 0); 7 al_set_target_bitmap(al_get_backbuffer(DISPLAY)); 8 if (d == SCREEN) { updateScreen(); } 9 } 10 else 11 { 12 13 al_set_target_bitmap(bufmap[d]); 14 al_draw_bitmap_region(bufmap[s], sx, sy, w, h, dx, dy, 0); 15 al_set_target_bitmap(al_get_backbuffer(DISPLAY)); 16 if (d == SCREEN) { updateScreen(); } 17 }

Elias
Member #358
May 2000

Hm, well, it does make sense to only use the temporary bitmap when needed, so it's not necessarily bad.

Still, if you really get the "Assertion failed: bitmap != dest && bitmap != dest->parent" with your middle solution in the first post then somehow either bitmap[s] or bitmap[d] must have been identical to (or a sub-bitmap of) tempbuf. Which would indicate a bug somewhere in the code which sets up the bufmap[] array and somehow puts tempbuf in there. Or maybe there is a buffer overflow and since you declare tempbuf right after the array it somehow uses that for e.g. tempbuf[10].

[edit:]

ALLEGRO_BITMAP *bufmap[9]; //<! Array of 10 buffers for holding graphics

Note that the comment there is mis-leading, the array has only 9 bitmaps.

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

nshade
Member #4,372
February 2004

bufmap[0] to bufmap[9] is 10 elements (right?)

My initialization code looks like this.

//Create and clear temp buffer
  tempbuf = al_create_bitmap(GameWidth, GameHeight);
  al_set_target_bitmap(tempbuf);
  al_clear_to_color(al_map_rgb(0, 0, 0));
  al_set_target_bitmap(al_get_backbuffer(DISPLAY));
        if (AllocBuffer(7) != 7) TermErr(0);

AllocBuffer() is defined below...

int AllocBuffer(int num)
{
  int x;
  if (num > 10) num = 10;
  if (num <= 0) num = 0;
  for (x = 1; x <= num; x++) {
    bufmap[x] = al_create_bitmap(GameWidth, GameHeight);
    if (bufmap[x] == NULL) break;
  }
  return(x - 1);
}

Looks OK to me. However my "Big Hammer" approach isn't copying all the data for some reason. I'm looking at the mechanics right now.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

nshade
Member #4,372
February 2004

I found out what my problem was. It was a dumb error on my part..

al_set_target_bitmap(tempbuf);   //Set target to temp buffer
al_draw_bitmap_region(bufmap[s], sx, sy, w, h, dx, dy, 0); //copy bitmap to new area (Source sx,sy to Destination dx,dy)
al_set_target_bitmap(bufmap[d]); //Set target to original buffer
al_draw_bitmap_region(tempbuf, dx, dy, w, h, dx, dy, 0);  //DESTINATION LOCATION IS THE SAME AS SOURCE AS WE ARE COPYING BACK!!!! (dx,dy to dx,dy)

yup, I was copying source area location when I should have been copying the destination

What a dumb bug.

Audric
Member #907
January 2001

The error that Edgar pointed out is going to cause you much bigger problems than that.
I also find it very suspicious how AllocBuffer() doesn't initialize the first element of bufmap, you probably wanted:

int AllocBuffer(int num)
{
  int x;
  if (num > 10) num = 10;
  if (num <= 0) num = 0;
  for (x = 0; x < num; x++) { // was: x = 1 and x <= num
    bufmap[x] = al_create_bitmap(GameWidth, GameHeight);
    if (bufmap[x] == NULL) break;
  }
  return x - 1;
}

nshade
Member #4,372
February 2004

I readjusted the array elements.

In the original code the "screen" buffer (Bufmap[0]) is treated differently. I do as well, as that is what the game "expects" even though it's all the same. It's initialized when Allegro is initialized.

Go to: