Files | |
file | render.c |
The C source file for a fairly optimized 2D rendering system built on SDL. | |
file | render.h |
The header file for a fairly optimized 2D rendering system built on SDL. | |
Data Structures | |
struct | DisplayInfo_t |
Contains globally accessible information about the display. More... | |
struct | Layer_t |
Describes a layer for rendering. More... | |
struct | RenderItem_t |
The fundamental unit for a visible rectangular region. More... | |
struct | UpdateList_t |
Contains a list of rectangles that must be updated. More... | |
Defines | |
#define | BACK_STATES 2 |
The number of previous rendered states stored. | |
#define | ClipRectToRect(clip, limit) |
Clips a rectangle to fit within the given bounding rectangle. | |
#define | ClipRectToWH(clip, width, height) |
Clips a rectangle to fit within a physical region defined by a width and a height. | |
#define | FASTEST_SURFACE |
Evaluates to the fastest (hopefully) type of surface, hardware or software, at runtime. | |
#define | MAX_LAYERS 6 |
The total number of layers that will be available for rendering. | |
Typedefs | |
typedef void(*) | ItemRenderer (SDL_Surface *dest, RenderItem *item) |
A function pointer type that references a function called upon to render an item. | |
typedef Layer_t | Layer |
typedef RenderItem_t | RenderItem |
Functions | |
void | AddRenderItem (RenderItem *item, int layer) |
Adds a new RenderItem to the world list of a Layer. | |
static void | AddToUpdateLists (RenderItem *item, SDL_Rect *rect) |
Adds a rectangle to the update lists. | |
void | ClearRenderItem (RenderItem *item) |
Makes an item no longer visible until the next PlaceRenderItem() call on the item. | |
static Bool | FindNextCollision (RenderItem *item) |
Finds the next rectangle in the update list that the given item collides with and sets the physDest field to the overlapping region. | |
void | ForceDirtyFrame () |
Set the dirty flag to force the renderer to perform a partial redraw for the next frame. | |
void | ForceRenderAll () |
Force everything to be redrwan for the next frame. | |
void | GenericSurfaceRenderer (SDL_Surface *dest, RenderItem *item) |
Renders a surface pointed to by item->data. | |
void | PlaceRenderItem (RenderItem *item) |
Places a render item on the physical display based on information set within the item. | |
void | RemoveRenderItem (RenderItem *item) |
Removes a RenderItem from a Layer. | |
void | Render () |
Renders a frame. | |
void | RenderClearStates (Uint8 numStates) |
Clears all display state information and optionally changes the number of states to use. | |
Bool | RenderInit (Uint16 numRects, Uint8 numStates) |
Initalizes the rendering system. | |
void | RenderUninit () |
Uninitializes the rendering system. | |
Bool | RenderWillRenderAll () |
Tells if the next call to Render() will render an entire frame rather than just a changed portion. | |
Bool | ResizeWindow (Uint16 w, Uint16 h) |
A utility function for resizing the program's window. | |
void | SetLayerOffset (Layer *layer, Sint16 x, Sint16 y) |
Changes the layer's offset from the physical display. | |
void | SolidFillRenderer (SDL_Surface *dest, RenderItem *item) |
Renders a solid rectangle who's color is stored at item->data. | |
Variables | |
DisplayInfo_t | dInfo |
Global information about the display. | |
Layer | layers [6] |
The global set of Layers. | |
static struct UpdateList_t | updateList |
Contains a list of rectangles that must be updated. |
This is the generalized flow of execution of a program using this rendering system:
Macros that affect the renderers operation:
The system allows for single and double buffered operation. When single buffered operation is performed on a windowed GUI (X11, Windows), the operation is very close to double buffered and lacks flicker. It is still a single buffered setup because the program will only have access to one buffer. Everything is drawn to this buffer, and from there is copied to the frame buffer that only the windowed GUI can access. The buffer the program draws onto is not in video memory, is not visible, and therefore no flicker will occur for the same reasons as using double buffering.
Single buffered operation usually is required when hardware graphics acceleraion is not available. Hardware acceleration may or may not be availble with double buffering. Care must be taken with placing SDL surfaces in graphics or system memory to achive the best performance. Always favoring graphics memory will ensure that some operations will be slow and some systems will run the program slow. Search online for more information. When running without hardware acceleration, this is usually a non-issue becuase graphics memory is not availble. In that case, SDL's optimized software blits (espically between surfaces with the same format) and the rendering system's ability to minimize updates to the display can together yield decent to excellent performance.
Copyright (C) 2007 Jeff Jackowski
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Or visit their website at: http://www.gnu.org/
#define BACK_STATES 2 |
The number of previous rendered states stored.
The value must be at least 1 for single buffered output and 2 for double buffered output.
Definition at line 118 of file render.h.
Referenced by RenderInit().
#define ClipRectToRect | ( | clip, | |||
limit | ) |
Value:
{ \ int t; \ if ((t = (limit)->x - (clip)->x) > 0) { \ (clip)->w -= t; \ (clip)->x = (limit)->x; \ } \ if ((t = ((clip)->x + (Sint16)(clip)->w) - ((limit)->x + (limit)->w)) > 0) { \ (clip)->w -= t; \ } \ if ((Sint16)((clip)->w) < 0) { \ (clip)->w = 0; \ } \ if ((t = (limit)->y - (clip)->y) > 0) { \ (clip)->h -= t; \ (clip)->y = (limit)->y; \ } \ if ((t = ((clip)->y + (Sint16)(clip)->h) - ((limit)->y + (limit)->h)) > 0) { \ (clip)->h -= t; \ } \ if ((Sint16)((clip)->h) < 0) { \ (clip)->h = 0; \ } \ }
clip | A pointer to the SDL_Rect to be clipped. It will be modified. If the width or height equals zero, then the input clip did overlap the bounding rectangle. | |
limit | A pointer to the bounding rectangle. |
#define ClipRectToWH | ( | clip, | |||
width, | |||||
height | ) |
Value:
{ \ int t; \ if ((clip)->x < 0) { \ (clip)->w += (clip)->x; \ (clip)->x = 0; \ } \ if ((t = ((clip)->x + (Sint16)(clip)->w) - (width)) > 0) { \ (clip)->w -= t; \ } \ if ((Sint16)((clip)->w) < 0) { \ (clip)->w = 0; \ } \ if ((clip)->y < 0) { \ (clip)->h += (clip)->y; \ (clip)->y = 0; \ } \ if ((t = ((clip)->y + (Sint16)(clip)->h) - (height)) > 0) { \ (clip)->h -= t; \ } \ if ((Sint16)((clip)->h) < 0) { \ (clip)->h = 0; \ } \ }
Works like ClipRectToRect() but assumes limit's x & y coordinates are zero. Should be more efficent than using ClipRectToRect().
clip | A pointer to the SDL_Rect to be clipped. It will be modified. If the width or height equals zero, then the input clip did overlap the bounding rectangle. | |
width | The maximum width. | |
height | The maximum height. |
Definition at line 645 of file render.h.
Referenced by PlacePlayerLabel(), PlaceRenderItem(), and Render().
#define FASTEST_SURFACE |
Value:
Evaluates to the fastest (hopefully) type of surface, hardware or software, at runtime.
Definition at line 214 of file render.h.
Referenced by GraphicReset().
#define MAX_LAYERS 6 |
The total number of layers that will be available for rendering.
Definition at line 125 of file render.h.
Referenced by AddRenderItem(), and Render().
typedef void(*) ItemRenderer(SDL_Surface *dest, RenderItem *item) |
A function pointer type that references a function called upon to render an item.
Allows great flexibility with what can be rendered. For items flagged as transparent, the region of the target surface where the item should be drawn already has current image data for layers beneath the one holding the item to be rendered.
dest | The surface that is the target of the rendering operation. | |
item | The RenderItem that the function is expected to render. |
typedef struct RenderItem_t RenderItem |
void AddRenderItem | ( | RenderItem * | item, | |
int | layer | |||
) |
Adds a new RenderItem to the world list of a Layer.
It will initally be set to not draw. Call PlaceRenderItem() next to position the item on screen and draw it on the next call to Render().
item | The item to add to the list of items a layer contains. item's src field (RenderItem::src) will be initalized such that it will indicate the entire item will need to be drawn. For this to be valid when PlaceRenderItem() is called, the item's width and height in loc (RenderItem::loc) must be set prior to calling this function. | |
layer | The index of the Layer. For RTSA, they are enumerated in LAYERS. |
Definition at line 182 of file render.c.
References RenderItem_t::enableDraw, FALSE, layers, RenderItem_t::loc, MAX_LAYERS, RenderItem_t::next, RenderItem_t::parent, RenderItem_t::prev, RenderItem_t::renderer, RenderItem_t::src, Layer_t::worldListFirst, and Layer_t::worldListLast.
Referenced by AddNotice(), AddPlayer(), BfldErrInit(), BfldErrResize(), GameInit(), NetStatInit(), ObstacleInit(), SetupMenu(), SplashInit(), TeamSelInit(), TextSetup(), and TextSetupStateSplash().
static void AddToUpdateLists | ( | RenderItem * | item, | |
SDL_Rect * | rect | |||
) | [static] |
Adds a rectangle to the update lists.
For internal use only.
item | The item to update. The RenderItem::rectIndex field is changed to the index of the associated rectange in the update list. | |
rect | The rectangle to add to the update list. Its value will not be changed. |
Definition at line 256 of file render.c.
References _restrict_, UpdateList_t::currState, UpdateList_t::numRects, UpdateList_t::rects, state, UpdateList_t::totalStates, and updateList.
Referenced by PlaceRenderItem().
void ClearRenderItem | ( | RenderItem * | item | ) |
Makes an item no longer visible until the next PlaceRenderItem() call on the item.
More efficent than calling PlaceRenderItem() after putting the item out of view. Does not change the location of the item. The best performance with the current implementation is achived if all ClearRenderItem() calls are made before any PlaceRenderItem() calls prior to the frame render.
item | The render item which will not be visible in the next frame. |
Definition at line 488 of file render.c.
References UpdateList_t::currState, dInfo, UpdateList_t::dirty, RenderItem_t::dirty, RenderItem_t::enableDraw, FALSE, RenderItem_t::loc, UpdateList_t::numRects, DisplayInfo_t::ph, RenderItem_t::physDest, RenderItem_t::prevStates, DisplayInfo_t::pw, UpdateList_t::rects, state, UpdateList_t::totalStates, updateList, and RenderItem_t::visible.
Referenced by AddNotice(), DisablePlayerLabels(), GameRun(), MoveShell(), NetStatFocus(), NetStatUpdate(), PlacePlayerLabel(), ReadPlayer(), RemoveAllNotices(), RemoveOneNotice(), RemovePlayer(), TeamSelUninit(), TeamSelUpdate(), and UpdatePlayers().
static Bool FindNextCollision | ( | RenderItem * | item | ) | [static] |
Finds the next rectangle in the update list that the given item collides with and sets the physDest field to the overlapping region.
Intended for use with visible, non-dirty items to assure they are drawn properly when a dirty item overlaps them. The collision detection will start from one index past item->rectIndex[0] (so -1 will start at 0) and will modify the value to be the index of the next collision.
For internal use only.
item | The visible non-dirty item that may need to be redrawn. |
Definition at line 547 of file render.c.
References _restrict_, UpdateList_t::currState, FALSE, UpdateList_t::numRects, UpdateList_t::rects, TRUE, and updateList.
void ForceDirtyFrame | ( | ) |
Set the dirty flag to force the renderer to perform a partial redraw for the next frame.
This is not needed after calls to PlaceRenderItem() and ClearRenderItem(), but is needed after changing layer offsets. The macros LayerOffset(), LayerHorizOffset(), and LayerVertOffset() all call this function.
Definition at line 178 of file render.c.
References UpdateList_t::dirty, UpdateList_t::totalStates, and updateList.
void ForceRenderAll | ( | ) |
Force everything to be redrwan for the next frame.
For best performance, call this prior to clearing, removing, or placing rener items. The extra logic to compute the changed regions on screen will be skipped. Only affects the next frame.
Definition at line 169 of file render.c.
References UpdateList_t::dirty, UpdateList_t::renderAll, UpdateList_t::totalStates, TRUE, and updateList.
Referenced by GameRun(), GameUninit(), GraphicReset(), and ResizeWindow().
void GenericSurfaceRenderer | ( | SDL_Surface * | dest, | |
RenderItem * | item | |||
) |
Renders a surface pointed to by item->data.
To avoid clipping the source and destination rectangles again (already clipped by the render system), SDL_LowerBlit() is called.
dest | The surface that is the target of the rendering operation. | |
item | The RenderItem that the function is expected to render. Its data field (RenderItem::data) must point to a valid SDL_Surface. |
Definition at line 807 of file render.c.
References RenderItem_t::data, RenderItem_t::physDest, and RenderItem_t::src.
Referenced by BfldErrUninit(), GameInit(), GameUninit(), GraphicReset(), SplashUninit(), TextRenderStringV(), and TextSetup().
void PlaceRenderItem | ( | RenderItem * | item | ) |
Places a render item on the physical display based on information set within the item.
Avoid calling this function more than once per frame per item.
Definition at line 390 of file render.c.
References _restrict_, AddToUpdateLists(), ClipRectToWH, dInfo, UpdateList_t::dirty, FALSE, DisplayInfo_t::ph, DisplayInfo_t::pw, UpdateList_t::renderAll, UpdateList_t::totalStates, TRUE, and updateList.
Referenced by BfldErrResize(), BfldErrRun(), EnablePlayerLabels(), GameInit(), GameRun(), MenuRun(), NetStatFocus(), NetStatUpdate(), ObstacleInit(), PlaceMarkers(), PlacePlayerLabel(), RenderGame(), RenderScore(), SetLayerOffset(), SetupMenu(), SplashResize(), TeamSelInput(), TeamSelUpdate(), and UpdateNotices().
Here is the call graph for this function:
void RemoveRenderItem | ( | RenderItem * | item | ) |
Removes a RenderItem from a Layer.
item | The item to remove. |
Definition at line 212 of file render.c.
References RenderItem_t::next, RenderItem_t::parent, RenderItem_t::prev, Layer_t::worldListFirst, and Layer_t::worldListLast.
Referenced by BfldErrUninit(), GameUninit(), ObstacleUninit(), RemoveAllNotices(), RemoveMenu(), RemoveOneNotice(), RemovePlayer(), SplashUninit(), TeamSelUninit(), and TextUnsetState().
void Render | ( | ) |
Renders a frame.
Issues:
Definition at line 606 of file render.c.
References _restrict_, ClipRectToWH, dInfo, DisplayInfo_t::display, FALSE, layers, MAX_LAYERS, DisplayInfo_t::ph, DisplayInfo_t::pw, UpdateList_t::renderAll, state, UpdateList_t::totalStates, and updateList.
Referenced by main().
void RenderClearStates | ( | Uint8 | numStates | ) |
Clears all display state information and optionally changes the number of states to use.
This is required after changing the size of the window or the display resolution, and if there is a change between single and double buffered output.
numStates | The number of visual states the renderer should use, or zero if the value should not change. See RenderInit() for more details. |
Definition at line 151 of file render.c.
References FALSE.
Bool RenderInit | ( | Uint16 | numRects, | |
Uint8 | numStates | |||
) |
Initalizes the rendering system.
numRects | The maximum number of rectangular regions that will ever need to be updated between frames. This number must be greater than zero, and should be a good bit higher to render most things. | |
numStates | The number of visual states the renderer should use. To assure correct operation, use one state for single-buffered output, two for double-buffered output, ect... The value must be greater than 0 (if you've got no states then you don't need to render) and not greater than BACK_STATES. |
Definition at line 117 of file render.c.
References BACK_STATES, FALSE, layers, TRUE, and updateList.
Referenced by main().
void RenderUninit | ( | ) |
Uninitializes the rendering system.
Deallocates all memory allocated by the rendering system.
Definition at line 155 of file render.c.
References UpdateList_t::length, UpdateList_t::numRects, UpdateList_t::rects, UpdateList_t::totalStates, and updateList.
Referenced by main().
Bool RenderWillRenderAll | ( | ) |
Tells if the next call to Render() will render an entire frame rather than just a changed portion.
Definition at line 174 of file render.c.
References UpdateList_t::renderAll, and updateList.
Referenced by PlacePlayerLabel().
Bool ResizeWindow | ( | Uint16 | w, | |
Uint16 | h | |||
) |
A utility function for resizing the program's window.
It will use flags stored in videoFlags, a Uint32 defined non-static in render.c. Set the value to the flags needed.
w | The new width of the window. | |
h | The new height of the window. |
Definition at line 827 of file render.c.
References dInfo, DisplayInfo_t::display, FALSE, ForceRenderAll(), DisplayInfo_t::lh, DisplayInfo_t::luh, DisplayInfo_t::luw, DisplayInfo_t::lw, DisplayInfo_t::ph, DisplayInfo_t::pw, rounddivup, and TRUE.
Referenced by BfldErrRun(), GameRun(), MenuRun(), and SplashRun().
Here is the call graph for this function:
void SetLayerOffset | ( | Layer * | layer, | |
Sint16 | x, | |||
Sint16 | y | |||
) |
Changes the layer's offset from the physical display.
This offset is added to the coordinates of the layer's items. For best performance, change the location of the items in the affected layer first by changing RenderItem::loc and do not call PlaceRenderItem() on those items. After that, call SetLayerOffset().
layer | A pointer to the layer to modify. | |
x | The new horizontal offset. | |
y | The new vertical offset. |
Definition at line 518 of file render.c.
References _restrict_, and PlaceRenderItem().
Referenced by GameInit(), and SetupScrolling().
Here is the call graph for this function:
void SolidFillRenderer | ( | SDL_Surface * | dest, | |
RenderItem * | item | |||
) |
Renders a solid rectangle who's color is stored at item->data.
dest | The surface that is the target of the rendering operation. | |
item | The RenderItem that the function is expected to render. Its data field (RenderItem::data) must point to an Uin32 with a valid device specific color code. |
Definition at line 815 of file render.c.
References RenderItem_t::data, and RenderItem_t::physDest.
Referenced by AddPlayer(), BfldErrInit(), GameRun(), GraphicReset(), ObstacleInit(), SetupMenu(), and SplashInit().
struct DisplayInfo_t dInfo |
Global information about the display.
Definition at line 40 of file render.c.
Referenced by AddNotice(), AddPlayer(), BfldErrInit(), BfldErrResize(), ClearRenderItem(), ColorBlend(), DrawTank(), GameInit(), GameRun(), GameUninit(), GraphicReset(), main(), MenuRun(), MoveShell(), MoveTank(), ObstacleInit(), PlacePlayerLabel(), PlaceRenderItem(), ReadPlayer(), Render(), RenderGame(), RenderScore(), ResizeWindow(), SetupColorVals(), SetupMenu(), SetupScrolling(), SpawnTank(), SplashInit(), SplashResize(), TeamSelInit(), and UpdateNotices().
The global set of Layers.
Lower values are further back in the Z-order. See LAYERS for a list of valid layers and their intended use.
Definition at line 41 of file render.c.
Referenced by AddRenderItem(), GameInit(), MenuRootInit(), Render(), RenderInit(), and SetupScrolling().
struct UpdateList_t updateList [static] |
Contains a list of rectangles that must be updated.
The list holds changes for the current frame, and if double buffering is used, for the next frame.
For internal use only.
Referenced by AddToUpdateLists(), ClearRenderItem(), FindNextCollision(), ForceDirtyFrame(), ForceRenderAll(), PlaceRenderItem(), Render(), RenderInit(), RenderUninit(), and RenderWillRenderAll().