/*======================================================================*/
/* 3DLib								*/
/*									*/
/* 2D Textures header file						*/
/*									*/
/* AUTHOR:	Gabor Nagy						*/
/* DATE:	1996-Nov-14 23:53:43					*/
/*									*/
/* 3DLib(TM) Copyright (C) 1995 by Gabor Nagy. All rights reserved.	*/
/*======================================================================*/
#ifndef _E3DTexture_h
#define _E3DTexture_h

#include <Image/Image.h>

#ifndef _E3DGeometry_h
#include <E3D/Geometry.h>
#endif

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

#ifdef USEOpenGL
#define E3dGL2DTxtNONE	0
#endif	// USEOpenGL

/*----------------------------------------------------------------------*/
/* 2D texture								*/
/*----------------------------------------------------------------------*/
enum
{
 E3dTXT_STATIC,
 E3dTXT_SEQUENCE,
 E3dTXT_LIST
};


enum
{
 E3dTXT_FREEHAND=0,		// No mapping, STs were edited by hand, or computed by the creator of the object
 E3dTXT_XY,			// Linear
 E3dTXT_XZ,
 E3dTXT_YZ,
 E3dTXT_PERSPECTIVE,
 E3dTXT_UV,
 E3dTXT_CYLINDRICAL,
 E3dTXT_SPHERICAL,
 E3dTXT_ENVIRONMENT_MAP,	// Needs a fish-eye image...
 E3dTXT_AFTER_REFLECT,
 E3dTXT_WITHOUT_REFLECT
};


#define	E3dTXTF_PIXELINTERPOLATION	 1
#define	E3dTXTF_SWAP_ST			(1<<1)
#define	E3dTXTF_ALTERNATE_S		(1<<2)
#define	E3dTXTF_ALTERNATE_T		(1<<3)
#define	E3dTXTF_TRANSPARENCYBW		(1<<4)
#define	E3dTXTF_CROPPING		(1<<5)
#define	E3dTXTF_ALL			0x3F

#define E3dTXTB_ALPHA			 1
#define E3dTXTB_INTENSITY		 2
#define E3dTXTB_NO_MASK			 3

enum
{
 E3dGLTxtPropsFaceted=1,
 E3dGLTxtPropsInterpolated,
 E3dGLTxtPropsFacetedTiled,
 E3dGLTxtPropsInterpolatedTiled
};

enum
{
 E3dGLT_ENV_NONE=0,
 E3dGLT_ENV_1COMPONENT_BLEND,
 E3dGLT_ENV_1COMPONENT_MODLULATE,
 E3dGLT_ENV_3COMPONENT_DECAL,
 E3dGLT_ENV_3COMPONENT_MODULATE
};


typedef struct E3d2DTexture_S	E3d2DTexture;

typedef struct
{
 char*		Name;
 int		(*EditProc)(E3d2DTexture*);
 int		(*DestroyProc)(E3d2DTexture*);
 int		(*GetImageProc)(E3d2DTexture*, double, int, int, int, int);
 EResource*	Resources;	// Resource list
} E3d2DTextureShaderClass;


#define E3d2DTextureShaderCore()\
 E3d2DTextureShaderClass*	Class


typedef struct
{
 E3d2DTextureShaderCore();
} E3d2DTextureShader;



struct E3d2DTexture_S
{
 unsigned int		RefCnt;				// Reference count

 char*			Name;				// Texture name

 E3d2DTextureShader*	Shader;				// Shader that creates the image
 int			Animation;			// Tells how to get the current texture image

 char*			FileName;			// Texture file name with path
 short			Flags;				// Pixel interpolation, Swap ST, ST alternation, crop
 int			NumOfComponents;		// 1,2,3 or 4 (Intensity, Intensity+Alpha, RGB or RGBA)

#ifdef USEOpenGL
 GLuint			GLIndex;			// Index of texture for OpenGL
 EpImage*		GLImage;			// EpImage of the texture for OpenGL (if NULL, it's the same as Image)
 int			GLAlphaFunction;		// GL_ALWAYS means alpha-testing disabled
 float			GLAlphaReference;
#endif // USEOpenGL

 EpImage*		Image;				// EpImage of the texture
 unsigned int		XSize, YSize;			// Size of the whole picture

// Mapping
//
 int			MappingMethod;			// Mapping (projection) method

 E3d3DPosition		Translation;			// Translation of texture (UOffset, VOffset, 0.0)
 E3d3DPosition		Scaling;			// Scaling of texture (UScaling, VScaling, 1.0)
 E3dRotation		Rotation;			// Rotation of texture
 E3dCoordinate		SScaling, TScaling;		// Size of application zone in S and T
 E3dCoordinate		SOffset, TOffset;		// Offset of application zone in S and T
 int			SCropMin, SCropMax;		// Cropping info
 int			TCropMin, TCropMax;		// Cropping info
 int			SCount, TCount;			// Repetition of image in S and T

// Application of the Texture
//
 int			BlendingMask;			// What to blend with the Material
 float			BlendingFactor;			// Blending factor
 float			AmbientFactor;			// Blending factor on Ambient
 float			DiffuseFactor;			// Blending factor on Diffuse
 float			SpecularFactor;			// Blending factor on Specular
 float			ReflectivityFactor;		// Blending factor on Reflectivity
 float			TransparencyFactor;		// Blending factor on Transparency
 float			RoughnessFactor;		// Blending factor on Roughness
 float			ReflectionMapFactor;		// Blending factor on Reflectivity mapping

 E3d3DPosition		SchemPosition;			// Position on schematic view
};


typedef int	(*E3d2DTextureShaderEditProc)(E3d2DTexture*);
typedef int	(*E3d2DTextureShaderGetImageProc)(E3d2DTexture*, double, int, int, int, int);


enum
{
 E3dTXMAP_NONE=0,
 E3dTXMAP_POLYGROUP,
 E3dTXMAP_POLYGONS,	// Selected Polygons
 E3dTXMAP_GEOMETRY,
 E3dTXMAP_MODEL,
 E3dTXMAP_BRANCH,
 E3dTXMAP_TREE
};


// This gets attached to the actual Geometries (Mesh, Patch etc.) and SubGeometries (PolyGroup etc.)
//
typedef struct E3d2DTextureMapper
{
 E3d2DTexture*	T2DTexture;
 int		MapOn;				// Mapping target (PolyGroup, Mesh, Model, Branch etc)
 E3dGeometry*	Geometry;
 E3d3DPosition  ProjectorCenter;		// Center of texture projector model
 E3d3DPosition	CenterOffset;			// Position of the Mapper's center relative to the Model's
 E3dMatrix   	ProjectorMatrix;		// Transformation matrix of texture projector model
 E3dMatrix   	VertexToPixelMatrix;		// Matrix of vertex->pixel transformation for linear projections
} E3d2DTextureMapper;


/*----------------------------------------------------------------------*/




/*----------------------------------------------------------------------*/
/* 3D texture								*/
/*----------------------------------------------------------------------*/
typedef struct E3d3DTexture
{
 unsigned int		RefCnt;				// Reference count
 char*			Name;
 char*			FileName;
 char*			Prefix;
 E3d3DPosition		Translation;
 E3d3DPosition		Scaling;
 E3dRotation		Rotation;
 E3d3DPosition		SchemPosition;			// Position on schematic view
} E3d3DTexture;
/*----------------------------------------------------------------------*/

#define E3dTXTGEO_ALL	NULL


/*--------------------------------------------------------------*/
/* Global variables						*/
/*--------------------------------------------------------------*/
extern EpImage*	E3d_NotFound2DTextureImage;

/*--------------------------------------------------------------*/
/* Function prototypes						*/
/*--------------------------------------------------------------*/
extern void		E3d_Print2DTexture(E3d2DTexture* L2DTexture);

extern void		E3d_2DTextureDefault(E3d2DTexture* L2DTexture);
extern E3d2DTexture*	E3d_2DTextureAllocate(void);
extern void		E3d_2DTextureFree(E3d2DTexture* L2DTexture);

extern E3d2DTexture*	E3d_2DTextureClone(E3d2DTexture* L2DTexture, E3d2DTexture** L2DTextures, unsigned int LNumOf2DTextures);

extern void		E3d_2DTextureMapperDefault(E3d2DTextureMapper* L2DTextureMapper, E3d2DTexture* L2DTexture);
extern void		E3d_2DTextureMappersFree(E3d2DTextureMapper* L2DTextureMappers, unsigned int LNumOfTextureMappers);

extern E3d2DTextureShaderClass*	E3d_2DTextureShaderClassRegister(char* LName, int (*LEditProc)(E3d2DTexture*), int (*LDestroyProc)(E3d2DTexture*), int (*LGetImageProc)(E3d2DTexture*, double, int, int, int, int), EResource* LResources);
extern void			E3d_2DTextureShaderClassDeactivate(E3d2DTextureShaderClass* LClass);
extern void			E3d_2DTextureShaderClassRemove(E3d2DTextureShaderClass* LClass);



#ifdef USEOpenGL
extern void		E3dGL_2DTextureSetMapping(E3d2DTexture* L2DTexture);
extern void		E3d_2DTextureFreeGLImage(EpImage* LGLImage, GLuint LGLIndex);
#endif // USEOpenGL

extern void		E3d_3DTextureFree(E3d3DTexture* L3DTexture);


extern int		E3d_GeometryMap2DTexture(E3dGeometry* LGeometry, E3d2DTexture* L2DTexture);




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

#endif	// _E3DTexture_h
