Re: [AD] new_api_branch: al_create_display and blit patch |
[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
On Sunday 15 May 2005 00:58, Evert Glebbeek wrote:
> Two patches attached. The first removes the v_w and v_h parameters from
> al_create_display, conforming more to the original design. For the
> compatibility layer this means that set_gfx_mode() now ignores the last
> two parameters completely. I don't think it's really important in
> practice.
Commited with updates. This means that for instance exupdate from 4.2 won't
work with page flipping in X11 or other platforms for which the vram is a
single surface. No problem because the new display API does the page
flipping anyway. Attached is a hacked-up exupdate for those who want to
take a look at it.
I've spend the afternoon trying to get `video bitmaps' to work somewhat
sensibly in X11 (ie, by allocating them all as seperate entities rather
than as subbitmaps of a large bitmap) and I've more or less figured out
that the way it is currently done is about optimal: I was able to get the
new code to run, but not without insane flickering otherwise. It's not a
big issue though: it's up to the graphics driver to decide how video
bitmaps are best implemented and if the current way is the best, then so
be it. To make this work, all display drivers need to be aware of the
flags passed to al_create_display(). This is a rather lengthy and boring
update I've worked around for now.
I have hit a bit of a snag though: when doing page flipping, X event queue
is flooded. From what I can tell, it's the same problem that used to
plague expal. This doesn't happen with 4.2, so it's due to a difference
between the 4.2 and 4.3 X11 driver. Probably there needs to be an XSync()
somewhere, but I can't figure out where. Someone with a better
understanding of the driver than I have may want to have a look at it.
I haven't commited my blit() patch yet.
By the way, can we have a compat header file for compatibility stuff, just
as we have compat C files? It'll help clean up some of the headers.
Evert
/*
* Example program for the Allegro library, by Shawn Hargreaves.
*
* This program demonstrates how to support double buffering,
* page flipping, and triple buffering as options within a single
* program, and how to make things run at a constant rate no
* matter what the speed of your computer. You have to use this
* example from the commandline to specify as first parameter a
* number which represents the type of video update you want: 1
* for double buffering with memory bitmaps, 2 for page flipping,
* 3 for triple buffering and 4 for double buffering with system
* bitmaps. After this, a dialog allows you to select a screen
* resolution and finally you will see a kaleidoscopic animation,
* along with a frames per second counter on the top left of
* the screen.
*/
#include <allegro.h>
/* number of video memory pages:
* 1 = double buffered
* 2 = page flipping
* 3 = triple buffered
*/
int num_pages;
int use_system_bitmaps;
/* counters for speed control and frame rate measurement */
volatile int update_count = 0;
volatile int frame_count = 0;
volatile int fps = 0;
/* timer callback for controlling the program speed */
void timer_proc(void)
{
update_count++;
}
END_OF_FUNCTION(timer_proc)
/* timer callback for measuring the framerate */
void fps_proc(void)
{
fps = frame_count;
frame_count = 0;
}
END_OF_FUNCTION(fps_proc)
/* some rotation values for the graphical effect */
fixed r1 = 0;
fixed r2 = 0;
fixed r3 = 0;
fixed r4 = 0;
/* helper to draw four mirrored versions of a triangle */
void kalid(BITMAP *bmp, int x1, int y1, int x2, int y2, int x3, int y3,
int r, int g, int b)
{
triangle(bmp, SCREEN_W/2+x1, SCREEN_H/2+y1, SCREEN_W/2+x2, SCREEN_H/2+y2,
SCREEN_W/2+x3, SCREEN_H/2+y3, makecol(r, g, b));
triangle(bmp, SCREEN_W/2-x1, SCREEN_H/2+y1, SCREEN_W/2-x2, SCREEN_H/2+y2,
SCREEN_W/2-x3, SCREEN_H/2+y3, makecol(r, g, b));
triangle(bmp, SCREEN_W/2-x1, SCREEN_H/2-y1, SCREEN_W/2-x2, SCREEN_H/2-y2,
SCREEN_W/2-x3, SCREEN_H/2-y3, makecol(r, g, b));
triangle(bmp, SCREEN_W/2+x1, SCREEN_H/2-y1, SCREEN_W/2+x2, SCREEN_H/2-y2,
SCREEN_W/2+x3, SCREEN_H/2-y3, makecol(r, g, b));
}
/* draws the current animation frame into the specified bitmap */
void draw_screen(BITMAP *bmp)
{
fixed c1 = fixcos(r1);
fixed c2 = fixcos(r2);
fixed c3 = fixcos(r3);
fixed c4 = fixcos(r4);
fixed s1 = fixsin(r1);
fixed s2 = fixsin(r2);
fixed s3 = fixsin(r3);
fixed s4 = fixsin(r4);
acquire_bitmap(bmp);
clear_bitmap(bmp);
xor_mode(TRUE);
kalid(bmp, fixtoi(c1*SCREEN_W/3), fixtoi(s1*SCREEN_H/3),
fixtoi(c2*SCREEN_W/3), fixtoi(s2*SCREEN_H/3),
fixtoi(c3*SCREEN_W/3), fixtoi(s3*SCREEN_H/3),
127+fixtoi(c1*127), 127+fixtoi(c2*127), 127+fixtoi(c3*127));
kalid(bmp, fixtoi(s1*SCREEN_W/3), fixtoi(c2*SCREEN_H/3),
fixtoi(s3*SCREEN_W/3), fixtoi(c4*SCREEN_H/3),
fixtoi(c3*SCREEN_W/3), fixtoi(s4*SCREEN_H/3),
127+fixtoi(s1*127), 127+fixtoi(c4*127), 127+fixtoi(s4*127));
kalid(bmp, fixtoi(fixmul(s2, c3)*SCREEN_W/3), fixtoi(c1*SCREEN_H/3),
fixtoi(c4*SCREEN_W/3), fixtoi(fixmul(c2, s3)*SCREEN_H/3),
fixtoi(fixmul(c3, s4)*SCREEN_W/3), fixtoi(s1*SCREEN_H/3),
127+fixtoi(s2*127), 127+fixtoi(c3*127), 127+fixtoi(s3*127));
xor_mode(FALSE);
if (num_pages == 1) {
if (use_system_bitmaps)
textout_ex(bmp, font, "Double buffered (system bitmap)", 0, 0,
makecol(255, 255, 255), -1);
else
textout_ex(bmp, font, "Double buffered (memory bitmap)", 0, 0,
makecol(255, 255, 255), -1);
}
else if (num_pages == 2)
textout_ex(bmp, font, "Page flipping (two pages of vram)", 0, 0,
makecol(255, 255, 255), -1);
else
textout_ex(bmp, font, "Triple buffered (three pages of vram)", 0, 0,
makecol(255, 255, 255), -1);
textout_ex(bmp, font, gfx_driver->name, 0, 16, makecol(255, 255, 255), -1);
textprintf_ex(bmp, font, 0, 32, makecol(255, 255, 255), -1, "FPS: %d", fps);
release_bitmap(bmp);
}
/* called at a regular speed to update the program state */
void do_update(void)
{
r1 += ftofix(0.5);
r2 += ftofix(0.6);
r3 += ftofix(0.11);
r4 += ftofix(0.13);
}
int main(int argc, char *argv[])
{
PALETTE pal;
int card = GFX_AUTODETECT;
int w, h, bpp, i;
int flags = 0;
int update_flags[] = { AL_UPDATE_DOUBLE_BUFFER, AL_UPDATE_PAGE_FLIP,
AL_UPDATE_TRIPLE_BUFFER, AL_UPDATE_DOUBLE_BUFFER };
if (allegro_init() != 0)
return 1;
/* check command line arguments */
if (argc == 2)
num_pages = atoi(argv[1]);
else
num_pages = 0;
if (num_pages)
flags = update_flags[num_pages-1];
if (num_pages == 4) {
num_pages = 1;
use_system_bitmaps = TRUE;
}
else
use_system_bitmaps = FALSE;
if ((num_pages < 1) || (num_pages > 3)) {
allegro_message("\nUsage: 'exupdate num_pages', where num_pages is one of:\n\n"
"1 = double buffered (memory bitmap)\n\n"
" + easy, reliable\n"
" + drawing onto a memory bitmap is very fast\n"
" - blitting the finished image to the screen can be quite slow\n\n"
"2 = page flipping (two pages of video memory)\n\n"
" + avoids the need for a memory to screen blit of the completed image\n"
" + can use hardware acceleration when it is available\n"
" - drawing directly to vram can be slower than using a memory bitmap\n"
" - requires a card with enough video memory for two screen pages\n\n"
"3 = triple buffered (three pages of video memory)\n\n"
" + like page flipping, but faster and smoother\n"
" - requires a card with enough video memory for three screen pages\n"
" - only possible with some graphics drivers\n\n"
"4 = double buffered (system bitmap)\n\n"
" + as easy as normal double buffering\n"
" + system bitmaps can be hardware accelerated on some platforms\n"
" - drawing to system bitmaps is sometimes slower than memory bitmaps\n\n");
return 1;
}
/* set up Allegro */
install_keyboard();
install_timer();
install_mouse();
if (al_create_display(GFX_SAFE, 0, 8, 320, 200) == NULL) {
allegro_message("Unable to set any graphic mode\n%s\n", allegro_error);
return 1;
}
set_palette(desktop_palette);
w = SCREEN_W;
h = SCREEN_H;
bpp = bitmap_color_depth(screen);
if (!gfx_mode_select_ex(&card, &w, &h, &bpp))
return 0;
al_destroy_display(al_main_display);
if (al_create_display(card, flags, bpp, w, h) == NULL) {
allegro_message("Error setting graphics mode\n%s\n", allegro_error);
return 1;
}
generate_332_palette(pal);
pal[0].r = pal[0].g = pal[0].b = 0;
set_palette(pal);
/* install timer handlers to control and measure the program speed */
install_int_ex(timer_proc, BPS_TO_TIMER(60));
install_int_ex(fps_proc, BPS_TO_TIMER(1));
/* main program loop */
while (!keypressed()) {
/* draw the next frame of graphics */
draw_screen(al_get_buffer(al_main_display));
al_flip_display(al_main_display);
/* update the program state */
while (update_count > 0) {
do_update();
update_count--;
}
frame_count++;
}
al_destroy_display(al_main_display);
return 0;
}
END_OF_MAIN()