/*==============================================================*/
/* 3DLib							*/
/*								*/
/* Rendering related structures header file			*/
/*								*/
/* DATE:	1996-Nov-27 23:23:18				*/
/*								*/
/* 3DLib Copyright (C) 1995 by Gabor Nagy. All rights reserved.	*/
/*==============================================================*/
#ifndef _E3DRendering_h
#define _E3DRendering_h


#ifndef _E3DCamera_h
#include <E3D/Camera.h>
#endif

#ifndef _E3DRay_h
#include <E3D/Ray.h>
#endif

/*
#ifndef _E3DScene_h
#include <E3D/Scene.h>
#endif
*/


#if defined (__cplusplus) && (!(defined (__CPLUSLIBS)))
extern "C" {
#endif


// Renderer types
//
enum
{
 E3dRENDER_RAYCASTING=1,
 E3dRENDER_RAYTRACING,
 E3dRENDER_PHOTONMAPPING
};


// Anti-aliasing
//
enum
{
 E3dAA_NONE=0,
 E3dAA_2x,
 E3dAA_4x,
 E3dAA_6x,
 E3dAA_9x,
 E3dAA_ADAPTIVE_3x3,
 E3dAA_ADAPTIVE_4x4,
 E3dAA_STOCHASTIC,
 E3dAA_STOCHASTIC_3x3,
 E3dAA_STOCHASTIC_4x4
};


// Update-flags
//
#define	E3dUF_VOXELIZE		0x01
#define	E3dUF_READ_TEXTURES	0x02
#define	E3dUF_ALL		0x03

typedef struct E3dRenderInfo_S	E3dRenderInfo;

#ifndef _E3dScene
#define _E3dScene
typedef struct E3dScene_S	E3dScene;
#endif

#ifndef _E3dWindow
#define _E3dWindow
typedef struct E3dWindow_S	E3dWindow;
#endif

// Renderers
//
typedef int		(*E3dRendererProc)(E3dWindow*, E3dScene*, E3dRenderInfo*, EBool, EBool);

#define E3dRendererCore()\
 char*			Name;\
 unsigned int		StructSize;\
 E3dRendererProc	RenderProc


typedef struct
{
 E3dRendererCore();
} E3dRenderer;



struct E3dRenderInfo_S
{
 E3dCamera*	Camera;		// Currently used Camera

 E3dCamera**	Cameras;	// Cameras defined
 unsigned int	NumOfCameras;

 int		Algorithm;

 E3dRenderer*	Renderer;

// Image
//
 unsigned int	ImageXSize, ImageYSize,			// Changeable by user
		WorkingImageXSize, WorkingImageYSize,	// Copied from ImageXSize/ImageYSize when starting a render
		WindowXSize, WindowYSize;

 unsigned char	StartPixelSize;			// 2, 4, 8, 16 etc. for progressive, pixelized rendering
 unsigned char	AntiAliasing;
 EBool		CreateHDRImage;



 double		SizeFactor;			// atan(FieldOfView/2)*WindowYSize, for LODs

 E3dCoordinate	Brightness, Gamma;



// Ray-tracing
//
 unsigned int	MaxRayDepth;



// Atmospheric effects
//
 EcRGBfColor	FogColor;
 E3dCoordinate	FogNear, FogFar;

 EcRGBAiColor	BackgroundRGBAiColor;

 EcRGBfColor	SceneAmbientColor;


// For uniform-grid subdivision
//
 int		GridXCount, GridYCount, GridZCount;


 EBool		DoubleBuffer, Interlace, ClearFrameBuffer, ClearZBuffer,
		BackfaceCulling,
		AlphaBlending,
		Textures, Shadows, Reflections, Transparency, Refractions,
		Fog;


// Internal variables for the renderer
//
 EpImage*	CanvasImage;
// Pixmap		CanvasPixmap;
 unsigned int	UpdateFlags;
 int		LinesDone,
		CurrentPixelSize;		// For progressive-resolution rendering
 long		FrameStartTime;

 EBool		Rendering, GoRender, FirstIteration, RestartRender;
};



extern E3dRenderer**	E3d_Renderers;
extern int		E3d_NumOfRenderers;


extern E3dRenderer*	E3d_RendererFindByName(char* LName);
extern E3dRenderer*	E3d_RendererRegister(E3dRenderer* LClassTemplate);
extern void		E3d_RendererRemove(E3dRenderer* LClass);
extern void		E3d_RendererDeactivate(E3dRenderer* LClass);


extern int		E3d_PolyGroupCountTriangles(E3dPolyGroup* LPolyGroup);


extern void		E3d_RenderInfoDefault(E3dRenderInfo* LRenderInfo);
extern void		E3d_RenderInfoCopy(E3dRenderInfo* LSRenderInfo, E3dRenderInfo* LRenderInfo);

extern void		E3d_SceneResetForRendering(E3dScene* LScene);

extern int		E3d_RayGridBoundsIntersect(E3dScene* LScene, E3dRay* LRay);
extern void		E3d_GridAddTriangle(E3dScene* LScene, E3dRTriangle* LRTriangle, E3dPolyGroup* LPolyGroup);

extern void		E3d_RayDDAInit(E3dScene* LScene, E3dRay* LRay);
extern void		E3d_RayDDAInitStartVoxel(E3dScene* LScene, E3dRay* LRay);
extern void		E3d_RayDDAInitStartSet(E3dScene* LScene, E3dRay* LRay);


extern E3dRTriangle*	E3d_RayIntersectVoxels(E3dScene* LScene, E3dRay* LRay, E3dCoordinate* LUVTRet, void* LExcludeFace);
extern E3dRTriangle*	E3d_RayIntersectVoxelsBackFaceCull(E3dScene* LScene, E3dRay* LRay, E3dCoordinate* LUVTRet, void* LExcludeFace);
extern EBool		E3d_ShadowRayIntersectVoxels(E3dScene* LScene, E3dRay* LRay, void* LExcludeFace, E3dCoordinate LLightDistance);
extern E3dRTriangle*	E3d_RayIntersectVoxelsTest(E3dScene* LScene, E3dRay* LRay, void* LExcludeFace);
extern E3dRTriangle*	E3d_RayIntersectVoxelsTestStartSet(E3dScene* LScene, E3dRay* LRay, void* LExcludeFace);


extern void		E3d_IlluminatePoint(E3dScene* LScene, E3dSurfacePoint* LPoint, E3dMaterial* LMaterial, EcRGBAfColor* LIllumination);
extern void		E3d_IlluminatePointShadowing(E3dScene* LScene, E3dSurfacePoint* LPoint, E3dMaterial* LMaterial, EcRGBAfColor* LIllumination, E3dRTriangle* LExcludeRTriangle);


#if defined (__cplusplus) && (!(defined (__CPLUSLIBS)))
}	// Close scope of 'extern "C"' declaration which encloses file.
#endif

#endif	// _E3DRendering_h
