home *** CD-ROM | disk | FTP | other *** search
-
- This is a fast framebuffer-level graphics library for linear 1, 2, 3 and 4
- byte-per-pixel modes (256-color, hicolor, truecolor). It uses a limited
- number of functions from svgalib (libvga) for low-level hardware
- communication (the library is included in the svgalib shared image).
- In particular, svgalib maps the 64K VGA frame buffer window, and this library
- directly addresses the buffer. For SVGA modes that use more than 64K of
- screen memory, SVGA paging is required when writing to the physical screen;
- this is done automatically for most functions (at a certain cost).
- Alternatively, any number of virtual screens of any type in system memory can
- be used, which can then be copied to the physical screen. There is also
- support for 4 bytes per pixel framebuffers (and copying them to a 3 bytes per
- pixel context), and limited planar 256 color mode support (copyscreen,
- aligned putbox).
-
- The planar 256 color modes (available on all VGA cards) can now be used
- with a virtual screen, which is copied to the physical screen (with optional
- page-flipping).
-
- Bitmaps are raw, with one (or more) bytes per pixel (like pixmaps in X),
- stored in row-major order. They are usually manipulated with the getbox
- and putbox functions.
-
- A graphics context is just a structure that holds the size of the associated
- graphics screen, how it is organized, clipping status etc. You can define a
- custom virtual (system memory) graphics context of any size with the
- setcontextvirtual function. All operations work on the current context.
-
- Any questions, bug-reports, additions, suggestions etc. are welcome.
-
-
- Functions (all have a "gl_" prefix):
-
- - simple line drawing
-
- setpixel( int x, int y, int c )
- Draw a single pixel at position (x, y) in color c. The lower
- 8, 15, 16 or 24 bits of the color are significant, depending
- on the number of colors the current mode supports.
-
- setpixelrgb( int x, int y, int r, int g, int b )
- Draw a single pixel at (x, y) with color components r, g,
- and b, ranging from 0 to 255. In 256 color mode, only
- meaningful if the RGB palette is set (setrgbpalette).
-
- int getpixel( int x, int y )
- Returns color of pixel at position (x, y).
-
- getpixelrgb( int x, int y, int *r, int *g, int *b )
- Store color components from pixel at (x, y) ranging from 0
- to 255, into integers pointed to by r, g and b.
-
- int rgbcolor( int r, int g, int b )
- Returns pixel value that corresponds with the given color
- components. Used by setpixelrgb.
-
- line( int x1, int y1, int x2, int y2, int c )
- Draw a line from (x1, y1) to (x2, y2) inclusive in
- color c.
-
- hline( int x1, int y, int x2, int c )
- Draw a horizontal line from (x1, y) to (x2, y) in color c.
-
- circle( int x, int y, int r, int c )
- Draw a circle of radius r in color c.
-
-
- - box (bitmap) functions
-
- fillbox( int x, int y, int w, int h, int c )
- Screen position (x, y), box size (w, h).
- Fill a rectangular area of the screen with a single color.
-
- getbox( int x, int y, int w, int h, void *dp )
- Bitmap data pointer dp. Bitmaps are in row-major order.
- Copy a rectangular bitmap from the screen to a buffer.
-
- putbox( int x, int y, int w, int h, void *dp )
- Bitmap data pointer dp.
- Copy a bitmap to a rectangular area of the screen.
-
- putboxpart( int x, int y, int w, int h, int bw, int bh, void *bp,
- int xo, int yo )
- Copy a partial bitmap to the screen. (w, h) is the size
- of the partial bitmap, (bw, bh) that of the source bitmap,
- and (xo, yo) is the offset in pixels into the source bitmap.
-
- putboxmask( int x, int y, int w, int h, void *dp )
- As putbox, but do not write bitmap pixels of color zero.
-
- copybox( int x1, int y1, int w, int h, int x2, int y2 )
- Copy the rectangular area at (x1, y1) of size (w, h),
- to (x2, y2) (bitblit).
-
- copyboxtocontext( int x1, int y1, int w, int h, GraphicsContext *gc,
- int x2, int y2 )
- Copy the rectangular area at (x1, y1) of size (w, h), to
- position (x2, y2) in the context gc.
-
- copyboxfromtocontext( GraphicsContext *gc, int x1, int y1, int w,
- int h, int x2, int y2 )
- Copy the rectangular area at (x1, y1) in the context gc, of
- size (w, h), to position (x2, y2) in the current context.
- This is more efficient than copyboxtocontext.
-
-
- - compiled bitmaps (linear 256 color mode only)
-
- compileboxmask( int w, int h, void *sdp, void *ddp )
- Convert rectangular masked bitmap of size (w, h) at sdp to
- a compressed format that allows faster drawing, which is
- stored at ddp. Allocating w * h bytes for the compiled
- version is usually enough; an upper limit should be
- (w + 2) * h.
-
- int compiledboxmasksize( int w, int h, void *sdp )
- Returns the size of the compiled version of the masked
- bitmap of size (w, h) at sdp that will be generated by
- compileboxmask.
-
- putboxmaskcompiled( int x, int y, int w, int h, void *dp )
- Write compiled bitmap to screen. This is significantly
- faster than non-compiled masked bitmaps, especially for
- sparse bitmaps.
-
-
- - clipping
-
- enableclipping()
- Enable automatic clipping in most functions.
-
- disableclipping()
- Disable clipping.
-
- setclippingwindow( int x1, int y1, int x2, int y2 )
- Set the clipping window to the rectangle with top-left
- corner (x1, y1) and bottom-right corner (x2, y2) (incl.).
-
-
- - graphics contexts and virtual screens
-
- setcontextvga( int mode )
- Set the graphics context to the physical screen of a
- vga mode (as defined in svgalib). The mode must be set
- first. The only thing you can do with a planar (mode X-like)
- 256 color mode is aligned putbox, and use it as a target for
- copyscreen.
-
- setcontextvgavirtual( int mode )
- Allocate a virtual screen in system memory identical to
- the graphics mode, and make that the current graphics
- context.
-
- setcontextvirtual( int w, int h, int bpp, int bitspp, void *vbuf )
- Define the current graphics context to have a width of w
- pixels, height h, bpp bytes per pixel, bitspp significant
- color bits per pixel (8, 15, 16 or 24), with the framebuffer
- at vbuf. A 4 bytes per pixel context, with 24 significant
- color bits is also valid.
-
- getcontext( GraphicsContext *gc )
- Save the current context in a structure variable.
-
- setcontext( GraphicsContext *gc )
- Restore a previously saved context (make it the current
- context).
-
- freecontext( GraphicsContext *gc )
- Free the space allocated for the virtual screen in the
- given context.
-
- copyscreen( GraphicsContext *gc )
- Copy the current graphics context contents (screen data) to
- the specified graphics context (the physical screen, for
- example). Contexts are assumed to be identical in size.
-
- setscreenoffset( int o )
- Set the offset in pixels into video memory for copyscreen
- and copyboxtoscreen, allows for page-flipping. Must be a
- multiple of the scanline width in bytes. It is reset to
- zero after completion of copyscreen.
-
- int enablepageflipping( GraphicsContext *gc )
- Enable page flipping or triple buffering in copyscreen if
- the physical context gc can do it. Returns 3 if triple
- buffering will be used, 2 for page flipping, 0 if page
- flipping is not possible (due to video memory/mode
- limitations). When pageflipping is enabled, the screenoffset
- is ignored in copyscreen.
-
-
- - text writing, font handling
-
- setfont( int fw, int fh, void *fp )
- Use the font stored as character bitmaps at fp, with
- characters of size (fw, fh), as the basic font for write
- operations. Note that the font included in the library must
- be expanded first, because it is stored bit-per-pixel;
- this is not required if the FONT_COMPRESSED writemode
- flag is set.
-
- setwritemode( int m )
- Sets writemode flags. If WRITEMODE_MASKED is set (as opposed
- to WRITEMODE_OVERWRITE), only foreground pixels of the font
- are used for write operations; the screen background is not
- erased. If FONT_COMPRESSED is set (as opposed to
- FONT_EXPANDED), text writes will use the compressed
- bit-per-pixel font rather than the expanded font.
-
- write( int x, int y, char *s )
- Write string s at (x, y) using currently selected font.
-
- writen( int x, int y, int n, char *s )
- Write n character string s at (x, y).
-
- expandfont( int fw, int fh, int c, void *sfp, void *dfp )
- Convert bit-per-pixel font at sfp, with characters of size
- (fw, fh), to an expanded font of character bitmaps, stored at
- dfp (size will be 256 * fw * fw * BYTESPERPIXEL). All
- non-zero pixels are set to color c.
-
- colorfont( int fw, int fh, int c, void *fp )
- Set all nonzero pixels in the expanded font to color c.
-
- setfontcolors( int bg, int fg )
- Set the background and foreground colors for the compressed
- font write mode.
-
-
- - VGA 256-color palette handling
-
- These functions are only valid in 256-color modes.
-
- getpalettecolor( int c, int *r, int *g, int *b )
- Get red, green and blue values (in the range 0-63) of
- color c from the color-lookup-table, and store them as
- integers in the memory locations pointed to by r, g and b.
-
- setpalettecolor( int c, int r, int g, int b )
- Set RGB values (0-63) for color c.
-
- getpalettecolors( int s, int n, void *dp )
- Get RGB values of n colors starting at s, which are stored
- as a table of groups of three bytes at dp.
-
- setpalettecolors( int s, int n, void *dp )
- Set RGB values of n colors starting at color s.
-
- getpalette( void *p )
- Equivalent to getpalettecolors(0, 256, p).
-
- setpalette( void *p )
- Equivalent to setpalettecolors(0, 256, p).
-
- setrgbpalette()
- Set 256-color RGB palette (bits 0-2 blue, 3-5 green,
- 6-7 red). Use with setpixelrgb.
-
-
- - miscellaneous
-
- clearscreen( int c )
- Fill the entire screen with color c.
-
- scalebox( int w1, int h1, void *sdp, int w2, int h2, void *ddp )
- Scale the bitmap of size (w1, h1) at sdp to size (w2, h2)
- and store it at ddp, which must be a large enough buffer.
- The pixel size of the current graphics context is used.
-
- setdisplaystart(int x, int y)
- Set the physical display start address to the pixel at (x,
- y). Can be used for hardware scrolling, or for page flipping
- (e.g. setdisplaystart(0, HEIGHT) displays from the second
- page). Make sure the scanline width (BYTEWIDTH) in bytes
- of the current context corresponds with the physical
- screen.
-
-
- Macros defined in vgagl.h:
-
- WIDTH The width in pixels of the current graphics context.
- HEIGHT Height in pixels.
- BYTESPERPIXEL Number of bytes per pixel (1, 2, 3 or 4).
- BYTEWIDTH Width of a scanline in bytes.
- COLORS Number of colors.
- BITSPERPIXEL Number of significant color bits.
- VBUF Address of the framebuffer.
- __clip Clipping flag.
- __clipx1 Top-left corner of clipping window.
- __clipy1
- __clipx2 Bottom-right corner of clipping window.
- __clipy2
-
-
- Use the environment variable GSVGAMODE to select the graphics mode used by
- the testgl program (e.g. export GSVGAMODE=G640x480x256).
-
- It may be interesting to compare the framebuffer video speeds for certain
- modes, especially among Vesa Local Bus cards (even if only 320x200x256
- works). There is considerable variation in performance among VLB motherboard
- implementations and cards. If you want, you can mail them to me
- (hhanemaa@cs.ruu.nl) and I'll collect the results at this place. Please state
- CPU, card type/chipset, and bus type (of the card)/(ISA) bus speed.
-
- The speedtest program is using aligned REP STOSL (memset), which is
- relatively slow on a 486 (4 cycles); unrolled MOV's may be faster. It does
- show that many VLB cards have in fact only a 16-bit bus interface (like my
- Cirrus 5426 based card). The maximum throughput using STOSL on a 386 (5
- cycles) is about 15M/s at 16-bit VLB 40MHz, 30M/s with 32 bits. Anyone with
- an ET4000/W32(i) to show off?
-
- The 'fun' program displays a frame rate that is also very dependent on general
- memory architecture (it uses two virtual screens). Notice that the frame rate
- has a significant variation between runs (up to 15% on my machine), but it
- doesn't change within a run. I believe this is because of pages mapping to
- the same external cache slot, which happens quite often with a direct mapped
- cache (a bad thing for a multi-tasking VM OS). This means that if you were
- to run a small but memory-intensive program taking say a day to calculate
- something, it would be a good idea to display timed progress information at
- the start. Restarting until the speed is good would possibly save several
- hours of computation time.
-
- Note: there seem to be VLB motherboards around that have problems with
- (sound) DMA when writing video data to the local bus (possibly related to
- running the VLB in 'slave' mode).
-
- Speeds are in MByte/s.
- bus 256-color hicolor truec.
- card system speed 320x200 640x480 800x600 640x480 640x480
- AVGA3, CL-GD5426, VLB 386DX/40 40.0 12.5 13.7 12.8 7.6 4.6
- --same, high MCLK 386DX/40 40.0 15.5 15.5 15.5 11.7 8.4
- --same 486SX/40 40.0 15.6 15.6 15.6 11.7 8.4
- --same, low write delay 486SX/40 40.0 - 19.5 - - -
- Trident 9000, 512K ISA 386DX/40 8.0 2.1 2.2 2.2 - -
- Trident 8900C, ISA 386DX/33 2.6 3.1 2.1 - -
- Tseng MegaVGA/1024 ISA 486DX/33 13.3 8.5 8.5 8.5 8.5 6.0
- --ET4000, AT&T491/2 DAC 386SX/40 10.0 4.8 4.8 4.8 4.8 4.8
- Trident 9000, 512K ISA 486DX/33 13.3 2.9 2.3 2.5 - -
- S3-805 VLB (stosl) 486DX2/66 33 10.8 - - - -
- --same (stosw) 486DX2/66 33 16.0 - - - -
- ATI Ultra Pro EISA 486DX/50 8 6.2 6.2 6.2 6.2 6.2
- Morse KP1024 ET4000 486SX/40 10.0 3.8 3.8 3.8
- --same 486SX/40 13.3 5.2 5.2 5.2
- Oak OTI-087 486DX2/66 33 7.7 6.6 6.7
- CL-GD5428 (same mb) 486DX2/66 33 8.0 6.8 6.8
- CL-GD5434E VLB 0-wait 486SX/33 33 56.1 56.1 54.2 52.5 48.5
- --same, non 0-wait 486SX/33 33 30.2 29.1 28.1 25.4
-
- Note
-
- For three bytes per pixel (true color) modes, it is possible that
- pixels cross a SVGA segment boundary. This should be correctly
- handled by most functions. It can be avoided by using a logical
- scanline length that is a divisor of 65536 (a power of 2), like 1024
- (as opposed to 960) for 320x200 and 2048 (1920) for 640x480. For
- 800x600, this is impractical (4096 as opposed to 2400 doesn't fit in
- 2MB). Alternatively, avoid those functions by using a virtual screen.
-
-
- Question: How do I poll the keyboard without waiting and handle multiple
- keypresses?
-
- You can have complete keyboard control by using RAW mode. An example should
- be in the kbd-08? package (nic.funet.fi, /pub/Linux/PEOPLE/Linus or similar).
-
- There is now a low-level keyboard interface in svgalib.
- There is also a seperate 'rawkey' library for use with svgalib, by Russell
- Marks.
-
-
- Q: What's the fuss about a DLL library?
- A: The building of a DLL library includes a conversion, at the assembler
- level, of all references in the library code of exported global variables
- into indirect references with some overhead added to preserve register
- values. This is not very efficient if the global variables are used all
- over the place (e.g. currentcontext and its fields). The testgl program
- ran 20% slower because of this. Therefore, the library internally uses a
- copy of currentcontext that is not exported. This means that the current
- context may only be changed with vgagl functions.
-