/***************************************************************************
 *                                                                         *
 * Module  : bapipe.h                                                      *
 *                                                                         *
 * Purpose : Renderware device specific rendering pipeline                 *
 *                                                                         *
 **************************************************************************/

#ifndef RWPIPE_H
#define RWPIPE_H

/****************************************************************************
 Includes
 */

#include "batypes.h"
#include "batype.h"
#include "bamemory.h"
#include "baresour.h"
#include "bamatrix.h"
#include "bacamera.h"

/****************************************************************************
 Defines
 */

/* RWPUBLIC */

/****************************************************************************
 Global Types
 */

/* The pipeline doesn't know about the representation of a light.  It's only
 * when an implementation of fpLight and fpApplyLight are supplied that things
 * become known.  Until then, just the vertex formats are known.
 */
typedef RwResEntry * (*RwInstanceFunction)(void *object);
typedef void (*RwTransformFunction)(RwResEntry *repEntry);
typedef void (*RwPreLightFunction)(RwResEntry *repEntry);
typedef void (*RwApplyLightFunction)(RwResEntry *repEntry, const void *light, const RwMatrix *inverseMat, RwReal invScale, const RwSurfaceProperties *surfaceProps);
typedef void (*RwLightFunction)(RwResEntry *repEntry, RwApplyLightFunction applyLight);
typedef void (*RwPostLightFunction)(RwResEntry *repEntry);
typedef void (*RwRenderFunction)(RwResEntry *repEntry);

typedef struct RwRenderPipeline RwRenderPipeline;
struct RwRenderPipeline
{
    /* Function pointers for pipeline elements */
    /* Hence can be substituted with others */

    RwInstanceFunction        fpInstance;
    RwTransformFunction       fpTransform;
    RwPreLightFunction        fpPreLight;
    RwApplyLightFunction      fpApplyLight;
    RwLightFunction           fpLight;
    RwPostLightFunction       fpPostLight;
    RwRenderFunction          fpRender;
};



/* RWPUBLICEND */

typedef RwBool (*RwRenderPipelinePushContextFunction)(const RwRenderPipeline *pipeline);
typedef RwBool (*RwRenderPipelinePopContextFunction)(void);

typedef struct rwPipeGlobals rwPipeGlobals;
struct rwPipeGlobals
{
    RwFreeList                              *pipelineFreeList;
    RwRenderPipelinePushContextFunction     fpPushContext;
    RwRenderPipelinePopContextFunction      fpPopContext;
    RwInt32                                 pipeDepth;
    const RwRenderPipeline                  *renderPipes[rwMAXPIPECONTEXT];
};


/* RWPUBLIC */
/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

extern RwRenderPipeline *RwRenderPipelineCreate(void);
extern RwBool RwRenderPipelineDestroy(RwRenderPipeline *pipeline);
extern const RwRenderPipeline *RwRenderPipelinePushContext(const RwRenderPipeline *pipeline);
extern void *RwRenderPipelineExecute(void *object);
extern const RwRenderPipeline *RwRenderPipelinePopContext(void);

/* RWPUBLICEND */

extern void *_rwRenderPipelineOpen(void *instance, RwInt32 offset, RwInt32 size);
extern void *_rwRenderPipelineClose(void *instance, RwInt32 offset, RwInt32 size);
extern const RwRenderPipeline *_rwRenderPipelineGetCurrent(void);
extern void _rwRenderPipeSetContextFns(RwRenderPipelinePushContextFunction fpPushContext,
                                      RwRenderPipelinePopContextFunction fpPopContext);

extern RwBool _rwPipeAttach(void);
extern void _rwPipeInitForCamera(const RwCamera *camera);
extern RwBool _rwPipeSetupIm3DPipe(RwRenderPipeline *pipe);

/* RWPUBLIC */
#ifdef    __cplusplus
}
#endif                          /* __cplusplus */

/* RWPUBLICEND */

#endif /* RWPIPE_H */
