#ifndef INCLUDED_PIXELSHADER_H #define INCLUDED_PIXELSHADER_H #include "ps_Vector.h" class ps_Pixel { public: ps_Pixel(); ps_Pixel(unsigned char gray); ps_Pixel(unsigned char r, unsigned char g, unsigned char b); unsigned char getGray() const; unsigned char red; unsigned char green; unsigned char blue; }; class ps_PixelShaderInfo { public: ps_Pixel pixel; float pixelZ; float minZ; float maxZ; bool bUseColor; unsigned char intensity; }; class ps_PixelShader { public: // Construction ps_PixelShader(); // Modifiers void setAmbientLightLevel( float ambient ); void enableLighting( bool bEnable = true ); void enableWater( bool bEnable = true ); void setLightDirection( const ps_Vector& lightDir ); // lightDir is a vector pointing in // the direction the light is shining. // The light is assumed to be infinitely // far away. void setLightDirection( float altitude, float azimuth ); void setWaterAlpha( unsigned char waterAlpha ); void setWaterColor( const ps_Pixel& waterColor ); void setWaterLevel( float waterLevel ); // Accessors float getAmbientLightLevel() const; bool isLightingEnabled() const; bool isWaterEnabled() const; const ps_Vector& getLightDirection() const; void getLightDirection( float& altitude, float& azimuth ); unsigned char getWaterAlpha() const; const ps_Pixel& getWaterColor() const; float getWaterLevel() const; // Shading function - must be overwritten in subclasses virtual void shade(ps_PixelShaderInfo& info) const = 0; float getIntensity( const ps_Vector& normal ) const; protected: // Helper functions void addWater( ps_PixelShaderInfo& info ) const; // Data members float _ambientLightLevel; bool _bLightingEnabled; bool _bWaterEnabled; ps_Vector _lightDirection; unsigned char _waterAlpha; ps_Pixel _waterColor; float _waterLevel; }; inline void ps_PixelShader::setAmbientLightLevel( float ambient ) { _ambientLightLevel = ambient; // Make sure the value is between 0.0 and 1.0 if ( _ambientLightLevel < 0.0 ) { _ambientLightLevel = 0.0; } else if ( _ambientLightLevel > 1.0 ) { _ambientLightLevel = 1.0; } } inline void ps_PixelShader::enableLighting( bool bEnable ) { _bLightingEnabled = bEnable; } inline void ps_PixelShader::enableWater( bool bEnable ) { _bWaterEnabled = bEnable; } inline void ps_PixelShader::setLightDirection( const ps_Vector& lightDir ) { _lightDirection = lightDir * -1.0; _lightDirection.normalize(); } inline void ps_PixelShader::setWaterAlpha( unsigned char waterAlpha ) { _waterAlpha = waterAlpha; } inline void ps_PixelShader::setWaterColor( const ps_Pixel& waterColor ) { _waterColor = waterColor; } inline void ps_PixelShader::setWaterLevel( float waterLevel ) { _waterLevel = waterLevel; } inline float ps_PixelShader::getAmbientLightLevel() const { return _ambientLightLevel; } inline bool ps_PixelShader::isLightingEnabled() const { return _bLightingEnabled; } inline bool ps_PixelShader::isWaterEnabled() const { return _bWaterEnabled; } inline const ps_Vector& ps_PixelShader::getLightDirection() const { return _lightDirection; } inline unsigned char ps_PixelShader::getWaterAlpha() const { return _waterAlpha; } inline const ps_Pixel& ps_PixelShader::getWaterColor() const { return _waterColor; } inline float ps_PixelShader::getWaterLevel() const { return _waterLevel; } inline float ps_PixelShader::getIntensity( const ps_Vector& normal ) const { float inten = normal.dot( _lightDirection ) + _ambientLightLevel; if ( inten < 0.0 ) { inten = 0.0; } else if ( inten > 1.0 ) { inten = 1.0; } return ( inten ); } class ps_DaylightShader : public ps_PixelShader { public: // Constructor ps_DaylightShader(); // Overidden shade function void shade(ps_PixelShaderInfo& info) const; // Modifiers void setColor( const ps_Pixel& color); // Accessors const ps_Pixel& getColor() const; protected: ps_Pixel _color; }; inline void ps_DaylightShader::setColor( const ps_Pixel& color ) { _color = color; } inline const ps_Pixel& ps_DaylightShader::getColor() const { return _color; } class ps_GradientShader : public ps_PixelShader { public: ps_GradientShader(); void shade(ps_PixelShaderInfo& info) const; void setLowColor(ps_Pixel const& lowColor); void setHighColor(ps_Pixel const& highColor); const ps_Pixel& getLowColor() const; const ps_Pixel& getHighColor() const; protected: ps_Pixel _lowColor; ps_Pixel _highColor; }; inline void ps_GradientShader::setLowColor(ps_Pixel const& lowColor) { _lowColor = lowColor; } inline void ps_GradientShader::setHighColor(ps_Pixel const& highColor) { _highColor = highColor; } inline const ps_Pixel& ps_GradientShader::getLowColor() const { return _lowColor; } inline const ps_Pixel& ps_GradientShader::getHighColor() const { return _highColor; } class ps_HSVShader : public ps_PixelShader { public: ps_HSVShader(); void shade(ps_PixelShaderInfo& info) const; void setLowColorStart(double deg); // 0.0 <= deg <= 360.0. Controls where the color mapped to the // lowest elevation starts in HSV space. // Default: 0.0 void setSaturation(double sat); // 0.0 <= sat <= 1.0 // Default: 1.0 void setValue(double val); // 0.0 <= val <= 1.0 // Default: 1.0 void setRange(double range); // 1.0 < range; // Default: 360.0 double getLowColorStart() const; double getSaturation() const; double getValue() const; double getRange() const; protected: double _lowColorStart; double _saturation; double _value; double _range; }; inline void ps_HSVShader::setLowColorStart(double deg) { _lowColorStart = deg; } inline void ps_HSVShader::setSaturation(double sat) { _saturation = sat; } inline void ps_HSVShader::setValue(double val) { _value = val; } inline void ps_HSVShader::setRange(double range) { _range = range; } inline double ps_HSVShader::getLowColorStart() const { return _lowColorStart; } inline double ps_HSVShader::getSaturation() const { return _saturation; } inline double ps_HSVShader::getValue() const { return _value; } inline double ps_HSVShader::getRange() const { return _range; } class ps_ColorRampShader : public ps_PixelShader { public: ps_ColorRampShader(); void shade(ps_PixelShaderInfo& info) const; }; #endif // INCLUDED_PIXELSHADER_H