Render System

A system to perform fairly optimized 2D rendering by only redrawing what has changed every frame rather than the whole frame. More...


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.

Detailed Description

A system to perform fairly optimized 2D rendering by only redrawing what has changed every frame rather than the whole frame.

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 Documentation

#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.

Warning:
Presently values greater than 2 are not fully supported; error directives will point out the spots if BACK_STATES is set to 3 or more. Should none of the code marked by error directives cause trouble, consider the result untested.

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; \
    } \
}
Clips a rectangle to fit within the given bounding rectangle.

Parameters:
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.
Author:
Jeff Jackowski

Definition at line 610 of file render.h.

#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; \
    } \
}
Clips a rectangle to fit within a physical region defined by a width and a height.

Works like ClipRectToRect() but assumes limit's x & y coordinates are zero. Should be more efficent than using ClipRectToRect().

Parameters:
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.
Author:
Jeff Jackowski

Definition at line 645 of file render.h.

Referenced by PlacePlayerLabel(), PlaceRenderItem(), and Render().

#define FASTEST_SURFACE

Value:

((dInfo.display->flags & SDL_HWACCEL) ? \
                       SDL_HWSURFACE : SDL_SWSURFACE)
Evaluates to the fastest (hopefully) type of surface, hardware or software, at runtime.

Author:
Jeff Jackowski

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 Documentation

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.

Parameters:
dest The surface that is the target of the rendering operation.
item The RenderItem that the function is expected to render.
relatesalso RenderItem_t
Author:
Jeff Jackowski

Definition at line 229 of file render.h.

typedef struct Layer_t Layer

Definition at line 207 of file render.h.

typedef struct RenderItem_t RenderItem

Definition at line 205 of file render.h.


Function Documentation

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().

Precondition:
item is not a member of another layer, and its parent pointer is NULL.
Parameters:
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.
relatesalso Layer_t
Author:
Jeff Jackowski

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.

Parameters:
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.
Author:
Jeff Jackowski

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.

Parameters:
item The render item which will not be visible in the next frame.
relatesalso RenderItem_t
Author:
Jeff Jackowski

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.

Parameters:
item The visible non-dirty item that may need to be redrawn.
Returns:
True if there was a collision, false otherwise.
Author:
Jeff Jackowski

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.

Author:
Jeff Jackowski

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.

Author:
Jeff Jackowski

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.

Parameters:
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.
relatesalso RenderItem_t
Author:
Jeff Jackowski

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.

Warning:
Changing the position on an item without calling PlaceRenderItem() can cause incorrect rendering of multiple items.
Postcondition:
The fields used to place the item are:
Precondition:
The fields updated by this call are:
relatesalso RenderItem_t
Author:
Jeff Jackowski

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.

Precondition:
The item is not visible, either by being positioned off-screen, or through a call to ClearRenderItem(). Or where the item was visible will be redrawn through other means.
Parameters:
item The item to remove.
relatesalso Layer_t
Author:
Jeff Jackowski

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:

Author:
Jeff Jackowski

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.

Todo:
Implement this function.
Parameters:
numStates The number of visual states the renderer should use, or zero if the value should not change. See RenderInit() for more details.
Author:
Jeff Jackowski

Definition at line 151 of file render.c.

References FALSE.

Bool RenderInit ( Uint16  numRects,
Uint8  numStates 
)

Initalizes the rendering system.

Warning:
This function should only be called once before a call to RenderUninit().
Parameters:
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.
Returns:
True if the operation succeeded. Inadequate memory and invalid parameters can cause a failure.
Author:
Jeff Jackowski

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.

Author:
Jeff Jackowski

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.

Returns:
True if a whole frame will be rendered, false if only a partial frame will be rendered.
Author:
Jeff Jackowski

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.

Parameters:
w The new width of the window.
h The new height of the window.
Returns:
True on sucess, false if the window could not be resized.
Author:
Jeff Jackowski

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().

Parameters:
layer A pointer to the layer to modify.
x The new horizontal offset.
y The new vertical offset.
relatesalso Layer_t
Author:
Jeff Jackowski

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.

Parameters:
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.
relatesalso RenderItem_t
Author:
Jeff Jackowski

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().


Variable Documentation

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().

Layer layers[6]

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.

Author:
Jeff Jackowski

Referenced by AddToUpdateLists(), ClearRenderItem(), FindNextCollision(), ForceDirtyFrame(), ForceRenderAll(), PlaceRenderItem(), Render(), RenderInit(), RenderUninit(), and RenderWillRenderAll().


Generated on Mon May 28 04:41:43 2007 for Retro Tank Super Attack by  doxygen 1.5.2