/* -*- C++ -*- */

#ifndef _DRAW3D_H_
#define _DRAW3D_H_

/** tpye used for units measures and coordinates. */
typedef int MeasureUnit;

/** Stores a rgb-color (from 0 to 255). */
class Color
{
public:
	Color (const int _r, const int _g, const int _b) { r=_r; g=_g; b=_b; };
	Color (const Color& color) { *this=color; };
	Color() { Color (0, 0, 0); };

	int getR() const { return r; };
	int getG() const { return g; };
	int getB() const { return b; };

	Color& operator= (const Color& _newValue) { r=_newValue.r; g=_newValue.g; b=_newValue.b; return *this; };
	friend Color operator* (const Color& c, const float value) { Color c2 ((int) (c.r*value), (int) (c.g*value), (int) (c.b*value)); return c2; };

protected:
	int r,g,b;
};

/** Class used to store and manipulate 3D coordinates. */
class Position
{
public:
	Position (MeasureUnit _x, MeasureUnit _y, MeasureUnit _z) { x=_x; y=_y; z=_z; };
	Position (const Position& pos) { *this=pos; };
	Position() { Position (0, 0, 0); };

	Position& operator= (const Position& _newPos) { x=_newPos.x; y=_newPos.y; z=_newPos.z; return *this; };
	bool operator== (const Position& _compareTo) const { return x==_compareTo.x && y==_compareTo.y && z==_compareTo.z; };
	Position& operator+= (const Position& _add) { x+=_add.x; y+=_add.y; z+=_add.z; return *this; };
	Position& operator-= (const Position& _sub) { x-=_sub.x; y-=_sub.y; z-=_sub.z; return *this; };
	friend Position operator+ (const Position& _add1, const Position& _add2) { Position r (_add1); return r+=_add2; };
	friend Position operator- (const Position& _sub1, const Position& _sub2) { Position r (_sub1); return r-=_sub2; };

	MeasureUnit getX() const { return x; };
	MeasureUnit getY() const { return y; };
	MeasureUnit getZ() const { return z; };

protected:
	MeasureUnit x,y,z;
};


//**************************************************


/** Abstract class for drawing in 3D. Uses no GDI dependent functions,
 * so it must be derived for Windows/X11.
 * Drawing of rectangles is optimized.
 * Provides a secondary buffer for fast moving of sprites.
 */
class Draw3D
{
public:
	Draw3D();
	virtual ~Draw3D();

	/** Sets the foreground color for the following operations.
	 * Default is 255,255,255
	 */
	virtual void setForegroundColor (const Color& newColor) { currentColor=newColor; };

	/** Sets the background color for the following operations.
	 * Default is 0,0,0
	 */
	virtual void setBackgroundColor (const Color& newColor) { backgroundColor=newColor; };

	/** Draws a line between pos0 and pos1.
	 */
	void drawLine (const Position& pos0, const Position& pos1);

	/** Draws a polygon between pos[0],pos[1],..pos[n-1].
	 */
	void drawLineStrip (const Position pos[], const int n);

	/** Draws a polygon between pos[0],pos[1],..pos[n-1],pos[0].
	 */
	void drawPolygon (const Position pos[], const int n);

	/** Fills the rectangle between x0,y0 and y0, y1 with constant z.
	 */
	void drawRectangleZ (const Position& p0, const Position& p1);

	/** Fills the rectangle between y0,z0 and y0,z1 with constant x.
	 */
	void drawRectangleX (const Position& p0, const Position& p1);

	/** Fills the rectangle between x0,z0 and x0,z1 with constant y.
	 */
	void drawRectangleY (const Position& p0, const Position& p1);

	/** Saves all the image data since last clear in buffer. */
	virtual void saveInBuffer()=0;
	/** Restores the data saved in buffer by saveInBuffer. */
	virtual void restoreBuffer()=0;

	/** Drawing starts, prepare buffer and paint devices. */
	virtual void startDrawing()=0;
	
	/** Drawing ended. Must be called before updateDisplay. */
	virtual void endDrawing()=0;
	
	/** Clears the display with backgroundColor. */
	virtual void clear()=0;

	/** Updates the display with operations since last clear. */
	virtual void updateDisplay()=0;

	/** Sets the parameters for perspective projection.
	 * Initially -1,1,-1,1,1,0.5 . */
	void setPerspective (MeasureUnit _leftX, MeasureUnit _rightX,
			     MeasureUnit _lowerY, MeasureUnit _upperY,
			     MeasureUnit _nearZ,
			     double _perspectiveFactor) { leftX=_leftX; rightX=_rightX; lowerY=_lowerY; upperY=_upperY; nearZ=_nearZ; perspectiveFactor=_perspectiveFactor; };

	static void setGlobalInstance (Draw3D *instance) { globalInstance=instance; };

	static Draw3D* getGlobalInstance() { return globalInstance; };

protected:

	/** Points to an implemented Draw3D. */
	static Draw3D *globalInstance;

	/** Color used for following 3D operations. */
	Color currentColor;

	/** Background color. */
	Color backgroundColor;

	/** Does a projection of 3D coordinates to 2D coordinates. */
	virtual void projectTo2D (const Position *pos, int *x, int *y);

	/** Draws a line between x0,y0 and x1,y1 in current color. */
	virtual void drawLine2D (const int x0, const int y0,
				 const int x1, const int y1)=0;

	/** Draws a line between
	 * xValues2D[0],yValues2D[0]...xValues2D[size-1],yValues2D[size-1]
	 * in current color.
	 */
	virtual void drawLineStrip2D()=0;

	/** Draws a polygon and fills it with currentColor. First point 
	 * may be different from last point.
	 */
	virtual void drawFilledPolygon2D()=0;

	/** Used for effizient storing of 2D Coordiantes in path of
	 * drawXXX3D,drawLineStrip.
	 */
	struct
	{
		int maxValues;
		int size;
		int *xValues;
		int *yValues;
	} coordinatesBuffer;

	/** Checks if xValues2D and yValues2D can hold max n values,
	 * else resizes them.
	 */
	void maxAllocateBuffer (int n);

	/** Parameters for projection of 3D coordinates to 2D coordinates,
	 * with z=nearZ, perspective Projection. */
	MeasureUnit leftX, lowerY,
		rightX, upperY,
		nearZ;

	/** 0,0=lower left corner. */
	int width2D, height2D;

	float perspectiveFactor;
};

#endif _DRAW3D_H_

Documentation generated by skyhunter@Dagobah on Wed Sep 16 18:39:03 MEST 1998