What form of bitmap is faster?
Kevin Epps

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

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.

Kevin Epps

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

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.

CGamesPlay

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.

Kevin Epps

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

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...

Kevin Epps

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

Which is your bitmap depth? 8bpp?

Kevin Epps

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

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.

Kevin Epps

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

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?

Kevin Epps

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

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

Kevin Epps

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

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

Kevin Epps

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
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.
Thread #558321. Printed from Allegro.cc