Allegro.cc - Online Community

Allegro.cc Forums » Game Design & Concepts » What form of bitmap is faster?

This thread is locked; no one can reply to it. rss feed Print
What form of bitmap is faster?
Kevin Epps
Member #5,856
May 2005
avatar

Which bitmaps use less memory?

Reg Bitmap?
Video Bitmap?
System Bitmap?
Loaded Bitmap?
Datafile Bitmap?
Loaded Bitmap and then copied to Video Bitmap?
Loaded Bitmap and then copied to System Bitmap?
Loaded Bitmap and then copied to Reg Bitmap?

ReyBrujo
Moderator
January 2001
avatar

Hmmm... less memory, or faster? For memory purposes, Reg Bitmap, Loaded Bitmap and Datafile Bitmap are all the same, they use RAM memory. Video Bitmap to Video Bitmap is faster if it works with HW acceleration, but you have limited Video memory. But, on the other side, copying any non-video bitmap to a video bitmap is SLOW.

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

Kevin Epps
Member #5,856
May 2005
avatar

Yeah. Faster. That's what I meant to say.

So video to Video...

What kind of method can I use to use this type of method if I'm loading png's, gif's, and bitmaps?

ReyBrujo
Moderator
January 2001
avatar

Page flipping. Use create_video_bitmap to create two bitmaps. If you have a fixed amount of sprites, and enough video bitmap, you can create a small square of video bitmap and blit your loaded sprites there. Then, instead of blitting from the datafiles to the video bitmap, you could blit from that small square to the video bitmap.

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

CGamesPlay
Member #2,559
July 2002
avatar

Once you load the bitmap, the file type has nothing to do with how it looks in memory. Furthermore, where you load it from doesn't either. Any loaded bitmap goes into a memory bitmap, you have to copy it to video or system manually.

This is a program I wrote to test blits.

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

Kevin Epps
Member #5,856
May 2005
avatar

This is what I did before the game loop:

1 BITMAP *layer_one;
2 layer_one = create_video_bitmap(3200, 480);
3 BITMAP *layer_two;
4 layer_two = create_video_bitmap(3200, 480);
5 BITMAP *layer_three;
6 layer_three = create_video_bitmap(3200, 480);
7 BITMAP *layer_four;
8 layer_four = create_video_bitmap(3200, 480);
9 BITMAP *layer_six;
10 layer_six = create_video_bitmap(3200, 480);
11 BITMAP *layer_seven;
12 layer_seven = create_video_bitmap(3200, 480);
13 BITMAP *layer_eight;
14 layer_eight = create_video_bitmap(3200, 480);
15 BITMAP *layer_nine;
16 layer_nine = create_video_bitmap(3200, 480);
17 clear_to_color(layer_one, makecol(255,0,255));
18 clear_to_color(layer_two, makecol(255,0,255));
19 clear_to_color(layer_three, makecol(255,0,255));
20 clear_to_color(layer_four, makecol(255,0,255));
21 clear_to_color(layer_six, makecol(255,0,255));
22 clear_to_color(layer_seven, makecol(255,0,255));
23 clear_to_color(layer_eight, makecol(255,0,255));
24 clear_to_color(layer_nine, makecol(255,0,255));
25 temp = load_png("keiku01f.png", NULL);
26 bg = load_bitmap("forest-5.gif", NULL);
27 grass[0] = load_png("grass_1.png", NULL);
28 grass[1] = load_png("grass_2.png", NULL);
29 grass[2] = load_png("grass_3.png", NULL);
30 grass[3] = load_png("grass_upper.png", NULL);
31 foreground = load_png("foreground-2.png", NULL);
32 front_trees = load_png("front_trees.png", NULL);
33 draw_sprite(layer_one, bg, 0, 0);
34 draw_sprite(layer_two, foreground, 0, 0);
35 draw_sprite(layer_three, grass[3], 0, 0);
36 draw_sprite(layer_four, grass[0], 0, 0);
37 draw_sprite(layer_six, grass[0], 0, 0);
38 draw_sprite(layer_seven, grass[1], 0, 0);
39 draw_sprite(layer_eight, grass[2], 0, 0);
40 draw_sprite(layer_nine, front_trees, 0, 0);
41 destroy_bitmap(bg);
42 destroy_bitmap(foreground);
43 destroy_bitmap(front_trees);
44 destroy_bitmap(grass[0]);
45 destroy_bitmap(grass[1]);
46 destroy_bitmap(grass[2]);
47 destroy_bitmap(grass[3]);

After that, I'm just drawing the the layers(ie layer_one, etc.) to video memory in the loop. So I guess I have it where it needs to be then. Thanks guys! :)

ReyBrujo
Moderator
January 2001
avatar

Geez... your video card? And how much memory it does have? I think I would not be able to allocate that much memory with my 64mb one...

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

Kevin Epps
Member #5,856
May 2005
avatar

Oh really? Is that considered a lot of memory? So what size should the video memory bitmaps be, just the size of the screen?

I think my Video memory is around 8mb for the Rage Pro and 64mb for the Radeon.

Rage Pro 128 8mb

Radeon x300 64mb

ReyBrujo
Moderator
January 2001
avatar

Which is your bitmap depth? 8bpp?

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

Kevin Epps
Member #5,856
May 2005
avatar

16bpp. I also made sure that the pics loaded were at screen's width or maybe double(just one) and it works much better, too. So all of the created video bitmaps are only the width of the screen.

HoHo
Member #4,534
April 2004
avatar

16bbp is two bytes per pixel. You create eight 3200x480 images. That is 12MiB of memory. Of course some memory is for the screen bitmap and buffer too. That is not too much by todays standards but certainly it will never work on anything that has below 16MiB of Vram.

__________
In theory, there is no difference between theory and practice. But, in practice, there is - Jan L.A. van de Snepscheut
MMORPG's...Many Men Online Role Playing Girls - Radagar
"Is Java REALLY slower? Does STL really bloat your exes? Find out with your friendly host, HoHo, and his benchmarking machine!" - Jakub Wasilewski

Kevin Epps
Member #5,856
May 2005
avatar

Ok.

I've changed those video sizes to 640x480l.

So now I've created 8 640x480 video bitmaps. It seems to work fine on the Rage as well. Even with more than one character sprite on the screen.

Neil Walker
Member #210
April 2000
avatar

Why do you need 3200 width bitmaps? or is this something different to your tilemap program?

Also, why are you creating a bitmap, colouring it magenta then drawing masked images to it, why not just create the bitmaps then blit the image, saving the clear_to_colour() commands?

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

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

Kevin Epps
Member #5,856
May 2005
avatar

They're not 3200 now. They're 640.

As far as the clear color. I was told that the draw_sprite call was faster than the blit call. Is that wrong?

Neil Walker
Member #210
April 2000
avatar

But you aren't doing that create_bitmap every loop are you?

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

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

Kevin Epps
Member #5,856
May 2005
avatar

no.

Here's what i have now.

1 Layer layer[9];
2 bg = load_bitmap("forest-6.gif", NULL);
3 grass[0] = load_png("grass_1_2.png", NULL);
4 grass[1] = load_png("grass_2_2.png", NULL);
5 grass[2] = load_png("grass_3_2.png", NULL);
6 grass[3] = load_png("grass_upper_2.png", NULL);
7 foreground = load_bitmap("foreground-2.gif", NULL);
8 front_trees = load_png("front_trees_2.png", NULL);
9 layer[0].init(bg, 0, 0.2);
10 layer[1].init(foreground, 0, 0.4);
11 layer[2].init(grass[3], 335, 0.6);
12 layer[3].init(grass[0], 355, 0.8);
13 layer[5].init(grass[0], 419, 1.0);
14 layer[6].init(grass[1], 429, 1.2);
15 layer[7].init(grass[2], 439, 1.4);
16 layer[8].init(front_trees, 0, 1.6);
17 destroy_bitmap(bg);
18 destroy_bitmap(foreground);
19 destroy_bitmap(front_trees);
20 destroy_bitmap(grass[0]);
21 destroy_bitmap(grass[1]);
22 destroy_bitmap(grass[2]);
23 destroy_bitmap(grass[3]);

Each file is 640x480
Here's the init function:

void init(BITMAP *src, int src_y, float src_speed)
  {
    sprite = create_video_bitmap(src->w, src->h);
    clear_to_color(sprite, makecol(255,0,255));
    draw_sprite(sprite, src, 0, 0);
    y = src_y;
    speed = src_speed;
  }

And here's how it's drawn:

1 masked_blit(layer[0].sprite, buffer, 0, 0, -((int)(camera.x*layer[0].speed)%layer[0].sprite->w), layer[0].y - camera.y*layer[0].speed, layer[0].sprite->w, layer[0].sprite->h);
2 masked_blit(layer[0].sprite, buffer, 0, 0, layer[0].sprite->w - ((int)(camera.x*layer[0].speed)%layer[0].sprite->w), layer[0].y - camera.y*layer[0].speed, layer[0].sprite->w, layer[0].sprite->h);
3 masked_blit(layer[1].sprite, buffer, 0, 0, -((int)(camera.x*layer[1].speed)%layer[1].sprite->w), layer[1].y - camera.y*layer[1].speed, layer[1].sprite->w, layer[1].sprite->h);
4 masked_blit(layer[1].sprite, buffer, 0, 0, layer[1].sprite->w - ((int)(camera.x*layer[1].speed)%layer[1].sprite->w), layer[1].y - camera.y*layer[1].speed, layer[1].sprite->w, layer[1].sprite->h);
5 masked_blit(layer[2].sprite, buffer, 0, 0, -((int)(camera.x*layer[2].speed)%layer[2].sprite->w), layer[2].y - camera.y*layer[2].speed, layer[2].sprite->w, layer[2].sprite->h);
6 masked_blit(layer[2].sprite, buffer, 0, 0, layer[2].sprite->w - ((int)(camera.x*layer[2].speed)%layer[2].sprite->w), layer[2].y - camera.y*layer[2].speed, layer[2].sprite->w, layer[2].sprite->h);
7 masked_blit(layer[3].sprite, buffer, 0, 0, -((int)(camera.x*layer[3].speed)%layer[3].sprite->w), layer[3].y - camera.y*layer[3].speed, layer[3].sprite->w, layer[3].sprite->h);
8 masked_blit(layer[3].sprite, buffer, 0, 0, layer[3].sprite->w - ((int)(camera.x*layer[3].speed)%layer[3].sprite->w), layer[3].y - camera.y*layer[3].speed, layer[3].sprite->w, layer[3].sprite->h);
9 MapDrawBGT(buffer, camera.x, camera.y, 0, 0, WIDTH-1, HEIGHT-1);
10 //draw foreground tiles
11 MapDrawFG(buffer, camera.x, camera.y, 0, 0, WIDTH-1, HEIGHT-1, 0);
12 player.draw(buffer, camera.x, camera.y);
13 masked_blit(layer[5].sprite, buffer, 0, 0, -((int)(camera.x*layer[5].speed)%layer[5].sprite->w), layer[5].y - camera.y*layer[5].speed, layer[5].sprite->w, layer[5].sprite->h);
14 masked_blit(layer[5].sprite, buffer, 0, 0, layer[5].sprite->w - ((int)(camera.x*layer[5].speed)%layer[5].sprite->w), layer[5].y - camera.y*layer[5].speed, layer[5].sprite->w, layer[5].sprite->h);
15 masked_blit(layer[6].sprite, buffer, 0, 0, -((int)(camera.x*layer[6].speed)%layer[6].sprite->w), layer[6].y - camera.y*layer[6].speed, layer[6].sprite->w, layer[6].sprite->h);
16 masked_blit(layer[6].sprite, buffer, 0, 0, layer[6].sprite->w - ((int)(camera.x*layer[6].speed)%layer[6].sprite->w), layer[6].y - camera.y*layer[6].speed, layer[6].sprite->w, layer[6].sprite->h);
17 masked_blit(layer[7].sprite, buffer, 0, 0, -((int)(camera.x*layer[7].speed)%layer[7].sprite->w), layer[7].y - camera.y*layer[7].speed, layer[7].sprite->w, layer[7].sprite->h);
18 masked_blit(layer[7].sprite, buffer, 0, 0, layer[7].sprite->w - ((int)(camera.x*layer[7].speed)%layer[7].sprite->w), layer[7].y - camera.y*layer[7].speed, layer[7].sprite->w, layer[7].sprite->h);
19 masked_blit(layer[8].sprite, buffer, 0, 0, -((int)(camera.x*layer[8].speed)%layer[8].sprite->w), layer[8].y - camera.y*layer[8].speed, layer[8].sprite->w, layer[8].sprite->h);
20 masked_blit(layer[8].sprite, buffer, 0, 0, layer[8].sprite->w - ((int)(camera.x*layer[8].speed)%layer[8].sprite->w), layer[8].y - camera.y*layer[8].speed, layer[8].sprite->w, layer[8].sprite->h);

And this works well for me now. And yes, I know that I need a for loop there and I will add it, but I also have problems when I add a for loop inside of the drawing loop. But anyway it works fine.

ReyBrujo
Moderator
January 2001
avatar

Aren't you overwritting the sprite sprite with a new one everytime you call the init function?

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

Kevin Epps
Member #5,856
May 2005
avatar

Sort of.

I'm just creating each layer sprite as a video bitmap and then drawing the 1st paramerter(loaded bitmap) to it so the now the sprite will be a video bitmap of the loaded bitmap. That's all. When an object is created, the sprite is NULL;

Tobias Dammers
Member #2,604
August 2002
avatar

Can you see that this:
 masked_blit(layer[0].sprite, buffer, 0, 0, -((int)(camera.x*layer[0].speed)%layer[0].sprite->w), layer[0].y - camera.y*layer[0].speed, layer[0].sprite->w, layer[0].sprite->h);
		masked_blit(layer[0].sprite, buffer, 0, 0, layer[0].sprite->w - ((int)(camera.x*layer[0].speed)%layer[0].sprite->w), layer[0].y - camera.y*layer[0].speed, layer[0].sprite->w, layer[0].sprite->h);
		masked_blit(layer[1].sprite, buffer, 0, 0, -((int)(camera.x*layer[1].speed)%layer[1].sprite->w), layer[1].y - camera.y*layer[1].speed, layer[1].sprite->w, layer[1].sprite->h);
		masked_blit(layer[1].sprite, buffer, 0, 0, layer[1].sprite->w - ((int)(camera.x*layer[1].speed)%layer[1].sprite->w), layer[1].y - camera.y*layer[1].speed, layer[1].sprite->w, layer[1].sprite->h);
		masked_blit(layer[2].sprite, buffer, 0, 0, -((int)(camera.x*layer[2].speed)%layer[2].sprite->w), layer[2].y - camera.y*layer[2].speed, layer[2].sprite->w, layer[2].sprite->h);
		masked_blit(layer[2].sprite, buffer, 0, 0, layer[2].sprite->w - ((int)(camera.x*layer[2].speed)%layer[2].sprite->w), layer[2].y - camera.y*layer[2].speed, layer[2].sprite->w, layer[2].sprite->h);
		masked_blit(layer[3].sprite, buffer, 0, 0, -((int)(camera.x*layer[3].speed)%layer[3].sprite->w), layer[3].y - camera.y*layer[3].speed, layer[3].sprite->w, layer[3].sprite->h);
		masked_blit(layer[3].sprite, buffer, 0, 0, layer[3].sprite->w - ((int)(camera.x*layer[3].speed)%layer[3].sprite->w), layer[3].y - camera.y*layer[3].speed, layer[3].sprite->w, layer[3].sprite->h);
		MapDrawBGT(buffer, camera.x, camera.y, 0, 0, WIDTH-1, HEIGHT-1);
		//draw foreground tiles
		MapDrawFG(buffer, camera.x, camera.y, 0, 0, WIDTH-1, HEIGHT-1, 0);
		player.draw(buffer, camera.x, camera.y);
		masked_blit(layer[5].sprite, buffer, 0, 0, -((int)(camera.x*layer[5].speed)%layer[5].sprite->w), layer[5].y - camera.y*layer[5].speed, layer[5].sprite->w, layer[5].sprite->h);
		masked_blit(layer[5].sprite, buffer, 0, 0, layer[5].sprite->w - ((int)(camera.x*layer[5].speed)%layer[5].sprite->w), layer[5].y - camera.y*layer[5].speed, layer[5].sprite->w, layer[5].sprite->h);
		masked_blit(layer[6].sprite, buffer, 0, 0, -((int)(camera.x*layer[6].speed)%layer[6].sprite->w), layer[6].y - camera.y*layer[6].speed, layer[6].sprite->w, layer[6].sprite->h);
		masked_blit(layer[6].sprite, buffer, 0, 0, layer[6].sprite->w - ((int)(camera.x*layer[6].speed)%layer[6].sprite->w), layer[6].y - camera.y*layer[6].speed, layer[6].sprite->w, layer[6].sprite->h);
		masked_blit(layer[7].sprite, buffer, 0, 0, -((int)(camera.x*layer[7].speed)%layer[7].sprite->w), layer[7].y - camera.y*layer[7].speed, layer[7].sprite->w, layer[7].sprite->h);
		masked_blit(layer[7].sprite, buffer, 0, 0, layer[7].sprite->w - ((int)(camera.x*layer[7].speed)%layer[7].sprite->w), layer[7].y - camera.y*layer[7].speed, layer[7].sprite->w, layer[7].sprite->h);
		masked_blit(layer[8].sprite, buffer, 0, 0, -((int)(camera.x*layer[8].speed)%layer[8].sprite->w), layer[8].y - camera.y*layer[8].speed, layer[8].sprite->w, layer[8].sprite->h);
		masked_blit(layer[8].sprite, buffer, 0, 0, layer[8].sprite->w - ((int)(camera.x*layer[8].speed)%layer[8].sprite->w), layer[8].y - camera.y*layer[8].speed, layer[8].sprite->w, layer[8].sprite->h);
...contains tons of duplicate code? Duplicate code is a sign that your layout isn't structured well. I'd recommend using a dedicated function for blitting a layer:
void draw_layer(int i) {
		masked_blit(layer[i].sprite, buffer, 0, 0, -((int)(camera.x*layer[i].speed)%layer[i].sprite->w), layer[i].y - camera.y*layer[i].speed, layer[i].sprite->w, layer[i].sprite->h);
		masked_blit(layer[i].sprite, buffer, 0, 0, layer[i].sprite->w - ((int)(camera.x*layer[i].speed)%layer[i].sprite->w), layer[i].y - camera.y*layer[i].speed, layer[i].sprite->w, layer[i].sprite->h);
}

Then your drawing code looks like this:
int l;

for (l = 0; l < 4; ++l)
  draw_layer(l);
MapDrawBGT(buffer, camera.x, camera.y, 0, 0, WIDTH-1, HEIGHT-1);
//draw foreground tiles
MapDrawFG(buffer, camera.x, camera.y, 0, 0, WIDTH-1, HEIGHT-1, 0);
player.draw(buffer, camera.x, camera.y);
for (l = 4; l < 9; ++l)
  draw_layer(l);
Much cleaner, and compiler-friendly. If you want to avoid the function call and loop overhead (but in this situation, that's silly IMHO), you can mark draw_code() as inline, and specify -funroll-loops -funroll-all-loops when compiling.

As for the draw_sprite() vs. blit() thing; the way you do it is certainly not the fastest, but I suggest that since it works, you leave it exactly as it is (avoiding color conversion issues). It's initialization code we're talking about here, no need to optimize unless loading takes more than 60 seconds.
For the record: draw_sprite() is not faster than blit(). It can be faster than masked_blit() under certain circumstances, and it may be as fast as blit() for accelerated video-video operations.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

Go to: