DYT/Tool/osgOcean/include/osgOcean/GodRays
2024-11-22 23:19:31 +08:00

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.
* &param 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
};
};
}