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:
@@ -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.
|
||||
Reference in New Issue
Block a user