//////////////////////////////////////////////////////////////////////////////
//
// Asura_Platform_RenderSkin.h
//
// Copyright (c) 2005 Rebellion. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////////

// B E G I N   F I L E   W R A P P E R ///////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef ___ASURA_PLATFORM_RENDERSKIN_H___
#define ___ASURA_PLATFORM_RENDERSKIN_H___ 1

// M A C R O S ///////////////////////////////////////////////////////////////

// This many QWs at the beginning of SPR are required for internal use by
// the smooth skin rendering code.
#define ASURA_PS2_SMOOTHSKIN_SPR_QWS_RESERVED (0x40)

// F O R W A R D   D E C L A R A T I O N S ///////////////////////////////////

class Asura_Animation;
class Asura_SphericalHarmonics_Order2_RGB;
class Asura_Vector_3;

class Asura_PS2_SmoothSkin_MaterialHdr;
union Asura_PS2_QW;

// C L A S S E S /////////////////////////////////////////////////////////////

class Asura_PS2_SmoothSkin_Renderer
{

public:

    // T Y P E S /////////////////////////////////////////////////////////////

    typedef void (*RSCallback)( Asura_PS2_QW* pxRSBfr );

    // C L A S S   M E T H O D S /////////////////////////////////////////////

    //
    // Startup.
    //

    static bool Begin( const Asura_Animation* pxAnim,
                       u_int uCamVisFlags,
                       bool  bRenderShadow,
                       const Asura_Vector_3& xBSCentre,
                       float fBSRadius );

    static void GetHdrData( u_int* puNumMaterials,
                            const int** ppiMaterialIDs,
                            const Asura_PS2_SmoothSkin_MaterialHdr** ppxFirstMaterialHdr,
                            u_int* puFirstDataChainAddr );

    //
    // Renderstate.
    //

    static void SetTexture( int iTexID );

    // Note that you cannot modify the number of passes made using the
    // callback. To be sure state is reset afterwards, you must call both
    // SetTexture() and ChangeMaterialAndSendRS() with no callback.
    static void ChangeMaterialAndSendRS( int iMaterialID, u_int uMaterialFlags, RSCallback pfnModifyCB = NULL );

    //
    // Renderstate callbacks.
    //

    static void CB_JustWriteZ( Asura_PS2_QW* pxRSBfr );
    static void CB_IgnoreTextureAlpha( Asura_PS2_QW* pxRSBfr );

    //
    // Transforms.
    //

    // Note that any transform inserted will last for the duration of the
    // skin's rendering. It will not affect lighting calculations, only
    // transform, clipping and reflection based stuff.
    static void InsertWorldspaceTransform( const Asura_PS2_QW* pxTransform );

    //
    // Data transfer and rendering
    //
    
    static void UploadBoneData( void );

    static void UploadCamData( void );

    static void UploadLightData( const Asura_SphericalHarmonics_Order2_RGB& xSH, float fAlpha );

    static void UploadShadowData( void ); 
    
    static void RenderForMaterial( const Asura_PS2_SmoothSkin_MaterialHdr** ppxMaterialHdr, u_int* puChainAddr );

    //
    // Tidy up.
    //

    static void End( void );

};
// End class Asura_PS2_SmoothSkin_Renderer.

// E N D   F I L E   W R A P P E R ///////////////////////////////////////////

#endif // #ifndef ___ASURA_PLATFORM_RENDERSKIN_H___
