218 lines
5.9 KiB
Plaintext
218 lines
5.9 KiB
Plaintext
/*
|
|
* This source file is part of the osgOcean library
|
|
*
|
|
* Copyright (C) 2009 Kim Bale
|
|
* Copyright (C) 2009 The University of Hull, UK
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it under
|
|
* the terms of the GNU Lesser General Public License as published by the Free Software
|
|
* Foundation; either version 3 of the License, or (at your option) any later
|
|
* version.
|
|
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
* http://www.gnu.org/copyleft/lesser.txt.
|
|
*/
|
|
|
|
#pragma once
|
|
#include <osgOcean/Export>
|
|
#include <osg/Geode>
|
|
#include <osg/Geometry>
|
|
#include <osg/BlendFunc>
|
|
#include <osg/Texture2D>
|
|
#include <osg/Version>
|
|
#include <osgDB/ReadFile>
|
|
#include <osgUtil/CullVisitor>
|
|
#include <string>
|
|
#include <osgOcean/WaterTrochoids>
|
|
|
|
namespace osgOcean
|
|
{
|
|
/**
|
|
* Creates and animates God Ray geometry.
|
|
*/
|
|
class OSGOCEAN_EXPORT GodRays : public osg::Geode
|
|
{
|
|
private:
|
|
bool _isDirty; /**< Rebuild flag. */
|
|
bool _isStateDirty; /**< Rebuild stateset flag. */
|
|
unsigned int _numOfRays; /**< Number of ray parallepipeds (_numOfRays*_numOfRays). */
|
|
WaterTrochoids _trochoids; /**< Generates and packs the trochoid variables required in the vertex shader. */
|
|
osg::Vec3f _sunDirection; /**< Direction of the sun. */
|
|
osg::Vec3f _extinction; /**< Extinction coeffecient (RGB) Controls the dispersion of light along the the length of the God Ray */
|
|
float _baseWaterHeight; /**< Height of the ocean surface */
|
|
|
|
osg::ref_ptr<osg::StateSet> _stateSet;
|
|
osg::ref_ptr<osg::FloatArray> _constants; /**< Stores the trochoid variables. */
|
|
|
|
public:
|
|
GodRays(void);
|
|
GodRays(unsigned int numOfRays, const osg::Vec3f& sunDir, float baseWaterHeight);
|
|
GodRays(const GodRays& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY );
|
|
|
|
virtual const char* libraryName() const { return "osgOcean"; }
|
|
virtual const char* className() const { return "GodRays"; }
|
|
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const GodRays*>(obj) != 0; }
|
|
|
|
protected:
|
|
~GodRays(void){};
|
|
|
|
public:
|
|
/**
|
|
* Create and add a grid of vertices for vertex shader displacement, and add the glare quad geometry.
|
|
*/
|
|
void build(void);
|
|
|
|
/**
|
|
* Creates God Rays stateset.
|
|
* Loads shaders and set uniforms.
|
|
* Sets up trochoid generation.
|
|
*/
|
|
void buildStateSet(void);
|
|
|
|
/**
|
|
* Sets the number rays along one axis of the grid.
|
|
* Dirties the geometry.
|
|
*/
|
|
inline void setNumOfRays( unsigned int num ){
|
|
_numOfRays = num;
|
|
_isDirty = true;
|
|
}
|
|
|
|
inline void setBaseWaterLevel(float height){
|
|
_baseWaterHeight = height;
|
|
}
|
|
|
|
/**
|
|
* Sets the sun direction.
|
|
* If stateset is valid it will also update the uniform.
|
|
*/
|
|
inline void setSunDirection(const osg::Vec3f& dir)
|
|
{
|
|
_sunDirection = dir;
|
|
|
|
if( _stateSet.valid() )
|
|
_stateSet->getUniform("uSunDir")->set(dir);
|
|
}
|
|
|
|
/**
|
|
* Set the extinction coefficient (RGB).
|
|
* If stateset is valid it will also update the uniform.
|
|
*/
|
|
inline void setExtinctionCoeff( const osg::Vec3f& coeff )
|
|
{
|
|
_extinction = coeff;
|
|
|
|
if( _stateSet.valid() )
|
|
_stateSet->getUniform("uExtinction_c")->set(coeff);
|
|
}
|
|
|
|
private:
|
|
/**
|
|
* Create the geometry and textures for the glare quad and attaches shaders.
|
|
*/
|
|
osg::Geometry* createGlareQuad(void);
|
|
|
|
/**
|
|
* Create the parallepiped geometry for the rays and attaches shaders.
|
|
*/
|
|
osg::Geometry* createRayShafts(void);
|
|
|
|
/**
|
|
* Updates shader uniforms and updates trochoids.
|
|
* Builds geometry/stateset if dirty flags are set.
|
|
*/
|
|
void update(float time, const osg::Vec3f& eye, const double& fov );
|
|
|
|
inline int idx( int c, int r, int rowLen )
|
|
{
|
|
return c+r*rowLen;
|
|
}
|
|
|
|
/**
|
|
* Loads and returns god ray shaders.
|
|
*/
|
|
osg::Program* createGodRayProgram(void);
|
|
|
|
/**
|
|
* Loads and returns god ray glare shaders.
|
|
*/
|
|
osg::Program* createGodRayGlareProgram(void);
|
|
|
|
/**
|
|
* Computes the refracted ray.
|
|
* @param I Incident ray.
|
|
* @param N Surface normal.
|
|
* ¶m ration Refractive index ratio (1/1.333 for water).
|
|
*/
|
|
osg::Vec3f refract( const float ratio, const osg::Vec3f& I, const osg::Vec3f& N );
|
|
|
|
// ---------------------------------------------
|
|
// Callback declarations
|
|
// ---------------------------------------------
|
|
|
|
protected:
|
|
/**
|
|
* Datatype for storing values from the cull visitor.
|
|
*/
|
|
class GodRayDataType: public osg::Referenced
|
|
{
|
|
private:
|
|
GodRays& _godRays;
|
|
osg::Vec3f _eye;
|
|
double _fov;
|
|
|
|
public:
|
|
GodRayDataType( GodRays& godRays );
|
|
|
|
GodRayDataType( const GodRayDataType& copy,
|
|
const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY );
|
|
|
|
inline void setEye( const osg::Vec3f& eye ){
|
|
_eye = eye;
|
|
}
|
|
|
|
inline void setFOV( const double& fov ){
|
|
_fov = fov;
|
|
}
|
|
|
|
inline const osg::Vec3f& getEye( void ) const{
|
|
return _eye;
|
|
}
|
|
|
|
void update( float time );
|
|
};
|
|
|
|
/**
|
|
* Update/Cull animation callback.
|
|
* Cull callback stores the eye position and the field of view.
|
|
* Update callback calls GodRays::update().
|
|
*/
|
|
class GodRayAnimationCallback: public osg::NodeCallback
|
|
{
|
|
public:
|
|
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
|
|
};
|
|
|
|
/**
|
|
* Custom compute bound callback.
|
|
* Needed as translations are done within the vertex shader.
|
|
* Moves the bounding box along with the eye's (x,y) position.
|
|
*/
|
|
class ComputeBoundsCallback: public osg::Drawable::ComputeBoundingBoxCallback
|
|
{
|
|
private:
|
|
GodRays& _rays;
|
|
public:
|
|
ComputeBoundsCallback( GodRays& rays );
|
|
|
|
#if OSG_VERSION_LESS_THAN(3,3,2)
|
|
virtual osg::BoundingBox computeBound(const osg::Drawable&) const;
|
|
#else
|
|
virtual osg::BoundingBox computeBoundingBox(const osg::Drawable&) const;
|
|
#endif
|
|
};
|
|
};
|
|
}
|