New document, describing the graphics libraries

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@676 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
mcmartin
2003-02-05 01:34:52 +00:00
parent 4f006f65f0
commit 23f8be1d0c
+260
View File
@@ -0,0 +1,260 @@
The TFB Graphics Libraries
Initial documentation by Michael Martin, 4 Feb 2003
The graphics system in UQM has three major subsystems:
- The "legacy" system, which most of the core code uses. This
involves the foo_blt () routines in 3do_blt.c, and the data
types CONTEXT, FRAME, DRAWABLE, and possibly others. I'm
less familiar with this code, and want to eradicate as much of it as
I can, but for now, its lowest level has been rewritten as direct
calls to:
- The TFB_Draw* commands, documented below in great detail. These
routines deal with the datatype TFB_Image, and the more primitive
TFB_Canvas. They also support drawing to one of several 'screens',
but since only one thread should be allowed to touch the screen,
the TFB_DrawScreen routines end up constructing inputs to:
- The DCQ/DrawCommand library. This is a ring queue with commands for
rendering graphics on the actual screen. It interacts to some
degree with the CONTEXT datatype, but otherwise is defined entirely
in terms of TFB_Images and TFB_Canvases.
THE LEGACY LIBRARY
--------------------
The datatypes the code uses directly are CONTEXT, FRAME, and FONT, all
of which are really pointers to void. Pointers to those are PCONTEXT,
PFRAME, and PFONT. Then there's DRAWABLE, which is a DWORD, and its
pointer type PDRAWABLE. (These are defined in sc2code/libs/gfxlib.h.)
I'm not sure how DRAWABLE values are transformed into actual drawable
entities.
The full structures for these are in various files in
sc2code/libs/graphics.
context.h: defines CONTEXT_DESC and PCONTEXT_DESC (and the equivalent
CONTEXTPTR -- insert various sorts of incomprenshible
muttering here),
display.h: defines a DISPLAY_INTERFACE and PDISPLAY_INTERFACE type (as
well as a global _pCurDisplay).
drawable.h: defines FRAME_DESC and DRAWABLE_DESC, and the pointer
types PFRAME_DESC and PDRAWABLE_DESC. FRAME_DESC includes
an element "DataOffs", which, horrifyingly, appears to be
a deliberate index past the end of the struct. Given a
PFRAME_DESC x, (void *)(x[x->DataOffs]) is a void pointer
castable to TFB_Image.)
font.h: defines FONT_DESC and PFONT_DESC.
(Details on how all these data types work is forthcoming.)
THE TFB_DRAW LIBRARY
----------------------
The TFB_Draw commands have a single header file:
sc2code/libs/graphics/tfb_draw.h. This file declares the following
data types:
SCREEN: This is an enum, naming the various screens that the DrawCmd
library can draw to. Valid values at present are
TFB_SCREEN_MAIN, TFB_SCREEN_EXTRA, and TFB_SCREEN_TRANSITION.
These correspond to various objects that are of type TFB_Canvas.
(The maximal number of screens is provided by a bogus last
element, TFB_GFX_NUMSCREENS. Keep that as the last element
and the allocators will operate properly regardless of any
screens you may later want to add.)
TFB_Canvas: This is, for the purposes of most of the code, a void
pointer. The implementations of TFB_DrawCanvas commands
cast them to the appropriate type. (The only
implementation of these commands casts them to
SDL_Surface*.)
TFB_Palette: Four UBYTES, r, g, b, and 'unused'. This is designed at
present to be directly castable to SDL_Color, which most
things do. We should probably do something about that at
some point.
TFB_Image: The most important image structure. This has two
TFB_Canvases (one for the 'core' image, one for a scaled
version of it), a pointer to a TFB_Palette array, a
colormap index, a scaling constant, a Mutex from the
threading library (to ensure internal consistency if
multiple threads are doing stuff), and a 'dirty bit' which
means that, if the image is scaled, the ScaledImg needs to
be recomputed.
TFB_DrawScreen
--------------
When you wish to draw graphics directly on the screen, you call these
routines, which enqueue the DrawCommands:
----
void TFB_DrawScreen_Line (int x1, int y1, int x2, int y2,
int r, int g, int b,
SCREEN dest);
Draws a line from (x1, y1)-(x2, y2) of a color specified by r, g, and
b on the specified screen.
We have a known bug here in that if a corner of one of these lines is
outside of the context's clipping rectangle, the slope of the line may
change.
----
void TFB_DrawScreen_Rect (PRECT rect,
int r, int g, int b,
SCREEN dest);
Draws a (filled) rectangle with the specified color on the destination
screen. PRECT is part of the legacy library.
void TFB_DrawScreen_Copy (PRECT r, SCREEN src, SCREEN dest);
Copies data between screens. The PRECT defines the region to copy.
This can be handy in saving and restoring background information.
----
void TFB_DrawScreen_Image (TFB_Image *img,
int x, int y,
BOOLEAN scaled,
TFB_Palette *palette,
SCREEN dest);
void TFB_DrawScreen_FilledImage (TFB_Image *img,
int x, int y,
BOOLEAN scaled,
int r, int g, int b,
SCREEN dest);
These two routines draw images. img, x, and y are all straightforward
(x and y refer to the upper left of the image), and scaled indicates
whether or not the NormalImg or ScaledImg should be used, and dest
names the target screen.
For TFB_DrawScreen_Image, the 'palette' argument refers to a
256-element array of TFB_Palette that describes the palette to use.
(The default is cached in TFB_Image itself.) Various techniques are
used to cache the palette values to keep spurious palette-switch
commands from flooding the DrawCmd queue. However, switching the
palette many times per frame is likely to seriously degrade
performance.
TFB_DrawScreen_FilledImage draws every non-transparent pixel in img in
the color specified by r, g, b. (Fonts and some menus do this.)
----
void TFB_DrawScreen_WaitForSignal (void);
Puts this thread to sleep until all commands queued to this point are
executed. Mostly used to keep from spamming the DrawCmd queue, and to
ensure proper operation of the next two routines.
----
void TFB_DrawScreen_CopyToImage (TFB_Image *img,
PRECT lpRect,
SCREEN src);
Load the pixels from the rectangle lpRect in screen src into img. If
you're actually working with the pixels directly, you'll want to do a
TFB_DrawScreen_WaitForSignal () to ensure the image has actually been
updated. (If you're just passing it to other TFB_DrawScreen commands,
that's unnecessary, because ordering within a thread is guaranteed.)
----
void TFB_DrawScreen_DeleteImage (TFB_Image *img);
Deallocates all memory associated with img. This REALLY doesn't
belong here. It should be a TFB_DrawImage command, with a requirement
that you WaitForSignal lfirst.
----
TFB_DrawImage
-------------
These routines are similar to a subset of the TFB_DrawScreen commands,
except that instead of drawing on the screen at some later time, they
draw directly and immediately onto a TFB_Image. The arguments all
mean the same things as they did for TFB_DrawScreen.
----
void TFB_DrawImage_Line (int x1, int y1, int x2, int y2,
int r, int g, int b,
TFB_Image *dest);
void TFB_DrawImage_Rect (PRECT rect,
int r, int g, int b,
TFB_Image *image);
void TFB_DrawImage_Image (TFB_Image *img,
int x, int y,
BOOLEAN scaled,
TFB_Palette *palette,
TFB_Image *target);
void TFB_DrawImage_FilledImage (TFB_Image *img,
int x, int y,
BOOLEAN scaled,
int r, int g, int b,
TFB_Image *target);
----
There are some obvious operations missing here. Creation and
destruction of TFB_Images are the main gaps. The ability to 'wrap' a
TFB_Canvas with a fresh TFB_Image would probably be nice too.
TFB_DrawCanvas
--------------
These routines are, quite literally, identical in every way to the
TFB_DrawImage routines, except that they draw on TFB_Canvases instead.
They are defined in graphics-library-specific locations. There is, at
present, only one implementation of these, in
libs/graphics/sdl/canvas.c.
void TFB_DrawCanvas_Line (int x1, int y1, int x2, int y2,
int r, int g, int b,
TFB_Canvas dest);
void TFB_DrawCanvas_Rect (PRECT rect,
int r, int g, int b,
TFB_Canvas image);
void TFB_DrawCanvas_Image (TFB_Image *img,
int x, int y,
BOOLEAN scaled,
TFB_Palette *palette,
TFB_Canvas target);
void TFB_DrawCanvas_FilledImage (TFB_Image *img,
int x, int y,
BOOLEAN scaled,
int r, int g, int b,
TFB_Canvas target);
----
Commentary on needed operations also mirrors that of TFB_Image.
DRAWCMD LIBRARY
-----------------
Documentation yet to be written. UQM code shouldn't really mess with
the DrawCmd library directly.