//***************************************************************************
//
//  Copyright (c) 1999 - 2006 Intel Corporation
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
//***************************************************************************

/**
	@file	IFXDevice.h
			The IFXDevice interface.
*/

#ifndef __IFXDEVICE_H__
#define __IFXDEVICE_H__

#include "IFXUnknown.h"
#include "IFXView.h"
#include "IFXRenderContext.h"

// {1FD3AD90-A90E-11d3-94A5-00A0C9A0FBAE}
IFXDEFINE_GUID(IID_IFXDevice,
0x1fd3ad90, 0xa90e, 0x11d3, 0x94, 0xa5, 0x0, 0xa0, 0xc9, 0xa0, 0xfb, 0xae);

/**
 *	The IFXDevice interface encapsulates a window that will contain
 *	3D rendered images.  The window can use a specific renderer
 *	(DX8, DX7, OpenGL, etc.), or use the default renderer associated
 *	with the singleton IFXRenderServices object.  Similarly, the
 *	AntiAliasing mode (and whether or not it is enabled) can use the
 *	settings contained in the IFXRenderServices object, or can be
 *	set unique to this instance of IFXDevice.
 *
 *	3D rendering only occurs after associating an allocated window
 *	and an IFXView with the IFXDevice.  The IFXView object represents
 *	a camera in a 3D scene, and the window can be thought of as the
 *	print that will receive snapshot taken with the camera.  Images
 *	are generated by calling the Render() method.
 */
class IFXDevice : public IFXUnknown
{
public:

	/**
	 *	This is the default target frame rate when using automatic frame
	 *	rate determined CLOD.
	 */
	#define	DEFAULT_TARGETFRAMERATE		30.0

	/**
	 *	Initialize the IFXDevice.  This must be called before any other
	 *	method is used.
	 *
	 *	@return	An IFXRESULT value.
	 *
	 *	@note	Reinitialization is not supported.
	 */
	virtual IFXRESULT IFXAPI Initialize()=0;

	/**
		Adds a view to the end of the view list which is rendered by the 
		Render function.

		@param	pView			Interface pointer to a view node to be added 
								to the end of the view list used for 
								rendering.
		@param	viewInstance	Instance index of the view node specified by 
								pView to use for rendering.  This value must 
								be less than that reported by the 
								IFXView::GetNumberOfInstances function.

		@return	Upon success, IFX_OK is returned and the specified view node 
				instance will be added to the end of the list.  Otherwise, 
				one of the following failures are returned:  
				IFX_E_INVALID_POINTER, IFX_E_INVALID_RANGE, 
				IFX_E_NOT_INITIALIZED and IFX_E_UNDEFINED.
	*/
	virtual IFXRESULT IFXAPI AppendView( 
								IFXView*	pView,
								U32			viewInstance ) = 0;

	/**
		Get a view from the view list which is rendered by the Render 
		function.

		@param	index			Base zero, view list index of the view 
								desired.  The total number of available 
								views can be obtained using the 
								GetViewCount function.
		@param	ppView			Pointer to a view node interface pointer 
								that upon success will be intialized to the 
								specified view in the view list.  As usual, 
								the caller is responsible for releasing the  
								interface reference when finished using it.  
								NULL can be specified if this data is not 
								desired.
		@param	pViewInstance	Pointer to a U32 that upon success will be 
								initialized to the specified view's instance 
								indice that is used when rendering.  NULL 
								can be specified if this data is not desired.

		@return	Upon success, IFX_OK is returned and the requested view node 
				data is handed back.  Otherwise, one of the following 
				failures are returned: IFX_E_INVALID_RANGE and 
				IFX_E_NOT_INITIALIZED.

		@note	When a node has more than one parent, or one of its 
				ancestors has more than one parent, the node will have more 
				than one instance in the world.
	*/
	virtual IFXRESULT IFXAPI GetView( 
								U32			index, 
								IFXView**	ppView, 
								U32*		pViewInstance ) = 0;

	/**
		Get the total number of views in the view list which is rendered by 
		the Render function.

		@param	rViewCount	Reference to a U32 that upon success will be 
							initialized with the number of view node 
							instances that are in the view list.

		@return	Upon success, IFX_OK is returned and the count of associated 
				view node instances is handed back.  Otherwise, one of the 
				following failures are returned: IFX_E_NOT_INITIALIZED.
	*/
	virtual IFXRESULT IFXAPI GetViewCount( 
								U32&		rViewCount ) = 0;

	/**
		Removes the last view in the view list which is rendered by the 
		Render function.

		@return	Upon success, IFX_OK is returned and the last view node 
				instance will have been removed from the end of the list.
				Otherwise, one of the following failures are returned:  
				IFX_E_CANNOT_FIND (indicates there is no last view node 
				instance to remove) and IFX_E_NOT_INITIALIZED.  
	*/
	virtual IFXRESULT IFXAPI RemoveLastView() = 0;

	/**
	 *	Retreives the size of the window attached to this IFXDevice object.
	 *
	 *	@param	rcWindow	A reference to an IFXRect object that will receive
	 *						the dimensions of the window attached to this
	 *						IFXDevice.
	 *
	 *	@return	An IFXRESULT value.
	 *
	 *	@retval	IFX_OK	No error.
	 */
	virtual IFXRESULT IFXAPI GetWindowSize(IFXRect& rcWindow) const=0;

	/**
	 *	Renders an image using the IFXView (camera) instances attached to 
	 *	this IFXDevice and displays the result in the window attached to this
	 *	IFXDevice.
	 *
	 *	@return An IFXRESULT value.
	 *
	 *	@retval	IFX_OK	No error.
	 *	@retval	IFX_E_SUBSYSTEM_FAILURE	An uncorrectable failure occurred
	 *				in the rendering subsystem while rendering the image.
	 *				This can occur when a video card's resources are lost
	 *				to another process.  The device must be destroyed and
	 *				re-created to continue (and even that may not work).
	 *	@retval	IFX_E_INVALID_RANGE
	 *				One of the associated views cannot be rendered because 
	 *				the instance index is no longer valid.
	 */
	virtual IFXRESULT IFXAPI Render()=0;

	/**
	*  Sets the current window parameters.
	*
	*  @param  rWindow An input reference to an IFXRenderWindow object specifying the
	*          parameters for the window.
	*
	*  @return An IFXRESULT code.
	*
	*  @retval IFX_OK No error
	*/
	virtual IFXRESULT IFXAPI SetWindow(IFXRenderWindow& rWindow)=0;

	/**
	 *	Attaches a destination buffer for the rendered image.  The type
	 *	of destination buffer is determined by the @a bDTS parameter.
	 *
	 *	If @a bDTS is @b TRUE, then pvWindow represents an OS native
	 *	window.  On Microsoft* Windows*, this must be an HDC attached
	 *	directly to a window (note: not an HDC*).  On Apple* MacOS*, this
	 *	value must be a WindowPtr value.
	 *
	 *	If @a bDTS is @b FALSE, then pvWindow represents an offscreen
	 *	memory buffer.  On Microsoft* Windows*, this must be and HDC to
	 *	an offscreen bitmap.  On Apple* MacOS*, this must be an an offscreen
	 *	CGraphPtr.
	 *
	 *	@param	pvWindow	An input value that represents the destination
	 *						buffer for the rendered image.  See above for
	 *						an explanation of what this value may be.
	 *	@param	bDTS		Boolean describing whether or not the rendered
	 *						image appears directly on screen or not.  DTS =
	 *						Direct-To-Screen.  If @a bDTS is @b FALSE, the
	 *						rendered image will be located in an offscreen
	 *						memory buffer.
	 *
	 *	@return	An IFXRESULT value.
	 *
	 *	@retval	IFX_OK	No error.
	 *	@retval	IFX_E_INVALID_POINTER	The value specified for @a pvWindow
	 *									was 0.
	 *	@retval	IFX_E_INVALID_RANGE		The value specified for @a pvWindow
	 *									was not matched correctly with the
	 *									value for @a bDTS.
	 */
	virtual IFXRESULT IFXAPI SetWindowPtr(IFXHANDLE pvWindow)=0;
	virtual IFXRESULT IFXAPI SetDTS(BOOL bDTS)=0;

	/**
	 *	Sets the portion of the attached window to receive the rendered image.
	 *
	 *	@param	rcWindow	Input IFXRect that determines what portion of the
	 *						attached window will receive the rendered image
	 *						during a Render() call.
	 *
	 *	@return	An IFXRESULT value.
	 *
	 *	@retval	IFX_OK	No error.
	 *	@retval	IFX_E_INVALID_RANGE	The @a rcWindow.m_Width or
	 *								@a rcWindow.m_Height value was 0.
	 */
	virtual IFXRESULT IFXAPI SetWindowSize(const IFXRect& rcWindow)=0;

	/**
	 *	Sets whether or not un-rendered pixels in the rendered buffer will be left
	 *	untouched or cleared to the attached IFXView's clear color.  This
	 *	property is only regarded when the @a bDTS parameter to SetWindowPtr()
	 *	is @b FALSE.
	 *
	 *	@param	bTransparent	Input BOOL specifying whether or not to use
	 *							"transparent" rendering (leaving un-touched pixels
	 *							in the rendered area untouched).
	 *
	 *	@return An IFXRESULT value.
	 *	@retval	IFX_OK	No error.
	 */
	virtual IFXRESULT IFXAPI SetTransparent(BOOL bTransparent)=0;

	/**
	 *	Retreives the Anti-Aliasing enabled property.  This property can be
	 *	one of 3 values:
	 *		- @b IFX_AA_DEFAULT - Uses value in the IFXRenderServices object.
	 *		- @b IFX_AA_DISABLED - Not using anti-aliased rendering.
	 *		- @b IFX_AA_ENABLED - Is using anti-aliased rendering.
	 *
	 *	@param	eAAEnabled	Output IFXenum value receiving the anti-aliasing
	 *						enabled property.
	 *
	 *	@return	An IFXRESULT value.
	 *
	 *	@retval	IFX_OK	No error.
	 */
	virtual IFXRESULT IFXAPI GetAAEnabled(IFXenum& eAAEnabled)=0;

	/**
	 *	Sets the anti-aliasing enabled property.  This property can be
	 *	one of 3 values.
	 *		- @b IFX_AA_DEFAULT - Uses the value in the IFXRenderServices object.
	 *		- @b IFX_AA_DISABLED - Not using anti-aliased rendering.
	 *		- @b IFX_AA_ENABLED - Is using anti-aliased rendering.
	 *
	 *	@param	eAAEnabled	Input IFXenum value specifying the anti-aliasing
	 *						enabled property.
	 *
	 *	@return	An IFXRESULT value.
	 *
	 *	@retval	IFX_OK	No error.
	 *	@retval	IFX_E_INVALID_RANGE	The value specified for @a eAAEnabled is
	 *								is not valid.
	 */
	virtual IFXRESULT IFXAPI SetAAEnabled(IFXenum  eAAEnabled)=0;

	/**
	 *	Retreives the anti-aliasing mode property.  This property can be
	 *	one of the following values:
	 *		- @b IFX_AA_DEFAULT - Uses the value in the IFXRenderServices object.
	 *		- @b IFX_AA_2X - Performs 2X anti-aliasing.
	 *		- @b IFX_AA_3X - Performs 3X anti-aliasing.  On many cards this is
	 *			Quincunx* anti-aliasing.
	 *		- @b IFX_AA_4X - Performs 4X anti-aliasing.
	 *		- @b IFX_AA_4X_SW - Performs 4X anti-aliasing partially implemented
	 *			in software.  This is much slower than @b IFX_AA_4X.
	 *
	 *	@param	eAAMode	Output IFXenum to receive the anti-aliasing mode.
	 *
	 *	@return	An IFXRESULT value.
	 *
	 *	@retval	IFX_OK	No error.
	 */
	virtual IFXRESULT IFXAPI GetAAMode(IFXenum& eAAMode)=0;

	/**
	 *	Sets the anti-aliasing mode property.  This property can be
	 *	one of the following values:
	 *		- @b IFX_AA_DEFAULT - Uses the value in the IFXRenderServices object.
	 *		- @b IFX_AA_2X - Performs 2X anti-aliasing.
	 *		- @b IFX_AA_3X - Performs 3X anti-aliasing.  On many cards this is
	 *			Quincunx* anti-aliasing.
	 *		- @b IFX_AA_4X - Performs 4X anti-aliasing.
	 *		- @b IFX_AA_4X_SW - Performs 4X anti-aliasing partially implemented
	 *			in software.  This is much slower than @b IFX_AA_4X.
	 *
	 *	@param	eAAMode	Input IFXenum specifying the desired anti-aliasing mode.
	 *
	 *	@return	An IFXRESULT value.
	 *
	 *	@retval	IFX_OK	No error.
	 *	@retval	IFX_E_INVALID_RANGE	The value specified for @a eAAMode is not valid.
	 *								Either the mode is not supported by the rendering
	 *								device, or the enum value is invalid.
	 */
	virtual IFXRESULT IFXAPI SetAAMode(IFXenum  eAAMode)=0;

	/**
	 *	Retreives capability information about the associated rendering
	 *	device.
	 *
	 *	@param	rCaps	Reference to an IFXRenderCaps object that will be
	 *					filled with capability information about the
	 *					underlying rendering device.
	 *
	 *	@return	An IFXRESULT value.
	 *	@retval	IFX_OK	No error.
	 */
	virtual IFXRESULT IFXAPI GetRenderCaps(IFXRenderCaps& rCaps)=0;

	/**
	 *	Sets the renderer type used for this device.  The @a uRenderId must be
	 *	either 0 or an id that was previously registered with
	 *	IFXRenderServices::RegisterRenderer().
	 *
	 *	@param	uRenderId	Input U32 representing the id of the renderer type
	 *						to use for this device.  If this value is 0, the
	 *						device will used the preferred renderer set in
	 *						the IFXRenderServices object.  If non-zero, this
	 *						must correspond to a registered renderer type.
	 *
	 *	@return	An IFXRESULT value.
	 *
	 *	@retval	IFX_OK	No error.
	 *	@retval	IFX_E_INVALID_RANGE	The @a uRenderId value specified was invalid.
	 */
	virtual IFXRESULT IFXAPI SetRenderer(U32 uRenderId)=0;

	/**
	 *	Get the currently set renderer type for this device.
	 *
	 *	@param	uRenderId	Reference to a U32 value to be filled in with the
	 *						currently set renderer id.
	 *
	 *	@return	An IFXRESULT value.
	 *
	 *	@retval	IFX_OK	No error.
	 */
	virtual IFXRESULT IFXAPI GetRenderer(U32& uRenderId)=0;

	/**
	 *	Get the currently set target framerate.  The target framerate is used
	 *	by the CLOD system to dynamically adjust geometry complexity.
	 *
	 *	@param	pfTargetFramerate	Pointer to an F32 value that will receive
	 *								the current target framerate.
	 *
	 *	@return	An IFXRESULT value.
	 *
	 *	@retval	IFX_OK	No error.
	 *	@retval	IFX_E_INVALID_POINTER	The argument @a pfTargetFramerate was NULL.
	 */
	virtual IFXRESULT IFXAPI GetTargetFramerate(F32 *pfTargetFramerate)=0;

	/**
	 *	Set the target framerate.  If the use of target framerate is enabled, the
	 *	CLOD system will dynamically adjust geometry complexity so that actual
	 *	framerate approaches this target framerate.
	 *
	 *	@param	fTargetFramerate	Input F32 specifying the new target framerate.
	 *
	 *	@return	An IFXRESULT value.
	 *
	 *	@retval	IFX_OK	No error.
	 */
	virtual IFXRESULT IFXAPI SetTargetFramerate(F32 fTargetFramerate)=0;

	/**
	 *	Retreives whether or not the use of CLOD to reach the target framerate is
	 *	enabled.
	 *
	 *	@param	puUseTargetFramerate	Pointer to a U32 value that will be filled
	 *									with 1 if we are using CLOD to reach the
	 *									target framerate, or 0 otherwise.
	 *
	 *	@return	An IFXRESULT value.
	 *
	 *	@retval	IFX_OK	No error.
	 *	@retval	IFX_E_INVALID_POINTER	The value specified for @a puUseTargetFramerate
	 *									was NULL.
	 */
	virtual IFXRESULT IFXAPI GetUseTargetFramerate(U32 *puUseTargetFramerate)=0;

	/**
	 *	Enables or disables the use of CLOD to reach the target framerate.
	 *
	 *	@param	puUseTargetFramerate An address of an output boolean value that
	 *                               specifies whether or not the target
	 *                               framerate will be used to determine the
	 *                               CLOD resolution.
	 *                               If a value of 0 is returned, target frame-
	 *								 rate is disabled, otherwise it is enabled.
	 *
	 *	@return	An IFXRESULT value.
	 *
	 *	@retval	IFX_OK	No error.
	 */
	virtual IFXRESULT IFXAPI SetUseTargetFramerate (U32 uUseTargetFramerate)=0;

	/**
	 *	Set the pixel aspect of the device.  The pixel aspect can be changed when
	 *	the display device used has a pixel aspect other than 1.0.  For instance, you
	 *	are using a standard 4:3 resolution (1600x1200) on a widescreen 16:9
	 *	monitor.  In that case, you would use a pixel aspect ratio of 1.333333.
	 *
	 *	@param	fAspect	The new pixel aspect ratio to use.  Must be a positive
	 *					non-zero number.
	 *
	 *	@return	An IFXRESULT value.
	 *
	 *	@retval	IFX_OK	No error.
	 *	@retval	IFX_E_INVALID_RANGE	The value specified with @a fAspect was either
	 *								0.0 or negative.
	 */
	virtual IFXRESULT IFXAPI SetPixelAspect(F32 fAspect)=0;

	/**
	 *	Clear all rendering statistical information for this device.
	 *
	 *	@return An IFXRESULT value.
	 *
	 *	@retval	IFX_OK	No error.
	 */
	virtual IFXRESULT IFXAPI ClearRenderInfo()=0;

	/**
	 *	Retreive rendering statistical information for this device.  The information
	 *	is relative to either the creation of the device, or last time
	 *	ClearRenderInfo() was called.
	 *
	 *	@param	eRenderInfo	Input IFXenum specifying which information to return.
	 *						Possible values are:
	 *							- @b IFX_NUM_FACES: Number of faces (polygons) rendered.
	 *							- @b IFX_NUM_VERTICES: Number of vertices rendered.
	 *							- @b IFX_NUM_MESHES: Number of meshes (surfaces) rendered.
	 *							- @b IFX_NUM_RENDER_CALLS: Number of draw calls placed
	 *								to the underlying rendering system.
	 *
	 *	@return	A U32 value containing the requested information.  If @a eRenderInfo
	 *			was invalid, 0 is returned.
	 */
	virtual U32		  IFXAPI GetRenderInfo(IFXenum eRenderInfo)=0;
};

#endif
