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

		I3DShPostRenderer.h

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

		I3DShPostRenderer definition

		Author:	Ray Dream
		Date:	3/2/98

		Revision History

		when		who			what & why
		==========	==========	======================================================

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

#ifndef __I3DSHPOSTRENDERER__
#define __I3DSHPOSTRENDERER__

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "APITypes.h"
#include "MCCompObj.h"
#include "I3DExPostRenderer.h"
#include "BitField.h"

struct IShRasterLayer;
struct IShChannel;
class  TChannelDataBucket;
class  TMCRect;

struct I3DShCamera;

//****** Globally Unique Ids **************************************************

MCDEFINE_GUID(IID_I3DShPostRenderer, 0x8108eb88, 0x40c3, 0x11d1, 0xa0, 0xa0, 0x0, 0xaa, 0x0, 0xd3, 0x7, 0xeb);

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

struct I3DShScene;


/// \addtogroup ShellInterface
/// \{

/// <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>There are two interfaces to access postRenderer: The shell interface (I3DShPostRenderer) and
/// the external interface (I3DExPostRenderer) . You can get one from the other using QueryInterface.</P>
///
/// <P>Whenever it is possible you should use the Shell interface (I3DShPostRenderer) to access the component
/// because the Shell will make sure that the parameter map of the external component is valid.
/// This is especially important if the component is animated. For more information on components
/// see the Overview of the SDK.</P>
/// 
/// \see I3DShPostRenderer
///
struct I3DShPostRenderer: public IMCUnknown
{
	// ****************************************************************************
	//								SetScene
	// 
	/// Sets the scene that is rendered.
	/// 
	/// \param scene  The scene that is rendered.
	/// 
	virtual MCCOMErr	MCCOMAPI SetScene		(I3DShScene* scene)=0;

	// ****************************************************************************
	//								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.
	///
	virtual MCCOMErr	MCCOMAPI GetBufferNeeds	(RenderFilterNeeds& needs)=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,				// screen coordinates of the image
												 const TBBox2D& productionFrame)=0;	// screen coordinates of the production frame
	
	// ****************************************************************************
	//								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 compositedOutputTile Pointers to the compisited pixel buckets (see GetEffectCompositionMode())
	/// \param uvBox The screen coordinates of the tile
	///
	virtual MCCOMErr	MCCOMAPI DrawRect		(const TMCRect& outputRect,
												 const TChannelDataBucket* outputTile[],
												 const TChannelDataBucket* compositedOutputTile[],
												 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;

	// ****************************************************************************
	//								SetRaytracer
	// 
	/// Sets the raytracer
	/// 
	/// \param raytracer  A pointer to a raytracer
	/// 
	virtual void		MCCOMAPI SetRaytracer(I3DExRaytracer* raytracer) =0;

	// ****************************************************************************
	//								GetEffectCompositionMode
	// 
	/// Returns the effect compositing mode for multipass rendering.
	/// 
	virtual IShRasterLayer::ELayerMode	MCCOMAPI GetEffectCompositionMode() = 0;
};


/// \}


// ****************************************************************************
//					Utilities

/// \addtogroup Data
/// \{

/// A bit field that specifies which GBuffers are needed for a particular post renderer.
/// 
class RenderFilterNeeds
{
	public:
		RenderFilterNeeds() : fFlags(0) {}

		boolean		IsOn		(int32 flag) const 		{ return fFlags.TestBit(flag); }
		void		Set			(int32 flag) 			{ fFlags.SetBitValue(flag, true); }
		void		Clear		(int32 flag) 			{ fFlags.SetBitValue(flag, false); }
		void		ClearAll	()						{ fFlags.ClearAllBits(); }

		void		operator |=	(const RenderFilterNeeds& needs) { fFlags.SetMasked(needs.fFlags.GetBits()); }

	protected:
		TBitField64		fFlags;
};
/// \}

#endif