I don't exactly know where to put this, and its from the Lithtech Jupiter documentation, could be useful, i just don't know lol...anyway here it is
ILTDrawPrim
The ILTDrawPrim interface exposes low-level primitive rendering to the game code. ILTDrawPrim functions can be used to draw arbitrary polygons, including triangles, quads, strips, lines, points, and fans. These primitives can be flat-shaded or Gouraud-shaded, and also textured or untextured. Alpha blending is supported in both textures and vertex colors.
ILTDrawPrim is not only useful for rendering special polygons that will appear in the final game, but it can also be used for debugging purposes. Various types of debugging geometry can be used to test an object’s size, collisions, or just to test the appearance of a texture.
ILTDrawPrim uses structures to contain relevant vertex and polygon information. These structures are defined in the iltdrawprim.h header file.
Vertex Structures
The first set of structures defined contain vertex information. These various vertex structures provide a base upon which the polygon structures depend.
For all polygon structures, the vertex structures contain the coordinate information and the Gouraud-shading color information. For textured polygons, the vertex structures contain the u and v information.
Flat-shaded vertex structures do not contain color data and only represent the location of the vertex. The color of a flat-shaded polygon is set in the polygon structure.
The vertex structures include LT_VERTRGBA, LT_VERTF, LT_VERTFT, LT_VERTG, and LT_VERTGT.
Line Structures
Structures defining primitive lines include LT_LINEF, LT_LINEFT, LT_LINEG, and LT_LINEGT.
Triangle Structures
Structures defining primitive triangles include LT_POLYF3, LT_POLYFT3, LT_POLYG3, and LT_POLYGT3.
Quadrilateral Structures
Structures defining primitive quadrilaterals include LT_POLYF4, LT_POLYFT4, LT_POLYG4, and LT_POLYGT4.
Accessing the ILTDrawPrim Interface
The polygon structures listed above are available for creation when the LithTech header files are included in a project. Before calling the ILTDrawPrim functions, however, the game code must acquire a handle to LithTech’s instantiation of the ILTDrawPrim interface. The game code should not instantiate ILTDrawPrim.
The Interface Manager exposes one ILTDrawPrim instance for the game code to access. The game code can acquire a handle to this instance by associating it with an ILTDrawPrim pointer using the define_holder macro (defined in ltmodule.h).
The code snippet below first creates an ILTDrawPrim pointer (g_pILTDrawPrim). The define_holder macro is then used to set the address of the g_pILTDrawPrim pointer to the location for the ILTDrawPrim instance.
Code:
#include “iltdrawprim.h”
static ILTDrawPrim *g_pILTDrawPrim;
define_holder(ILTDrawPrim, g_pILTDrawPrim);
After setting the correct address for the g_pILTDrawPrim pointer as shown above, the ILTDrawPrim functions can be called.
Note: LithTech uses another unexposed instantiation of the
ILTDrawPrim interface to provide internal 2D rendering, text and user interface, and console functionality.
Primitive Structure Helper Functions
The ILTDrawPrim interface provides several helper functions to quickly set values for primitive quadrilateral structures. These helper functions include SetALPHA, SetALPHA4, SetRGB, SetRGBA, SetRGB4, SetRGBA4, SetUV4, SetUVWH, SetXY4, and SetXYWH.
These functions are overloaded for two or more quadrilateral structures.
State-setting Functions
The ILTDrawPrim interface includes a series of functions to set various states for drawing primitives. The game code only references one ILTDrawPrim instance. Therefore, each DrawPrim* call implements the same set of states. Whereas these states may be modified by any number of areas in the game code, the current state settings cannot be guaranteed. Therefore, states should be set (or reset) before each block of DrawPrim calls to insure that the desired states are actually used.
The state-setting functions include SetAlphaBlendMode, SetAlphaTestMode, SetCamera, SetClipMode, SetColorOp, SetCullMode, SetFillMode, SetTexture, SetTransformType, and SetZBufferMode.
Draw Functions
The ILTDrawPrim interface exposes several overloaded drawing functions, including DrawPrim, DrawPrimPoint, DrawPrimFan, and DrawPrimStrip. When one of these functions is called, the primitive is immediately rendered to the screen.
The current state settings (described above) identify the characteristics of any primitive drawn with one of the DrawPrim* functions. The states are not protected from modification from other areas of the code. If you call other functions, they may mofidy the current states in DrawPrim. Therefore, all of the states should be set before each block of DrawPrim, DrawPrimPoint, DrawPrimFan, or DrawPrimStrip function calls.
Checkerboard Sample Code
The following code sample implements various functions of the ILTDrawPrim interface to render a checkerboard pattern onto the screen.
Code:
#include "iltdrawprim.h"
// acquire the interface from the Interface Manager
static ILTDrawPrim *g_pLTDrawPrim;
define_holder(ILTDrawPrim, g_pLTDrawPrim);
void DrawCheckerboard()
{
// initialize
uint32 idx;
uint32 x, y;
uint32 tileWidth, tileWeight;
uint32 screenWidth, screenHeight;
LT_POLYF4 pPolyArray[25]; // a 5 x 5 grid of 4-sided polygons
g_pLTClient->GetSurfaceDims(g_pLTClient->GetScreenSurface(),
&screenWidth, &screenHeight);
tileWidth = screenWidth / 5;
tileWeight = screenHeight / 5;
for (y=0; y<5; y++)
{
for (x=0; x<5; x++)
{
idx = y * 5 + x;
// set white or black color
pPolyArray[idx].rgba.r = 255 * (idx % 2);
pPolyArray[idx].rgba.g = 255 * (idx % 2);
pPolyArray[idx].rgba.b= 255 * (idx % 2);
pPolyArray[idx].rgba.a= 255;
// vertices are clockwise from upper left
pPolyArray[idx].verts[0].x = float(x * tileWidth);
pPolyArray[idx].verts[0].y = float(y * tileWeight);
pPolyArray[idx].verts[0].z = 0;
pPolyArray[idx].verts[1].x = float(x * tileWidth + tileWidth);
pPolyArray[idx].verts[1].y = float(y * tileWeight);
pPolyArray[idx].verts[1].z = 0;
pPolyArray[idx].verts[2].x = float(x * tileWidth + tileWidth);
pPolyArray[idx].verts[2].y = float(y * tileWeight + tileWeight);
pPolyArray[idx].verts[2].z = 0;
pPolyArray[idx].verts[3].x = float(x * tileWidth);
pPolyArray[idx].verts[3].y = float(y * tileWeight + tileWeight);
pPolyArray[idx].verts[3].z = 0;
}
}
// render (each frame)
// set up the render state
g_pLTDrawPrim->SetTransformType(DRAWPRIM_TRANSFORM_SCREEN);
g_pLTDrawPrim->SetColorOp(DRAWPRIM_NOCOLOROP);
g_pLTDrawPrim->SetAlphaBlendMode(DRAWPRIM_NOBLEND);
g_pLTDrawPrim->SetZBufferMode(DRAWPRIM_NOZ);
g_pLTDrawPrim->SetAlphaTestMode(DRAWPRIM_NOALPHATEST);
g_pLTDrawPrim->SetClipMode(DRAWPRIM_FASTCLIP);
g_pLTDrawPrim->SetFillMode(DRAWPRIM_FILL);
// draw our checkerboard array
g_pLTDrawPrim->DrawPrim(pPolyArray, 25);
}
here are the header files that you might need
iltdrawprim.h
Code:
//-------------------------------------------------------------------
//
// MODULE : ILTDRAWPRIM.H
//
// PURPOSE : Defines engine interface ILTDrawPrimitive
//
// CREATED : On 8/11/00 At 10:40:21 AM
//
//-------------------------------------------------------------------
#ifndef __ILTDRAWPRIM_H__
#define __ILTDRAWPRIM_H__
#ifndef __LTBASEDEFS_H__
#include "ltbasedefs.h"
#endif
#ifndef __LTBASETYPES_H__
#include "ltbasetypes.h"
#endif
#ifndef __LTMODULT_H__
#include "ltmodule.h"
#endif
#ifndef __ILTTEXINTERFACE_H__
#include "ilttexinterface.h"
#endif
#ifndef __LTMODULE_H__
#include "ltmodule.h"
#endif
// screen near z -- use this value if you want your polygons to draw
// in front of everything
#ifdef _WIN32
#define SCREEN_NEAR_Z 0.0
#endif
//-----------------------------
// Vertex Primitive Definitions
//-----------------------------
// RGBA Colour def
/*!
Contains the RGBA data for a vertex. Also provides the Compact
operator to convert the RGBA data to a uint32. Gouraud shaded
vertices use this structure.
*/
struct LT_VERTRGBA
{
// convert r,g,b,a to a uint32
uint32 Compact() {
return (((uint32)a << 24) | ((uint32)r << 16) |
((uint32)g << 8) | (uint32)b);
}
uint8 b, g, r, a;
};
// Textured gouraud shaded vertex
/*!
Contains coordinate, color, and texture information for a textured,
Gouraud shaded vertex.
*/
struct LT_VERTGT
{
float x,y,z;
LT_VERTRGBA rgba;
float u, v;
LT_VERTGT() : z(SCREEN_NEAR_Z) {}
};
// Textured flat shaded vertex
/*!
Contains coordinate and texture information for a textured, flat-shaded vertex.
*/
struct LT_VERTFT
{
float x,y,z;
float u, v;
LT_VERTFT() : z(SCREEN_NEAR_Z) {}
};
// Gouraud shaded vertex
/*!
Contains coordinate and color information for a Gouraud-shaded vertex.
*/
struct LT_VERTG
{
float x,y,z;
LT_VERTRGBA rgba;
LT_VERTG() : z(SCREEN_NEAR_Z) {}
};
// Flat shaded vertex
/*!
Contains coordinate information for a flat-shaded vertex.
*/
struct LT_VERTF
{
float x,y,z;
LT_VERTF() : z(SCREEN_NEAR_Z) {}
};
//------------------------------
// Polygon Primitive Definitions
//------------------------------
// Textured gouraud shaded triangle
/*!
Contains vertex structure information for a textured, Gouraud shaded triangle.
*/
struct LT_POLYGT3
{
LT_VERTGT verts[3];
};
// Textured flat shaded triangle
/*!
Contains vertex structure information and color information for a textured, flat-shaded triangle.
*/
struct LT_POLYFT3
{
LT_VERTFT verts[3];
LT_VERTRGBA rgba;
};
// Gouruad shaded triangle
/*!
Contains vertex structure information for a Gouraud shaded triangle.
*/
struct LT_POLYG3
{
LT_VERTG verts[3];
};
// Flat shaded triangle
/*!
Contains vertex structure information and color informaiton for a flat-shaded triangle.
*/
struct LT_POLYF3
{
LT_VERTF verts[3];
LT_VERTRGBA rgba;
};
// Textured gouraud shaded quad
/*!
Contains vertex structure information for a textured, Gouraud shaded quadrilateral.
*/
struct LT_POLYGT4
{
LT_VERTGT verts[4];
};
// Textured flat shaded quad
/*!
Contains vertex structure information and color information for a textured, flat-shaded triangle.
*/
struct LT_POLYFT4
{
LT_VERTFT verts[4];
LT_VERTRGBA rgba;
};
// Gouruad shaded quad
/*!
Contains vertex structure information for a Gouraud shaded quadrilateral.
*/
struct LT_POLYG4
{
LT_VERTG verts[4];
};
// Flat shaded quad
/*!
Contains vertex structure information and color information for flat
shaded quadrilateral.
*/
struct LT_POLYF4
{
LT_VERTF verts[4];
LT_VERTRGBA rgba;
};
// Textured gouraud shaded line
/*!
Contains vertex structure information for a textured, Gouraud shaded line.
*/
struct LT_LINEGT
{
LT_VERTGT verts[2];
};
// Textured flat shaded line
/*!
Contains vertex structure information and color information for a textured, flat-shaded line.
*/
struct LT_LINEFT
{
LT_VERTFT verts[2];
LT_VERTRGBA rgba;
};
// Gouruad shaded line
/*!
Contains vertex structure information for a Gouraud shaded line.
*/
struct LT_LINEG
{
LT_VERTG verts[2];
};
// Flat shaded line
/*!
Contains vertex structure information and color information for a flat
shaded line.
*/
struct LT_LINEF
{
LT_VERTF verts[2];
LT_VERTRGBA rgba;
};
//------------------
// ILTDrawPrim enums
//------------------
/*!
Enumerates the transform types in which a primitive is drawn.
\see ILTDrawPrim::SetTransformType()
*/
enum ELTTransformType
{
/*!
The primitive is drawn in camera space.
*/
DRAWPRIM_TRANSFORM_CAMERA,
/*!
The primitive is drawn in screen space.
*/
DRAWPRIM_TRANSFORM_SCREEN,
/*!
The primitive is drawn in world space.
*/
DRAWPRIM_TRANSFORM_WORLD
} ;
// Function decoder :
// Cs - Source Color, As - Source Alpha, Cd - Dest Color, Ad - Dest Alpha
/*!
Enumerates the alpha blend modes with which a primitive is drawn. The blend mode defines how the source color (Cs), source alpha value(As), destination color(Cd), and destination alpha value(Ad) interact. PlayStation 2 (which does not support full collor modulate) supports the \b DRAWPRIM_BLEND_ADD, \b DRAWPRIM_BLEND_MOD_SRCALPHA, and \b DRAWPRIM_NOBLEND values.
\see ILTDrawPrim::SetAlphaBlendMode()
*/
enum ELTBlendMode
{
/*!
No blending is done. The source color is drawn with no modification. This is the default value.
*/
DRAWPRIM_NOBLEND,
/*!
The source color is added to the destination color (Cs + Cd).
*/
DRAWPRIM_BLEND_ADD,
/*!
Cs * (1 - Cd) + Cd
*/
DRAWPRIM_BLEND_SATURATE,
/*!
Cs * As + Cd * (1 - As)
*/
DRAWPRIM_BLEND_MOD_SRCALPHA,
/*!
Cs * Cs + Cd * (1 - Cs)
*/
DRAWPRIM_BLEND_MOD_SRCCOLOR,
/*!
Cs * Cd + Cd * (1 - Cd)
*/
DRAWPRIM_BLEND_MOD_DSTCOLOR,
/*!
Cs * Cs + Cd * Cd
*/
DRAWPRIM_BLEND_MUL_SRCCOL_DSTCOL,
/*!
Cs * As + Cd
*/
DRAWPRIM_BLEND_MUL_SRCALPHA_ONE,
/*!
Cs * As
*/
DRAWPRIM_BLEND_MUL_SRCALPHA,
/*!
Cs * Cs + Cd
*/
DRAWPRIM_BLEND_MUL_SRCCOL_ONE,
/*!
Cs * Cd
*/
DRAWPRIM_BLEND_MUL_DSTCOL_ZERO
};
/*!
Enumerates the z-buffering modes for drawing primitives.
\see ILTDrawPrim::SetZBufferMode()
*/
enum ELTZBufferMode
{
/*!
Read/write z-buffering enabled.
*/
DRAWPRIM_ZRW,
/*!
Read-only z-buffering enabled.
*/
DRAWPRIM_ZRO,
/*!
No z-buffering.
*/
DRAWPRIM_NOZ
};
// Pixels pass the AlphaTest if they satisfy the AlphaTest specified
// alpha test function - from the list below. AlphaRef Value is 0.5f.
/*!
Enumerates the modes for alpha testing on primitives. An alpha test compares the vertex alpha value of each pixel in the primitive to the alpha value fo the texture. If the test is true, then the pixel is rendered. If the test is false, the pixel does not render.
\see ILTDrawPrim::SetTransformType()
*/
enum ELTTestMode
{
/*!
No test is conducted. All pixels in the primitive are drawn.
*/
DRAWPRIM_NOALPHATEST,
/*!
If the alpha value of the pixel is less than the alpha value of the texel, the pixel is drawn.
*/
DRAWPRIM_ALPHATEST_LESS,
/*!
If the alpha value of the pixel is less than or equal to the alpha value of the texel, the pixel is drawn.
*/
DRAWPRIM_ALPHATEST_LESSEQUAL,
/*!
If the alpha value of the pixel is greater than the alpha value of the texel, the pixel is drawn.
*/
DRAWPRIM_ALPHATEST_GREATER,
/*!
If the alpha value of the pixel is greater than or equal to the alpha value of the texel, the pixel is drawn.
*/
DRAWPRIM_ALPHATEST_GREATEREQUAL,
/*!
If the alpha value of the pixel is equal to the alpha value of the texel, the pixel is drawn.
*/
DRAWPRIM_ALPHATEST_EQUAL,
/*!
If the alpha value of the pixel is not equal to the alpha value of the texel, the pixel is drawn.
*/
DRAWPRIM_ALPHATEST_NOTEQUAL
};
/*!
Enumerates the texture-to-color behaviors for primitives. This state is only useful for textured primitives.
\see ILTDrawPrim::SetColorOp()
*/
enum ELTColorOp
{
/*!
The color of the texture is ignored and only the color of the primitive is drawn.
*/
DRAWPRIM_NOCOLOROP,
/*!
Each of the pixel colors of the primitive is multiplied with the pixel color of the texture.
*/
DRAWPRIM_MODULATE,
/*!
Each of the pixel colors of the primitive is added to the pixel color of the texture. This value is not supported on the PlayStation 2 platform.
*/
DRAWPRIM_ADD,
/*!
The color of the primitive is ignored and only the color of the texture is drawn.
*/
DRAWPRIM_DECAL,
};
/*!
Enumerates the clip modes for drawing primitives.
\see ILTDrawPrim::SetClipMode()
*/
enum ELTClipMode
{
/*!
The primitive is not clipped if it penetrates the guardband.
*/
DRAWPRIM_NOCLIP,
/*!
If any portion of the primitive lies outside the guardband it will be rejected and no portion of the primitive will be drawn.
*/
DRAWPRIM_FASTCLIP,
/*!
Portions of the primitive that lie outside the guardband will not be rendered.
*/
DRAWPRIM_FULLCLIP
} ;
/*!
Enumerates the fill modes for drawing primitives.
\see ILTDrawPrim::SetFillMode()
*/
enum ELTDPFillMode
{
/*!
Only a wire frame is drawn for the primitive.
*/
DRAWPRIM_WIRE,
/*!
The primitive is filled with the appropriate color and texture.
*/
DRAWPRIM_FILL
};
/*!
Enumerates the cull modes for drawing primitives.
\see ILTDrawPrim::SetCullMode()
*/
enum ELTDPCullMode
{
/*!
No culling is done. All primitives are rendered regardless of winding order.
*/
DRAWPRIM_CULL_NONE, // Don't CULL
/*!
Primitives with counter-clockwise winding orders relative to the camera are not rendered.
*/
DRAWPRIM_CULL_CCW,
/*!
Primtives with clockwise winding orders relative to the camera are not rendered.
*/
DRAWPRIM_CULL_CW // CULL Clockwise
};
/*!
The ILTDrawPrim is a low level polygon based drawing/rendering interface.
Define a holder to get this interface like this:
\code
define_holder(ILTDrawPrim, your_var);
\endcode
*/
class ILTDrawPrim : public IBase
{
public :
interface_version(ILTDrawPrim, 0);
/*!
Called to begin a draw primitive block. This is for optimizing draw primitive
calls. Calls to have the engine render anything not through the draw primitive
cannot be made inside this block.
Used for: Rendering.
*/
virtual LTRESULT BeginDrawPrim() = 0;
/*!
Called to end a draw primitive block.
Used for: Rendering.
*/
virtual LTRESULT EndDrawPrim() = 0;
/*!
\param hCamera The handle of the camera.
Set the camera relative to which the primitive is drawn.
Used for: Rendering.
*/
virtual LTRESULT SetCamera(const HOBJECT hCamera) = 0;
/*!
\param hTexure The handle of the texture.
Set the texture used by the primitive. If a texture is not set using this function, all textured polygons will be rendered with random texture data.
Used for: Rendering.
*/
virtual LTRESULT SetTexture(const HTEXTURE hTexture) = 0;
/*!
\param eType An \b ELTTransformType enum value.
Set the transform type in which the primitive is drawn.
Used for: Rendering.
*/
virtual LTRESULT SetTransformType(const ELTTransformType eType) = 0;
/*!
\param eColorOp An \b ELTColorOp enum value.
Set the texture-to-color behavior of the primitive.
Used for: Rendering.
*/
virtual LTRESULT SetColorOp(const ELTColorOp eColorOp) = 0;
/*!
\param eBlendMode An \b ELTBlendMode enum value.
Set the alpha blend mode of the primitive.
Used for: Rendering.
*/
virtual LTRESULT SetAlphaBlendMode(const ELTBlendMode eBlendMode) = 0;
/*!
\param eZBufferMode An \b ELTZBufferMode enum value.
Set the z-buffering mode for drawing primitives.
Used for: Rendering.
*/
virtual LTRESULT SetZBufferMode(const ELTZBufferMode eZBufferMode) = 0;
/*!
\param eTestMode An \b ELTTestMode enum value.
Set the alpha test mode for drawing primitives.
Used for: Rendering.
*/
virtual LTRESULT SetAlphaTestMode(const ELTTestMode eTestMode) = 0;
/*!
\param eClipMode An \b ELTClipMode enum value.
Set the clip mode for drawing primitives.
Used for: Rendering.
*/
virtual LTRESULT SetClipMode(const ELTClipMode eClipMode) = 0;
/*!
\param efillmode An \b ELTDPFillMode enum value.
Set the fill mode for drawing primitives.
Used for: Rendering.
*/
virtual LTRESULT SetFillMode(ELTDPFillMode efillmode) = 0;
/*!
\param ecullmode An \b ELTDPCullMode enum value.
Set the cull mode for drawing primitives.
Used for: Rendering.
*/
virtual LTRESULT SetCullMode(ELTDPCullMode ecullmode) = 0;
/*!
\param bFogEnable An \b boolean indicating whether or not fog should be enabled
Set the fog enabled status for drawing primitives.
Used for: Rendering.
*/
virtual LTRESULT SetFogEnable(bool bFogEnable) = 0;
/*!
\param bReallyClose - Specifies whether or not the draw primitive will be rendered in the really close range.
Specifiy whether or not to be in really close space for rendering
Used for: Rendering.
*/
virtual LTRESULT SetReallyClose(bool bReallyClose) = 0;
/*!
\param nEffectShaderID - Specifies the effect shader ID.
Specify the Effect Shader to use when rendering this prim.
Used for: Rendering.
*/
virtual LTRESULT SetEffectShaderID(uint32 nEffectShaderID) = 0;
/*!
Store off the current viweport
Used for: Rendering.
*/
virtual void SaveViewport() = 0;
/*!
Restore the saved viewport
Used for: Rendering.
*/
virtual void RestoreViewport() = 0;
/*!
\param pPrim A pointer to an array of polygon structures to draw.
\param nCount The number of polygons (default value is 1) in the array identified by the \b pPrim parameter.
Draw one or more polgons of one type (line, triangle, or quadrilateral). This overloaded function supports the following structures: \b LT_LINEF, \b LT_LINEFT, \b LT_LINEG, \b LT_LINEGT, \b LT_POLYF3, \b LT_POLYFT3, \b LT_POLYG3, \b LT_POLYGT3, \b LT_POLYF4, \b LT_POLYFT4, \b LT_POLYG4, and\b LT_POLYGT4.
Used for: Rendering.
*/
virtual LTRESULT DrawPrim (LT_POLYGT3 *pPrim,
const uint32 nCount = 1) = 0;
virtual LTRESULT DrawPrim (LT_POLYFT3 *pPrim,
const uint32 nCount = 1) = 0;
virtual LTRESULT DrawPrim (LT_POLYG3 *pPrim,
const uint32 nCount = 1) = 0;
virtual LTRESULT DrawPrim (LT_POLYF3 *pPrim,
const uint32 nCount = 1) = 0;
virtual LTRESULT DrawPrim (LT_POLYGT4 *pPrim,
const uint32 nCount = 1) = 0;
// special version added by adam s. for optimized wide font rendering
virtual LTRESULT DrawPrim (LT_POLYGT4 **ppPrim,
const uint32 nCount = 1) = 0;
virtual LTRESULT DrawPrim (LT_POLYFT4 *pPrim,
const uint32 nCount = 1) = 0;
virtual LTRESULT DrawPrim (LT_POLYG4 *pPrim,
const uint32 nCount = 1) = 0;
virtual LTRESULT DrawPrim (LT_POLYF4 *pPrim,
const uint32 nCount = 1) = 0;
virtual LTRESULT DrawPrim (LT_LINEGT *pPrim,
const uint32 nCount = 1) = 0;
virtual LTRESULT DrawPrim (LT_LINEFT *pPrim,
const uint32 nCount = 1) = 0;
virtual LTRESULT DrawPrim (LT_LINEG *pPrim,
const uint32 nCount = 1) = 0;
virtual LTRESULT DrawPrim (LT_LINEF *pPrim,
const uint32 nCount = 1) = 0;
virtual LTRESULT DrawPrimPoint (LT_VERTGT *pVerts,
const uint32 nCount = 1) = 0;
virtual LTRESULT DrawPrimPoint (LT_VERTG *pVerts,
const uint32 nCount = 1) = 0;
/*!
\param pVerts A pointer to an array structures that identify the vertices of the fan. Three or more vertices are required. The first vertex structure in this array defines the source vertex for the fan. This overloaded functions supports the following vertex structures: \b LT_VERTF, \b LT_VERTFT, \b LT_VERTG, and\b LT_VERTGT.
\param nCount The number of vertex structures in the array identified by the \b pVerts parameter.
\param rgba The color for flat shaded fans.
Draw a primitive triangle fan. Each vertex in the array creates a triangle with the previous vertex in the arary and the source vertex.
Used for: Rendering.
*/
virtual LTRESULT DrawPrimFan (LT_VERTGT *pVerts,
const uint32 nCount) = 0;
virtual LTRESULT DrawPrimFan (LT_VERTFT *pVerts,
const uint32 nCount,
LT_VERTRGBA rgba) = 0;
virtual LTRESULT DrawPrimFan (LT_VERTG *pVerts,
const uint32 nCount) = 0;
virtual LTRESULT DrawPrimFan (LT_VERTF *pVerts,
const uint32 nCount,
LT_VERTRGBA rgba) = 0;
/*!
\param pVerts A pointer to an array of structures that identify the vertices of the strip. Three or more vertices are required. The first vertex structure in this array defines the source vertex for the strip. This overloaded functions supports the following vertex structures: \b LT_VERTF, \b LT_VERTFT, \b LT_VERTG, and\b LT_VERTGT.
\param nCount The number of vertex structures in the array identified by the \b pVerts parameter.
\param rgba The color for flat shaded strips.
Draw a primitive triangle strip. Each vertex in the array creates a triangle with the previous two vertices in the array.
Used for: Rendering.
*/
virtual LTRESULT DrawPrimStrip (LT_VERTGT *pVerts,
const uint32 nCount) = 0;
virtual LTRESULT DrawPrimStrip (LT_VERTFT *pVerts,
const uint32 nCount,
LT_VERTRGBA rgba) = 0;
virtual LTRESULT DrawPrimStrip (LT_VERTG *pVerts,
const uint32 nCount) = 0;
virtual LTRESULT DrawPrimStrip (LT_VERTF *pVerts,
const uint32 nCount,
LT_VERTRGBA rgba) = 0;
/*!
\param pPrim (return) A pointer to the polygon structure to which the coordinate parameters \b x0, \b y0, \b x1, \b y1, \b x2, \b y2, \b x3, and \b y3 are applied. This overloaded function supports the \b LT_POLYF4, \b LT_POLYFT4, \b LT_POLYG4, and \b LT_POLYGT4 structures.
\param x0 The x-coordinate of the first vertex of the quadrilateral. All eight of the coordinate parameters are applied to the quadrilateral in winding order.
\param y0 The y-coordinate of the first vertex of the quadrilateral.
\param x1 The x-coordinate of the second vertex of the quadrilateral.
\param y1 The y-coordinate of the second vertex of the quadrilateral.
\param x2 The x-coordinate of the third vertex of the quadrilateral.
\param y2 The y-coordinate of the third vertex of the quadrilateral.
\param x3 The x-coordinate of the fourth vertex of the quadrilateral.
\param y3 The y-coordinate of the fourth vertex of the quadrilateral.
Set vertex coordinates for a primitive quadrilateral.
Used for: Rendering.
*/
virtual void SetXY4 (LT_POLYGT4 *pPrim,
float x0, float y0,
float x1, float y1,
float x2, float y2,
float x3, float y3) = 0;
virtual void SetXY4 (LT_POLYFT4 *pPrim,
float x0, float y0,
float x1, float y1,
float x2, float y2,
float x3, float y3) = 0;
virtual void SetXY4 (LT_POLYG4 *pPrim,
float x0, float y0,
float x1, float y1,
float x2, float y2,
float x3, float y3) = 0;
virtual void SetXY4 (LT_POLYF4 *pPrim,
float x0, float y0,
float x1, float y1,
float x2, float y2,
float x3, float y3) = 0;
/*!
\param pPrim (return) A pointer to the polygon structure for which the vertices is set.
\param x The x-coordinate of the upper left vertex of the quadrilateral.
\param y The y-coordinate of the upper left vertex of the quadrilateral.
\param w The width of the quadrilateral.
\param h The height the quadrilateral.
Set vertex coordinates for a primitive quadrilateral give a source vertex, width, and height. The x and y coordinates for the upper left vertex are set with the \b x and \b y parameters. The other three vertices are calculated using the width and height (\b w and \b h parameters, respectively).
Used for: Rendering.
*/
virtual void SetXYWH (LT_POLYGT4 *pPrim,
float x, float y,
float w, float h) = 0;
virtual void SetXYWH (LT_POLYFT4 *pPrim,
float x, float y,
float w, float h) = 0;
virtual void SetXYWH (LT_POLYG4 *pPrim,
float x, float y,
float w, float h) = 0;
virtual void SetXYWH (LT_POLYF4 *pPrim,
float x, float y,
float w, float h) = 0;
/*!
\param pPrim (return) A pointer to the polygon structure for which the texture data is set. This overloaded function supports the \b LT_POLYGT4 and \b LT_POLYFT4 structures.
\param u0 The u texture value for the upper left vertex of the quadrilateral.
\param v0 The v texture value for the upper left vertex of the quadrilateral.
\param u1 The u texture value for the second vertex of the quadrilateral.
\param v1 The v texture value for the second vertex of the quadrilateral.
\param u2 The u texture value for the third vertex of the quadrilateral.
\param v2 The v texture value for the third vertex of the quadrilateral.
\param u3 The u texture value for the fourth vertex of the quadrilateral.
\param v3 The v texture value for the fourth vertex of the quadrilateral.
Set the texture data for each vertex in a quadrilateral structure.
Used for: Rendering.
*/
virtual void SetUV4 (LT_POLYGT4 *pPrim,
float u0, float v0,
float u1, float v1,
float u2, float v2,
float u3, float v3) = 0;
virtual void SetUV4 (LT_POLYFT4 *pPrim,
float u0, float v0,
float u1, float v1,
float u2, float v2,
float u3, float v3) = 0;
/*!
\param pPrim (return) A pointer to the polygon structure for which the texture data is set. This overloaded function supports the \b LT_POLYGT4 and \b LT_POLYFT4 structures.
\param u The u texture value for the upper left vertex of the quadrilateral.
\param v The v texture value for the upper left vertex of the quadrilateral.
\param w The width of the texture.
\param h The height of the texture.
Set the texture data for each vertex in a quadrilateral structure. The upper left vertex is set explicity by the \b u and \b v parameters. The other three vertices are calculated using the width and height (\b w and \b h parameters, respectively).
Used for: Rendering.
*/
virtual void SetUVWH (LT_POLYGT4 *pPrim,
float u, float v,
float w, float h) = 0;
virtual void SetUVWH (LT_POLYGT4 *pPrim, HTEXTURE pTex,
float u, float v,
float w, float h) = 0;
virtual void SetUVWH (LT_POLYFT4 *pPrim,
float u, float v,
float w, float h) = 0;
/*!
\param pPrim (return) A pointer to the polygon structure for which the color data is set. This overloaded function supports the \b LT_POLYF4, \b LT_POLYG4, \b LT_POLYGT4 and \b LT_POLYFT4 structures.
\param color The RGB color of all vertices in the quadrilateral.
Set a single RGB color for all vertices in a quadrilateral structure.
Used for: Rendering.
*/
virtual void SetRGB(LT_POLYGT4 *pPrim, uint32 color) = 0;
virtual void SetRGB(LT_POLYFT4 *pPrim, uint32 color) = 0;
virtual void SetRGB(LT_POLYG4 *pPrim, uint32 color) = 0;
virtual void SetRGB(LT_POLYF4 *pPrim, uint32 color) = 0;
/*!
\param pPrim (return) A pointer to the polygon structure for which the color data is set. This overloaded function supports the \b LT_POLYF4, \b LT_POLYG4, \b LT_POLYGT4 and \b LT_POLYFT4 structures.
\param color The RGBA color of all vertices in the quadrilateral.
Set a single RGBA color for all vertices in a quadrilateral structure.
Used for: Rendering.
*/
virtual void SetRGBA(LT_POLYGT4 *pPrim, uint32 color) = 0;
virtual void SetRGBA(LT_POLYFT4 *pPrim, uint32 color) = 0;
virtual void SetRGBA(LT_POLYG4 *pPrim, uint32 color) = 0;
virtual void SetRGBA(LT_POLYF4 *pPrim, uint32 color) = 0;
// ------------------------------------------
// Note: it makes no sense to have a SetRGB4 on flat shaded polys
/*!
\param pPrim (return) A pointer to the polygon structure for which the color data is set. This overloaded function supports the \b LT_POLYG4 and \b LT_POLYGT4 structures.
\param color0 The RGB color of the first (upper left) vertex of the quadrilateral.
\param color1 The RGB color of the second vertex of the quadrilateral.
\param color2 The RGB color of the third vertex of the quadrilateral.
\param color3 The RGB color of the fourth vertex of the quadrilateral.
Set the RGB color for each vertex in a quadrilateral.
Used for: Rendering.
*/
virtual void SetRGB4(LT_POLYGT4 *pPrim,
uint32 color0, uint32 color1,
uint32 color2, uint32 color3) = 0;
virtual void SetRGB4(LT_POLYG4 *pPrim,
uint32 color0, uint32 color1,
uint32 color2, uint32 color3) = 0;
/*!
\param pPrim (return) A pointer to the polygon structure for which the color data is set. This overloaded function supports the \b LT_POLYG4 and \b LT_POLYGT4 structures.
\param color0 The RGBA color of the first (upper left) vertex of the quadrilateral.
\param color1 The RGBA color of the second vertex of the quadrilateral.
\param color2 The RGBA color of the third vertex of the quadrilateral.
\param color3 The RGBA color of the fourth vertex of the quadrilateral.
Set the RGBA color for each vertex in a quadrilateral.
Used for: Rendering.
*/
virtual void SetRGBA4(LT_POLYGT4 *pPrim,
uint32 color0, uint32 color1,
uint32 color2, uint32 color3) = 0;
virtual void SetRGBA4(LT_POLYG4 *pPrim,
uint32 color0, uint32 color1,
uint32 color2, uint32 color3) = 0;
/*!
\param pPrim (return) A pointer to the polygon structure for which the color data is set. This overloaded function supports the \b LT_POLYF4, \b LT_POLYFT4, \b LT_POLYG4 and \b LT_POLYGT4 structures.
\param alpha The alpha value for the entire quadrilateral.
Set the alpha value for a quadrilateral.
Used for: Rendering.
*/
virtual void SetALPHA(LT_POLYGT4 *pPrim, uint8 alpha) = 0;
virtual void SetALPHA(LT_POLYG4 *pPrim, uint8 alpha) = 0;
virtual void SetALPHA(LT_POLYFT4 *pPrim, uint8 alpha) = 0;
virtual void SetALPHA(LT_POLYF4 *pPrim, uint8 alpha) = 0;
/*!
\param pPrim (return) A pointer to the polygon structure for which the alpha value is set. This overloaded function supports the \b LT_POLYG4 and \b LT_POLYGT4 structures.
\param alpha0 The alpha value of the first (upper left) vertex of the quadrilateral.
\param alpha1 The alpha value of the second vertex of the quadrilateral.
\param alpha2 The alpha value of the third vertex of the quadrilateral.
\param alpha3 The alpha value of the fourth vertex of the quadrilateral.
Set the alpha value for each vertex in a quadrilateral.
Used for: Rendering.
*/
virtual void SetALPHA4(LT_POLYGT4 *pPrim,
uint8 alpha0, uint8 alpha1,
uint8 alpha2, uint8 alpha3) = 0;
virtual void SetALPHA4(LT_POLYG4 *pPrim,
uint8 alpha0, uint8 alpha1,
uint8 alpha2, uint8 alpha3) = 0;
};
// For now just expose this to everyone to use.
// extern ILTDrawPrim* gDrawPrim;
#endif // __ILTDRAWPRIM_H_
ilttexinterface.h
Code:
/*! The ILTTexture interface allows the game to modify textures. */
#ifndef __ILTTEXINTERFACE_H__
#define __ILTTEXINTERFACE_H__
#ifndef __LTBASETYPES_H__
#include "ltbasetypes.h"
#endif
#ifndef __LTMODULE_H__
#include "ltmodule.h"
#endif
#ifndef __LTBASEDEFS_H__
#include "ltbasedefs.h"
#endif
/*! Some of these types are not supported on all platforms. For the
PS2, the \b A value represents a value between 0.0 and 2.0 where 128 =
1.0 and 255 = 2.0 */
enum ETextureType
{
TEXTURETYPE_INVALID = 0, // an error
TEXTURETYPE_ARGB8888 = 1, // PC Only
TEXTURETYPE_ARGB4444 = 2, // PC Only
TEXTURETYPE_ARGB1555 = 3, // PC Only
TEXTURETYPE_RGB565 = 4, // PC Only
TEXTURETYPE_***1 = 5, // PC Only
TEXTURETYPE_***3 = 6, // PC Only
TEXTURETYPE_***5 = 7, // PC Only
};
enum ETextureMod
{
TEXTURE_DATACHANGED = 0,
TEXTURE_PALETTECHANGED = 1,
TEXTURE_DATAANDPALETTECHANGED = 2,
};
const uint32 TEXTUREFLAG_FULLBRIGHT = (1<<0);
const uint32 TEXTUREFLAG_PREFER16BIT = (1<<1);
const uint32 TEXTUREFLAG_NOSYSCACHE = (1<<6); // Tells the engine to not keep a system memory copy of the texture.
const uint32 TEXTUREFLAG_PREFER4444 = (1<<7); // If in 16-bit mode, use a 4444 texture for this.
const uint32 TEXTUREFLAG_PREFER5551 = (1<<8); // Use 5551 if 16-bit.
const uint32 TEXTUREFLAG_32BITSYSCOPY = (1<<9); // If there is a sys copy - don't convert it to device specific format (keep it 32 bit).
// Moved to ltbasedefs.h
//class SharedTexture;
//typedef SharedTexture* HTEXTURE;
/*!
The ILTTexInterface interface exposes texture manipulation functionality
to the game code. It enables direct access to texture data. This
direct access means that the texture won't be converted to a new format,
and will therefore result in faster texture rendering.
Define a holder to get this interface like this:
\code
define_holder(ILTTexInterface, your_var);
\endcode
*/
class ILTTexInterface : public IBase {
public:
//set the interface version number
interface_version(ILTTexInterface, 0);
/*!
\param hTexture (return) Texture handle.
\param pFilename Texture filename.
\result \b LT_ERROR - Texture not found.
\result \b LT_OK - Texture found.
Retrieves a handle to an existing texture given a filename.
Used for: Special FX.
*/
virtual LTRESULT FindTextureFromName(HTEXTURE &hTexture,
const char *pFilename) = 0;
/*!
\param hTexture The address of the converted texture.
\param pFilename Points to a char array containing the relative path to the resource directory in which the .DTX file is located.
\return \b LT_MISSINGFILE - \em pFilename is invalid (can't find file).
\return \b LT_ERROR - Internal error.
\return \b LT_OK - Successful.
Creates a texture from a .DTX file. A .DTX file is created using the DEdit tool (see the Game Content Creation Guide).
If the .DTX file was created with the DTX_32BITSYSCOPY bit set, the texture will not be converted (the system memory copy will remain RGBA_8888).
To determine the format type of the new texture, use ILTTexInterface::GetTextureType.
Used for: Special FX.
*/
virtual LTRESULT CreateTextureFromName(HTEXTURE &hTexture,
const char *pFilename) = 0;
/*!
\param hTexture (return) Texture handle.
\param eTextureType Type (see TEXTURETYPE_ enum, above).
\param TextureFlags Flags (see TEXTUREFLAG_ values, above).
\param pData Pointer to the texture data.
\param nWidth Width.
\param nHeight Height.
\param nAutoGenMipMaps Request auto creation of nAutoGenMipMaps
number of mip maps. They will be down
sampled. Set this param to 0 to autogen
all the way down to 1x1.
\return \b LT_ERROR - Texture could not be created.
\return \b LT_OK - Successful.
Creates a texture from the passed in data.
Used for: Special FX.
*/
virtual LTRESULT CreateTextureFromData(HTEXTURE &hTexture,
ETextureType eTextureType, uint32 TextureFlags,
uint8 *pData, uint32 nWidth, uint32 nHeight,
uint32 nAutoGenMipMaps = 1) = 0;
/*!
\param hTexture Texture handle.
\param pData (return) Texture pixel data pointer
\param nWidth (return) The width of the surface that is locked in pixels.
\param nHeight (return) The height of the surface that is locked in pixels.
\param nPitch (return) Size (in bytes) of a row of pixel data.
\param eType (return) Format of the texture data
\return \b LT_OK - Successful.
Fetch a pointer to the texture RGB raw data. This data cannot be modified
and the pointer should only be used immediately after obtaining it without any
other texture calls since the engine is free to unload the texture if it rebinds it
Used for: Special FX.
*/
virtual LTRESULT GetTextureData(const HTEXTURE hTexture,
const uint8* &pData,
uint32& nWidth,
uint32& nHeight,
uint32& nPitch,
ETextureType& eType) = 0;
/*!
\param hTexture Texture handle.
\param eChanged Indicate is the texture pixel data and/or palette has changed.
\param nMipMap Mipmap to unlock.
\return \b LT_OK - Successful.
Let the engine know that we are finished modifing the texture
Used for: Special FX.
*/
virtual LTRESULT FlushTextureData (const HTEXTURE hTexture,
ETextureMod eChanged = TEXTURE_DATAANDPALETTECHANGED,
uint32 nMipMap = 0) = 0;
/*!
\param hTexture Texture handle.
\param nWidth (return) Texture width.
\param nHeight (return) Texture height.
\return \b LT_OK - Successful.
Get information about the texture.
Used for: Special FX.
*/
virtual LTRESULT GetTextureDims(const HTEXTURE hTexture,
uint32 &nWidth, uint32 &nHeight) = 0;
/*!
\param hTexture Texture handle.
\param eTextureType (return) The texture type.
\return \b LT_OK - Successful.
Get information about the texture.
Used for: Special FX.
*/
virtual LTRESULT GetTextureType(const HTEXTURE hTexture,
ETextureType &eTextureType) = 0;
/*!
\param hTexture Texture handle.
\return \b LT_OK - Successful.
You should call ReleaseTextureHandle after you are done with your texture
so that it can be freed. If it is not also being used by the engine, it
will be freed.
Used for: Special FX.
*/
virtual bool ReleaseTextureHandle(const HTEXTURE hTexture) = 0;
/*!
\param hTexture Texture handle
\return \b Reference count of texture
Call AddRefTextureHandle to artificially increment the reference count of a texture.
Used for: Special FX.
*/
virtual uint32 AddRefTextureHandle(const HTEXTURE hTexture) = 0;
};
#endif //! __ILTTEXINTERFACE_H__
ltmodule.h
Code:
#ifndef __LTMODULE_H__
#define __LTMODULE_H__
//****************************************************************************************
//
//
// This header file contains classes and templates needed
// to implement standard interfaces used in the LithTech
// engine. The main sections are the interface base class,
// the interface holder class, and the API database class.
//
// Important classes:
//
// IBase
// Used as a base class for all Lithtech modules.
//
// Important macros:
//
// interface_version
//
// interface_version_derived
//
// declare_interface
//
// instantiate_interface
//
// define_interface
//
// implements_also
//
// define_holder
//
// define_holder_to_instance
//
// link_to_implementation
//
//
//
//****************************************************************************************
//need these headers.
//for int32, etc.
#ifndef __LTINTEGER_H__
#include "ltinteger.h"
#endif
//for NULL
#ifndef __STDLIB_H__
#include <stdlib.h>
#define __STDLIB_H__
#endif
#ifndef __LINUX
#define LTMODULE_EXPORT __declspec(dllexport)
#else
#define LTMODULE_EXPORT
#endif
//****************************************************************************************
//
//
// Interface base class and implementation.
//
//
//****************************************************************************************
/*!
IBase is the root class of all interfaces managed by the engine.
The members of the class are for internal use only. They are declared
and defined for IBase derived class using the other Interface Manager
macros.
*/
class IBase {
public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
//returns the name of the implementation class.
virtual const char *_InterfaceImplementation() = 0;
#endif
};
/*!
\param interface_name The interface class name, without quotes.
\param version_num The version number of the interface.
This macro defines the version number of your interface. It must be
placed in your interface class in a public section. The version number
is an unsigned integer. The suggested range of the version number
is 0 to 99.
Any time the interface class "footprint" is changed, the version number should
be incremented. Changes to the footprint include adding, removing, or
rearranging functions, changes in function parameter lists, or any other change
which will affect the compiled binary format of the class or it's virtual function
table.
The version number is checked any time a holder asks for an implementation
of an interface. If the version number doesnt match, a debug assertion is triggered,
and the holder value will be \b NULL.
*/
#define interface_version(interface_name, version_num) \
enum { _##interface_name##_VERSION_ = version_num} \
/*!
\param interface_name The derived interface class name, without quotes.
\param base_name The parent class name of the interface class.
\param version_num The version number of the derived interface.
This macro is a variation on the \b interface_version macro. It is used when one
interface class is derived from another interface class that has its own
version number.
*/
#define interface_version_derived(interface_name, base_name, version_num) \
enum { _##interface_name##_VERSION_ = version_num + \
base_name::_##base_name##_VERSION_ * 100} \
/*!
\param impl_class The name of this class.
This macro must be put in a public section of any class that is going to be
instantiated with the \b instantiate_interface or \b define_interface macros.
It defines the \b IBase virtual functions in your class so that it can
be instantiated.
*/
#define declare_interface(impl_class) \
virtual const char *_InterfaceImplementation() {return #impl_class;} \
/*!
\param impl_class The name of the class that is to be instantiated.
\param interface_name The name of the interface class that is exposed to others.
\param instance_name A token (no quotes) that identifies this instance of the interface.
This macro is used to instantiate an interface implementation class. It
instantiates your implementation class as a static global variable and
inserts it into the interface manager.
The interface name joined with the instance name is used to identify the
instantiated object. Other implementations of the same interface can be instantiated
and inserted into the interface manager as long as instance name is different
from all others. Instance names must be valid C++ tokens, and are specified
in the macro without any enclosing quotation marks.
Interface implementations are retrieved from the interface manager with the
\b define_holder and the \b define_holder_to_instance macros.
*/
#define instantiate_interface(impl_class, interface_class, instance_name) \
/* Declare a global instance of our implementation class. */ \
/* It is not static so that we will get link errors if two instances */ \
/* are created with the same instance name. */ \
static impl_class __impl_instance_##impl_class##_##instance_name##__; \
/* Declare a pointer to the instance, so that we can reference it and */ \
/* get proper linkage if the instance is defined in a lib. */ \
impl_class *__impl_ptr_##impl_class##_##instance_name##__ = \
&__impl_instance_##impl_class##_##instance_name##__; \
/* Delcare a global instance of our CAPIInterfaceDefines class, to register */ \
/* our implementation class for the given interaface class name. */ \
static CAPIInstanceDefines<impl_class> \
__impl_##impl_class##_defines_##interface_class##_##instance_name##__( \
&__impl_instance_##impl_class##_##instance_name##__, \
#interface_class "." #instance_name, \
interface_class::_##interface_class##_VERSION_); \
/* Make a static search structure we can use to find this interface */ \
/* definition in a compiled object file. */ \
static SStaticSearchInterface \
__var_search_##interface_class##_##impl_class##_##instance_name##_ = { \
SEARCH_MARKER_INTERFACE, SEARCH_MARKER_INT, #interface_class, \
#impl_class, #instance_name, \
interface_class::_##interface_class##_VERSION_}; \
/*!
\param impl_class_name The class name of the implementation (not interface) class.
\param instance_name The instance name used when the implementation class was instantiated.
This macro is used to insure proper linkage when interface implementations are
defined in library files.
When an interface contains all pure virtual functions (as most do), the C/C++ linker does
not count references to those pure virtual functions do not as references to the
implementation class functions. When a interface implementation class is
properly insulated from other modules, there will be no direct reference to any
of the implementation class functions or other tokens. Therefore, the C/C++ linker
will "throw out" everything in the implementation class' \b OBJ file. The result
will be that the interface goes unimplemented, and holders to the interface will
be \b NULL.
To prevent this, somewhere in your \b EXE or \b DLL project files, you should
use the \b link_to_implementation macro. This macro will generate a reference
to a specific token defined in the \b instantiate_instance and
\b define_interface macros, so that the implementation class will be correctly
linked in.
Using this macro does not require that any header file for the specified
implementation class itself be included.
*/
#define link_to_implementation(impl_class_name, instance_name) \
/* Forward declare the implementation class name. */ \
class impl_class_name; \
/* declare an extern to the implementation instance pointer */ \
extern impl_class_name *__impl_ptr_##impl_class_name##_##instance_name##__; \
/* Reference the pointer to the instance defined in the lib. */ \
impl_class_name *__for_linker_ptr_##impl_class_name##_##instance_name##__ = \
__impl_ptr_##impl_class_name##_##instance_name##__; \
/*!
\param impl_class The name of the class that is to be instantiated.
\param interface_class The name of the interface class that is exposed to others.
This macro is the simple way to instantiate an interface implementation class.
Using this macro is equivalent to using the \b instantiate_interface macro with the
third parameter set to \b Default.
Interface implementations with the instance name \b Default can be retrieved with the
simpler \b define_holder macro.
*/
#define define_interface(impl_class, interface_class) \
instantiate_interface(impl_class, interface_class, Default); \
/*!
\param impl_class The class name of the implementation class.
\param other_instance_name The instance name that was used when the implementation class was instantiated.
\param interface_class The alternate interface name that the specified instance implements.
\param instance_name The instance name that is associated with the new \b interface_class.
A single instance of an implementation class can sometimes implement more than
one exposed interface. Use this macro to allow the same implementation instance
to be inserted and retrieved from the interface manager with another interface
class/instance name combination.
*/
#define implements_also(impl_class, other_instance_name, interface_class, instance_name)\
/* Delcare a global instance of our CAPIInterfaceDefines class, to register */ \
/* our implementation class for the given interaface class name. */ \
static CAPIInstanceDefines<impl_class> \
__impl_##impl_class##_defines_##interface_class##_##instance_name##__( \
&__impl_instance_##impl_class##_##other_instance_name##__, \
#interface_class "." #instance_name, \
interface_class::_##interface_class##_VERSION_); \
#ifndef DOXYGEN_SHOULD_SKIP_THIS
//
//Internal implementation details.
//
//
//This structure is used so that we can parse a compiled object file
//and find information about the interface holders used.
//
typedef struct {
//marks the beginning of the structure.
char marker[32];
int32 marker_int;
char interface_name[64];
char instance_name[64];
char implementation[64];
int32 version;
} SStaticSearchInterface;
//
//The marker string we use for static search.
//
#define SEARCH_MARKER_BASE "__search_marker"
#define SEARCH_MARKER_INTERFACE SEARCH_MARKER_BASE "_interface__"
#define SEARCH_MARKER_HOLDER SEARCH_MARKER_BASE "_holder__"
#define SEARCH_MARKER_INT 0xfaceface
//
//
//CAPIInstance is used to hold a global reference to the API implementation
//class and register it with the API database when the EXE or DLL is loaded.
//We define a variable of the interface in this class so that we can pass
//an initialized object of that type to the interface database.
//
//
template <class I>
class CAPIInstanceDefines {
public:
CAPIInstanceDefines(I *implementation, const char *implemented_class_name, int32 interface_version);
~CAPIInstanceDefines();
//pointer to the implementation, so we can reference it in our destructor
I *implementation;
//the class name that this implementation implements.
const char *implemented_class_name;
};
#endif //DOXYGEN_SHOULD_SKIP_THIS
//****************************************************************************************
//
//
// Interface holder class.
//
//
//****************************************************************************************
/*!
\param interface_name The name of the interface that you want a pointer to.
\param ptr_var The name of your variable.
\param instance_name The instance name of the interface implementation that you want.
This macro is used to retrieve an implementation of the desired interface. It should be
used at global scope, as such:
\code
#include "someinterfaceheader.h"
static ISomeInterface *ptr_to_someinterface;
define_holder_to_instance(ISomeInterface, ptr_to_someinterface, Default);
\endcode
If the instance name is \b Default, the more simple \b define_holder macro may be used.
*/
#define define_holder_to_instance(interface_name, ptr_var, instance_name) \
/* Make a static search struct for this holder so that we can search */ \
/* for this holder definition in a compiled object file. */ \
static SStaticSearchHolder \
__var_search_holder_##interface_name##_##instance_name##_= { \
SEARCH_MARKER_HOLDER, SEARCH_MARKER_INT, \
#interface_name, #instance_name, \
interface_name::_##interface_name##_VERSION_}; \
/* Define the holder variable itself. */ \
static CAPIHolder<interface_name> \
__api_holder_##interface_name##_##instance_name##__( \
#interface_name "." #instance_name, \
ptr_var, interface_name::_##interface_name##_VERSION_); \
/*!
\param interface_name The name of the interface that you want a pointer to.
\param ptr_var The name of your variable.
This macro is used to retrieve an implementation of the desired interface. It
is identical to the \b define_holder_to_instance and specifying \b Default as
the instance name.
*/
#define define_holder(interface_name, ptr_var) \
define_holder_to_instance(interface_name, ptr_var, Default); \
#ifndef DOXYGEN_SHOULD_SKIP_THIS
//
//Internal implementation details.
//
//
//This structure is used so that we can parse a compiled object file
//and find information about the interface holders used.
//
typedef struct {
//marks the beginning of the structure.
char marker[32];
//non-string marker
int32 marker_int;
char interface_name[64];
char instance_name[64];
int32 version;
} SStaticSearchHolder;
//
//
//Base API holder class. This class is used to keep track of
//a pointer to an interface. If the interface is ever unloaded
//the pointer will be cleared. Also, when the API becomes available,
//the holder will be notified. This class is not to be used directly,
//instead use the derived template class, with the template parameter
//being the API you wish to use.
//
//
class CAPIHolderBase {
public:
CAPIHolderBase(const char *api_string_name, int32 version);
virtual ~CAPIHolderBase();
//
//functions used by the interface database.
//
//Called by the database to tell us the
//interface we pointed to has been removed.
virtual void APIRemoved() = 0;
//Called when the interface we want is found.
virtual void APIFound(IBase *api) = 0;
//returns the interface we are currently connected to.
virtual IBase *Interface() = 0;
//returns the name of the api we want
__inline const char *InterfaceName();
//returns the version of the api we want.
__inline int32 Version();
protected:
//string name of the api. Taken from the constructor, the string
//pointed to by this var is not managed in any way, and is assumed to
//be allocated on the static heap.
const char *api_name;
//version of the api header file that was used when this var was compiled.
int32 version;
};
//
//
//Template class that is actually used to hold an interface of a
//particular type.
//
//
template <class I>
class CAPIHolder : public CAPIHolderBase {
public:
CAPIHolder(const char *api_string_name, I *&holder_var, int32 version);
~CAPIHolder();
//
//functions used by the interface database.
//
//Called by the database to tell us the
//interface we pointed to has been removed.
virtual void APIRemoved();
//Called when the interface we want is found.
virtual void APIFound(IBase *api);
//returns the interface we are currently connected to.
virtual IBase *Interface();
public:
//pointer to the interface that we keep track of.
I *&p;
};
//
//
// CAPIHolderBase functions.
//
//
const char *CAPIHolderBase::InterfaceName() {
return api_name;
}
int32 CAPIHolderBase::Version() {
return version;
}
//****************************************************************************************
//
//
// API Database class.
//
//
//****************************************************************************************
//class forward references.
template <class C, class id_type> class database_array;
template <class C> class database_list;
class CInterfaceDatabase;
class CInterfaceNameMgr;
class CInterfaceChooser;
//
//Global functions for DLL-enabled systems.
//
//
//If the database is defined in a DLL, this function should be called so that
//the DLL can merge it's database with the database of the loading executable.
//
extern "C" LTMODULE_EXPORT void SetMasterDatabase(CInterfaceDatabase *master_database);
//typedef for pointer to a SetMasterDatabase function
typedef void (*TSetMasterFn)(CInterfaceDatabase *master_database);
//
//Returns a pointer to the master database for this module. Use this function
//to get the database to pass to the SetMasterDatabase function of a DLL.
//
CInterfaceDatabase *GetMasterDatabase();
//
//Tracked pointer template. Used during program shutdown/cleanup when we have
//multiple system modules (EXEs, DLLs, ect) that have been loaded where each has
//their own API Database functions linked in, but ultimately all point
//to a single master database.
//
//CPointerTracked implents a class that is used to keep track of the pointer.
//The class C specified must implement the following functions:
// CPointerTracked<C> *&C::PointerTrackedList();
//
template <class C>
class CPointerTracked {
public:
__inline CPointerTracked();
__inline CPointerTracked(C *obj);
~CPointerTracked();
//sets the object we point to.
__inline CPointerTracked<C> &operator=(C *obj);
__inline CPointerTracked<C> &operator=(CPointerTracked<C> &other);
//dereference operator
__inline C *operator->();
//cast to our pointer type.
__inline operator C *();
//comparison operators.
__inline bool operator==(C *obj);
__inline bool operator!=(C *obj);
//returns false if the pointer is NULL.
__inline operator bool();
//returns true if the pointer is NULL.
__inline bool IsNull();
protected:
//The actual pointer to the object we point to.
C *pointer;
//The object we point to has access to us as part of a
//doubly linked, circular list
CPointerTracked<C> *prev, *next;
//does the actual set work.
void Set(C *obj);
void Unset();
};
//
//CPointerTrackedTarget is used by an object that is pointed to with
//CPointerTracked. When an instance of this class is embedded
//within the object that is tracked, its destructor will ensure that
//all tracked pointers to the object are set to NULL.
//
template <class C>
class CPointerTrackedTarget {
public:
__inline CPointerTrackedTarget();
__inline ~CPointerTrackedTarget();
//gets the list head.
operator CPointerTracked<C> *&() { return tracked_pointers; }
//makes all tracked pointer that reference us point to NULL.
void RedirectPointers(C *new_value);
protected:
//the pointer to the head element of the list of pointers that reverence us
CPointerTracked<C> *tracked_pointers;
};
//
//Use this macro in a public section of a class declaration
//to quickly define the functions needed by CPointerTracked.
//Pass in the class name itself as the parameter.
//It defines a pointer to a CPointerTracked<C> structure, and
//the following functions:
// CPointerTracked<C> *&PointerTrackedList();
// Returns the pointer to the first pointer_tracker. The
// other pointer_trackers are part of a list connected to the first.
//
#define define_pointer_tracked_target(classname) \
protected: \
/*Pointer to the head of the tracked pointers list */ \
CPointerTrackedTarget<classname> _##classname##our_tracked_pointers; \
public: \
__inline CPointerTracked<classname> *&PointerTrackedList() { \
return _##classname##our_tracked_pointers;} \
//
//
//The API Database class. The database is separated into 2 main parts.
//The first part is a public interface, which is mostly static functions.
//The functions are static and access an actual database object through
//a set of global pointers set up so that every EXE or DLL that is
//loaded can point to a single global database. The static interface
//is mostly responsible for keeping track of the lifetime of each
//EXE/DLL's database pointers, and the database object itself.
//The actual work of the database is done inside the private non-static
//interface, which is called from the public static interface.
//
//
//enum returned when chooser run functions are called.
typedef enum {
CR_BAD_PARAM, //chooser passed in was bad.
CR_BAD_STATE, //database has invalid state.
CR_BAD_INTERFACE, //interface specified by chooser doesnt exist.
CR_BAD_CHOOSER, //the chooser given isnt in the database at all.
CR_CHOOSER_WAS_OVERRIDDEN, //the given chooser isnt allowed to control the interface, another chooser already is.
CR_CANT_SET, //tried to choose the implementation, but couldn't.
CR_OK, //interface implementation selected successfully.
} EChooserRun;
class CInterfaceDatabase {
public:
CInterfaceDatabase();
~CInterfaceDatabase();
//standard pointer_tracked interface.
define_pointer_tracked_target(CInterfaceDatabase);
//
//Functions used to query or modify the database.
//
//adds an api to the database.
static void AddAPI(IBase *api, const char *implemented_class_name, int32 interface_version);
//removes an interface from the database.
//Anyone using the interface will be disconnected.
static void RemoveAPI(IBase *api, const char *implemented_class_name);
//registers the holder with the database. When the
//database gets the interface that the holder needs,
//the holder's APIFound function will be called.
static void AddHolder(CAPIHolderBase *api_holder);
//removes an API holder from the database.
static void RemoveHolder(CAPIHolderBase *api_holder);
//adds a chooser
static void AddChooser(CInterfaceChooser *chooser);
//removes a chooser from the database.
static void RemoveChooser(CInterfaceChooser *chooser);
//calls a chooser's Run function
static EChooserRun RunChooser(CInterfaceChooser *chooser);
//keeps a global count of all objects in the database that belong
//to 'this' executable.
static void DatabaseItemCountInc();
static void DatabaseItemCountDec();
//takes all the entries out of the given database, while
//inserting them into us. It is virtual so that it is called
//in the same module that the 'this' was allocated from.
virtual void TransferFrom(CInterfaceDatabase *other);
//destroys the database. It is virtual so that the delete operator
//will be called from the same module that allocated the object.
virtual void Destroy();
private:
//
//Our data
//
//Collection of CInterfaceNameMgr objects. Each unique interface
//goes with its own CInterfaceNameMgr object.
database_array<CInterfaceNameMgr, const char *> *interfaces;
//when we end up with version mismatch, we put info in these vars.
bool version_check_failed;
char *version_check_interface_name;
//sets version check vars.
void VersionError(const char *interface_name);
//
//Non-static worker functions called from the public interface.
//
//adds an interface implementation to the database.
virtual void Add(IBase *api, const char *implementation_class_name, int32 interface_version);
//removes an interface implementation from the database
virtual void Remove(IBase *api, const char *implementation_class_name);
//adds an interface holder to the database
virtual void Add(CAPIHolderBase *holder);
//removes an interface holder from the database
virtual void Remove(CAPIHolderBase *holder);
//adds a chooser
virtual void Add(CInterfaceChooser *chooser);
//removes a chooser
virtual void Remove(CInterfaceChooser *chooser);
//runs a chooser
virtual EChooserRun Run(CInterfaceChooser *chooser);
//
//Helper functions used by the public interface.
//
//returns true if the database is empty.
virtual bool IsEmpty();
};
//
//CInterfaceNameMgr is an object that keeps track of a set of implementations
//for a given interface, and the holders that use that interface. It also keeps
//a CInterfaceChooser object that determines which of the possible implementations
//should be used at any given time.
//
class CInterfaceNameMgr {
public:
CInterfaceNameMgr(const char *name, int32 version);
virtual ~CInterfaceNameMgr();
//adds an interface implementation
void Add(IBase *api);
//adds a holder that uses our interface
void Add(CAPIHolderBase *holder);
//adds a chooser
void Add(CInterfaceChooser *chooser);
//removes an interface implementation.
void Remove(IBase *api);
//removes a holder
void Remove(CAPIHolderBase *holder);
//removes a chooser
void Remove(CInterfaceChooser *chooser);
//runs a chooser
EChooserRun Run(CInterfaceChooser *chooser);
//returns the name that this mgr mgrs
inline const char *InterfaceName();
//returns version number of the interface that is mgr'd.
inline int32 InterfaceVersion();
//returns true if there are no objects contained in this mgr.
bool IsEmpty();
//steals all the data from the given mgr and merges it with
//our own existing data.
void TransferFrom(CInterfaceNameMgr *other);
//
//Interface used by the choosers
//
//tells the name mgr to use the implementation with the given name.
//Returns true if that implementation was found and is now being used.
bool UseImplementation(const char *name);
//gets the number of implementations we have.
uint32 NumImplementations();
//gets the name of an implementation. returns NULL on error.
const char *ImplemenationName(uint32 index);
protected:
//the name of the interface
char *name;
//the version of the interface.
int32 version;
//the array of interface implementations.
database_array<IBase, const char *> *interfaces;
//the array of holders that use this interface
database_list<CAPIHolderBase> *holders;
//the current interface we are using.
IBase *current_interface;
//stack of choosers, the last inserted is the one used.
database_list<CInterfaceChooser> *choosers;
//
//Private helper functions.
//
//connects all holders to the given interface
void ConnectHolders(IBase *api);
//connect the given holder to the current interface
void ConnectHolder(CAPIHolderBase *holder);
//disconnects all the holders in the mgr
void DisconnectHolders();
};
//
//CInterfaceNameMgr inline functions
//
const char *CInterfaceNameMgr::InterfaceName() {
return name;
}
int32 CInterfaceNameMgr::InterfaceVersion() {
return version;
}
//
//
//CInterfaceChooser is a base class for objects that can decide which of
//a set of interface implementations should be used at any given time.
//When the Add, Remove, and Run functions get called, the chooser has a chance
//to call the CInterfaceNameMgr::UseImplementation(). If it fails to
//pick a valid interface implementation from the ones in the mgr, a default
//choice will be made.
//
//
class CInterfaceChooser {
public:
//Init function takes the name and version number of the
//interface we are set up to control.
void Init(const char *name, int32 version);
//called when an implementation is added to the name mgr.
virtual void Add(IBase *api, CInterfaceNameMgr *mgr) = 0;
//called when an implementation is removed from the name mgr
virtual void Remove(IBase *api, CInterfaceNameMgr *mgr) = 0;
//called to let the chooser pick an implementation. To trigger
//this function to get called, use CInterfaceDatabase::RunChooser().
virtual EChooserRun Run(CInterfaceNameMgr *mgr) = 0;
//returns the name and version number of the interface we control
inline const char *InterfaceName();
inline int32 InterfaceVersion();
protected:
//name of the interface we control.
const char *name;
//version of the interface we control.
int32 version;
};
//
//CInterfaceChooser inline functions.
//
const char *CInterfaceChooser::InterfaceName() {
return name;
}
int32 CInterfaceChooser::InterfaceVersion() {
return version;
}
//
//This interface chooser takes an array of strings that are interface implementation
//names, and exposes an interface to select the current implementation via string.
//Selecting an implementation causes that selection to become the new default.
//
class CInterfaceChooserList : private CInterfaceChooser {
public:
//Init takes the full list of implementation names, and the default name.
void Init(const char *name, int32 version, uint32 num_choices, const char **choices, const char *def_name);
//changes the current implementation.
EChooserRun SetImplementation(uint32 index);
EChooserRun SetImplementation(const char *name);
//base class overrides.
virtual void Add(IBase *api, CInterfaceNameMgr *mgr);
virtual void Remove(IBase *api, CInterfaceNameMgr *mgr);
virtual EChooserRun Run(CInterfaceNameMgr *mgr);
protected:
//our list of names.
const char **choices;
//how many there are
uint32 num_choices;
//the default imp name.
char def_name[64];
};
//
//
//Macros to set up chooser vars.
//
//
//
//Use define_chooser_list like this:
//
//static const char *names[] = {"IFooImp1", "IFooImp2", "IFooImp3"};
//static const char *def_imp = names[1];
//static CInterfaceChooserList our_chooser;
//define_chooser_list(IFoo, our_chooser, names, def_imp);
//
//void bar(uint32 num) {
// //pick that interface
// our_chooser.SetImplementation(num);
//}
//
#define define_chooser_list(interface_name, var, imp_names, default_imp) \
/* make a function that will get called to initialize our chooser. */ \
void __chooser_list_init_hook_##var##_() { \
/* initialize the object */ \
var->Init(#interface_name, interface_name::_##interface_name##_VERSION_, \
sizeof(imp_names)/sizeof(imp_names[0]), imp_names, default_imp); \
} \
/* make the CChooserRegister variable */ \
static CChooserRegister __chooser_register_##var##_(var, \
__chooser_list_init_hook_##var##_); \
//
//
//Object used to register a CInterfaceChooser with the database.
//
//
class CChooserRegister {
public:
//the constructor allocates the object, then calls the hook function.
inline CChooserRegister(CInterfaceChooser &chooser_var, void (*hook)());
inline ~CChooserRegister();
protected:
//chooser var we control
CInterfaceChooser &chooser_var;
};
//
//ChooserRegister inline functions
//
CChooserRegister::CChooserRegister(CInterfaceChooser &var, void (*hook)())
: chooser_var(var)
{
//call the hook function
hook();
//increment database item count
CInterfaceDatabase::DatabaseItemCountInc();
//put the chooser in the database.
CInterfaceDatabase::AddChooser(&chooser_var);
}
CChooserRegister::~CChooserRegister() {
//remove the chooser from the database.
CInterfaceDatabase::RemoveChooser(&chooser_var);
//decrement database item count
CInterfaceDatabase::DatabaseItemCountDec();
}
//****************************************************************************************
//****************************************************************************************
//
//
//
//macros that will eventually be moved to some shared header file.
//
//
//
//
//****************************************************************************************
//****************************************************************************************
//delete macros.
#define delca(var) if (var != NULL) {delete [] var; var = NULL;}
#define delc(var) if (var != NULL) {delete var; var = NULL;}
//
//ASSERT style macros, but opposite semanticly.
//
#ifdef _DEBUG
#if defined(__LINUX)
#define BREAK1()
#else
#define BREAK1() __asm {int 3}
#endif
#define BREAK(expression) if (expression) {BREAK1();}
#else
#define BREAK1()
#define BREAK(expression)
#endif
#define IFBREAKRETURN(expression) if (expression) {BREAK1(); return;}
#define IFBREAKNULL(expression) if (expression) {BREAK1(); return NULL;}
#define IFBREAKRETURNVAL(expression, val) if (expression) {BREAK1(); return val;}
#define IFBREAKFALSE(expression) if (expression) {BREAK1(); return false;}
#define IFBREAKBREAK(expression) if (expression) {BREAK1(); break;}
//
//lets you define a block of code that looks like a function that will
//get called on shutdown.
//Use it like this.
// FILE_SHUTDOWN(us) {
// //our shutdown code...
// }
//
#define FILE_SHUTDOWN(name) \
class _FILE_SHUTDOWN_class_##name##_ { \
public: \
/* a destructor */ \
~_FILE_SHUTDOWN_class_##name##_(); \
}; \
/*global var of that type.*/ \
_FILE_SHUTDOWN_class_##name##_ _FILE_SHUTDOWN_var_##name##_; \
/* body of destructor*/ \
_FILE_SHUTDOWN_class_##name##_::~_FILE_SHUTDOWN_class_##name##_()
//
//lets you define a block of code that looks like a function that will
//get called on initialization, before main.
//Use it like this.
// FILE_INIT(us) {
// //our shutdown code...
// }
//
#define FILE_INIT(name) \
class _FILE_INIT_class_##name##_ { \
public: \
/* a destructor */ \
_FILE_INIT_class_##name##_(); \
}; \
/*global var of that type.*/ \
_FILE_INIT_class_##name##_ _FILE_INIT_var_##name##_; \
/* body of destructor*/ \
_FILE_INIT_class_##name##_::_FILE_INIT_class_##name##_()
/////////////////////////////////////////
template <class I>
CAPIInstanceDefines<I>::CAPIInstanceDefines(I *implementation, const char *implemented_class_name, int32 interface_version) {
//save a pointer to this implementaiton that we can use in our destructor
this->implementation = implementation;
//save the name of the implemented class.
this->implemented_class_name = implemented_class_name;
//increment the global database item count.
CInterfaceDatabase::DatabaseItemCountInc();
//register the api with the database.
CInterfaceDatabase::AddAPI(implementation, implemented_class_name, interface_version);
}
template <class I>
CAPIInstanceDefines<I>::~CAPIInstanceDefines() {
//get our api out of the database.
CInterfaceDatabase::RemoveAPI(implementation, implemented_class_name);
//decrement the global database item count.
CInterfaceDatabase::DatabaseItemCountDec();
}
//
//
// CAPIHolder functions.
//
//
template <class I>
CAPIHolder<I>::CAPIHolder(const char *api_string_name, I *&var, int32 version)
: CAPIHolderBase(api_string_name, version), p(var)
{
//initialize our interface pointer.
p = NULL;
//increment database item count.
CInterfaceDatabase::DatabaseItemCountInc();
//tell the api database that we exist and need an interface.
CInterfaceDatabase::AddHolder(this);
}
template <class I>
CAPIHolder<I>::~CAPIHolder() {
//we are being deleted, clear the pointer we keep track of.
p = NULL;
//tell the database that we no longer exist.
CInterfaceDatabase::RemoveHolder(this);
//decrement database item count
CInterfaceDatabase::DatabaseItemCountDec();
}
template <class I>
void CAPIHolder<I>::APIRemoved() {
//clear our pointer
p = NULL;
}
template <class I>
void CAPIHolder<I>::APIFound(IBase *api) {
//set the pointer. we assume the database has given us the correct api type.
p = (I *)api;
}
template <class I>
IBase *CAPIHolder<I>::Interface() {
//return our pointer
return p;
}
#endif //DOXYGEN_SHOULD_SKIP_THIS
#endif