/****************************************************************************************

		I3DExPostRenderer.h

		Copyright: (c) 2001 Eovia Corp. All rights reserved.

		I3DExPostRenderer definition

		Author:	Ray Dream
		Date:	3/2/98

		Revision History

		when		who					what & why
		==========	================	======================================================
		08/26/99	cph					Added family ids
		08/11/99	Guillaume&Christy	Added inheritance to all the Basic* classes

*****************************************************************************************/
#ifndef __I3DEXPOSTRENDERER__
#define __I3DEXPOSTRENDERER__

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "IExtension.h"
#include "I3DShScene.h"
#include "I3DShUtilities.h"
#include "InterfaceIDs.h"
#include "IShRasterLayer.h"

//****** Globally Unique Ids *************************************************
MCDEFINE_GUID_H(IID_I3DExPostRenderer);
MCDEFINE_GUID_H(IID_I3DExPostRenderer2);
MCDEFINE_GUID_H(IID_I3DExPostRenderer3);
//MCDEFINE_GUID(IID_I3DExPostRenderer10, 0xf62a58a1L, 0xf76d, 0x11cf, 0x9a, 0x2c, 0x00, 0x20, 0xaf, 0x28, 0x19, 0x3a);

//****** Family Id *************************************************

const FourCharT kPostRendererFamilyID = kRID_PostRendererFamilyID;

struct IShRasterLayer;
class  TChannelDataBucket;
struct IShChannel;
struct I3DExRaytracer;
class  RenderFilterNeeds;


/*****************************************************************************\
*  I3DExPostRenderer                                                          *
*                                                                             *
*  Post Renderers                                                             *
*                                                                             *
\*****************************************************************************/

#ifndef qDemoVersion //regular interface

/// \addtogroup ExternalInterface
///
/// \{

/// <P>Post Renderers are instantiated at the end of the rendering to add a post processing
/// effect to the image. They can use the information stored in GBuffers.</P>
///
/// <P>Post Renderers can be instantiated in two different ways:</P>
///
///    - They can be added in the scene properties (Filter tab) if they apply globally to
///    the whole scene.
///
///    - They can also be hidden (subFamily="Hidden") and associated with a particular
///      datacomponent (see I3DExDataComponent) that will instantiate them when it is
///      enabled. This allow for instance to have a per object effect (like the 3D Aura).
///
/// <P>To implement your own post renderer, you should derive your class from TBasicPostRenderer which
/// provides a default implementation for the methods of I3DExPostRenderer</P>
///
/// <P>To access an existing postRenderer, use I3DShPostRenderer.
///
struct I3DExPostRenderer: public IMCUnknown
{
	// ****************************************************************************
	//								GetBufferNeeds
	// 
	/// Identifies which GBuffers are necessary to compute this post renderer. To find
	/// the various contants used for GBuffer check at the end of I3DExPostRenderer.h
	///
	/// \param needs	A bit field that identifies which GBuffers are necessary. The bits
	///					are set to 1 if the corresponding GBuffer should be filled.
	/// \param renderer Not used
	///
	virtual void		MCCOMAPI GetBufferNeeds(RenderFilterNeeds& needs, void* renderer) = 0;

	// ****************************************************************************
	//								PrepareDraw
	// 
	/// Called at the begginning of postrendering to initialise the postrenderer.
	///
	/// \param input The color buffer of the image.
	/// \param bounds The image rectangle in pixels
	/// \param buffers The array of pointers to the GBuffers (The pointers are null if the corresponding buffer is not allocated)
	/// \param scene The scene being rendered
	/// \param renderingCamera The current renderingCamera
	/// \param uvBox screen Coordinates of the image to render
	/// \param productionFrame Screen coordinates of the production frame
	///
	virtual MCCOMErr MCCOMAPI PrepareDraw		(IShRasterLayer*	input,
												 const TMCRect&		bounds,
												 IShChannel*		buffers[],
												 I3DShScene*		scene,
												 I3DShCamera*		renderingCamera,
												 const TBBox2D&		uvBox,
												 const TBBox2D&		productionFrame)=0; 
	
	// ****************************************************************************
	//								DrawRect
	// 
	/// Called for each tile of the output image. This is where the actual rendering
	/// takes place.
	///
	/// \param outputRect The Rectangle of the tile (in pixels)
	/// \param outputTile Pointers to pixel buckets (R,G,B,A) of the output tile.
	/// \param uvBox The screen coordinates of the tile
	///
	virtual MCCOMErr	MCCOMAPI DrawRect		(const TMCRect& outputRect,
												 const TChannelDataBucket* outputTile[],
												 const TBBox2D &uvBox)=0;

	// ****************************************************************************
	//								FinishDraw
	// 
	/// Called for clean up at the end of the postrendering (after DrawRect()).
	///
	virtual MCCOMErr	MCCOMAPI FinishDraw()=0;

	// ****************************************************************************
	//								BeginRender
	// 
	/// Called at the beginning of the rendering of an animation. This can be used
	/// if you want to create a Post Renderer that depends on previous frames.
	///
	/// \param beginTime The time at which the rendering starts (in MicroTick)
	/// \param endTime The time at which the rendering ends (in MicroTick)
	/// \param framePerSeconds The number of frame per second
	/// \param nbrFrames The total number of frame that will be rendered.
	/// \param isRenderMovie True if an animation is being rendered.
	///
	virtual MCCOMErr	MCCOMAPI BeginRender	(MicroTick beginTime,MicroTick endTime, 
													uint32 framePerSeconds,
													int32	nbrFrames, boolean isRenderMovie)=0;


	// ****************************************************************************
	//								EndRender
	// 
	/// Called at the end of the rendering of an animation.
	///
	///
	virtual MCCOMErr	MCCOMAPI EndRender		()=0;

};

/// \}

#else 	//(qDemoVersion) begin scrambled interface

struct I3DExPostRenderer: public IMCUnknown
{
	virtual MCCOMErr	MCCOMAPI EndRender		()=0;	
	virtual void		MCCOMAPI GetBufferNeeds(RenderFilterNeeds& needs, void* renderer) = 0;
	virtual MCCOMErr	MCCOMAPI FinishDraw()=0;		
	virtual MCCOMErr	MCCOMAPI DrawRect		(const TMCRect& outputRect,
												 const TChannelDataBucket* outputTile[],
												 const TBBox2D &uvBox)=0;
	virtual MCCOMErr MCCOMAPI PrepareDraw		(IShRasterLayer*	input,				// color buffer
												 const TMCRect&		bounds,				// image rectangle in pixels
												 IShChannel*		buffers[],			// gBuffers ( null pointers for those that are not filled
												 I3DShScene*		scene,				// current scene
												 I3DShCamera*		renderingCamera,	// current renderingCamera
												 const TBBox2D&		uvBox,				// screen coordinates of the image to render
												 const TBBox2D&		productionFrame)=0; // screen coordinates of the production frame		
	virtual MCCOMErr	MCCOMAPI BeginRender	(MicroTick beginTime,MicroTick endTime, 
													uint32 framePerSeconds,
													int32	nbrFrames, boolean isRenderMovie)=0;
};

#endif	//(qDemoVersion) end scrambled


/// \addtogroup ExternalInterface
///
/// \{

/// Extra methods for I3DExPostRenderer, that should be merged in when we get to Cararra 6
struct I3DExPostRenderer2: public IMCUnknown
{
		// ****************************************************************************
	//								SetRaytracer
	// 
	/// Sets the raytracer
	/// 
	/// \param raytracer  A pointer to a raytracer
	/// 
	virtual void		MCCOMAPI SetRaytracer(I3DExRaytracer* raytracer) =0;

};

struct I3DExPostRenderer3 : public IMCUnknown
{
	virtual IShRasterLayer::ELayerMode	MCCOMAPI GetEffectCompositionMode() = 0;

	virtual MCCOMErr					MCCOMAPI DrawRect2(const TMCRect& outputRect,
														   const TChannelDataBucket* outputTile[],
														   const TChannelDataBucket* compositedOutputTile[],
														   const TBBox2D &uvBox) = 0;
};

/// \}


// ***************************************************************************
//						GBuffers

enum
{
	// 3D
	k32Distance,						// real32
	k32PositionX,						// real32
	k32PositionY,						// real32
	k32PositionZ,						// real32
	k32NormalX,							// real32
	k32NormalY,							// real32
	k32NormalZ,							// real32
	k32Index,							// int32
	k32SurfaceU,						// real32
	k32SurfaceV,						// real32
	k32BackwardVelocityX,				// real32
	k32BackwardVelocityY,				// real32
	k32ForwardVelocityX,				// real32
	k32ForwardVelocityY,				// real32

	// Fragments
	k32FragmentWeight,					// real32
	k32FragmentColor,					// TMCColorRGBA8

	// Material
	k32MaterialDiffuseColor,			// TMCColorRGBA8
	k32MaterialSpecularColor,			// TMCColorRGBA8
	k32MaterialSpecularSizeValue,		// TMCColorRGBA8
	k32MaterialAmbientValue,			// TMCColorRGBA8
	k32MaterialLambertValue,			// TMCColorRGBA8
	k32MaterialReflectionColor,			// TMCColorRGBA8
	k32MaterialTransparencyColor,		// TMCColorRGBA8
	k32MaterialRefractionValue,			// TMCColorRGBA8
	k32MaterialGlowColor,				// TMCColorRGBA8

	// Image
	k32Background,						// TMCColorRGBA8
	k32Alpha,							// real32
	k32LightingAmbient,					// TMCColorRGBA8
	k32AmbientOcclusion,				// real32
	k32LightingDiffuse,					// TMCColorRGBA8
	k32LightingSpecular,				// TMCColorRGBA8
	k32LightingShadow,					// TMCColorRGBA8
	k32LightingDiffuseSpecularShadow,	// TMCColorRGBA8
	k32LightingGlow,					// TMCColorRGBA8
	k32LightingReflection,				// TMCColorRGBA8
	k32LightingRefraction,				// TMCColorRGBA8
	k32LightingGlobalIllumination,		// TMCColorRGBA8
	k32LightingCaustics,				// TMCColorRGBA8
	k32LightingSubsurfaceScattering,	// TMCColorSignedRGB8
	k32ImageAtmosphereMult,				// TMCColorRGBE8
	k32ImageAtmosphereAdd,				// TMCColorSignedRGB8
	k32ImageVolumePrimitivesMult,		// TMCColorRGBE8
	k32ImageVolumePrimitivesAdd,		// TMCColorSignedRGB8
	k32ImageVolumetricEffects,			// TMCColorSignedRGB8

	kNbr32GBuffer
};


#endif
