///////////////////////////////////////////////////////////////////////  
//  Textures.hlsl
//
//	This file contains texture setup & sample functions used by the SpeedTree
//	vertex and pixel shaders.  These shaders will compile with HLSL and Cg compilers.
//
//
//	*** INTERACTIVE DATA VISUALIZATION (IDV) CONFIDENTIAL AND PROPRIETARY INFORMATION ***
//
//	This software is supplied under the terms of a license agreement or
//	nondisclosure agreement with Interactive Data Visualization, Inc. and
//  may not be copied, disclosed, or exploited except in accordance with 
//  the terms of that agreement.
//
//      Copyright (c) 2003-2010 IDV, Inc.
//      All rights reserved in all media.
//
//      IDV, Inc.
//      Web: http://www.idvinc.com


///////////////////////////////////////////////////////////////////////  
//  Common texture filters and sampler setup defines
//
//	A word on the coding standard used in the following macros:
//    - A macro is ALL CAPS if the macro was defined during compilation by the CPU or
//		if it is intended to be used as a pure text replacement
//	  - A macro is mixed-case if it is intended to look or function like a function call

#ifdef SPEEDTREE_DIRECTX10

	#define SPEEDTREE_FILTER \
			Filter = MIN_MAG_MIP_LINEAR; \
			AddressU = Wrap; \
			AddressV = Wrap;	
			
	#ifdef SPEEDTREE_MAX_ANISOTROPY
		#define SPEEDTREE_ANISOTROPY_FILTER \
			Filter = Anisotropic; \
			MaxAnisotropy = SPEEDTREE_MAX_ANISOTROPY;
	#else
		#define SPEEDTREE_ANISOTROPY_FILTER SPEEDTREE_FILTER
	#endif

	#define CreateTextureSampler(name, sam_reg, filter) \
			Texture2D g_t##name; \
			SamplerState sam##name { \
			filter }
		
	#define CreateTextureShadowSampler(name, sam_reg) \
			Texture2D g_t##name; \
			SamplerComparisonState sam##name { \
			Filter = COMPARISON_MIN_MAG_LINEAR_MIP_POINT; \
			AddressU  = Border; \
			AddressV  = Border; \
			BorderColor = float4(1, 1, 1, 1); \
			ComparisonFunc = LESS_EQUAL; }
		
	#define SampleTexture(name, texcoord) \
		g_t##name.Sample(sam##name, texcoord)
		
	#define SampleTextureLod(name, texcoord, lod) \
		g_t##name.SampleLevel(sam##name, texcoord, lod)
		
	// possibly SampleCmp ?
	#define SampleTextureCompare(texture, sampler, texcoord) \
		((texture).SampleCmpLevelZero((sampler), (texcoord).xy, (texcoord).z))

#else
	
	#ifdef SPEEDTREE_DIRECTX9
		
		#define SPEEDTREE_FILTER \
				MagFilter = Linear; \
				MinFilter = Linear; \
				MipFilter = Linear;	
				
		#ifdef SPEEDTREE_MAX_ANISOTROPY
			#define SPEEDTREE_ANISOTROPY_FILTER \
				MagFilter = Linear; \
				MinFilter = ANISOTROPIC; \
				MipFilter = Linear; \
				MaxAnisotropy = SPEEDTREE_MAX_ANISOTROPY;
		#else
			#define SPEEDTREE_ANISOTROPY_FILTER SPEEDTREE_FILTER
		#endif

		#define CreateTextureSampler(name, sam_reg, filter) \
			texture g_t##name; \
			sampler2D sam##name : register(sam_reg) = sampler_state { \
			Texture = <g_t##name>; \
			filter };
			
		#ifdef SPEEDTREE_XBOX_360
			#define CreateTextureShadowSampler(name, sam_reg) \
				texture g_t##name; \
				sampler2D sam##name : register(sam_reg) = sampler_state { \
				Texture = <g_t##name>; \
				BorderColor = 0xffffffff; \
				MinFilter = Point; \
				MagFilter = Point; \
				MipFilter = None; \
				AddressU  = Border; \
				AddressV  = Border; };
		#else
			#define CreateTextureShadowSampler(name, sam_reg) \
				texture g_t##name; \
				sampler2D sam##name : register(sam_reg) = sampler_state { \
				Texture = <g_t##name>; \
				BorderColor = 0xffffffff; \
				MinFilter = Linear; \
				MagFilter = Linear; \
				MipFilter = None; \
				AddressU  = Border; \
				AddressV  = Border; };
		#endif
		
	#else

		// OpenGL macros

		#define SPEEDTREE_FILTER 0
		#define SPEEDTREE_ANISOTROPY_FILTER 0
		
		#define CreateTextureSampler(name, sam_reg, filter) \
			texture g_t##name; \
			sampler2D sam##name : register(sam_reg) = sampler_state { \
			Texture = <g_t##name>; }
			
		#define CreateTextureShadowSampler(name, sam_reg) \
			texture g_t##name; \
			sampler2D sam##name : register(sam_reg) = sampler_state { \
			Texture = <g_t##name>; \
			BorderColor = 0xffffffff; \
			AddressU  = Border; \
			AddressV  = Border; }
			
	#endif
	
	#define SampleTexture(name, texcoord) \
		tex2D(sam##name, texcoord)
		
	#define SampleTextureLod(name, texcoord, lod) \
		tex2Dlod(sam##name, float4((texcoord).xy, 0.0, lod))
		
	#define SampleTextureCompare(texture, sampler, texcoord) \
		tex2Dproj((sampler), texcoord).r

#endif


///////////////////////////////////////////////////////////////////////  
//	Texture/material bank used for geometry types

CreateTextureSampler(Diffuse, s0, SPEEDTREE_ANISOTROPY_FILTER);
CreateTextureSampler(Normal, s1, SPEEDTREE_ANISOTROPY_FILTER);
CreateTextureSampler(Specular, s2, SPEEDTREE_ANISOTROPY_FILTER);
CreateTextureSampler(DetailDiffuse, s3, SPEEDTREE_ANISOTROPY_FILTER);
CreateTextureSampler(DetailNormal, s4, SPEEDTREE_ANISOTROPY_FILTER);


///////////////////////////////////////////////////////////////////////  
//	Textures shared by terrain & grass

CreateTextureSampler(TerrainNormalMap, s0, SPEEDTREE_ANISOTROPY_FILTER);
CreateTextureSampler(TerrainSplatMap, s1, SPEEDTREE_ANISOTROPY_FILTER);
CreateTextureSampler(TerrainSplatLayer0, s2, SPEEDTREE_ANISOTROPY_FILTER);
CreateTextureSampler(TerrainSplatLayer1, s3, SPEEDTREE_ANISOTROPY_FILTER);
CreateTextureSampler(TerrainSplatLayer2, s4, SPEEDTREE_ANISOTROPY_FILTER);

CreateTextureSampler(GrassBlades, s5, SPEEDTREE_FILTER);


///////////////////////////////////////////////////////////////////////  
//	Overlay texture

CreateTextureShadowSampler(Overlay, s10);


///////////////////////////////////////////////////////////////////////  
//	Shadow maps, used by most of the shaders

#ifdef SPEEDTREE_SHADOWS_ENABLED
	CreateTextureShadowSampler(ShadowMap0, s6);
	CreateTextureShadowSampler(ShadowMap1, s7);
	CreateTextureShadowSampler(ShadowMap2, s8);
	CreateTextureShadowSampler(ShadowMap3, s9);
#endif



