Hi there.
I've been experimenting with a program that plots a number of points on the screen, which causes the effect of a cloud rising from the bottom to the top of the screen.
The program is listed below. The programming is nowhere near perfect, however i've run into a problem. As soon as I use the set_palette command to get the palette from a background scrren that i'm loading, the program runs at a snails pace. If I remove the command, the program runs nice and quick.
The background screen is an 8 bit 800x600 screen.
Any ideas as to what could be causing this.
Thanks in advance.
//
// Particle Experiment Program
//
#include <allegro.h>
// Declare Bitmaps
BITMAP *buffer1;
BITMAP *mainscreen;
PALLETE startup;
// Init graphics
int init_graphics()
{
buffer1=create_bitmap(800,600);
mainscreen=load_bitmap("background.pcx",startup);
set_palette(startup);
}
// define structure for holding star particle details
// x,y = xy position
// dx,dy = x,y velocity
// col = current colour
struct{
int enabled, x,y,dx,dy,col;
} stars[1000];
// Initialise star starting positions
int init_stars()
{
srand( time(NULL) );
int n;
for (n=0; n<=500;n++){
stars[n].x=400;
stars[n].y=500;
stars[n].dx=0;
stars[n].dy=0;
stars[n].col=(n/2);
}
}
// Display rising cloud
int stars_rising_cloud()
{
int n;
// Update star positions
for (n=0; n<=500;n++){
stars[n].x+=(rand()%13)-6;
stars[n].y-=(rand()%3);
}
// Put background screen on buffer first
blit(mainscreen, buffer1, 0, 0, 0, 0, 800, 600);
// Draw stars on buffer and then blit to scren
for (n=0; n<=500;n++){
putpixel(buffer1, stars[n].x,stars[n].y,stars[n].col);
}
blit(buffer1, screen, 0, 0, 0, 0, buffer1->w, buffer1->h);
}
int main(void)
{
int n;
/* you should always do this at the start of Allegro programs */
if (allegro_init() != 0)
return 1;
/* set up the keyboard handler */
install_keyboard();
/* set a graphics mode */
set_gfx_mode(GFX_AUTODETECT, 800, 600, 0, 0) != 0;
/* set colour depth to 16 bits */
set_color_depth(16);
// Initialsie stuff
init_graphics();
init_stars();
// Do stars_rising_cloud loop 700 times
for (n=0; n<=50;n++){
stars_rising_cloud();
}
/* you must always release bitmaps before calling any input functions */
release_screen();
/* wait for a keypress */
readkey();
return 0;
}
END_OF_MAIN()
set_palette can cause the program to wait for a fresh vertical blank interrupt before changing the colours which can halve your frame rate. However, unless your palette changes you only need to call it once outside your main loop.
Do not call the function inside your main loop!
Also set the color depth before setting the gfx mode.
On another note, you're allocating 1000 stars, but only using 501. 1002 rand() calls may not be that fast, and 501 putpixels may not be fast either.
Blit is your problem. It is slow.
1 | int stars_rising_cloud() |
2 | { |
3 | int n; |
4 | // Update star positions |
5 | for (n=0; n<=500;n++){ |
6 | stars[n].x+=(rand()%13)-6; |
7 | stars[n].y-=(rand()%3); |
8 | } |
9 | // Put background screen on buffer first |
10 | //blit(mainscreen, buffer1, 0, 0, 0, 0, 800, 600); |
11 | // Draw stars on buffer and then blit to scren |
12 | for (n=0; n<=500;n++){ |
13 | putpixel(screen, stars[n].x,stars[n].y,stars[n].col); |
14 | } |
15 | //blit(buffer1, screen, 0, 0, 0, 0, buffer1->w, buffer1->h); |
16 | |
17 | |
18 | } |
first off I don't have that background.pcx so I had to "invent one" and when I took out the first blit the program ran 2x faster. and instead of blitting I just wrote to the screen. Bad I know but I just wanted to see it faster.
Generally, when pasting source code its nice to encapsulate them in [code] tags. Like so:
<code> void foobar(int); int var = 5; foobar(5 * 2); </code>
Don't draw directly to the screen. Just don't.
Blit is your problem. It is slow.
Only because of how he's using it. The buffer is created as a 16-bit bitmap (since it's called after set_color_depth), but the screen is 8-bit (since set_gfx_mode is called before). Converting to paletted mode, especially without a lookup table, is excruciatingly slow.
More problems than you ever wanted to know about eh Gary?