![]() |
|
Graphics API proposal (take 5) |
Bob
Free Market Evangelist
September 2000
![]() |
Here's the current proposal for the graphics API. Includes a lot more documentation, more consistent, and should reflect the ideas gathered from the main developers and the community. Please comment on it!
Note that I have a partially working implementation (on Allegro's CVS). [code] /* What coding in Allegro 5 will look like. * * Graphics API only. * * Ignore anything that's not related to the graphics API. * Aditional notes are added after the code */ /* Main differences in between the Allegro 5 and Allegro 4 API: * * - No more global "screen" variable. You must use the object * returned by al_create_display * - Video bitmaps do not share the same space as the screen. * - Virtual screen size is removed from the main API. You may still * be able to access it via the new config routines. * - Allegro will do the screen updating itself. You don't need to * worry about it, unless you really want to. In that case, you can * always take care of it yourself, just like in Allegro 4. * - Function names have the conventional verb_noun arrangement. al_blit() * will probably be excepted from this simply due to widespread use. * - Redundant functions are eliminated: draw_sprite vs masked_blit, * clear_bitmap vs clear_color, etc. * - Support for multiple monitors and windows. * - The new config system allows per-driver options to be set very * easily without bloating the API. * - Pixels are now packed into a structure to allow support for varying * formats which may not fit 32-bits. * - Pixels can be unpacked to any other format - duals as a general purpose * color space conversion routines. * - Support for bitmaps of alternate color spaces (hsv, yuv). * - FBlend included. * - Lots of stuff will be moved to add-ons, such as the FLI playing routines, * the software 3D code. * * * Advantages of the new API: * - Much better support for various graphics hardware. * - Cleaner API * - Much faster since less assumptions are made / can be made by Allegro. * - More features (see above). */ #include <allegro5.h> int al_main() { /* Initialize Allegro. Depending on how the modular approach takes place, * this line may be written differently (if at all). */ allegro_init(); /* Set up some parameters for the graphics mode to be set. * We use the new config routines for this. */ al_set_int("/gfx/color_depth", 16); al_set_int("/gfx/refresh_rate", 70); /* This function will set up a new display for our use. It should not * shut down the previous display. The user needs to do that manually. * This allows us to support multiple windows or displays. However, if * a new disply can't be created because the previous one wasn't disposed * of (full screen mode), then NULL is returned and user should read the * manual. * * The update method for the display is specified here, so that Allegro can * reserve the necessary video pages (needed by some drivers). The user can * select the update mode he wants, but isn't guaranteed to get it. * We can query back what was set. * * One page can be be allocated if users want to do their own screen * update. Some drivers already use dbl buf and dirty rectangles. So * why not expose this to the user? * Also, this can speed up drivers that use double buffering, since * Allegro programs don't have to double buffer themselves, thus saving * quite a lot of expensive blit()s. * * I've removed virtual screens, as they're only used for h/w scrolling * under DOS which doesn't even work right on most (all?) video cards. * * Sets up the display mode to auto, on a 640x480x16 screen, * with no virtual screen, and two pages. * * Returns a pointer to an object representing this display. * * Nomenclature: al_create_display() or al_create_display_bitmap()? */ BITMAP *display1 = al_create_display(AL_GFX_AUTO, 640, 480, AL_GFX_TRIPLE_BUFFERING); if (!display1) { allegro_message("%s", al_get_str("/gfx/error")); return -1; } /* Additional display bitmaps can be obtained here (multi-monitors or multi-windows) * * BITMAP *display2 = al_create_display(AL_GFX_AUTO, 640, 480, AL_GFX_DIRTY_RECTANGLES); */ allegro_message("Set up a %ix%i display\n", display1->w, display1->h); /* We create an image in video ram (perhaps we should change the name * to avoid confusion with the old way video bitmaps are handled?). * * Video bitmaps are NOT allocated on the visible screen or any video * pages. They use other parts of the video memory. * * Disadvantages: two functions for allocated video bitmaps/video pages * instead of just one. * * Advantages: simplifies code on some drivers, allows Allegro to better * map to other displays (DreamCast's Tile Accelerator, GBA's * tiles, OpenGL's textures...). The user doesn't have to * allocate his own pages for buffering. * * Video bitmaps are still read/writable. A "backup" copy can be kept in * memory by Allegro for reading back if the hardware doesn't let us read * from video memory. */ AL_BITMAP *sprite = al_create_video_bitmap(64, 64); /* The new way to map and address pixels - allows for far more * flexibility in graphics. */ AL_COLOR col; al_clear_to_color(sprite, al_map_rgb(sprite, &col, 255, 128, 0)); do { /* Get the current buffer to the screen. This can be the backbuffer of * a double buffering scheme, the second page (or third page) in page flip, * or something entirely different. * * This allows the user to switch from any one display method to any * other without changing anything else in the code appart from the * display creation call. * * Alternativaly, users can use acquire_display_page() to get a specific page. * (check caps for support). * * The selected video page is also locked (DDraw). */ al_acquire_bitmap(display1); /* draw into screen */ al_line(display1, ...); al_blit(sprite, display1, ...); /* Unlocks the video page (DDraw) * al_release_display() and al_update_dispaly() are kept separate * so that many parts of the program can draw on screen. */ al_release_bitmap(display1); /* Display the current screen buffer on the display. Either page * flipping, dbl/tripple buffering, dirty rectangles, flushing the * GL pipeline, or anything else that needs to be done to get the * frame to be rendered. * * If only one page is being used, then nothing is done here, since * the user already draws in visible screen. */ al_show_display_bitmap(display1); } while (1); /* Now that we're done with the display, we can destroy it. * This can be done automagically by allegro_exit() too. */ al_destroy_display(display1); return 0; } /* Notes: We can also select color spaces, set overlay options, etc al_set_str("/gfx/color_space", "YUV"); al_set_int("/gfx/window_x", 50); al_set_float("/gfx/window_scale_x", 2.0); al_set_int("/gfx/resizable", TRUE); al_set_int("/gfx/windowed", TRUE); These settings will only take effect after the next call to set_gfx_mode. The user can reset the settings to default. al_set_boolean("/gfx/defaults", TRUE); // Note - not nice API, must change this Some add-ons may want to register their own GFX mode (like AllegroGL) #define GFX_FUNKY_NEW_MODE "gfx/device/Funky" al_register_gfx_mode(GFX_FUNKY_NEW_MODE, &vtable); Perhaps the vtable can also contain some form of version number so that future versions of Allegro can still use the old vtables? We can also ask the display system for information about it prior to setting the screen mode: al_set_str("gfx/query/device", GFX_DIRECTX_OVERLAY); int n = al_get_int("gfx/query/num_resolutions"); while (n--) { int x, y; al_set_int("/gfx/query/resolution", n); x = al_get_int("/gfx/query/width"); y = al_get_int("/gfx/query/height"); } The GFX_* are now strings (UTF-8?), which makes them a lot more flexible. Recap of all options: / /gfx - Graphics subsystems /num_devices - The number of devices supported on the system (GFX_*). or ID for query (string, for setting). /device - Sets the device number to set/read back settings from. /name - Full name of this device. /query/device - Sets the device number to query /query/num_resolutions - Returns the number of resolutions supported by this device. /query/resolutions - Sets the resolution number for query. /query/width - Queried resolution's width (pixels) /query/height - Queried resolution's height (pixels) /query/color_depth - Queried resolution's color depth /query/color_space - Queried resolution's color space (RGB, YUV, ...) /query/window_scale_x - Maximum X scale factor (float) for overlays /query/window_scale_y - Maximum Y scale factor (float) for overlays /query/resizable - Whether or not the display can be resized at run-time. /query/max_refresh_rate - Maximum refresh rate supported by the queried resolution. /defaults - Set to TRUE to reload default options. /color_depth - Color depth of the device (bits per pixel) /color_space - Color space of the device (RGB, YUV) /width - Width of the display (pixels) /height - Height of the display (pixels) /window_x - X Position of the app window on the desktop (pixels) /window_y - Y Position of the app window on the desktop (pixels) /window_scale_x - X scale factor (float) for overlays /window_scale_y - Y scale factor (float) for overlays /resizable - Indicates if this device should support resizability. /refresh_rate - Suggests a refresh rate for the display. /error - Returns the last error. Function list: al_create_display(); - Inits display device al_create_video_bitmap(); - Creates video bitmap al_create_video_page(); - Creates a video page al_clear_to_color(); - Clears a bitmap to a certain color al_acquire_bitmap(); - Acquires a bitmap (see Al 4.0) al_acquire_bitmap_page(); - Acquires a specific page of a display al_draw_line(); - Draws a line al_blit(); - blit al_release_bitmap(); - Releases a bitmap (see Al 4.0) al_show_display_bitmap(); - Shows this bitmap on it's display al_destroy_display(); - Shuts down a display. al_create_bitmap() - Creates a memory bitmap al_destroy_bitmap() - Destroys a bitmap al_map_rgb() - same as makecol() al_map_rgba() - same as makeacol() al_unpack_pixel() - General purpose pixel conversion routine. al_set_bitmap_flag() - Parametrizes the bitmap - undecided on implementation. */ [/code] I've also attached the current graphics.h file. It contains a lot of the Allegro internals, but it may be useful to some people. The current implementation relies heavily on Allegro 4 being under it. The new API will be progressivally moved in as it matures. [code] #ifndef AL_GRAPHICS_H #define AL_GRAPHICS_H #define AL_COLOR_COMPONENT_TYPE_PALETTE 0 #define AL_COLOR_COMPONENT_TYPE_ARGB 1 #define AL_COLOR_COMPONENT_TYPE_ARGB_F 2 #define AL_COLOR_COMPONENT_TYPE_ARGB_S 3 #define AL_COLOR_COMPONENT_TYPE_YUV 4 #define AL_COLOR_COMPONENT_TYPE_HSV 5 #define AL_COLOR_COMPONENT_TYPE_RAW -1 typedef struct AL_COLOR { union { struct { unsigned char r, g, b, a; } rgba; struct { unsigned char y, u, v; } yuv; struct { float h, s, v; } hsv; struct { float r, g, b, a; } rgba_f; struct { unsigned short r, g, b, a; } rgba_s; unsigned long raw[4]; // raw pixel data } c; int type; } AL_COLOR; typedef struct al_color_rgba_vector_t { unsigned long r, g, b, a; } al_color_rgba_vector_t; #define AL_COLOR_SPACE_PALETTE_8 0 #define AL_COLOR_SPACE_RGB_888 1 #define AL_COLOR_SPACE_RGB_565 2 #define AL_COLOR_SPACE_RGB_555 3 #define AL_COLOR_SPACE_RGB_332 4 #define AL_COLOR_SPACE_ARGB_8888 5 #define AL_COLOR_SPACE_ARGB_4444 6 #define AL_COLOR_SPACE_ARGB_1555 7 typedef struct al_color_space_t { int type; // RGB, RGBA or YUV int component_type; // float, byte, packed int num_components; int bytes_per_pixel; int bits_per_pixel; al_color_rgba_vector_t component_position; // valid only on > 32 bits al_color_rgba_vector_t component_shift; // valid only on <= 32 bits al_color_rgba_vector_t component_size; al_color_rgba_vector_t component_mask; } al_color_space_t; extern const al_color_space_t *al_color_space_palette_8, *al_color_space_rgb_888, *al_color_space_rgb_565, *al_color_space_rgb_555, *al_color_space_rgb_332, *al_color_space_argb_8888, *al_color_space_argb_4444, *al_color_space_argb_1555; /* Some defines for the update mechanism */ #define AL_GFX_UPDATE_DIRECT 0 #define AL_GFX_UPDATE_DIRTY_RECTANGLES 1 #define AL_GFX_UPDATE_DOUBLE_BUFFERING 2 #define AL_GFX_UPDATE_DOUBLE_VRAM_BUFFERING 3 #define AL_GFX_UPDATE_PAGE_FLIPING 4 #define AL_GFX_UPDATE_TRIPLE_BUFFERING 5 #define AL_GFX_UPDATE_AUTO -1 typedef struct AL_BITMAP AL_BITMAP; typedef struct AL_GFX_DRIVER { int id; AL_CONST char *name; AL_CONST char *desc; AL_METHOD(struct AL_BITMAP *, init, ()); AL_METHOD(void, exit, (struct AL_BITMAP *b)); AL_METHOD(void, set_palette, (struct AL_BITMAP *display, AL_CONST struct RGB *p, int from, int to, int retracesync)); AL_METHOD(struct AL_BITMAP *, al_create_video_bitmap, (struct AL_BITMAP* parent, int width, int height)); AL_METHOD(void, destroy_video_bitmap, (struct AL_BITMAP *bitmap)); AL_METHOD(void, update_display, (struct AL_BITMAP *bitmap)); AL_METHOD(struct AL_BITMAP *, create_system_bitmap, (AL_BITMAP *parent, int width, int height)); AL_METHOD(void, destroy_system_bitmap, (struct AL_BITMAP *bitmap)); AL_METHOD(int, set_mouse_bitmap, (struct AL_BITMAP *sprite, int xfocus, int yfocus)); AL_METHOD(int, show_mouse, (struct AL_BITMAP *bmp, int x, int y)); AL_METHOD(void, hide_mouse, (void)); AL_METHOD(void, move_mouse, (struct AL_BITMAP *bmp, int x, int y)); AL_METHOD(void, save_video_state, (void)); AL_METHOD(void, restore_video_state, (void)); AL_METHOD(GFX_MODE_LIST *, fetch_mode_list, (void)); long bank_size; /* bank size, in bytes */ long bank_gran; /* bank granularity, in bytes */ long vid_mem; /* video memory size, in bytes */ long vid_phys_base; /* physical address of video memory */ int windowed; /* true if driver runs windowed */ struct AL_GFX_VTABLE *vtable; /* Pointer to vtable for drawing on this driver's bitmap */ } AL_GFX_DRIVER; typedef struct AL_GFX_DRIVER_INSTANCE { struct AL_GFX_DRIVER *driver; struct BITMAP **video_pages; /* list of all associated video pages -- HACK until I get AL_BITMAP finished */ int num_video_pages; /* number of video pages */ int write_to_page; /* index of page to write to (for user programs) */ int update_method; /* how to update the screen */ } AL_GFX_DRIVER_INSTANCE; /* Internal to Allegro - use al_get_bool instead */ #define AL_GFX_CAN_FLIP 0x00000001 #define AL_GFX_CAN_TRIPLE_BUFFER 0x00000002 #define AL_GFX_HW_CURSOR 0x00000004 #define AL_GFX_HW_HLINE 0x00000008 #define AL_GFX_HW_HLINE_XOR 0x00000010 #define AL_GFX_HW_HLINE_SOLID_PATTERN 0x00000020 #define AL_GFX_HW_HLINE_COPY_PATTERN 0x00000040 #define AL_GFX_HW_FILL 0x00000080 #define AL_GFX_HW_FILL_XOR 0x00000100 #define AL_GFX_HW_FILL_SOLID_PATTERN 0x00000200 #define AL_GFX_HW_FILL_COPY_PATTERN 0x00000400 #define AL_GFX_HW_LINE 0x00000800 #define AL_GFX_HW_LINE_XOR 0x00001000 #define AL_GFX_HW_TRIANGLE 0x00002000 #define AL_GFX_HW_TRIANGLE_XOR 0x00004000 #define AL_GFX_HW_GLYPH 0x00008000 #define AL_GFX_HW_VRAM_BLIT 0x00010000 #define AL_GFX_HW_VRAM_BLIT_MASKED 0x00020000 #define AL_GFX_HW_MEM_BLIT 0x00040000 #define AL_GFX_HW_MEM_BLIT_MASKED 0x00080000 #define AL_GFX_HW_SYS_TO_VRAM_BLIT 0x00100000 #define AL_GFX_HW_SYS_TO_VRAM_BLIT_MASKED 0x00200000 /* Internal to Allegro */ AL_VAR(int, _gfx_capabilities); /* current driver capabilities */ typedef struct AL_GFX_VTABLE /* functions for drawing onto bitmaps */ { void *unwrite_bank; /* C function on some machines, asm on i386 */ AL_METHOD(void, set_clip, (struct AL_BITMAP *bmp)); AL_METHOD(void, acquire, (struct AL_BITMAP *bmp)); AL_METHOD(void, release, (struct AL_BITMAP *bmp)); AL_METHOD(struct AL_BITMAP *, create_sub_bitmap, (struct AL_BITMAP *parent, int x, int y, int width, int height)); AL_METHOD(void, created_sub_bitmap, (struct AL_BITMAP *bmp, struct AL_BITMAP *parent)); AL_METHOD(AL_COLOR, getpixel, (struct AL_BITMAP *bmp, int x, int y)); AL_METHOD(void, putpixel, (struct AL_BITMAP *bmp, int x, int y, AL_COLOR color)); AL_METHOD(void, vline, (struct AL_BITMAP *bmp, int x, int y1, int y2, AL_COLOR color)); AL_METHOD(void, hline, (struct AL_BITMAP *bmp, int x1, int y, int x2, AL_COLOR color)); AL_METHOD(void, hfill, (struct AL_BITMAP *bmp, int x1, int y, int x2, AL_COLOR color)); AL_METHOD(void, line, (struct AL_BITMAP *bmp, int x1, int y1, int x2, int y2, AL_COLOR color)); AL_METHOD(void, rectfill, (struct AL_BITMAP *bmp, int x1, int y1, int x2, int y2, AL_COLOR color)); AL_METHOD(int, triangle, (struct AL_BITMAP *bmp, int x1, int y1, int x2, int y2, int x3, int y3, AL_COLOR color)); AL_METHOD(void, draw_sprite, (struct AL_BITMAP *bmp, struct BITMAP *sprite, int x, int y, int v_flip, int h_flip)); AL_METHOD(void, draw_256_sprite, (struct AL_BITMAP *bmp, struct AL_BITMAP *sprite, int x, int y)); /* Should use FBlend's syntax? */ AL_METHOD(void, draw_trans_sprite, (struct AL_BITMAP *bmp, struct AL_BITMAP *sprite, int x, int y)); AL_METHOD(void, draw_trans_rgba_sprite, (struct AL_BITMAP *bmp, struct AL_BITMAP *sprite, int x, int y)); AL_METHOD(void, draw_lit_sprite, (struct AL_BITMAP *bmp, struct AL_BITMAP *sprite, int x, int y, AL_COLOR color)); /* What about those? */ AL_METHOD(void, draw_rle_sprite, (struct AL_BITMAP *bmp, AL_CONST struct RLE_SPRITE *sprite, int x, int y)); AL_METHOD(void, draw_trans_rle_sprite, (struct AL_BITMAP *bmp, AL_CONST struct RLE_SPRITE *sprite, int x, int y)); AL_METHOD(void, draw_trans_rgba_rle_sprite, (struct AL_BITMAP *bmp, AL_CONST struct RLE_SPRITE *sprite, int x, int y)); AL_METHOD(void, draw_lit_rle_sprite, (struct AL_BITMAP *bmp, AL_CONST struct RLE_SPRITE *sprite, int x, int y, AL_COLOR color)); /* What do those do? Should we keep them? Shouldn't all fonts be colored? */ AL_METHOD(void, draw_character, (struct AL_BITMAP *bmp, struct AL_BITMAP *sprite, int x, int y, AL_COLOR color)); AL_METHOD(void, draw_glyph, (struct AL_BITMAP *bmp, AL_CONST struct FONT_GLYPH *glyph, int x, int y, AL_COLOR color)); /* I'll do those later */ AL_METHOD(void, blit_from_memory, (struct AL_BITMAP *source, struct AL_BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height)); AL_METHOD(void, blit_to_memory, (struct AL_BITMAP *source, struct AL_BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height)); AL_METHOD(void, blit_from_system, (struct AL_BITMAP *source, struct AL_BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height)); AL_METHOD(void, blit_to_system, (struct AL_BITMAP *source, struct AL_BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height)); AL_METHOD(void, blit_to_self, (struct AL_BITMAP *source, struct AL_BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height)); /* Shouldn't blit_to_self be smarter? */ AL_METHOD(void, blit_to_self_forward, (struct AL_BITMAP *source, struct AL_BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height)); AL_METHOD(void, blit_to_self_backward, (struct AL_BITMAP *source, struct AL_BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height)); /* We need to merge color converters */ AL_METHOD(void, blit_between_formats, (struct AL_BITMAP *source, struct AL_BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height)); AL_METHOD(void, masked_blit, (struct AL_BITMAP *source, struct AL_BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height)); AL_METHOD(void, clear_to_color, (struct AL_BITMAP *bitmap, AL_COLOR color)); AL_METHOD(void, pivot_scaled_sprite_flip, (struct AL_BITMAP *bmp, struct AL_BITMAP *sprite, fixed x, fixed y, fixed cx, fixed cy, fixed angle, fixed scale, int v_flip)); AL_METHOD(void, draw_sprite_end, (void)); AL_METHOD(void, blit_end, (void)); AL_METHOD(AL_COLOR, map_rgb, (int r, int g, int b)); AL_METHOD(AL_COLOR, map_rgba, (int r, int g, int b, int a)); AL_METHOD(AL_COLOR, map_rgba_f, (float r, float g, float b, float a)); AL_METHOD(AL_COLOR, map_yuv, (int y, int u, int v)); AL_METHOD(AL_COLOR, map_yuv_f, (float y, float u, float v)); } AL_GFX_VTABLE; #define AL_BMP_VIDEO_DEVICE 1 #define AL_BMP_LINEAR 2 #define AL_BMP_FLAT_MEMORY 4 #define AL_BMP_PLANNAR 8 #define AL_BMP_PALETTIZED 16 #define AL_BMP_RLE_ENCODED 32 //stolen from SDL struct AL_BITMAP { int w, h; int id; int flags; al_color_space_t *color_space; AL_COLOR mask_color; /* mask color for this bitmap. Can make this user-writable? */ /* Reserved for gfx driver */ BITMAP *backbuffer; //Temporary 'hack' until I rewrite the line pointers struct AL_GFX_DRIVER_INSTANCE *driver; /* If not NULL, points to the gfx driver */ struct AL_GFX_VTABLE *vtable; }; /* Video Drivers */ #define AL_GFX_AUTO "Auto" extern int al_install_graphics(); extern int al_register_graphic_driver(AL_GFX_DRIVER *driver); extern AL_BITMAP *al_create_bitmap(int w, int h, int depth); extern AL_BITMAP *al_create_video_bitmap(AL_BITMAP *display, int w, int h); extern void al_destroy_bitmap(AL_BITMAP *bmp); extern AL_BITMAP *al_create_display(char *device, int w, int h, int update_method); extern void al_destroy_display(AL_BITMAP *dispaly); extern void al_acquire_display(AL_BITMAP *display); extern void al_release_display(AL_BITMAP *display); extern void al_update_display(AL_BITMAP *display); extern void al_blit(AL_BITMAP *src, AL_BITMAP *dest, int sx, int sy, int dx, int dy, int w, int h); extern void al_line(AL_BITMAP *dest, int x1, int y1, int x2, int y2, AL_COLOR* color); extern void al_clear_to_color(AL_BITMAP *dest, AL_COLOR* color); extern AL_COLOR *al_map_rgb(AL_BITMAP *bmp, AL_COLOR *c, int r, int g, int b); extern AL_COLOR *al_unpack_pixel(AL_COLOR *pixel, int type); #endif [/code] -- |
Thomas Fjellstrom
Member #476
June 2000
![]() |
Wery Interestink. I like. Only think I can think to ask is, how efficient can the Dirty rect handling be for most things? Isn't Dirty rects better to implement based on the ussage? I'm sure it won't play with the rect list every pixel or something stupid like that. Are they updated on al_update? Good work. Someone has to remind me to work on the Alsa midi driver (for alsa 0.9.*/1.0...). And maybe the pcm driver if I have time. (Im just waiting till the alsa midi api stabalizes.. If it hasn't, but I haven't heard anything about it yet...) -- |
Bob
Free Market Evangelist
September 2000
![]() |
AFAIK dirty rectangles would be implemented on a per-primitive scale. Each time you draw a primitive on the screen, a rectangle would be created and stored. It would then be compared to the current list of rectangles and merged / split with them to reduce / eliminate overlap. -- |
Richard Phipps
Member #1,632
November 2001
![]() |
Bob, I like it.. I think coloured fonts are a standard requirment of the new API. Also a user selectable mask colour would be very useful in allowing the user to create new masks. Would including bit masks on a seperate bitmap not be a little bit faster for masked_blitting? Or is the gain neglible? Rich |
lwithers
Member #630
September 2000
|
I agree with Richard on both coloured fonts (which are actually easier to implement than mono fonts) and that we should be able to use a separate mask bitmap. I think the separate mask bitmap would be slightly slower because you are reading twice as much stuff, but still... We could even have a 'create_mask()' function which returns an RLE mask, small and efficient. |
Richard Phipps
Member #1,632
November 2001
![]() |
If a RLE Mask was created and used then the source pixels would not be needed to be checked to see if they are the Mask Colour. All that would be needed would be a decreasing run_count variable. So this method may actually be quicker for masked_blitting (and allow different masks)! Rich |
spellcaster
Member #1,493
September 2001
![]() |
Regarding fonts: /** Renders an antialiased font using a given texture. @param dest pointer to the destination BITMAP @param x x position of the text @param y y position of the text @param font pointer to the used font @param texture pointer to a bitmap holding the color values to use for the text. @param text the string to print @return the x position of the string end */ int textoutAATextured(BITMAP *dest, int x, int y, FONT *font, BITMAP* texture, const char* string); This allows me to blit single colored antialiased fonts, colored antialised font, etc. I've also realized that even with just 4 levels of alpha you can get really nice looking fonts. If you're using 8 levels of alpha, there's almost no loss in quality compared to the 256 levels of antialiasing. My implementation is just a trivial one, but if one of the gurus (Bob?) would have a look at it, it could become a really fast routine. -- |
Peter Hull
Member #1,136
March 2001
|
BRILLIANT Would it be possible to get rid of 'blit' as a word and replace it with 'draw' (also losing the funny source, destination ordering) void al_draw(AL_BITMAP* dest, AL_BITMAP* src, int x, int y); void al_draw_section(AL_BITMAP* dest, AL_BITMAP* src, int x, int y, int sx, int sy, int sw, int sh); void al_draw_scaled(AL_BITMAP* dest, AL_BITMAP* src, int dx, int dy, int dw, int dh, int sx, int sy, int sw, int sh); Then something in the BITMAP vtable tells if it's masked or RLE or compiled or not. AL_BITMAP* al_create_masked(AL_BITMAP*); AL_BITMAP* al_create_rle(AL_BITMAP*); AL_BITMAP* al_create_compiled(AL_BITMAP*); ... AL_BITMAP* bmp=al_load_bitmap("xxx.bmp", palette); AL_BITMAP* bmp_m=al_create_masked(bmp); ... al_draw(screen, bmp, 0, 0); /* draw normal */ al_draw(screen, bmp_m, 0, 0); /* draw masked */
where bmp and bmp_m have the same sort of relationship as a bitmap and its sub-bitmap inline void al_draw(AL_BITMAP* d, AL_BITMAP* s, int x, int y) { (s->vtable->blit)(s, d, 0, 0, x, y, s->w, s->h); } inline AL_BITMAP* al_create_masked(AL_BITMAP* b) { AL_BITMAP* nb=create_bitmap(b->w, b->h); blit(b, nb, 0, 0, 0, 0, b->w, b->h); /* blit is a private API function */ nb->vtable->blit=blit_masked; return nb; } Sorry if I've mentioned this before. Pete ps. Spellcasters fonts are a great idea too
|
Mars
Member #971
February 2001
![]() |
Would font support be implemented as a module? It doesn't really belong to the absolute core functionality of Allegro. So if it can be seperated, it should be seperated. I quite like the graphics api. But I, too, have objections regarding the commeon implementation of dirty rectangles. I think in most cases you need to write your own routines to get really good performance, but for most people a standard Allegro system may be good enough. -- |
Thomas Harte
Member #33
April 2000
![]() |
I still say that : char string[30]; sprintf(string, "%s/color_depth", gfxname1); al_set_int(string, 16); ...
Why not either : disp1 = al_open("/gfx"); al_set_int(disp1, "/color_depth", 16); ... al_close(disp1); ? [My site] [Tetrominoes] |
Richard Phipps
Member #1,632
November 2001
![]() |
Ok, I sometimes need to use masked_blit and blit with the same bitmap. So having one command to do both will be a problem. Also I don't see what the problem is with al_blit(source, destination.. ); Just make sure all the drawing commands use the source, destination assumption. Rich. |
spellcaster
Member #1,493
September 2001
![]() |
I agee. So, the costs involved in switching would be quite high. Regarding the Quote: al_set_int("/gfx/color_depth", 16); How do you set the color depth for a certain window? Or display? Since multi window/ display is going to be supported in allegro5, don't we need to do something like: al_set_int("/gfx/display0/color_depth", 16); The problem here is, that before the call to al_create_display() it's not clear how many displays we're going to have. al_set_int("/gfx/display0/color_depth", 16); al_set_int("/gfx/display1/color_depth", 24); al_set_int("/gfx/display2/color_depth", 32); BITMAP *display0 = al_create_display(AL_GFX_AUTO, 640, 480, AL_GFX_TRIPLE_BUFFERING); BITMAP *display1 = al_create_display(AL_GFX_AUTO, 640, 480, AL_GFX_TRIPLE_BUFFERING); BITMAP *display2 = al_create_display(AL_GFX_AUTO, 640, 480, AL_GFX_TRIPLE_BUFFERING); How do we set display properties (like color depth) before we know how many displays are going to be created? -- |
Bob
Free Market Evangelist
September 2000
![]() |
spellcaster: It'll look more like this:
Quote: I still say that : Then create your displays from the same thread, or do the section locking yourself. Allegro 4.2/5.0 may get a mini synchronization module, so you can use the "platform independent" locks yourself. Peter Hull: blit stays. There's also no sense in making a copy of a bitmap just to set it's masked parameter. Better to have a function which can deal with masked bitmap, translucency and so on. Perhaps something like al_draw_bitmap(source, dest, AL_BITMAP_MASKED | AL_BITMAP_ADD, 0, 0, 0, 0, source->w, source->h); spellcaster: Quote: My implementation is just a trivial one, but if one of the gurus (Bob?) would have a look at it, it could become a really fast routine.
Probably not. I'd rather use color add effects instead - then we can re-use the blenders. Quote: If a RLE Mask was created and used then the source pixels would not be needed to be checked to see if they are the Mask Colour. All that would be needed would be a decreasing run_count variable. So this method may actually be quicker for masked_blitting (and allow different masks)! Sure, it would allow different masks. It'll be dog slow though. CPUs don't like if's. That's especially true when it can't predict when the jump will occur or not. If the CPU mispredicts the jump, then there's a cost of hundreds of cycles (if not more). If you look at the current implementation of masked_blit's SSE code, there are no conditional jumps beyond the loop management. Ideally, we could add a function that would draw a mask over a certain bitmap. Getting an MMX optimized version of that would be fairly trivial. User defined mask colors are still in limbo though. -- |
Richard Phipps
Member #1,632
November 2001
![]() |
Bob, I thought the RLE sprite blitting routines already in Allegro were supposed to be fast? Surely they involve if's in the inner loops? Where is the low-level source for the Blitting routines? I can't seem to find them besides the higher level blit routines. Rich. |
Peter Hull
Member #1,136
March 2001
|
OK then. I personally seem to use a bitmap either masked or not masked. Bob: I meant they would share pixel data- think of it as getting a different interface to a block of data. Rich: the only problem with blit is (1) I don't like the word Pete
|
Richard Phipps
Member #1,632
November 2001
![]() |
hmm.. the problem with al_draw is that doesn't explicitly say that it's for blitting. What I mean is that you could have al_draw_line, al_draw_rectangle, al_draw_circle, and then al_draw.. may be confusing what al_draw actually does to newbies at first. I agree blit is a bit of a technical word for newbies too. I suppose you could call it al_copy_block or al_draw_block, but that's getting a little long winded to type for a very common function name. I only use blit, never draw_sprite, which explains my source, destination bitmap bias. I think that this order should be the norm because all the drawing primitives have a source parameter. So to me it's natural that functions which use two bitmaps would have the source first too and then the destination bitmap. Rich |
lwithers
Member #630
September 2000
|
Quote: may be confusing what al_draw actually does to newbies at first. Yes, I agree: we really should call it al_blit. After all, `blit' is hardly too complex a word for people who program games for a hobby! Quote: all the drawing primitives have a source parameter No, they all have a destination parameter. Personally, I would prefer dest, src ordering since that is mainly what is used in the C library, and it mimics assignment, but I'm not really that bothered about it, because I never have problems with draw_sprite() or blit(), and I use both. |
Javier Gonzalez
Member #1,559
October 2001
![]() |
As I said in another topic in the allegro developers list, in Allegro 5 instead of so much defines we could use enums. eg: from #define AL_COLOR_COMPONENT_TYPE_PALETTE 0 #define AL_COLOR_COMPONENT_TYPE_ARGB 1 #define AL_COLOR_COMPONENT_TYPE_ARGB_F 2 #define AL_COLOR_COMPONENT_TYPE_ARGB_S 3 #define AL_COLOR_COMPONENT_TYPE_YUV 4 #define AL_COLOR_COMPONENT_TYPE_HSV 5 #define AL_COLOR_COMPONENT_TYPE_RAW -1 int type; to enum AL_COLOR_COMPONENT_TYPE { AL_COLOR_COMPONENT_TYPE_PALETTE, AL_COLOR_COMPONENT_TYPE_ARGB, AL_COLOR_COMPONENT_TYPE_ARGB_F, AL_COLOR_COMPONENT_TYPE_ARGB_S, AL_COLOR_COMPONENT_TYPE_YUV, AL_COLOR_COMPONENT_TYPE_HSV, AL_COLOR_COMPONENT_TYPE_RAW }; enum AL_COLOR_COMPONENT_TYPE type;
after all, that's what enums are for
|
Thomas Harte
Member #33
April 2000
![]() |
Quote: al_set_int("/gfx/windowed", TRUE); So it will not be possible to write an application which supports switching between windowed and full screen display? One other thing, what do you intend to do about the macros such as bmp_select and bmp_read_line? Will there names now fit the rest of the scheme, or will they remain confusing and seperate, appearing almost designed to confuse people you don't think should be using them, as they have done before? [My site] [Tetrominoes] |
Richard Phipps
Member #1,632
November 2001
![]() |
oopps! Sorry, I got that source - dest thing mixed up there! DOH! Oh well.. Rich |
Bob
Free Market Evangelist
September 2000
![]() |
Javier: Good idea. I forgot about that, thanks for reminding me of. I'll add it to the current codebase. Thomas: Edit: -- |
Javier Gonzalez
Member #1,559
October 2001
![]() |
I don't see what you mean, I just tried this program compiled with DJGPP (-Wall) and MSVC (max warning level):
and I didn't get any warning or error.
|
Bob
Free Market Evangelist
September 2000
![]() |
Ah ok - you're not using typedefs. In C, you need to use typedef, or else drag the word "enum" everywhere. If we use "typedef enum" in allegro.h, then they'll break in C++. -- |
Javier Gonzalez
Member #1,559
October 2001
![]() |
I still don't see the problem
and still no problems Are there still any other cons to not use them?
|
Thomas Harte
Member #33
April 2000
![]() |
Quote: Thomas: No, since changing display mode can break any video bitmaps you have you need to destroy and recreate those also. I was just wondering if Allegro was going to help at all with that issue? Of course I understand that it isn't an easy thing to do automatically since, for example, you may not be able to keep as much in video memory in the new mode as in the old, but certainly a large quantity of the work can be done for the user if memory copies are to be kept of video bitmaps anyway, which I'm sure I saw mentioned somewhere. So will there be a few new API functions for helping with this sort of thing, or will the user be entirely on their own? [My site] [Tetrominoes] |
|
|