/*****************************************************************************
* Rendering algorithm definitions and data structures interface.	     *
******************************************************************************
* (C) Gershon Elber, Technion, Israel Institute of Technology                *
******************************************************************************
* Written by:  Bassarab Dmitri & Plavnik Michael       Ver 0.2, Apr. 1995    *
*****************************************************************************/

#ifndef _RENDERER_H_
#define _RENDERER_H_

#include <irit_sm.h>
#include <allocate.h>
#include <symb_lib.h>
#include <iritgrap.h>
#include <ip_cnvrt.h>
#include <config.h>

#define AMBIENT_DEFAULT 0.2          
#define COSINE_DEFAULT 64
#define TRANSP_DEFAULT 0
#define X 0
#define Y 1
#define Z 2
#define R 0
#define G 1
#define B 2
#define POINT_LIGHT	0
#define VECTOR_LIGHT	1
#define FLAT    	0
#define GOURAUD 	1
#define PHONG   	2
#define MAX_NOISE	10

/* Left/right coordinate system dependences.                                 */
#define NEAREST_Z	 IRIT_INFNTY
#define FURTHEST_Z	-IRIT_INFNTY
#define VIEWER_SIGHT	 1
#define NEAR_THAN	 >
#define FURTHER_THAN	 <

#define APX_ZERO(x)             (APX_EQ(0.0, (x)))
#define MALLOC(type, n)         (type*) IritMalloc(sizeof(type)*(n))
#define FREE(p)			IritFree(p)
#define MAXM(a, b)              { if ((a) < (b)) a = b; }
#define MINM(a, b)              { if ((a) > (b)) a = b; }
#define IN(value, lower, upper) ((lower) <= (value) && (value)<=(upper))
#define IS_VIEWER_POINT()       (IritPrsrWasPrspMat)
#define PLANE_EQ_EVAL(pl, pt)   (DOT_PROD((pl), (pt)) + (pl)[3])

#define TEXTURE_TYPE_NONE	0
#define TEXTURE_TYPE_PROC	1
#define TEXTURE_TYPE_RSTR	2
#define TEXTURE_TYPE_SRF	3
#define TEXTURE_TYPE_BUMP	8  /* Can be combined with any of the above. */

#define STEXTURE_FUNC_NONE	0
#define STEXTURE_FUNC_SQRT	1
#define STEXTURE_FUNC_ABS	2

/* Used to define image data. */
typedef struct PixelStruct {
    ByteType r, g, b;
} PixelStruct;

/* We use FRGB format for the color values: each component is in [0,1].      */
typedef PointType ColorType;

/* Light intensivity components via shading  models used.                    */
typedef struct IntensivityStruct {
    RealType diff, spec;
} IntensivityStruct;

/* Scan-line algorithm interpolation values.                                 */
/* Add any for which you want to interpolate.                                */
typedef struct InterpolStruct {
    RealType w, z;				/* Homogen and Z coordinate. */
    RealType u, v;		 /* Bivariative texture mapping coordinates. */
    NormalType n;              /* Normal at the current interpolation point. */
    IntensivityStruct *i;/* Array of intensivity values for every light src. */
} InterpolStruct;

/* Working structure describing polygon edge; some fields are used in scan   */
/* line converting and interpolation.                                        */
typedef struct EdgeStruct {
    int x;/* Current X coordinate on the scan line, the lowest end at start. */
    int dx, dy, inc; /* Scan line converting integer algorithm data members. */
    int yMin;                             /* The lowest endpoint coordinate. */
    InterpolStruct value; /* Starting and later current interpolation value. */
    InterpolStruct dValue;              /* Increment of interpolation value. */
} EdgeStruct;
typedef EdgeStruct const *EdgeCPtrType;

/* Texture image: its size and 2D array of pixels.                           */
typedef struct ImageStruct {
  int xSize, ySize;                  
  PixelStruct *data;                       
} ImageStruct;

struct TextureStruct;
typedef void (*TextureFuncType)(PointType,
				NormalType,
				ColorType,
				struct TextureStruct *);
typedef struct TextureStruct {
    int type;				       /* Procedural/Raster/Surface. */

    /* Raster image texture. */
    ImageStruct *image;	    /* Points to texture image if exists, NULL else. */
    RealType uMin, uMax, vMin, vMax;                   /* Parametric domain .*/

    /* Surface style texture. */
    CagdSrfStruct *srf;		 /* A surface to evaluate for texture value. */
    CagdPType srfParamDomain[2];		/* Parametric domain of srf. */
    ImageStruct *srfScale;	    /* To map the value of srf into a color. */
    RealType srfScaleMinMax[2];  /* Values to be mapped to srfScale extrema. */
    int srfFunc;     /* If surface value should be piped through a function. */

    /* Procedure/volumetric type texture. */
    TextureFuncType vTexture;
	/* Pointer to the volumetric texture function if existst, NULL else. */
    VectorType tScale;                          /* Volumetric texture scale. */
    PixelStruct Color;           /* Color used in some volumetric texturing. */
    RealType Width;              /* Width used in some volumetric texturing. */
} TextureStruct;

/* Configuration attributes common to all polygons in the Object.            */
/* We use it to store otherwise unefficient accessed attributes.             */
typedef struct ObjectStruct {
    int power;              /* Power of cosine factor of specular component. */
    ColorType color;                                 /* Color of the object. */
    TextureStruct text;
    RealType transp;			      /* Transparency of the object. */
    int noShade;                            /* Pure color model (polylines). */
} ObjectStruct;

/* Flat, which is a polygon abstraction.				     */
typedef struct FlatStruct {
    struct FlatStruct *prev, *next;    		/* Double linked list links. */
    EdgeStruct *edge;	      /* Array of edges representing Flat's polygon. */
    int nEdges;			             /* Number of edges in the flat. */
    int yMin, yMax;		      /* Scan line range flat is located in. */
    IPPolygonStruct *poly;         /* Pointer to the compliant Irit polygon. */
    ObjectStruct *object;/* Pointer to the object that flat is contained in. */
    struct SeparateInfoStruct *info;
                /* Points to the shadows algorithm configuration attributes. */
    struct ShadowEdgePoolStruct *vPool;
     /* Array of data structures containing shadows representations of the   */
                                           /* flat (entry per light source). */
} FlatStruct;

/* Data structure describing light source.				     */
typedef struct LightStruct {
    struct LightDescriptorStruct *descriptor;           /* Light descriptor. */
    int type;                                          /* Light source type. */
    PointType where;                     /* Light source position or vector. */
    int shadow;                  /* True if that light source casts shadows. */
    ColorType color;                               /* Color of the light source. */
} LightStruct;

/* Some defenitions of the Light source descriptor (runtime binding).        */
typedef void (*SeparationInitProcType)(FlatStruct* f, LightStruct* l);
typedef int  (*TestSeparationProcType)(FlatStruct* p, FlatStruct* f);     
typedef void (*ProjectPolygonProcType)(FlatStruct* p, FlatStruct* f,
				       RealType r, VectorType v);

/* To implement run time polymorphism dependent on light source type we set  */
/* up descriptor object for each type of the light source.                   */
typedef struct LightDescriptorStruct {
                                          /* Shadows determination specific. */
    SeparationInitProcType SeparationInit;/* Flats separation initialization.*/
    TestSeparationProcType IsSeparated;         /* Flats separation checker. */
    ProjectPolygonProcType ProjectPoly;            /* Flat shadow projector. */
} LightDescriptorStruct;  

/* We use array of Light source objects.                                     */
typedef struct LightListStruct {
    int n;             				 /* Number of light sources. */
    LightStruct *src;     		   /* Array of light source objects. */
} LightListStruct;

/* We make use of Texture name to Texture functions mapping table.           */
/* That data structure describes a single entry.                             */
typedef struct ProcTextureStruct {
    char *name;		     /* Procedural volumetric texture symbolic name. */
    TextureFuncType vTexture;
} ProcTextureStruct;

/* Every scan line is represented in z-buffer by array of z-slots, mainly    */
/* formed by the linked list of z-points set up by different flats           */
/* projection.                                                               */
typedef struct ZPointStruct {
    struct ZPointStruct *next; /* Link to the next z-point at same location. */
    InterpolStruct value;          /* Interpolation values at that location. */
    FlatStruct *flat;  /* Points to a flat which is projected on that point. */
} ZPointStruct;

typedef struct ZSlotStruct {
    ZPointStruct bg;/* Head of the linked list, contains the nearest z-point.*/
    ZPointStruct *opaque;   /* Pointer to the nearest untransparent polygon. */
    ZPointStruct *tail;                          /* Tail of the linked list. */
    ColorType color;  /* Resulting color of z-slot, determined by all z-pts. */
} ZSlotStruct;

/* We store information about intersection of the current scan-line with     */
/* edges of the polygons in the array of following data structures.          */
typedef struct CrossStruct {
    int x;           			/* X coordinate of the intersection. */
    InterpolStruct value; 	      /* Interpolation values at that point. */
} CrossStruct;

/* GLOBAL configuration variables.                                           */
typedef struct GlobalOptionsStruct {
    int       XSize, YSize;	                 /* Size of the final image. */
    RealType  Ambient;          /* Ambient color fraction in the final color.*/
    ColorType BackGround;                   /* Background of the image color.*/
    int       BackFace;        /* Flag directing to remove back faced flats. */
    int       Srf2PlgOptimal;  /* Optimal argument of IritSurfaces2Polygons. */
    RealType  Srf2PlgFineness;/* Fineness of surface to polygons tesselation.*/
    SymbCrvApproxMethodType Crv2PllMethod;   /* Arg of IritCurves2Polylines. */
    int       Crv2PllSamples;     /* Number of samples to approximate curve. */
    int       ShadeModel;                 /* Type of shading model to apply. */
    int       Polylines; /* Flag directing to convert polylines to polygons. */
    RealType  PllMinW; 	            		 /* Polylines minimal width. */
    RealType  PllMaxW;			         /* Polylines maximal width. */
    int       Shadows;     /* Flag directing to apply shadows determination. */
    int       Transp;         /* Flag directing to apply transperancy model. */
    int       HasTime;             /* If TRUE, we compute animation at Time. */
    RealType  Time;            /* If HasTime, Time is set to animation time. */
    char     *FilterName;          /* Name of the antialias filter, or NULL. */
    int       ZDepth;    /* Flag directing to output image in zdepth format. */
    int       NormalReverse;       /* Flag directing to reverse every vertex */
                                     /* and plane normals before processing. */
    int       NFiles;         /* Number of file names passed to the program. */
    char    **Files;                 /* Array of pointers to the file names. */
    int       Verbose;                    /* Print some diagnostic messages. */
} GlobalOptionsStruct;


/* GLOBAL data structures.                                                   */

/* Virtual tables for point and infinite point light source types.           */
/* We use dynamic dispatch to make use of similarity of interfaces.          */
/* To simplify a matter we do not use static initialization but rely         */
/* on subsystem initialization routines to setup proper entries in tables.   */
typedef struct GlobalContextStruct {
    int        MaxEdges;               /* Maximal number of edges in a flat. */
    MatrixType ViewMat;     /* Comulative matrix of viewing transformations. */
    MatrixType InvMat;                           /* Inverse of "all" matrix. */
    PointType  Viewer;                      /* Viewer position or direction. */
    LightListStruct  Lights;                      /* Array of light sources. */
    LightDescriptorStruct PointLightDescriptor;
                                      /* Point type light source descriptor. */
    LightDescriptorStruct VectorLightDescriptor;           /* Vector --"--.  */
} GlobalContextStruct;

extern GlobalOptionsStruct Options;
extern GlobalContextStruct Context;
/* Mapping of predefined color constants to colors. */
extern ColorType Colors[];
/* Mapping of predefined textures names to functions. */
extern ProcTextureStruct ProcTextures[];

void GetOptions(int argc, char *argv[]);
void GetConfig(char *argv[]);
void PrintOptions(void);
void SetupAntialias(void);
IPObjectStruct *ParseFiles(int argc, char *argv[]);
IPObjectStruct *Map(IPObjectStruct *Objects);
void Polyline2Polygons(IPObjectStruct *Object);
IPObjectStruct *GatherLights(LightListStruct *Lights, IPObjectStruct* Objects);
FlatStruct *GatherFlats(IPObjectStruct *o);
FlatStruct *BucketSortFlats(FlatStruct *Flats);
void LightIntensivity(const PointType p,
		      const NormalType n,
		      LightStruct *l,
		      const ObjectStruct *o,
		      IntensivityStruct *i);
void ColorEval(int x, int y, ZPointStruct *z, ColorType r);
void AntialiasLine(ZSlotStruct *z);
InterpolStruct *InterpolCopy(InterpolStruct *Dst, InterpolStruct *Src);
InterpolStruct *InterpolDelta(InterpolStruct *Dst,
			      InterpolStruct *v1,
			      InterpolStruct *v2,
			      RealType d);
InterpolStruct *InterpolIncr(InterpolStruct *Dst, InterpolStruct *d);
PixelStruct *ImageGetPixel(ImageStruct *i, RealType v, RealType u);
void MarbleTexture(PointType Point,
		   NormalType Normal,
		   ColorType Color,
		   TextureStruct *Text);
void WoodTexture(PointType Point,
		 NormalType Normal,
		 ColorType Color,
		 TextureStruct *Text);
void ContourTexture(PointType Point,
		    NormalType Normal,
		    ColorType Color,
		    TextureStruct *Text);
void ContourNormalTexture(PointType Point,
			  NormalType Normal,
			  ColorType Color,
			  TextureStruct *Text);
void PolyEdgeIncr(EdgeStruct *PEdge);
void Shader(FlatStruct *Slot);

/* Image data files' manipulation routines. */
void ImageSetImageType(char *Image);
ImageStruct *ImageLoadImage(char *File);
void ImageOpenFile(char **argv, int XSize, int YSize);
void ImagePutLine(ByteType *Alpha, PixelStruct *);
void ImageCloseFile(void);
/* RLE image format support. */
ImageStruct *RLELoadImage(char *File);
void RLEOpenFile(char **argv, int XSize, int YSize);
void RLEPutLine(ByteType *Alpha, PixelStruct *);
void RLECloseFile(void);
/* PPM image format support. */
ImageStruct *PPMLoadImage(char *File);
void PPMOpenFile(char **argv, int XSize, int YSize);
void PPMPutLine(ByteType *Alpha, PixelStruct *);
void PPMCloseFile(void);

#endif
