replace oc to oe from code

This commit is contained in:
jiegeaiai 2024-12-25 07:55:37 +08:00
parent 5555a9fb4c
commit 437a1c5a31
90 changed files with 27 additions and 5566 deletions

View File

@ -89,7 +89,6 @@ INCLUDE_DIRECTORIES(
${Thirdparty}/breakpad/include ${Thirdparty}/breakpad/include
${Thirdparty}/3rdParty_x64/include ${Thirdparty}/3rdParty_x64/include
${Thirdparty}/OpenSceneGraph-3.6.5/include ${Thirdparty}/OpenSceneGraph-3.6.5/include
${Thirdparty}/osgOcean/include
${Thirdparty}/matlab/include ${Thirdparty}/matlab/include
# ${Thirdparty}/Python39/include # ${Thirdparty}/Python39/include
) )
@ -98,7 +97,6 @@ INCLUDE_DIRECTORIES(
${Thirdparty}/spdlog/lib ${Thirdparty}/spdlog/lib
${Thirdparty}/3rdParty_x64/lib ${Thirdparty}/3rdParty_x64/lib
${Thirdparty}/OpenSceneGraph-3.6.5/lib ${Thirdparty}/OpenSceneGraph-3.6.5/lib
${Thirdparty}/osgOcean/lib
${Thirdparty}/matlab/lib/win64/microsoft ${Thirdparty}/matlab/lib/win64/microsoft
# ${Thirdparty}/Python39/libs # ${Thirdparty}/Python39/libs
) )
@ -164,9 +162,10 @@ target_link_libraries(
osgUtil osgUtil
osgViewer osgViewer
osgShadow osgShadow
osgOcean
osgParticle osgParticle
osgSim osgSim
osgEarth
#Triton-MT-DLL
libMatlabDataArray libMatlabDataArray
libMatlabEngine libMatlabEngine
# python39 # python39

View File

@ -130,7 +130,7 @@ void SceneComponent::AttachScene(Entity* entity) {
return; return;
} }
OsgScene* scene = workspace->GetActiveScene(); /* OsgScene* scene = workspace->GetActiveScene();
if (nullptr == scene) { if (nullptr == scene) {
LOG_WARN("scene is nullptr"); LOG_WARN("scene is nullptr");
return; return;
@ -138,7 +138,7 @@ void SceneComponent::AttachScene(Entity* entity) {
UpdateLocationAndRotation(); UpdateLocationAndRotation();
scene->AddToOceanScene(mt_); scene->AddToOceanScene(mt_);*/
} }
void SceneComponent::AttachParent(Entity* entity) { void SceneComponent::AttachParent(Entity* entity) {

View File

@ -1,5 +1,5 @@
#include "scene/OsgScene.h" #include "scene/OsgScene.h"
#if 0
#include <osg/Shape> #include <osg/Shape>
#include <osg/ShapeDrawable> #include <osg/ShapeDrawable>
@ -599,3 +599,4 @@ void OsgScene::TestBuildModel() {
SetNodeMatrixPostion(lsjhqt, osg::Vec3f(0.0f, 0.0f, 0.0f), GetOceanScene()); SetNodeMatrixPostion(lsjhqt, osg::Vec3f(0.0f, 0.0f, 0.0f), GetOceanScene());
}*/ }*/
} }
#endif

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#if 0
#include <osg/Switch> #include <osg/Switch>
#include <osg/TextureCubeMap> #include <osg/TextureCubeMap>
@ -133,3 +134,4 @@ private:
osg::ref_ptr<osg::Switch> islandSwitch_; osg::ref_ptr<osg::Switch> islandSwitch_;
}; };
#endif

View File

@ -1,6 +1,6 @@
#include "scene/SkyDome.h" #include "scene/SkyDome.h"
#include <osgOcean/ShaderManager> //#include <osgOcean/ShaderManager>
SkyDome::SkyDome(void) { SkyDome::SkyDome(void) {
@ -38,7 +38,7 @@ osg::ref_ptr<osg::Program> SkyDome::createShader(void) {
osg::ref_ptr<osg::Program> program = new osg::Program; osg::ref_ptr<osg::Program> program = new osg::Program;
// Do not use shaders if they were globally disabled. // Do not use shaders if they were globally disabled.
if (osgOcean::ShaderManager::instance().areShadersEnabled()) { /* if (osgOcean::ShaderManager::instance().areShadersEnabled()) {
char vertexSource[] = char vertexSource[] =
"varying vec3 vTexCoord;\n" "varying vec3 vTexCoord;\n"
"\n" "\n"
@ -63,7 +63,7 @@ osg::ref_ptr<osg::Program> SkyDome::createShader(void) {
program->setName("sky_dome_shader"); program->setName("sky_dome_shader");
program->addShader(new osg::Shader(osg::Shader::VERTEX, vertexSource)); program->addShader(new osg::Shader(osg::Shader::VERTEX, vertexSource));
program->addShader(new osg::Shader(osg::Shader::FRAGMENT, fragmentSource)); program->addShader(new osg::Shader(osg::Shader::FRAGMENT, fragmentSource));
} }*/
return program; return program;
} }

View File

@ -32,11 +32,11 @@ WorkSpace::WorkSpace(const QString& name, QObject* parent)
} }
void WorkSpace::ViewReize(int width, int height) { void WorkSpace::ViewReize(int width, int height) {
if (nullptr != activeScene_ && nullptr != activeScene_->GetOceanScene()) { /* if (nullptr != activeScene_ && nullptr != activeScene_->GetOceanScene()) {
activeScene_->GetOceanScene()->setScreenDims(osg::Vec2s(width * 2, height * 2)); activeScene_->GetOceanScene()->setScreenDims(osg::Vec2s(width * 2, height * 2));
} else { } else {
LOG_WARN("secen_:{} or ocean is nullptr", spdlog::fmt_lib::ptr(activeScene_.get())); LOG_WARN("secen_:{} or ocean is nullptr", spdlog::fmt_lib::ptr(activeScene_.get()));
} }*/
} }
bool WorkSpace::CreateScene(const std::string& scene) { bool WorkSpace::CreateScene(const std::string& scene) {
@ -45,18 +45,18 @@ bool WorkSpace::CreateScene(const std::string& scene) {
return false; return false;
} }
if (nullptr != activeScene_) { /*if (nullptr != activeScene_) {
activeScene_->DetachView(view_); activeScene_->DetachView(view_);
} }*/
name_ = name_.fromStdString(scene); /* name_ = name_.fromStdString(scene);
activeScene_ = new OsgScene; activeScene_ = new OsgScene;
activeScene_->UseShadows(false); activeScene_->UseShadows(false);
activeScene_->ChangeScene(OsgScene::CLOUDY); activeScene_->ChangeScene(OsgScene::CLOUDY);
activeScene_->AttachView(view_); activeScene_->AttachView(view_);
activeScene_->InitEventHandle(view_); activeScene_->InitEventHandle(view_);*/
return true; return true;
} }
@ -81,13 +81,13 @@ void WorkSpace::RemoveEntity(Entity* entity) {
} }
} }
OsgScene* WorkSpace::GetActiveScene() const { //OsgScene* WorkSpace::GetActiveScene() const {
if (!activeScene_.valid()) { // if (!activeScene_.valid()) {
return nullptr; // return nullptr;
} // }
//
return activeScene_.get(); // return activeScene_.get();
} //}
bool WorkSpace::SetTimestep(Timestep* timestep) { bool WorkSpace::SetTimestep(Timestep* timestep) {
if (!timestep) { if (!timestep) {

View File

@ -45,7 +45,7 @@ public:
void ViewReize(int width, int height); void ViewReize(int width, int height);
bool CreateScene(const std::string& scene); bool CreateScene(const std::string& scene);
OsgScene* GetActiveScene() const; //OsgScene* GetActiveScene() const;
bool SetTimestep(class Timestep* timestep); bool SetTimestep(class Timestep* timestep);
bool SetTimestepPath(const QString& path); bool SetTimestepPath(const QString& path);
@ -84,7 +84,7 @@ private:
QString path_; QString path_;
std::vector<class Entity*> entities_; std::vector<class Entity*> entities_;
osg::ref_ptr<OsgScene> activeScene_; //osg::ref_ptr<OsgScene> activeScene_;
class OsgView* view_{ nullptr }; class OsgView* view_{ nullptr };
class Timestep* timestep_{ nullptr }; class Timestep* timestep_{ nullptr };
class LampStatus* lampStatus_{ nullptr }; class LampStatus* lampStatus_{ nullptr };

Binary file not shown.

Binary file not shown.

View File

@ -1,83 +0,0 @@
#extension GL_ARB_texture_rectangle : enable
uniform sampler2DRect osgOcean_FullColourMap; // full resolution image
uniform sampler2DRect osgOcean_FullDepthMap; // full resolution depth map
uniform sampler2DRect osgOcean_BlurMap; // downsampled and filtered image
uniform vec2 osgOcean_ScreenRes;
uniform vec2 osgOcean_ScreenResInv;
uniform vec2 osgOcean_LowRes;
#define NUM_TAPS 4
// maximum CoC radius and diameter in pixels
const vec2 vMaxCoC = vec2(5.0,10);
// scale factor for maximum CoC size on low res. image
const float radiusScale = 0.4;
// contains poisson-distributed positions on the unit circle
vec2 poisson[8];
void main(void)
{
poisson[0] = vec2( 0.0, 0.0);
poisson[1] = vec2( 0.527837, -0.085868);
poisson[2] = vec2(-0.040088, 0.536087);
poisson[3] = vec2(-0.670445, -0.179949);
poisson[4] = vec2(-0.419418, -0.616039);
poisson[5] = vec2( 0.440453, -0.639399);
poisson[6] = vec2(-0.757088, 0.349334);
poisson[7] = vec2( 0.574619, 0.685879);
// pixel size (1/image resolution) of full resolution image
vec2 pixelSizeHigh = osgOcean_ScreenResInv;
// pixel size of low resolution image
vec2 pixelSizeLow = 4.0 * pixelSizeHigh;
vec4 color = texture2DRect( osgOcean_FullColourMap, gl_TexCoord[0].st ); // fetch center tap
// float centerDepth = color.a; // save its depth
float centerDepth = texture2DRect( osgOcean_FullDepthMap, gl_TexCoord[0].st ).r; // save its depth
// convert depth into blur radius in pixels
float discRadius = abs(centerDepth * vMaxCoC.y - vMaxCoC.x);
// compute disc radius on low-res image
float discRadiusLow = discRadius * radiusScale;
vec4 colorAccum = vec4(0.0);
float depthAccum = 0.0;
for(int t = 0; t < NUM_TAPS; t++)
{
vec2 coordHigh = gl_TexCoord[0].st + ( osgOcean_ScreenRes * (pixelSizeHigh * poisson[t] * discRadius ));
vec2 coordLow = gl_TexCoord[1].st + ( osgOcean_LowRes * (pixelSizeLow * poisson[t] * discRadiusLow ));
// fetch low-res tap
vec4 tapLow = texture2DRect( osgOcean_BlurMap, coordLow );
// fetch high-res tap
vec4 tapHigh = texture2DRect( osgOcean_FullColourMap, coordHigh );
float tapHighDepth = texture2DRect( osgOcean_FullDepthMap, coordHigh ).r;
// put tap blurriness into [0, 1] range
float tapBlur = abs(tapHighDepth * 2.0 - 1.0);
// mix low- and hi-res taps based on tap blurriness
vec4 tapColor = mix(tapHigh, tapLow, tapBlur);
// apply leaking reduction: lower weight for taps that are
// closer than the center tap and in focus
float tapDepth = (tapHighDepth >= centerDepth) ? 1.0 : abs(tapHighDepth * 2.0 - 1.0);
// accumulate
colorAccum += tapColor * tapDepth;
depthAccum += tapDepth;
}
// normalize and return result
gl_FragColor = colorAccum / depthAccum;
}

View File

@ -1,11 +0,0 @@
uniform vec2 osgOcean_ScreenRes;
uniform vec2 osgOcean_LowRes;
void main( void )
{
gl_TexCoord[0] = gl_MultiTexCoord0 * vec4( osgOcean_ScreenRes, 1.0, 1.0 );
gl_TexCoord[1] = gl_MultiTexCoord0 * vec4( osgOcean_LowRes, 1.0, 1.0 );
gl_Position = ftransform();
}

View File

@ -1,27 +0,0 @@
#extension GL_ARB_texture_rectangle : enable
uniform sampler2DRect osgOcean_ColorTexture;
const vec2 s1 = vec2(-1, 1);
const vec2 s2 = vec2( 1, 1);
const vec2 s3 = vec2( 1,-1);
const vec2 s4 = vec2(-1,-1);
void main( void )
{
vec2 texCoordSample = vec2(0.0);
texCoordSample = gl_TexCoord[0].st + s1;
vec4 color = texture2DRect(osgOcean_ColorTexture, texCoordSample);
texCoordSample = gl_TexCoord[0].st + s2;
color += texture2DRect(osgOcean_ColorTexture, texCoordSample);
texCoordSample = gl_TexCoord[0].st + s3;
color += texture2DRect(osgOcean_ColorTexture, texCoordSample);
texCoordSample = gl_TexCoord[0].st + s4;
color += texture2DRect(osgOcean_ColorTexture, texCoordSample);
gl_FragColor = color * 0.25;
}

View File

@ -1,5 +0,0 @@
void main( void )
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}

View File

@ -1,41 +0,0 @@
#extension GL_ARB_texture_rectangle : enable
uniform sampler2DRect osgOcean_ColorTexture;
uniform sampler2DRect osgOcean_LuminanceTexture;
uniform float osgOcean_GlareThreshold;
const vec2 s1 = vec2(-1, 1);
const vec2 s2 = vec2( 1, 1);
const vec2 s3 = vec2( 1,-1);
const vec2 s4 = vec2(-1,-1);
void main( void )
{
vec2 texCoordSample = vec2(0.0);
texCoordSample = gl_TexCoord[0].st + s1;
vec4 color = texture2DRect(osgOcean_ColorTexture, texCoordSample);
float lum = texture2DRect(osgOcean_LuminanceTexture, texCoordSample).r;
texCoordSample = gl_TexCoord[0].st + s2;
color += texture2DRect(osgOcean_ColorTexture, texCoordSample);
lum += texture2DRect(osgOcean_LuminanceTexture, texCoordSample).r;
texCoordSample = gl_TexCoord[0].st + s3;
color += texture2DRect(osgOcean_ColorTexture, texCoordSample);
lum += texture2DRect(osgOcean_LuminanceTexture, texCoordSample).r;
texCoordSample = gl_TexCoord[0].st +s4;
color += texture2DRect(osgOcean_ColorTexture, texCoordSample);
lum += texture2DRect(osgOcean_LuminanceTexture, texCoordSample).r;
color = color*0.25;
lum = lum*0.25;
// only want very high luminance values to pass otherwise
// we get streaks all over the scene
if(lum >= osgOcean_GlareThreshold)
gl_FragColor = color;
else
gl_FragColor = vec4(0.0);
}

View File

@ -1,5 +0,0 @@
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}

View File

@ -1,19 +0,0 @@
#extension GL_ARB_texture_rectangle : enable
uniform sampler2DRect osgOcean_GaussianTexture;
void main( void )
{
vec2 texCoordSample = vec2( 0.0 );
vec4 color = 0.5 * texture2DRect( osgOcean_GaussianTexture, gl_TexCoord[0].st );
texCoordSample.x = gl_TexCoord[0].x;
texCoordSample.y = gl_TexCoord[0].y + 1.0;
color += 0.25 * texture2DRect( osgOcean_GaussianTexture, texCoordSample);
texCoordSample.y = gl_TexCoord[0].y - 1.0;
color += 0.25 * texture2DRect( osgOcean_GaussianTexture, texCoordSample);
gl_FragColor = color;
}

View File

@ -1,19 +0,0 @@
#extension GL_ARB_texture_rectangle : enable
uniform sampler2DRect osgOcean_GaussianTexture;
void main( void )
{
vec2 texCoordSample = vec2( 0.0 );
vec4 color = 0.5 * texture2DRect(osgOcean_GaussianTexture, gl_TexCoord[0].st );
texCoordSample.y = gl_TexCoord[0].y;
texCoordSample.x = gl_TexCoord[0].x + 1.0;
color += 0.25 * texture2DRect(osgOcean_GaussianTexture, texCoordSample);
texCoordSample.x = gl_TexCoord[0].x - 1.0;
color += 0.25 * texture2DRect(osgOcean_GaussianTexture, texCoordSample);
gl_FragColor = color;
}

View File

@ -1,20 +0,0 @@
#extension GL_ARB_texture_rectangle : enable
uniform sampler2DRect osgOcean_ColorBuffer;
uniform sampler2DRect osgOcean_StreakBuffer1;
uniform sampler2DRect osgOcean_StreakBuffer2;
uniform sampler2DRect osgOcean_StreakBuffer3;
uniform sampler2DRect osgOcean_StreakBuffer4;
void main(void)
{
vec4 fullColor = texture2DRect(osgOcean_ColorBuffer, gl_TexCoord[0].st );
vec4 streakColor1 = texture2DRect(osgOcean_StreakBuffer1, gl_TexCoord[1].st );
vec4 streakColor2 = texture2DRect(osgOcean_StreakBuffer2, gl_TexCoord[1].st );
vec4 streakColor3 = texture2DRect(osgOcean_StreakBuffer3, gl_TexCoord[1].st );
vec4 streakColor4 = texture2DRect(osgOcean_StreakBuffer4, gl_TexCoord[1].st );
vec4 streak = streakColor1+streakColor2+streakColor3+streakColor4;
gl_FragColor = streak+fullColor;
}

View File

@ -1,7 +0,0 @@
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[1] = gl_MultiTexCoord0 * vec4(0.25,0.25,1.0,1.0);
gl_Position = ftransform();
}

View File

@ -1,10 +0,0 @@
uniform sampler2D osgOcean_GlareTexture;
varying vec3 vIntensity;
void main(void)
{
vec3 color = texture2D( osgOcean_GlareTexture, gl_TexCoord[0].st ).rgb;
gl_FragColor = vec4((vIntensity*color.r)*1.5, 1.0 );
}

View File

@ -1,22 +0,0 @@
uniform vec3 osgOcean_Origin;
uniform vec3 osgOcean_Extinction_c;
uniform vec3 osgOcean_Eye;
uniform float osgOcean_Spacing;
varying vec3 vIntensity;
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
vec3 worldPos = gl_Vertex.xyz * vec3(osgOcean_Spacing,osgOcean_Spacing,1.0);
worldPos += osgOcean_Origin;
vec3 extinct = vec3(0.2,0.2,0.2);
float totalDist = length(worldPos-osgOcean_Eye)/3.0;
vIntensity = exp(-totalDist*osgOcean_Extinction_c);
vIntensity = clamp(vIntensity, 0.0, 1.0);
gl_Position = gl_ModelViewProjectionMatrix * vec4(worldPos,1.0);
}

View File

@ -1,55 +0,0 @@
uniform sampler2DRect osgOcean_GodRayTexture;
uniform vec3 osgOcean_SunDir;
uniform vec3 osgOcean_HGg; // Eccentricity constants controls power of forward scattering
uniform float osgOcean_Intensity; // Intensity tweak for god rays
uniform vec3 osgOcean_Eye;
varying vec3 vRay;
const float bias = 0.15; // used to hide aliasing
// Mie phase function
float computeMie(vec3 viewDir, vec3 sunDir)
{
float num = osgOcean_HGg.x;
float den = (osgOcean_HGg.y - osgOcean_HGg.z*dot(sunDir, viewDir));
den = inversesqrt(den);
float phase = num * (den*den*den);
return phase;
}
// ----------------------------------------------
// Main Program
// ----------------------------------------------
void main( void )
{
vec4 shafts;
// average the pixels out a little to hide aliasing
// TODO: Maybe try a weak blur filter
shafts += texture2DRect(osgOcean_GodRayTexture, gl_TexCoord[1].xy);
shafts += texture2DRect(osgOcean_GodRayTexture, gl_TexCoord[1].zw);
shafts += texture2DRect(osgOcean_GodRayTexture, gl_TexCoord[2].xy);
shafts += texture2DRect(osgOcean_GodRayTexture, gl_TexCoord[2].zw);
shafts /= 4.0;
vec3 rayNormalised = normalize(vRay-osgOcean_Eye);
float phase = computeMie(rayNormalised, -osgOcean_SunDir);
// Calculate final color, adding a little bias (0.15 here)
// to hide aliasing
vec3 colour = (bias+osgOcean_Intensity*shafts.rgb)*phase;
vec3 ray = ( rayNormalised + vec3(1.0) ) / 2.0;
gl_FragColor = vec4(colour, 1.0);
}

View File

@ -1,15 +0,0 @@
varying vec3 vRay;
void main( void )
{
gl_Position = gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[1].xy = gl_TexCoord[0].st;
gl_TexCoord[1].zw = gl_TexCoord[0].st + vec2(1.0, 0.0);
gl_TexCoord[2].xy = gl_TexCoord[0].st + vec2(1.0, 1.0);
gl_TexCoord[2].zw = gl_TexCoord[0].st + vec2(0.0, 1.0);
vRay = gl_Normal;
}

View File

@ -1,6 +0,0 @@
varying vec3 vIntensity;
void main(void)
{
gl_FragColor = vec4(vIntensity,1.0);
}

View File

@ -1,88 +0,0 @@
const int NUM_WAVES = 16;
uniform vec3 osgOcean_Origin; // central position of vertices - sun position on water surface
uniform vec3 osgOcean_Extinction_c; // extinction coefficient
uniform vec3 osgOcean_Eye; // Eye position in world space
uniform vec3 osgOcean_SunDir; // sunlight direction
uniform float osgOcean_Spacing; // spacing between vertices
uniform float osgOcean_Waves[NUM_WAVES * 5]; // wave constants
varying vec3 vIntensity;
float fastFresnel(vec3 I, vec3 N, float r0)
{
return r0 + (1.0-r0) * pow(1.0-dot(I, N), 5.0);
}
vec3 calculateWaterNormal(float x0, float y0)
{
vec3 t1 = vec3(1.0,0.0,0.0);
vec3 t2 = vec3(0.0,1.0,0.0);
int itr = NUM_WAVES/4;
for (int i = 0, j = 0; i < itr; i++, j += 20)
{
vec4 kx = vec4( osgOcean_Waves[j+0], osgOcean_Waves[j+1], osgOcean_Waves[j+2], osgOcean_Waves[j+3] );
vec4 ky = vec4( osgOcean_Waves[j+4], osgOcean_Waves[j+5], osgOcean_Waves[j+6], osgOcean_Waves[j+7] );
vec4 Ainvk = vec4( osgOcean_Waves[j+8], osgOcean_Waves[j+9], osgOcean_Waves[j+10], osgOcean_Waves[j+11] );
vec4 A = vec4( osgOcean_Waves[j+12], osgOcean_Waves[j+13], osgOcean_Waves[j+14], osgOcean_Waves[j+15] );
vec4 wt = vec4( osgOcean_Waves[j+16], osgOcean_Waves[j+17], osgOcean_Waves[j+18], osgOcean_Waves[j+19] );
vec4 phase = (kx*x0 + ky*y0 - wt);
vec4 sinp, cosp;
#if 1
sinp = sin(phase);
cosp = cos(phase);
#else
sincos(phase, sinp, cosp);
#endif
// Update tangent vector along x0
t1.x -= dot(Ainvk, kx*cosp*kx);
t1.y -= dot(Ainvk, ky*cosp*kx);
t1.z += dot(A, (-sinp)*(kx));
// Update tangent vector along y0
t2.x -= dot(Ainvk, kx*cosp*ky);
t2.y -= dot(Ainvk, ky*cosp*ky);
t2.z += dot(A, (-sinp)*(ky));
}
// Calculate and return normal
return normalize( cross(t1, t2) );
}
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
// Scale and translate the vertex on the water surface
vec3 worldPos = gl_Vertex.xyz * vec3(osgOcean_Spacing,osgOcean_Spacing,1.0);
worldPos += osgOcean_Origin;
// Calculate the water normal at this point
vec3 normal = calculateWaterNormal(worldPos.x, worldPos.y);
// Calculate transmittance
// BUG: makes intensity too small not sure why.
float transmittance = 1.0-fastFresnel(-osgOcean_SunDir, normal, 0.0204);
// Extrude bottom vertices along the direction of the refracted
// sunlight
if (gl_TexCoord[0].s > 0.0)
{
// Calculate refraction vector and extrude polygon
vec3 refr = refract(osgOcean_SunDir, normal, 0.75);
worldPos += refr*gl_TexCoord[0].s;
}
// Set intensity so that the further away you go from the surface
float totalDist = gl_TexCoord[0].s + length(worldPos-osgOcean_Eye);
vIntensity = exp(-totalDist*osgOcean_Extinction_c)*transmittance;
vIntensity = clamp(vIntensity, 0.0, 0.06);
// Transform position from world to clip space
gl_Position = gl_ModelViewProjectionMatrix * vec4(worldPos, 1.0 );
// Tweak z position not to clip shafts very close to the viewer
gl_Position.z = 0.01;
}

View File

@ -1,16 +0,0 @@
// osgOcean uniforms
// -------------------
uniform float osgOcean_WaterHeight;
// -------------------
varying vec4 vWorldVertex;
void main(void)
{
// Store the water depth
// maximum possible depth is 500,
// (a higher water depth value would not have a visible effect anyway)
gl_FragDepth = clamp((osgOcean_WaterHeight - vWorldVertex.z) / 500.0, 0.0, 1.0);
return;
}

View File

@ -1,24 +0,0 @@
// osgOcean uniforms
// -------------------
uniform float osgOcean_WaterHeight;
// ------------------
uniform mat4 osg_ViewMatrixInverse;
uniform mat4 osg_ViewMatrix;
varying vec4 vWorldVertex;
void main(void)
{
// Transform the vertex into world space
vWorldVertex = (osg_ViewMatrixInverse * gl_ModelViewMatrix) * gl_Vertex;
vWorldVertex.xyzw /= vWorldVertex.w;
// Project the vertex onto the ocean plane
vec4 projectedVertex = vWorldVertex;
projectedVertex.z = osgOcean_WaterHeight;
gl_Position = (gl_ProjectionMatrix * osg_ViewMatrix) * projectedVertex;
return;
}

View File

@ -1,124 +0,0 @@
// osgOcean Uniforms
// -----------------
uniform float osgOcean_DOF_Near;
uniform float osgOcean_DOF_Focus;
uniform float osgOcean_DOF_Far;
uniform float osgOcean_DOF_Clamp;
uniform float osgOcean_UnderwaterFogDensity;
uniform float osgOcean_AboveWaterFogDensity;
uniform vec4 osgOcean_UnderwaterFogColor;
uniform vec4 osgOcean_AboveWaterFogColor;
uniform float osgOcean_WaterHeight;
uniform bool osgOcean_EnableGlare;
uniform bool osgOcean_EnableDOF;
uniform bool osgOcean_EyeUnderwater;
uniform bool osgOcean_EnableUnderwaterScattering;
// -------------------
uniform sampler2D uTextureMap;
varying vec3 vExtinction;
varying vec3 vInScattering;
varying vec3 vNormal;
varying vec3 vLightDir;
varying vec3 vEyeVec;
varying float vWorldHeight;
float computeDepthBlur(float depth, float focus, float near, float far, float clampval )
{
float f;
if (depth < focus){
f = (depth - focus)/(focus - near);
}
else{
f = (depth - focus)/(far - focus);
f = clamp(f, 0.0, clampval);
}
return f * 0.5 + 0.5;
}
vec4 lighting( vec4 colormap )
{
vec4 final_color = gl_LightSource[osgOcean_LightID].ambient * colormap;
vec3 N = normalize(vNormal);
vec3 L = normalize(vLightDir);
float lambertTerm = dot(N,L);
if(lambertTerm > 0.0)
{
final_color += gl_LightSource[osgOcean_LightID].diffuse * lambertTerm * colormap;
vec3 E = normalize(vEyeVec);
vec3 R = reflect(-L, N);
float specular = pow( max(dot(R, E), 0.0), 2.0 );
final_color += gl_LightSource[osgOcean_LightID].specular * specular;
}
return final_color;
}
float computeFogFactor( float density, float fogCoord )
{
return exp2(density * fogCoord * fogCoord );
}
void main(void)
{
vec4 final_color;
vec4 textureColor = texture2D( uTextureMap, gl_TexCoord[0].st );
// Underwater
// +2 tweak here as waves peak above average wave height,
// and surface fog becomes visible.
if(osgOcean_EyeUnderwater && vWorldHeight < osgOcean_WaterHeight+2.0 )
{
final_color = lighting( textureColor );
// mix in underwater light
if(osgOcean_EnableUnderwaterScattering)
{
final_color.rgb = final_color.rgb * vExtinction + vInScattering;
}
float fogFactor = computeFogFactor( osgOcean_UnderwaterFogDensity, gl_FogFragCoord );
// write to depth buffer (actually a GL_LUMINANCE)
if(osgOcean_EnableDOF)
{
float depth = computeDepthBlur(gl_FogFragCoord, osgOcean_DOF_Focus, osgOcean_DOF_Near, osgOcean_DOF_Far, osgOcean_DOF_Clamp);
gl_FragData[1] = vec4(depth);
}
// color buffer
gl_FragData[0] = mix( osgOcean_UnderwaterFogColor, final_color, fogFactor );
}
// Above water
else
{
final_color = lighting( textureColor );
float fogFactor = computeFogFactor( osgOcean_AboveWaterFogDensity, gl_FogFragCoord );
final_color = mix( osgOcean_AboveWaterFogColor, final_color, fogFactor );
// write to luminance buffer
// might not need the IF here, glsl compiler doesn't complain if
// you try and write to a FragData index that doesn't exist. But since
// Mac GLSL support seems so fussy I'll leave it in.
if(osgOcean_EnableGlare)
{
gl_FragData[1] = vec4(0.0);
}
// write to color buffer
gl_FragData[0] = final_color;
}
}

View File

@ -1,49 +0,0 @@
// osgOcean Uniforms
// -----------------
uniform mat4 osg_ViewMatrixInverse;
uniform float osgOcean_WaterHeight;
uniform vec3 osgOcean_Eye;
uniform vec3 osgOcean_UnderwaterAttenuation;
uniform vec4 osgOcean_UnderwaterDiffuse;
uniform bool osgOcean_EnableUnderwaterScattering;
// -----------------
varying vec3 vExtinction;
varying vec3 vInScattering;
varying vec3 vNormal;
varying vec3 vLightDir;
varying vec3 vEyeVec;
varying float vWorldHeight;
void computeScattering( in vec3 eye, in vec3 worldVertex, out vec3 extinction, out vec3 inScattering )
{
float viewDist = length(eye-worldVertex);
float depth = max(osgOcean_WaterHeight-worldVertex.z, 0.0);
extinction = exp(-osgOcean_UnderwaterAttenuation*viewDist*2.0);
// Need to compute accurate kd constant.
// const vec3 kd = vec3(0.001, 0.001, 0.001);
inScattering = osgOcean_UnderwaterDiffuse.rgb * (1.0-extinction*exp(-depth*vec3(0.001)));
}
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
gl_FogFragCoord = gl_Position.z;
gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex; // for reflections
vNormal = gl_NormalMatrix * gl_Normal;
vLightDir = gl_LightSource[osgOcean_LightID].position.xyz;
vEyeVec = -vec3(gl_ModelViewMatrix*gl_Vertex);
vec4 worldVertex = (osg_ViewMatrixInverse*gl_ModelViewMatrix) * gl_Vertex;
if (osgOcean_EnableUnderwaterScattering)
computeScattering( osgOcean_Eye, worldVertex.xyz, vExtinction, vInScattering);
vWorldHeight = worldVertex.z;
}

View File

@ -1,128 +0,0 @@
// osgOcean Uniforms
// -----------------
uniform float osgOcean_DOF_Near;
uniform float osgOcean_DOF_Focus;
uniform float osgOcean_DOF_Far;
uniform float osgOcean_DOF_Clamp;
uniform float osgOcean_UnderwaterFogDensity;
uniform float osgOcean_AboveWaterFogDensity;
uniform vec4 osgOcean_UnderwaterFogColor;
uniform vec4 osgOcean_AboveWaterFogColor;
uniform float osgOcean_WaterHeight;
uniform bool osgOcean_EnableGlare;
uniform bool osgOcean_EnableDOF;
uniform bool osgOcean_EyeUnderwater;
uniform bool osgOcean_EnableUnderwaterScattering;
// -------------------
uniform sampler2D uTextureMap;
varying vec3 vExtinction;
varying vec3 vInScattering;
varying vec3 vNormal;
varying vec3 vLightDir;
varying vec3 vEyeVec;
varying float vWorldHeight;
uniform sampler2DShadow shadowTexture;
float computeDepthBlur(float depth, float focus, float near, float far, float clampval )
{
float f;
if (depth < focus){
f = (depth - focus)/(focus - near);
}
else{
f = (depth - focus)/(far - focus);
f = clamp(f, 0.0, clampval);
}
return f * 0.5 + 0.5;
}
vec4 lighting( vec4 colormap )
{
vec4 final_color = gl_LightSource[0].ambient * colormap;
float light = shadow2DProj( shadowTexture, gl_TexCoord[7] ).r;
vec3 N = normalize(vNormal);
vec3 L = normalize(vLightDir);
float lambertTerm = dot(N,L);
if(lambertTerm > 0.0)
{
final_color += gl_LightSource[0].diffuse * lambertTerm * colormap * light;
vec3 E = normalize(vEyeVec);
vec3 R = reflect(-L, N);
float specular = pow( max(dot(R, E), 0.0), 2.0 );
final_color += gl_LightSource[0].specular * specular * light;
}
return final_color;
}
float computeFogFactor( float density, float fogCoord )
{
return exp2(density * fogCoord * fogCoord );
}
void main(void)
{
vec4 final_color;
vec4 textureColor = texture2D( uTextureMap, gl_TexCoord[0].st );
// Underwater
// +2 tweak here as waves peak above average wave height,
// and surface fog becomes visible.
if(osgOcean_EyeUnderwater && vWorldHeight < osgOcean_WaterHeight+2.0 )
{
final_color = lighting( textureColor );
// mix in underwater light
if(osgOcean_EnableUnderwaterScattering)
{
final_color.rgb = final_color.rgb * vExtinction + vInScattering;
}
float fogFactor = computeFogFactor( osgOcean_UnderwaterFogDensity, gl_FogFragCoord );
// write to depth buffer (actually a GL_LUMINANCE)
if(osgOcean_EnableDOF)
{
float depth = computeDepthBlur(gl_FogFragCoord, osgOcean_DOF_Focus, osgOcean_DOF_Near, osgOcean_DOF_Far, osgOcean_DOF_Clamp);
gl_FragData[1] = vec4(depth);
}
// color buffer
gl_FragData[0] = mix( osgOcean_UnderwaterFogColor, final_color, fogFactor );
}
// Above water
else
{
final_color = lighting( textureColor );
float fogFactor = computeFogFactor( osgOcean_AboveWaterFogDensity, gl_FogFragCoord );
final_color = mix( osgOcean_AboveWaterFogColor, final_color, fogFactor );
// write to luminance buffer
// might not need the IF here, glsl compiler doesn't complain if
// you try and write to a FragData index that doesn't exist. But since
// Mac GLSL support seems so fussy I'll leave it in.
if(osgOcean_EnableGlare)
{
gl_FragData[1] = vec4(0.0);
}
// write to color buffer
gl_FragData[0] = final_color;
}
}

View File

@ -1,57 +0,0 @@
// osgOcean Uniforms
// -----------------
uniform mat4 osg_ViewMatrixInverse;
uniform float osgOcean_WaterHeight;
uniform vec3 osgOcean_Eye;
uniform vec3 osgOcean_UnderwaterAttenuation;
uniform vec4 osgOcean_UnderwaterDiffuse;
uniform bool osgOcean_EnableUnderwaterScattering;
// -----------------
varying vec3 vExtinction;
varying vec3 vInScattering;
varying vec3 vNormal;
varying vec3 vLightDir;
varying vec3 vEyeVec;
varying float vWorldHeight;
void computeScattering( in vec3 eye, in vec3 worldVertex, out vec3 extinction, out vec3 inScattering )
{
float viewDist = length(eye-worldVertex);
float depth = max(osgOcean_WaterHeight-worldVertex.z, 0.0);
extinction = exp(-osgOcean_UnderwaterAttenuation*viewDist*2.0);
// Need to compute accurate kd constant.
// const vec3 kd = vec3(0.001, 0.001, 0.001);
inScattering = osgOcean_UnderwaterDiffuse.rgb * (1.0-extinction*exp(-depth*vec3(0.001)));
}
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
gl_FogFragCoord = gl_Position.z;
vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;
gl_ClipVertex = ecPosition; // for reflections
vNormal = gl_NormalMatrix * gl_Normal;
vLightDir = gl_LightSource[0].position.xyz;
vEyeVec = -vec3(gl_ModelViewMatrix*gl_Vertex);
vec4 worldVertex = (osg_ViewMatrixInverse*gl_ModelViewMatrix) * gl_Vertex;
if (osgOcean_EnableUnderwaterScattering)
computeScattering( osgOcean_Eye, worldVertex.xyz, vExtinction, vInScattering);
vWorldHeight = worldVertex.z;
// Generate shadow map coords
gl_TexCoord[7].s = dot( ecPosition, gl_EyePlaneS[7] );
gl_TexCoord[7].t = dot( ecPosition, gl_EyePlaneT[7] );
gl_TexCoord[7].p = dot( ecPosition, gl_EyePlaneR[7] );
gl_TexCoord[7].q = dot( ecPosition, gl_EyePlaneQ[7] );
}

View File

@ -1,350 +0,0 @@
uniform bool osgOcean_EnableReflections;
uniform bool osgOcean_EnableRefractions;
uniform bool osgOcean_EnableHeightmap;
uniform bool osgOcean_EnableCrestFoam;
uniform bool osgOcean_EnableUnderwaterScattering;
uniform bool osgOcean_EnableDOF;
uniform bool osgOcean_EnableGlare;
uniform float osgOcean_DOF_Near;
uniform float osgOcean_DOF_Focus;
uniform float osgOcean_DOF_Far;
uniform float osgOcean_DOF_Clamp;
uniform float osgOcean_FresnelMul;
uniform samplerCube osgOcean_EnvironmentMap;
uniform sampler2D osgOcean_ReflectionMap;
uniform sampler2D osgOcean_RefractionMap;
uniform sampler2D osgOcean_RefractionDepthMap;
uniform sampler2D osgOcean_FoamMap;
uniform sampler2D osgOcean_NoiseMap;
uniform sampler2D osgOcean_Heightmap;
uniform float osgOcean_UnderwaterFogDensity;
uniform float osgOcean_AboveWaterFogDensity;
uniform vec4 osgOcean_UnderwaterFogColor;
uniform vec4 osgOcean_AboveWaterFogColor;
uniform vec3 osgOcean_UnderwaterAttenuation;
uniform vec4 osgOcean_UnderwaterDiffuse;
uniform mat4 osg_ViewMatrixInverse;
uniform mat4 osgOcean_RefractionInverseTransformation;
uniform vec2 osgOcean_ViewportDimensions;
uniform float osgOcean_WaterHeight;
uniform float osgOcean_FoamCapBottom;
uniform float osgOcean_FoamCapTop;
varying vec3 vNormal;
varying vec3 vViewerDir;
varying vec3 vLightDir;
varying vec4 vVertex;
varying vec4 vWorldVertex;
varying vec3 vExtinction;
varying vec3 vInScattering;
varying vec3 vWorldViewDir;
varying vec3 vWorldNormal;
varying float height;
mat4 worldObjectMatrix;
const float shininess = 2000.0;
const vec4 BlueEnvColor = vec4(0.75, 0.85, 1.0, 1.0);
vec4 distortGen( vec4 v, vec3 N )
{
// transposed
const mat4 mr =
mat4( 0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0 );
mat4 texgen_matrix = mr * gl_ProjectionMatrix * gl_ModelViewMatrix;
//float disp = 8.0;
float disp = 4.0;
vec4 tempPos;
tempPos.xy = v.xy + disp * N.xy;
tempPos.z = v.z;
tempPos.w = 1.0;
return texgen_matrix * tempPos;
}
vec3 reorientate( vec3 v )
{
float y = v.y;
v.y = -v.z;
v.z = y;
return v;
}
mat3 getLinearPart( mat4 m )
{
mat3 result;
result[0][0] = m[0][0];
result[0][1] = m[0][1];
result[0][2] = m[0][2];
result[1][0] = m[1][0];
result[1][1] = m[1][1];
result[1][2] = m[1][2];
result[2][0] = m[2][0];
result[2][1] = m[2][1];
result[2][2] = m[2][2];
return result;
}
float calcFresnel( float dotEN, float mul )
{
float fresnel = clamp( dotEN, 0.0, 1.0 ) + 1.0;
return pow(fresnel, -8.0) * mul;
}
float alphaHeight( float min, float max, float val)
{
if(max-min == 0.0)
return 1.0;
return (val - min) / (max - min);
}
float computeDepthBlur(float depth, float focus, float near, float far, float clampval )
{
float f;
if (depth < focus){
// scale depth value between near blur distance and focal distance to [-1, 0] range
f = (depth - focus)/(focus - near);
}
else{
// scale depth value between focal distance and far blur
// distance to [0, 1] range
f = (depth - focus)/(far - focus);
// clamp the far blur to a maximum blurriness
f = clamp(f, 0.0, clampval);
}
// scale and bias into [0, 1] range
return f * 0.5 + 0.5;
}
float luminance( vec4 color )
{
return (0.3*color.r) + (0.59*color.g) + (0.11*color.b);
}
float computeFogFactor( float density, float fogCoord )
{
return exp2(density * fogCoord * fogCoord );
}
// -------------------------------
// Main Program
// -------------------------------
void main( void )
{
vec4 final_color;
vec3 noiseNormal = vec3( texture2D( osgOcean_NoiseMap, gl_TexCoord[0].xy ) * 2.0 - 1.0 );
noiseNormal += vec3( texture2D( osgOcean_NoiseMap, gl_TexCoord[0].zw ) * 2.0 - 1.0 );
worldObjectMatrix = osg_ViewMatrixInverse * gl_ModelViewMatrix;
if(gl_FrontFacing)
{
vec3 N = normalize( vNormal + noiseNormal );
vec3 L = normalize( vLightDir );
vec3 E = normalize( vViewerDir );
vec3 R = reflect( -L, N );
vec4 specular_color = vec4(0.0);
float lambertTerm = dot(N,L);
if( lambertTerm > 0.0 )
{
float specCoeff = pow( max( dot(R, E), 0.0 ), shininess );
specular_color = gl_LightSource[osgOcean_LightID].diffuse * specCoeff * 6.0;
}
float dotEN = dot(E, N);
float dotLN = dot(L, N);
vec4 distortedVertex = distortGen(vVertex, N);
// Calculate the position in world space of the pixel on the ocean floor
vec4 refraction_ndc = vec4(gl_FragCoord.xy / osgOcean_ViewportDimensions, texture2DProj(osgOcean_RefractionDepthMap, distortedVertex).x, 1.0);
vec4 refraction_screen = refraction_ndc * 2.0 - 1.0;
vec4 refraction_world = osgOcean_RefractionInverseTransformation * refraction_screen;
refraction_world = refraction_world / refraction_world.w;
// The amount of water behind the pixel
// (water depth as seen from the camera position)
float waterDepth = distance(vWorldVertex, refraction_world);
vec4 refraction_dir = refraction_world - vWorldVertex;
vec4 env_color;
if(osgOcean_EnableReflections)
{
env_color = texture2DProj( osgOcean_ReflectionMap, distortedVertex );
}
else
{
env_color = BlueEnvColor * gl_LightSource[osgOcean_LightID].diffuse * vec4(vec3(1.25), 1.0);
}
// Determine refraction color
vec4 refraction_color = vec4( gl_Color.rgb, 1.0 );
// Only use refraction for under the ocean surface.
if(osgOcean_EnableRefractions)
{
vec4 refractionmap_color = texture2DProj(osgOcean_RefractionMap, distortedVertex );
if(osgOcean_EnableUnderwaterScattering)
{
// Compute underwater scattering the same way as when underwater,
// see vertex shader computeScattering() function, but a higher
// underwater attenuation factor is required so it matches the
// underwater look.
float depth = max(osgOcean_WaterHeight-vWorldVertex.z, 0.0);
vec3 extinction = exp(-osgOcean_UnderwaterAttenuation*waterDepth*4.0);
vec3 inScattering = osgOcean_UnderwaterDiffuse.rgb * vec3(0.6, 0.6, 0.5) * (1.0-extinction*exp(-depth*vec3(0.001)));
refraction_color.rgb = refractionmap_color.rgb * extinction + inScattering;
}
else
{
refraction_color.rgb *= refractionmap_color.rgb;
}
}
float fresnel = calcFresnel(dotEN, osgOcean_FresnelMul );
final_color = mix(refraction_color, env_color, fresnel) + specular_color;
// Store the color here to compute luminance later, we don't want
// foam or fog to be taken into account for this calculation.
vec4 lumColor = final_color;
float waterHeight = 0.0;
if (osgOcean_EnableHeightmap)
{
// The vertical distance between the ocean surface and ocean floor, this uses the projected heightmap
waterHeight = (texture2DProj(osgOcean_Heightmap, distortedVertex).x) * 500.0;
}
if(osgOcean_EnableCrestFoam)
{
if( vVertex.z > osgOcean_FoamCapBottom ||
(osgOcean_EnableHeightmap && waterHeight < 10.0))
{
vec4 foam_color = texture2D( osgOcean_FoamMap, gl_TexCoord[1].st / 10.0);
float alpha;
if (osgOcean_EnableHeightmap)
{
alpha = max(alphaHeight( osgOcean_FoamCapBottom, osgOcean_FoamCapTop, vVertex.z ) * (fresnel*2.0),
0.8 - clamp(waterHeight / 10.0, 0.0, 0.8));
}
else
{
alpha = alphaHeight( osgOcean_FoamCapBottom, osgOcean_FoamCapTop, vVertex.z ) * (fresnel*2.0);
}
final_color = final_color + (foam_color * alpha);
}
}
// exp2 fog
float fogFactor = computeFogFactor( osgOcean_AboveWaterFogDensity, gl_FogFragCoord );
final_color = mix( osgOcean_AboveWaterFogColor, final_color, fogFactor );
if(osgOcean_EnableGlare)
{
float lum = luminance(lumColor);
gl_FragData[1] = vec4(lum);
}
gl_FragData[0] = final_color;
}
else
{
vec3 E = normalize( vViewerDir );
vec3 N = -normalize( (vWorldNormal + noiseNormal) );
vec3 incident = normalize( vWorldViewDir );
//------ Find the reflection
// not really usable as we would need to use cubemap again..
// the ocean is blue not much to reflect back
//vec3 reflected = reflect( incident, -N );
//reflected = reorientate( reflected );
//vec3 reflVec = normalize( reflected );
//------ Find the refraction from cubemap
vec3 refracted = refract( incident, N, 1.3333333333 ); // 1.1 looks better? - messes up position of godrays though
refracted.z = refracted.z - 0.015; // on the fringes push it down to show base texture color
refracted = reorientate( refracted );
vec4 refractColor = textureCube( osgOcean_EnvironmentMap, refracted );
//------ Project texture where the light isn't internally reflected
if(osgOcean_EnableRefractions)
{
// if alpha is 1.0 then it's a sky pixel
if(refractColor.a == 1.0 )
{
vec4 env_color = texture2DProj( osgOcean_RefractionMap, distortGen(vVertex, N) );
refractColor.rgb = mix( refractColor.rgb, env_color.rgb, env_color.a );
}
}
// if it's not refracting in, add a bit of highlighting with fresnel
if( refractColor.a == 0.0 )
{
float fresnel = calcFresnel( dot(E, N), 0.7 );
refractColor.rgb = osgOcean_UnderwaterFogColor.rgb*fresnel + (1.0-fresnel)* refractColor.rgb;
}
// mix in underwater light
if(osgOcean_EnableUnderwaterScattering)
{
refractColor.rgb = refractColor.rgb * vExtinction + vInScattering;
}
float fogFactor = computeFogFactor( osgOcean_UnderwaterFogDensity, gl_FogFragCoord );
final_color = mix( osgOcean_UnderwaterFogColor, refractColor, fogFactor );
if(osgOcean_EnableDOF)
{
float depthBlur = computeDepthBlur( gl_FogFragCoord, osgOcean_DOF_Focus, osgOcean_DOF_Near, osgOcean_DOF_Far, osgOcean_DOF_Clamp );
gl_FragData[1] = vec4(depthBlur);
}
gl_FragData[0] = final_color;
}
}

View File

@ -1,136 +0,0 @@
uniform mat4 osg_ViewMatrixInverse;
uniform vec3 osgOcean_Eye;
uniform vec3 osgOcean_NoiseCoords0;
uniform vec3 osgOcean_NoiseCoords1;
uniform vec4 osgOcean_WaveTop;
uniform vec4 osgOcean_WaveBot;
uniform float osgOcean_FoamScale;
uniform float osgOcean_FrameTime;
// Used to blend the waves into a sinus curve near the shore
uniform sampler2D osgOcean_Heightmap;
uniform bool osgOcean_EnableHeightmap;
uniform bool osgOcean_EnableUnderwaterScattering;
uniform float osgOcean_WaterHeight;
uniform vec3 osgOcean_UnderwaterAttenuation;
uniform vec4 osgOcean_UnderwaterDiffuse;
varying vec4 vVertex;
varying vec4 vWorldVertex;
varying vec3 vNormal;
varying vec3 vViewerDir;
varying vec3 vLightDir;
varying vec3 vExtinction;
varying vec3 vInScattering;
varying vec3 vWorldViewDir;
varying vec3 vWorldNormal;
varying float height;
mat3 get3x3Matrix( mat4 m )
{
mat3 result;
result[0][0] = m[0][0];
result[0][1] = m[0][1];
result[0][2] = m[0][2];
result[1][0] = m[1][0];
result[1][1] = m[1][1];
result[1][2] = m[1][2];
result[2][0] = m[2][0];
result[2][1] = m[2][1];
result[2][2] = m[2][2];
return result;
}
void computeScattering( in vec3 eye, in vec3 worldVertex, out vec3 extinction, out vec3 inScattering )
{
float viewDist = length(eye-worldVertex);
float depth = max(osgOcean_WaterHeight-worldVertex.z, 0.0);
extinction = exp(-osgOcean_UnderwaterAttenuation*viewDist*2.0);
// Need to compute accurate kd constant.
// const vec3 kd = vec3(0.001, 0.001, 0.001);
inScattering = osgOcean_UnderwaterDiffuse.rgb * (1.0-extinction*exp(-depth*vec3(0.001)));
}
// -------------------------------
// Main Program
// -------------------------------
void main( void )
{
// Transform the vertex
vec4 inputVertex = gl_Vertex;
gl_Position = gl_ModelViewProjectionMatrix * inputVertex;
// Blend the wave into a sinus curve near the shore
// note that this requires a vertex shader texture lookup
// vertex has to be transformed a second time with the new z-value
if (osgOcean_EnableHeightmap)
{
vec2 screenCoords = gl_Position.xy / gl_Position.w;
height = pow(clamp(1.0 - texture2D(osgOcean_Heightmap, clamp(screenCoords * 0.5 + 0.5, 0.0, 1.0)).x, 0.0, 1.0), 32.0);
inputVertex = vec4(gl_Vertex.x,
gl_Vertex.y,
mix(gl_Vertex.z, sin(osgOcean_FrameTime), height),
gl_Vertex.w);
gl_Position = gl_ModelViewProjectionMatrix * inputVertex;
}
// -----------------------------------------------------------
// In object space
vVertex = inputVertex;
vLightDir = normalize( vec3( gl_ModelViewMatrixInverse * ( gl_LightSource[osgOcean_LightID].position ) ) );
vViewerDir = gl_ModelViewMatrixInverse[3].xyz - inputVertex.xyz;
vNormal = normalize(gl_Normal);
vec4 waveColorDiff = osgOcean_WaveTop - osgOcean_WaveBot;
gl_FrontColor = waveColorDiff *
clamp((gl_Vertex.z + osgOcean_Eye.z) * 0.1111111 + vNormal.z - 0.4666667, 0.0, 1.0) + osgOcean_WaveBot;
// -------------------------------------------------------------
mat4 modelMatrix = osg_ViewMatrixInverse * gl_ModelViewMatrix;
mat3 modelMatrix3x3 = get3x3Matrix( modelMatrix );
// world space
vWorldVertex = modelMatrix * gl_Vertex;
vWorldNormal = modelMatrix3x3 * gl_Normal;
vWorldViewDir = vWorldVertex.xyz - osgOcean_Eye.xyz;
// ------------- Texture Coords ---------------------------------
// Normal Map Coords
gl_TexCoord[0].xy = ( gl_Vertex.xy * osgOcean_NoiseCoords0.z + osgOcean_NoiseCoords0.xy );
gl_TexCoord[0].zw = ( gl_Vertex.xy * osgOcean_NoiseCoords1.z + osgOcean_NoiseCoords1.xy );
gl_TexCoord[0].y = -gl_TexCoord[0].y;
gl_TexCoord[0].w = -gl_TexCoord[0].w;
// Foam coords
gl_TexCoord[1].st = gl_Vertex.xy * osgOcean_FoamScale;
// Fog coords
gl_FogFragCoord = gl_Position.z;
if (osgOcean_EnableUnderwaterScattering)
computeScattering( osgOcean_Eye, vWorldVertex.xyz, vExtinction, vInScattering);
}

View File

@ -1,137 +0,0 @@
uniform mat4 osg_ViewMatrixInverse;
uniform float osg_FrameTime;
uniform vec3 osgOcean_Eye;
uniform vec3 osgOcean_NoiseCoords0;
uniform vec3 osgOcean_NoiseCoords1;
uniform vec4 osgOcean_WaveTop;
uniform vec4 osgOcean_WaveBot;
uniform float osgOcean_FoamScale;
// Used to blend the waves into a sinus curve near the shore
uniform sampler2D osgOcean_Heightmap;
uniform bool osgOcean_EnableHeightmap;
uniform bool osgOcean_EnableUnderwaterScattering;
uniform float osgOcean_WaterHeight;
uniform vec3 osgOcean_UnderwaterAttenuation;
uniform vec4 osgOcean_UnderwaterDiffuse;
varying vec4 vVertex;
varying vec4 vWorldVertex;
varying vec3 vNormal;
varying vec3 vViewerDir;
varying vec3 vLightDir;
varying vec3 vExtinction;
varying vec3 vInScattering;
varying vec3 vWorldViewDir;
varying vec3 vWorldNormal;
varying float height;
mat3 get3x3Matrix( mat4 m )
{
mat3 result;
result[0][0] = m[0][0];
result[0][1] = m[0][1];
result[0][2] = m[0][2];
result[1][0] = m[1][0];
result[1][1] = m[1][1];
result[1][2] = m[1][2];
result[2][0] = m[2][0];
result[2][1] = m[2][1];
result[2][2] = m[2][2];
return result;
}
void computeScattering( in vec3 eye, in vec3 worldVertex, out vec3 extinction, out vec3 inScattering )
{
float viewDist = length(eye-worldVertex);
float depth = max(osgOcean_WaterHeight-worldVertex.z, 0.0);
extinction = exp(-osgOcean_UnderwaterAttenuation*viewDist*2.0);
// Need to compute accurate kd constant.
// const vec3 kd = vec3(0.001, 0.001, 0.001);
inScattering = osgOcean_UnderwaterDiffuse.rgb * (1.0-extinction*exp(-depth*vec3(0.001)));
}
// -------------------------------
// Main Program
// -------------------------------
void main( void )
{
// Transform the vertex
vec4 inputVertex = gl_Vertex;
inputVertex.xyz += gl_Color.xyz;
gl_Position = gl_ModelViewProjectionMatrix * inputVertex;
// Blend the wave into a sinus curve near the shore
// note that this requires a vertex shader texture lookup
// vertex has to be transformed a second time with the new z-value
if (osgOcean_EnableHeightmap)
{
vec2 screenCoords = gl_Position.xy / gl_Position.w;
height = pow(clamp(1.0 - texture2D(osgOcean_Heightmap, clamp(screenCoords * 0.5 + 0.5, 0.0, 1.0)).x, 0.0, 1.0), 32.0);
inputVertex = vec4(inputVertex.x,
inputVertex.y,
mix(inputVertex.z, sin(osg_FrameTime), height),
inputVertex.w);
gl_Position = gl_ModelViewProjectionMatrix * inputVertex;
}
// -----------------------------------------------------------
// In object space
vVertex = inputVertex;
vLightDir = normalize( vec3( gl_ModelViewMatrixInverse * ( gl_LightSource[osgOcean_LightID].position ) ) );
vViewerDir = gl_ModelViewMatrixInverse[3].xyz - inputVertex.xyz;
vNormal = normalize(gl_Normal);
vec4 waveColorDiff = osgOcean_WaveTop-osgOcean_WaveBot;
gl_FrontColor = waveColorDiff *
clamp((inputVertex.z + osgOcean_Eye.z) * 0.1111111 + vNormal.z - 0.4666667, 0.0, 1.0) + osgOcean_WaveBot;
// -------------------------------------------------------------
mat4 modelMatrix = osg_ViewMatrixInverse * gl_ModelViewMatrix;
mat3 modelMatrix3x3 = get3x3Matrix( modelMatrix );
// world space
vWorldVertex = modelMatrix * inputVertex;
vWorldNormal = modelMatrix3x3 * gl_Normal;
vWorldViewDir = vWorldVertex.xyz - osgOcean_Eye.xyz;
// ------------- Texture Coords ---------------------------------
// Normal Map Coords
gl_TexCoord[0].xy = ( inputVertex.xy * osgOcean_NoiseCoords0.z + osgOcean_NoiseCoords0.xy );
gl_TexCoord[0].zw = ( inputVertex.xy * osgOcean_NoiseCoords1.z + osgOcean_NoiseCoords1.xy );
gl_TexCoord[0].y = -gl_TexCoord[0].y;
gl_TexCoord[0].w = -gl_TexCoord[0].w;
// Foam coords
gl_TexCoord[1].st = inputVertex.xy * osgOcean_FoamScale;
// Fog coords
gl_FogFragCoord = gl_Position.z;
if (osgOcean_EnableUnderwaterScattering)
computeScattering( osgOcean_Eye, vWorldVertex.xyz, vExtinction, vInScattering);
}

View File

@ -1,7 +0,0 @@
uniform sampler2D osgOcean_BaseTexture;
varying vec4 colour;
void main (void)
{
gl_FragColor = colour * texture2D( osgOcean_BaseTexture, gl_TexCoord[0].xy);
}

View File

@ -1,34 +0,0 @@
uniform float osgOcean_InversePeriod;
uniform vec4 osgOcean_ParticleColour;
uniform float osgOcean_ParticleSize;
uniform float osg_SimulationTime;
varying vec4 colour;
void main(void)
{
float startTime = gl_MultiTexCoord1.x;
vec4 v_current = gl_Vertex;
float disp = (osg_SimulationTime - startTime)*osgOcean_InversePeriod;
vec3 direction = sign(gl_Normal);
v_current.x = direction.x * fract( disp + gl_Vertex.x );
v_current.y = direction.y * fract( disp + gl_Vertex.y );
v_current.z = direction.z * fract( disp + gl_Vertex.z );
colour = osgOcean_ParticleColour;
gl_Position = gl_ModelViewProjectionMatrix * v_current;
float pointSize = abs(1280.0*osgOcean_ParticleSize / gl_Position.w);
gl_PointSize = ceil(pointSize);
colour.a = 0.05+(pointSize*pointSize)/(gl_PointSize*gl_PointSize);
gl_ClipVertex = v_current;
}

View File

@ -1,8 +0,0 @@
uniform sampler2D osgOcean_BaseTexture;
varying vec2 texCoord;
varying vec4 colour;
void main (void)
{
gl_FragColor = colour * texture2D( osgOcean_BaseTexture, texCoord);
}

View File

@ -1,52 +0,0 @@
uniform vec4 osgOcean_ParticleColour;
uniform float osgOcean_InversePeriod;
uniform float osgOcean_ParticleSize;
uniform float osg_SimulationTime;
uniform float osg_DeltaSimulationTime;
varying vec4 colour;
varying vec2 texCoord;
void main(void)
{
float startTime = gl_MultiTexCoord1.x;
texCoord = gl_MultiTexCoord0.xy;
float disp = (osg_SimulationTime - startTime)*osgOcean_InversePeriod;
vec4 v_previous = gl_Vertex;
vec3 direction = sign(gl_Normal);
v_previous.x = direction.x * fract( disp + gl_Vertex.x );
v_previous.y = direction.y * fract( disp + gl_Vertex.y );
v_previous.z = direction.z * fract( disp + gl_Vertex.z );
vec4 v_current = v_previous;
v_current.x += ( osg_DeltaSimulationTime * osgOcean_InversePeriod );
v_current.y += ( osg_DeltaSimulationTime * osgOcean_InversePeriod );
v_current.z += ( osg_DeltaSimulationTime * osgOcean_InversePeriod );
colour = osgOcean_ParticleColour;
vec4 v1 = gl_ModelViewMatrix * v_current;
vec4 v2 = gl_ModelViewMatrix * v_previous;
vec3 dv = v2.xyz - v1.xyz;
vec2 dv_normalized = normalize(dv.xy);
dv.xy += dv_normalized * osgOcean_ParticleSize;
vec2 dp = vec2( -dv_normalized.y, dv_normalized.x ) * osgOcean_ParticleSize;
float area = length(dv.xy);
colour.a = 0.05+(osgOcean_ParticleSize)/area;
v1.xyz += dv*texCoord.y;
v1.xy += dp*texCoord.x;
gl_Position = gl_ProjectionMatrix * v1;
gl_Position.z = 0.01;
gl_ClipVertex = v1;
}

View File

@ -1,36 +0,0 @@
#extension GL_ARB_texture_rectangle : enable
#define NUM_SAMPLES 4
uniform sampler2DRect osgOcean_Buffer;
uniform vec2 osgOcean_Direction;
uniform float osgOcean_Attenuation;
uniform float osgOcean_Pass;
void main(void)
{
vec2 sampleCoord = vec2(0.0);
vec3 cOut = vec3(0.0);
// sample weight = a^(b*s)
// a = attenuation
// b = 4^(pass-1)
// s = sample number
vec2 pxSize = vec2(0.5);
float b = pow( float(NUM_SAMPLES), float(osgOcean_Pass));
float sf = 0.0;
for (int s = 0; s < NUM_SAMPLES; s++)
{
sf = float(s);
float weight = pow(osgOcean_Attenuation, b * sf);
sampleCoord = gl_TexCoord[0].st + (osgOcean_Direction * b * vec2(sf) * pxSize);
cOut += clamp(weight,0.0,1.0) * texture2DRect(osgOcean_Buffer, sampleCoord).rgb;
}
vec3 streak = clamp(cOut, 0.0, 1.0);
gl_FragColor = vec4(streak,1.0);
}

View File

@ -1,6 +0,0 @@
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}

View File

@ -1,45 +0,0 @@
// Based on Jon Kennedy's heat haze shader
// Copyright (c) 2002-2006 3Dlabs Inc. Ltd.
uniform float osgOcean_Frequency;
uniform float osgOcean_Offset;
uniform float osgOcean_Speed;
uniform vec2 osgOcean_ScreenRes;
uniform sampler2DRect osgOcean_FrameBuffer;
varying vec4 vEyePos;
void main (void)
{
vec2 index;
// perform the div by w to put the texture into screen space
float recipW = 1.0 / vEyePos.w;
vec2 eye = vEyePos.xy * vec2(recipW);
float blend = max(1.0 - eye.y, 0.0);
// calc the wobble
// index.s = eye.x ;
index.s = eye.x + blend * sin( osgOcean_Frequency * 5.0 * eye.x + osgOcean_Offset * osgOcean_Speed ) * 0.004;
index.t = eye.y + blend * sin( osgOcean_Frequency * 5.0 * eye.y + osgOcean_Offset * osgOcean_Speed ) * 0.004;
// scale and shift so we're in the range 0-1
index.s = index.s * 0.5 + 0.5;
index.t = index.t * 0.5 + 0.5;
vec2 recipRes = vec2(1.0/osgOcean_ScreenRes.x, 1.0/osgOcean_ScreenRes.y);
index.s = clamp(index.s, 0.0, 1.0 - recipRes.x);
index.t = clamp(index.t, 0.0, 1.0 - recipRes.y);
// scale the texture so we just see the rendered framebuffer
index.s = index.s * osgOcean_ScreenRes.x;
index.t = index.t * osgOcean_ScreenRes.y;
vec3 RefractionColor = vec3( texture2DRect( osgOcean_FrameBuffer, index ) );
gl_FragColor = vec4( RefractionColor, 1.0 );
//gl_FragColor = texture2DRect( osgOcean_FrameBuffer, gl_TexCoord[0].st );
}

View File

@ -1,8 +0,0 @@
varying vec4 vEyePos;
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
vEyePos = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_Position = ftransform();
}

View File

@ -1,11 +0,0 @@
uniform samplerCube uEnvironmentMap;
varying vec3 vTexCoord;
void main(void)
{
vec3 texcoord = vec3(vTexCoord.x, vTexCoord.y, -vTexCoord.z);
gl_FragData[0] = textureCube( uEnvironmentMap, texcoord.xzy );
gl_FragData[0].a = 0.0;
gl_FragData[1] = vec4(0.0);
}

View File

@ -1,8 +0,0 @@
varying vec3 vTexCoord;
void main(void)
{
gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz, 1.0);
vTexCoord = gl_Vertex.xyz;
}

View File

@ -1,125 +0,0 @@
// osgOcean uniforms
// -------------------
uniform float osgOcean_DOF_Near;
uniform float osgOcean_DOF_Focus;
uniform float osgOcean_DOF_Far;
uniform float osgOcean_DOF_Clamp;
uniform bool osgOcean_EnableGlare;
uniform bool osgOcean_EnableDOF;
uniform bool osgOcean_EyeUnderwater;
uniform bool osgOcean_EnableUnderwaterScattering;
uniform float osgOcean_UnderwaterFogDensity;
uniform float osgOcean_AboveWaterFogDensity;
uniform float osgOcean_WaterHeight;
uniform vec4 osgOcean_UnderwaterFogColor;
uniform vec4 osgOcean_AboveWaterFogColor;
// -------------------
uniform sampler2D uTextureMap;
uniform sampler2D uOverlayMap;
uniform sampler2D uNormalMap;
varying vec3 vLightDir;
varying vec3 vEyeVec;
varying vec3 vExtinction;
varying vec3 vInScattering;
varying vec4 vWorldVertex;
varying float vUnitHeight;
float computeDepthBlur(float depth, float focus, float near, float far, float clampval )
{
float f;
if (depth < focus){
f = (depth - focus)/(focus - near);
}
else{
f = (depth - focus)/(far - focus);
f = clamp(f, 0.0, clampval);
}
return f * 0.5 + 0.5;
}
vec4 lighting( in vec4 colormap, in vec3 N )
{
vec4 final_color = gl_LightSource[osgOcean_LightID].ambient * colormap;
vec3 L = normalize(vLightDir);
float lambertTerm = dot(N,L);
if(lambertTerm > 0.0)
{
final_color += gl_LightSource[osgOcean_LightID].diffuse * lambertTerm * colormap;
vec3 E = normalize(vEyeVec);
vec3 R = reflect(-L, N);
float specular = pow( max(dot(R, E), 0.0), 2.0 );
final_color += gl_LightSource[osgOcean_LightID].specular * specular;
}
return final_color;
}
float computeFogFactor( float density, float fogCoord )
{
return exp2(density * fogCoord * fogCoord );
}
void main(void)
{
vec4 baseColor = texture2D( uTextureMap, gl_TexCoord[0].st );
vec4 overlayColor = texture2D( uOverlayMap, gl_TexCoord[1].st );
vec4 bumpColor = texture2D( uNormalMap, gl_TexCoord[0].st );
float unitHeight = clamp( vUnitHeight, 0.0, 1.0);
vec4 textureColor = mix(overlayColor, baseColor, unitHeight);
vec3 bump = (bumpColor.xyz*2.0)-1.0;
float fogFactor = 0.0;
vec4 fogColor;
vec4 final_color = lighting( textureColor, bump );
// +2 tweak here as waves peak above average wave height,
// and surface fog becomes visible.
if(osgOcean_EyeUnderwater && vWorldVertex.z < osgOcean_WaterHeight+2.0)
{
// mix in underwater light
if( osgOcean_EnableUnderwaterScattering )
{
final_color.rgb = final_color.rgb * vExtinction + vInScattering;
}
fogFactor = computeFogFactor( osgOcean_UnderwaterFogDensity, gl_FogFragCoord );
fogColor = osgOcean_UnderwaterFogColor;
// depth buffer
if(osgOcean_EnableDOF)
{
float depthBlur = computeDepthBlur( gl_FogFragCoord, osgOcean_DOF_Focus, osgOcean_DOF_Near, osgOcean_DOF_Far, osgOcean_DOF_Clamp );
gl_FragData[1] = vec4(depthBlur);
}
}
else
{
fogFactor = computeFogFactor( osgOcean_AboveWaterFogDensity, gl_FogFragCoord );
fogColor = osgOcean_AboveWaterFogColor;
// luminance buffer
if(osgOcean_EnableGlare)
{
gl_FragData[1] = vec4(0.0);
}
}
// color buffer
gl_FragData[0] = mix( fogColor, final_color, fogFactor );
}

View File

@ -1,79 +0,0 @@
// osgOcean uniforms
// -------------------
uniform float osgOcean_WaterHeight;
uniform vec3 osgOcean_Eye;
uniform vec3 osgOcean_UnderwaterAttenuation;
uniform vec4 osgOcean_UnderwaterDiffuse;
uniform bool osgOcean_EnableUnderwaterScattering;
// ------------------
uniform vec2 uHeightRange;
uniform float uOneOverHeight;
uniform mat4 osg_ViewMatrixInverse;
varying float vUnitHeight;
varying vec3 vLightDir;
varying vec3 vEyeVec;
varying vec3 vExtinction;
varying vec3 vInScattering;
varying vec4 vWorldVertex;
attribute vec3 aTangent;
void computeScattering( in vec3 eye, in vec3 worldVertex, out vec3 extinction, out vec3 inScattering )
{
float viewDist = length(eye-worldVertex);
float depth = max(osgOcean_WaterHeight-worldVertex.z, 0.0);
extinction = exp(-osgOcean_UnderwaterAttenuation*viewDist*2.0);
// Need to compute accurate kd constant.
// const vec3 kd = vec3(0.001, 0.001, 0.001);
inScattering = osgOcean_UnderwaterDiffuse.rgb * (1.0-extinction*exp(-depth*vec3(0.001)));
}
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0*vec4(16.0,16.0,1.0,1.0);
gl_TexCoord[1] = gl_MultiTexCoord0*vec4(20.0,20.0,1.0,1.0);
gl_TexCoord[2] = gl_MultiTexCoord0*vec4(25.0,25.0,1.0,1.0);
vec3 vertex = vec3(gl_ModelViewMatrix * gl_Vertex);
vEyeVec = -vertex;
vec3 n = normalize(gl_NormalMatrix * gl_Normal);
vec3 t = normalize(gl_NormalMatrix * aTangent);
vec3 b = cross(n, t);
vec3 tmpVec = vec3(gl_LightSource[0].position.xyz);
tmpVec = normalize(tmpVec);
vLightDir.x = dot(tmpVec, t);
vLightDir.y = dot(tmpVec, b);
vLightDir.z = dot(tmpVec, n);
tmpVec = -vertex;
vEyeVec.x = dot(tmpVec, t);
vEyeVec.y = dot(tmpVec, b);
vEyeVec.z = dot(tmpVec, n);
gl_Position = ftransform();
gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;
gl_FogFragCoord = gl_Position.z;
float inv = 1.0 / ( uHeightRange.y - (uHeightRange.x+65.0) );
vUnitHeight = inv * (gl_Vertex.z - (uHeightRange.x+65.0));
vWorldVertex = (osg_ViewMatrixInverse*gl_ModelViewMatrix) * gl_Vertex;
if( osgOcean_EnableUnderwaterScattering )
{
computeScattering( osgOcean_Eye, vWorldVertex.xyz, vExtinction, vInScattering );
}
gl_Position = ftransform();
}

View File

@ -1,129 +0,0 @@
// osgOcean uniforms
// -------------------
uniform float osgOcean_DOF_Near;
uniform float osgOcean_DOF_Focus;
uniform float osgOcean_DOF_Far;
uniform float osgOcean_DOF_Clamp;
uniform bool osgOcean_EnableGlare;
uniform bool osgOcean_EnableDOF;
uniform bool osgOcean_EyeUnderwater;
uniform bool osgOcean_EnableUnderwaterScattering;
uniform float osgOcean_UnderwaterFogDensity;
uniform float osgOcean_AboveWaterFogDensity;
uniform float osgOcean_WaterHeight;
uniform vec4 osgOcean_UnderwaterFogColor;
uniform vec4 osgOcean_AboveWaterFogColor;
// -------------------
uniform sampler2D uTextureMap;
uniform sampler2D uOverlayMap;
uniform sampler2D uNormalMap;
varying vec3 vLightDir;
varying vec3 vEyeVec;
varying vec3 vExtinction;
varying vec3 vInScattering;
varying vec4 vWorldVertex;
varying float vUnitHeight;
uniform sampler2DShadow shadowTexture;
float computeDepthBlur(float depth, float focus, float near, float far, float clampval )
{
float f;
if (depth < focus){
f = (depth - focus)/(focus - near);
}
else{
f = (depth - focus)/(far - focus);
f = clamp(f, 0.0, clampval);
}
return f * 0.5 + 0.5;
}
vec4 lighting( in vec4 colormap, in vec3 N )
{
vec4 final_color = gl_LightSource[osgOcean_LightID].ambient * colormap;
float light = shadow2DProj( shadowTexture, gl_TexCoord[7] ).r;
vec3 L = normalize(vLightDir);
float lambertTerm = dot(N,L);
if(lambertTerm > 0.0)
{
final_color += gl_LightSource[osgOcean_LightID].diffuse * lambertTerm * colormap * light;
vec3 E = normalize(vEyeVec);
vec3 R = reflect(-L, N);
float specular = pow( max(dot(R, E), 0.0), 2.0 );
final_color += gl_LightSource[osgOcean_LightID].specular * specular * light;
}
return final_color;
}
float computeFogFactor( float density, float fogCoord )
{
return exp2(density * fogCoord * fogCoord );
}
void main(void)
{
vec4 baseColor = texture2D( uTextureMap, gl_TexCoord[0].st );
vec4 overlayColor = texture2D( uOverlayMap, gl_TexCoord[1].st );
vec4 bumpColor = texture2D( uNormalMap, gl_TexCoord[0].st );
float unitHeight = clamp( vUnitHeight, 0.0, 1.0);
vec4 textureColor = mix(overlayColor, baseColor, unitHeight);
vec3 bump = (bumpColor.xyz*2.0)-1.0;
float fogFactor = 0.0;
vec4 fogColor;
vec4 final_color = lighting( textureColor, bump );
// +2 tweak here as waves peak above average wave height,
// and surface fog becomes visible.
if(osgOcean_EyeUnderwater && vWorldVertex.z < osgOcean_WaterHeight+2.0)
{
// mix in underwater light
if( osgOcean_EnableUnderwaterScattering )
{
final_color.rgb = final_color.rgb * vExtinction + vInScattering;
}
fogFactor = computeFogFactor( osgOcean_UnderwaterFogDensity, gl_FogFragCoord );
fogColor = osgOcean_UnderwaterFogColor;
// depth buffer
if(osgOcean_EnableDOF)
{
float depthBlur = computeDepthBlur( gl_FogFragCoord, osgOcean_DOF_Focus, osgOcean_DOF_Near, osgOcean_DOF_Far, osgOcean_DOF_Clamp );
gl_FragData[1] = vec4(depthBlur);
}
}
else
{
fogFactor = computeFogFactor( osgOcean_AboveWaterFogDensity, gl_FogFragCoord );
fogColor = osgOcean_AboveWaterFogColor;
// luminance buffer
if(osgOcean_EnableGlare)
{
gl_FragData[1] = vec4(0.0);
}
}
// color buffer
gl_FragData[0] = mix( fogColor, final_color, fogFactor );
}

View File

@ -1,86 +0,0 @@
// osgOcean uniforms
// -------------------
uniform float osgOcean_WaterHeight;
uniform vec3 osgOcean_Eye;
uniform vec3 osgOcean_UnderwaterAttenuation;
uniform vec4 osgOcean_UnderwaterDiffuse;
uniform bool osgOcean_EnableUnderwaterScattering;
// ------------------
uniform vec2 uHeightRange;
uniform float uOneOverHeight;
uniform mat4 osg_ViewMatrixInverse;
varying float vUnitHeight;
varying vec3 vLightDir;
varying vec3 vEyeVec;
varying vec3 vExtinction;
varying vec3 vInScattering;
varying vec4 vWorldVertex;
attribute vec3 aTangent;
void computeScattering( in vec3 eye, in vec3 worldVertex, out vec3 extinction, out vec3 inScattering )
{
float viewDist = length(eye-worldVertex);
float depth = max(osgOcean_WaterHeight-worldVertex.z, 0.0);
extinction = exp(-osgOcean_UnderwaterAttenuation*viewDist*2.0);
// Need to compute accurate kd constant.
// const vec3 kd = vec3(0.001, 0.001, 0.001);
inScattering = osgOcean_UnderwaterDiffuse.rgb * (1.0-extinction*exp(-depth*vec3(0.001)));
}
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0*vec4(16.0,16.0,1.0,1.0);
gl_TexCoord[1] = gl_MultiTexCoord0*vec4(20.0,20.0,1.0,1.0);
gl_TexCoord[2] = gl_MultiTexCoord0*vec4(25.0,25.0,1.0,1.0);
vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;
vec3 vertex = vec3(ecPosition);
vEyeVec = -vertex;
vec3 n = normalize(gl_NormalMatrix * gl_Normal);
vec3 t = normalize(gl_NormalMatrix * aTangent);
vec3 b = cross(n, t);
vec3 tmpVec = vec3(gl_LightSource[0].position.xyz);
tmpVec = normalize(tmpVec);
vLightDir.x = dot(tmpVec, t);
vLightDir.y = dot(tmpVec, b);
vLightDir.z = dot(tmpVec, n);
tmpVec = -vertex;
vEyeVec.x = dot(tmpVec, t);
vEyeVec.y = dot(tmpVec, b);
vEyeVec.z = dot(tmpVec, n);
gl_Position = ftransform();
gl_ClipVertex = ecPosition;
gl_FogFragCoord = gl_Position.z;
float inv = 1.0 / ( uHeightRange.y - (uHeightRange.x+65.0) );
vUnitHeight = inv * (gl_Vertex.z - (uHeightRange.x+65.0));
vWorldVertex = (osg_ViewMatrixInverse*gl_ModelViewMatrix) * gl_Vertex;
if( osgOcean_EnableUnderwaterScattering )
{
computeScattering( osgOcean_Eye, vWorldVertex.xyz, vExtinction, vInScattering );
}
// Generate shadow map coords
gl_TexCoord[7].s = dot( ecPosition, gl_EyePlaneS[7] );
gl_TexCoord[7].t = dot( ecPosition, gl_EyePlaneT[7] );
gl_TexCoord[7].p = dot( ecPosition, gl_EyePlaneR[7] );
gl_TexCoord[7].q = dot( ecPosition, gl_EyePlaneQ[7] );
gl_Position = ftransform();
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 363 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 528 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 559 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 568 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 286 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@ -1,72 +0,0 @@
/*
* 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 <osg/Geometry>
#include <osg/Math>
namespace osgOcean
{
class Cylinder : public osg::Geometry
{
protected:
osg::ref_ptr<osg::Vec4Array> _colorArray;
float _radius;
float _height;
unsigned _steps;
bool _hasTop;
bool _hasBottom;
public:
Cylinder( void );
Cylinder( float radius, float height, unsigned int steps, bool hasTop, bool hasBottom );
Cylinder( const Cylinder& copy, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY );
protected:
virtual ~Cylinder(void);
public:
virtual void build( float radius, float height, unsigned int steps, bool top, bool bottom );
virtual void build( void );
void setColor(const osg::Vec4f& color);
inline const float getRadius( void ) const{
return _radius;
}
inline const float getHeight( void ) const{
return _height;
}
inline const unsigned getSteps( void ) const{
return _steps;
}
inline const bool hasTop( void ) const{
return _hasTop;
}
inline const bool hasBottom( void ) const{
return _hasBottom;
}
};
}

View File

@ -1,85 +0,0 @@
/*
* 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/TextureRectangle>
namespace osgOcean
{
class OSGOCEAN_EXPORT DistortionSurface : public osg::Geode
{
public:
DistortionSurface( void );
DistortionSurface( const osg::Vec3f& corner, const osg::Vec2f& dims, osg::TextureRectangle* texture );
DistortionSurface( const DistortionSurface &copy,
const osg::CopyOp &copyop = osg::CopyOp::SHALLOW_COPY );
virtual const char* libraryName() const { return "osgOcean"; }
virtual const char* className() const { return "DistortionSurface"; }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const DistortionSurface*>(obj) != 0; }
void build( const osg::Vec3f& corner, const osg::Vec2f& dims, osg::TextureRectangle* texture );
void update(void);
private:
float _angle;
protected:
~DistortionSurface( void ){};
/**
* Add the default resource paths to osgDB::Registry.
* Checks if already present.
* paths: resources/textures and resources/shaders.
*/
void addResourcePaths(void);
private:
void update(const double& dt);
osg::Program* createShader(void);
private:
// ---------------------------------------------
// Callback declarations
// ---------------------------------------------
class DistortionDataType : public osg::Referenced
{
private:
DistortionSurface& _surface;
double _oldTime;
double _newTime;
public:
DistortionDataType( DistortionSurface& surface );
void update( const double& time );
};
class DistortionCallback: public osg::NodeCallback
{
public:
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
};
};
}

View File

@ -1,52 +0,0 @@
/*
* 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.
*/
#ifndef OSGOCEAN_EXPORT_
#define OSGOCEAN_EXPORT_ 1
#if defined(_MSC_VER)
#pragma warning( disable : 4121 )
#pragma warning( disable : 4244 )
#pragma warning( disable : 4251 )
#pragma warning( disable : 4267 )
#pragma warning( disable : 4275 )
#pragma warning( disable : 4290 )
#pragma warning( disable : 4786 )
#pragma warning( disable : 4305 )
#pragma warning( disable : 4996 )
#endif
#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) || defined( __BCPLUSPLUS__)
# if defined( OSG_LIBRARY_STATIC )
# define OSGOCEAN_EXPORT
# elif defined( OSGOCEAN_LIBRARY )
# define OSGOCEAN_EXPORT __declspec(dllexport)
# else
# define OSGOCEAN_EXPORT __declspec(dllimport)
# endif
#else
# define OSGOCEAN_EXPORT
#endif
/**
\namespace osgOcean
Some comment about what osgOcean is
*/
#endif

View File

@ -1,187 +0,0 @@
/*
* 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 <osgOcean/FFTOceanTechnique>
#include <osgOcean/MipmapGeometry>
#include <osgOcean/OceanTile>
#include <osg/Timer>
#include <osg/NodeCallback>
#include <osgUtil/CullVisitor>
#include <osg/Program>
namespace osgOcean
{
/**
* Creates and manages the ocean surface geometry and rendering.
* Uses a modified geomipmapping algorithm to provide level of detail.
* LOD is managed automatically within the update and cull traversals.
*/
class OSGOCEAN_EXPORT FFTOceanSurface : public FFTOceanTechnique
{
private:
unsigned int _totalPoints; /**< Total number of points on width/height. */
unsigned int _numVertices; /**< Total number of vertices in array. */
unsigned int _newNumVertices; /**< Number of vertices after updateMipmaps is called */
osg::ref_ptr<osg::Vec3Array> _activeVertices; /**< Active vertex buffer. */
osg::ref_ptr<osg::Vec3Array> _activeNormals; /**< Active normal buffer. */
std::vector< std::vector<OceanTile> > _mipmapData; /**< Wave tile data. */
std::vector< std::vector< osg::ref_ptr<MipmapGeometry> > > _mipmapGeom; /**< Geometry tiles. */
public:
FFTOceanSurface(unsigned int FFTGridSize = 64,
unsigned int resolution = 256,
unsigned int numTiles = 17,
const osg::Vec2f& windDirection = osg::Vec2f(1.1f, 1.1f),
float windSpeed = 12.f,
float depth = 1000.f,
float reflectionDamping = 0.35f,
float waveScale = 1e-8f,
bool isChoppy = true,
float choppyFactor = -2.5f,
float animLoopTime = 10.f,
unsigned int numFrames = 256 );
FFTOceanSurface( const FFTOceanSurface& copy,
const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY );
virtual const char* libraryName() const { return "osgOcean"; }
virtual const char* className() const { return "FFTOceanSurface"; }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const FFTOceanSurface*>(obj) != 0; }
protected:
~FFTOceanSurface(void);
public:
float getSurfaceHeightAt(float x, float y, osg::Vec3f* normal = NULL);
/**
* Checks for mipmap or frame changes and updates the geometry accordingly.
* Will rebuild state or geometry if found to be dirty.
*/
void update( unsigned int frame, const double& dt, const osg::Vec3f& eye );
/**
* Sets up geometry and mipmaping data.
* Forces stateset rebuid.
*/
void build( void );
private:
/**
* Creates ocean surface stateset.
* Loads shaders and adds uniforms and textures;
*/
void initStateSet( void );
/**
* Computes the ocean FFTs and stores vertices/normals for mipmap levels.
*/
void computeSea( unsigned int totalFrames );
/**
* Sets up with the ocean surface with mipmap geometry.
*/
void createOceanTiles( void );
/**
* Computes and assigns mipmap primitives to the geometry.
*/
void computePrimitives( void );
/**
* Copies vertices needs for the tiles into _activeVertices array.
*/
void computeVertices( unsigned int frame );
/**
* Checks for any changes in mipmap resolution based on eye position.
* @return true if any updates have occured.
*/
bool updateMipmaps( const osg::Vec3f& eye, unsigned int frame );
/**
* Adds primitives for main body of vertices.
*/
void addMainBody( MipmapGeometry* cTile );
/**
* Adds primitives for the right skirt.
*/
void addRightBorder ( MipmapGeometry* cTile, MipmapGeometry* xTile );
/**
* Adds primitives for the bottom skirt.
*/
void addBottomBorder( MipmapGeometry* cTile, MipmapGeometry* yTile );
/**
* Adds primitives for the corner piece.
*/
void addCornerPatch( MipmapGeometry* cTile, MipmapGeometry* xTile, MipmapGeometry* yTile, MipmapGeometry* xyTile );
/**
* Adds primitives for main body of the lowest resolution tile (2x2 vertices).
* This is a special case treated similar to a corner piece.
*/
void addMaxDistMainBody( MipmapGeometry* cTile, MipmapGeometry* xTile, MipmapGeometry* yTile, MipmapGeometry* xyTile );
/**
* Adds primitives for edge of the lowest resolution tile (2x2 vertices).
*/
void addMaxDistEdge( MipmapGeometry* cTile, MipmapGeometry* xTile, MipmapGeometry* yTile );
/**
* Compute noise coordinates for the fragment shader.
* @param noiseSize Size of noise tile (m).
* @param movement Number of tiles moved x,y.
* @param speed Speed of movement(m/s).
* @parem time Simulation Time.
*/
osg::Vec3f computeNoiseCoords(float noiseSize, const osg::Vec2f& movement, float speed, float time);
/**
* Creates a custom DOT3 noise map for the ocean surface.
* This will execute an FFT to generate a height field from which the normal map is generated.
* Default behaviour is to create a normal map using the params from the ocean geometry setup.
*/
osg::ref_ptr<osg::Texture2D> createNoiseMap( unsigned int FFTSize,
const osg::Vec2f& windDir,
float windSpeed,
float waveScale,
float tileResolution );
/**
* Convenience method for retrieving mipmap geometry from _oceanGeom.
*/
inline MipmapGeometry* getTile( unsigned int x, unsigned int y ){
return _mipmapGeom.at(y).at(x).get();
}
/**
* Convenience method for loading the ocean shader.
* @return NULL if shader files were not found
*/
osg::Program* createShader(void);
};
}// namespace

View File

@ -1,140 +0,0 @@
/*
* 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 <osgOcean/FFTOceanTechnique>
#include <osgOcean/MipmapGeometryVBO>
#include <osg/Timer>
#include <osg/NodeCallback>
#include <osgUtil/CullVisitor>
#include <osg/Program>
namespace osgOcean
{
/**
* Creates and manages the ocean surface geometry and rendering.
* Uses a modified geomipmapping algorithm to provide level of detail.
* LOD is managed automatically within the update and cull traversals.
*/
class OSGOCEAN_EXPORT FFTOceanSurfaceVBO : public FFTOceanTechnique
{
private:
osg::ref_ptr<osg::Vec3Array> _masterVertices;
osg::ref_ptr<osg::Vec3Array> _masterNormals;
std::vector< OceanTile > _mipmapData;
std::vector< std::vector< osg::ref_ptr<MipmapGeometryVBO> > > _mipmapGeom; /**< Geometry tiles. */
public:
FFTOceanSurfaceVBO(unsigned int FFTGridSize = 64,
unsigned int resolution = 256,
unsigned int numTiles = 17,
const osg::Vec2f& windDirection = osg::Vec2f(1.1f, 1.1f),
float windSpeed = 12.f,
float depth = 1000.f,
float reflectionDamping = 0.35f,
float waveScale = 1e-8f,
bool isChoppy = true,
float choppyFactor = -2.5f,
float animLoopTime = 10.f,
unsigned int numFrames = 256 );
FFTOceanSurfaceVBO( const FFTOceanSurfaceVBO& copy,
const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY );
virtual const char* libraryName() const { return "osgOcean"; }
virtual const char* className() const { return "FFTOceanSurfaceVBO"; }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const FFTOceanSurfaceVBO*>(obj) != 0; }
protected:
~FFTOceanSurfaceVBO(void);
public:
float getSurfaceHeightAt(float x, float y, osg::Vec3f* normal = NULL);
/**
* Checks for mipmap or frame changes and updates the geometry accordingly.
* Will rebuild state or geometry if found to be dirty.
*/
void update( unsigned int frame, const double& dt, const osg::Vec3f& eye );
/**
* Sets up geometry and mipmaping data.
* Forces stateset rebuid.
*/
void build( void );
void setMinDistances(std::vector<float> &minDistances);
private:
/**
* Creates ocean surface stateset.
* Loads shaders and adds uniforms and textures;
*/
void initStateSet( void );
/**
* Computes the ocean FFTs and stores vertices/normals for mipmap levels.
*/
void computeSea( unsigned int totalFrames );
/**
* Sets up with the ocean surface with mipmap geometry.
*/
void createOceanTiles( void );
void updateVertices(unsigned int frame);
bool updateLevels(const osg::Vec3f& eye);
/**
* Compute noise coordinates for the fragment shader.
* @param noiseSize Size of noise tile (m).
* @param movement Number of tiles moved x,y.
* @param speed Speed of movement(m/s).
* @parem time Simulation Time.
*/
osg::Vec3f computeNoiseCoords(float noiseSize, const osg::Vec2f& movement, float speed, double time);
/**
* Creates a custom DOT3 noise map for the ocean surface.
* This will execute an FFT to generate a height field from which the normal map is generated.
* Default behaviour is to create a normal map using the params from the ocean geometry setup.
*/
osg::ref_ptr<osg::Texture2D> createNoiseMap( unsigned int FFTSize,
const osg::Vec2f& windDir,
float windSpeed,
float waveScale,
float tileResolution );
/**
* Convenience method for retrieving mipmap geometry from _oceanGeom.
*/
inline MipmapGeometryVBO* getTile( unsigned int x, unsigned int y ){
return _mipmapGeom.at(y).at(x).get();
}
/**
* Convenience method for loading the ocean shader.
* @return NULL if shader files were not found
*/
osg::Program* createShader(void);
};
}// namespace

View File

@ -1,416 +0,0 @@
/*
* 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 <osgOcean/OceanTechnique>
#include <osgOcean/FFTSimulation>
#include <osgOcean/OceanTile>
#include <osg/Texture2D>
#include <osg/TextureCubeMap>
#include <osgDB/ReadFile>
#include <vector>
namespace osgOcean
{
class OSGOCEAN_EXPORT FFTOceanTechnique : public OceanTechnique
{
protected:
unsigned int _tileSize; /**< Size of FFT grid 2^n ie 128,64,32 etc. */
unsigned int _noiseTileSize; /**< Size of Noise FFT grid */
unsigned int _tileResolution; /**< Size of tile in world width/height. */
float _tileResInv; /**< 1 / _tileResoltion; */
unsigned int _noiseTileRes; /**< Size of noise tile in world width/height. */
unsigned int _numTiles; /**< Number of tiles on width/height. */
float _pointSpacing; /**< Spacing between points in real world. */
osg::Vec2f _windDirection; /**< Direction of wind. */
osg::Vec2f _noiseWindDir; /**< Direction of wind for noise tile. */
float _windSpeed; /**< Wind speed m/s */
float _noiseWindSpeed; /**< Wind speed for noise tile m/s */
float _waveScale; /**< Wave scale modifier. */
float _noiseWaveScale; /**< Wave scale modifier for noise tile. */
float _depth; /**< Depth (m). */
float _reflDampFactor; /**< Dampen waves going against the wind */
float _cycleTime; /**< Time before the ocean tiles loop. */
float _choppyFactor; /**< Amount of chop to add. */
bool _isChoppy; /**< Enable choppy waves generation. */
bool _isEndless; /**< Set whether the ocean is of fixed size. */
osg::Vec2f _startPos; /**< Start position of the surface ( -half width, half height ). */
const float _THRESHOLD; /**< Pixel threshold. */
const float _VRES; /**< Vertical resolution. */
float _C; /**< C constant. */
unsigned int _numLevels; /**< Number of mipmap levels. */
unsigned int _oldFrame; /**< Last ocean frame number. */
const unsigned int _NUMFRAMES; /**< Number of frames in the animation cycle */
osg::Vec4f _lightColor; /**< Color of the sun */
osg::Vec3f _waveTopColor; /**< Color for the upwelling shading. */
osg::Vec3f _waveBottomColor; /**< Color for the upwelling shading. */
bool _useCrestFoam; /**< Crest foam flag. */
float _foamCapTop; /**< Maximum height for foam caps. */
float _foamCapBottom; /**< Minimum height for foam caps. */
float _averageHeight; /**< Average height over the total tiles. */
float _maxHeight; /**< Maximum height over the total tiles. */
float _fresnelMul; /**< Fresnel multiplier uniform, typical values: (0.5-0.8). */
bool _isStateDirty;
std::vector<float> _minDist; /**< Minimum distances used for mipmap selection */
osg::ref_ptr<osg::TextureCubeMap> _environmentMap; /**< Cubemap used for refractions/reflections */
enum TEXTURE_UNITS{ ENV_MAP=0,REFLECT_MAP=1,REFRACT_MAP=2,REFRACTDEPTH_MAP=3,NORMAL_MAP=4,FOG_MAP=5,FOAM_MAP=6 };
public:
FFTOceanTechnique(unsigned int FFTGridSize,
unsigned int resolution,
unsigned int numTiles,
const osg::Vec2f& windDirection,
float windSpeed,
float depth,
float reflectionDamping,
float waveScale,
bool isChoppy,
float choppyFactor,
float animLoopTime,
unsigned int numFrames );
FFTOceanTechnique( const FFTOceanTechnique& copy,
const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY );
virtual const char* libraryName() const { return "osgOcean"; }
virtual const char* className() const { return "FFTOceanTechnique"; }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const FFTOceanTechnique*>(obj) != 0; }
protected:
virtual ~FFTOceanTechnique(void);
public:
/**
* Returns the height at the given point (in local space). If the
* address of a Vec3f is passed in the normal argument, the normal at
* that position will be calculated and stored in it.
*/
virtual float getSurfaceHeightAt(float x, float y, osg::Vec3f* normal = NULL);
/**
* Checks for mipmap or frame changes and updates the geometry accordingly.
* Will rebuild state or geometry if found to be dirty.
*/
virtual void update( unsigned int frame, const double& dt, const osg::Vec3f& eye )=0;
protected:
/**
* Convenience method for creating a Texture2D based on an image file path.
*/
osg::Texture2D* createTexture( const std::string& path, osg::Texture::WrapMode wrap );
// -------------------------------------------------------------
// inline accessors/mutators
// -------------------------------------------------------------
public:
inline void setEnvironmentMap( osg::TextureCubeMap* environmentMap ){
_environmentMap = environmentMap;
_isStateDirty = true;
}
inline void setWaveTopColor( const osg::Vec3f& color ){
_waveTopColor = color;
_isStateDirty = true;
}
inline const osg::Vec3f& getWaveTopColor( void ) const {
return _waveTopColor;
}
inline void setWaveBottomColor( const osg::Vec3f& color ){
_waveBottomColor = color;
_isStateDirty = true;
}
inline const osg::Vec3f& getWaveBottomColor( void ) const {
return _waveTopColor;
}
inline void setLightColor( const osg::Vec4f& color ){
_lightColor = color;
_isStateDirty = true;
}
inline osg::Vec4f getLightColor() const{
return _lightColor;
}
inline void enableCrestFoam( bool enable ){
_useCrestFoam = enable;
_isStateDirty = true;
}
inline bool isCrestFoamEnabled() const{
return _useCrestFoam;
}
inline void setFoamBottomHeight( float height ){
_foamCapBottom = height;
_isStateDirty = true;
}
inline void setFoamTopHeight( float height ){
_foamCapTop = height;
_isStateDirty = true;
}
inline void setFresnelMultiplier( float mul ){
_fresnelMul = mul;
_isStateDirty = true;
}
/**
* Enable/Disable endless ocean.
* Dirties geometry by default, pass dirty=false to dirty yourself later.
*/
inline void enableEndlessOcean( bool enable, bool dirty = true ){
_isEndless = enable;
if (dirty) _isDirty = true;
}
inline bool isEndlessOceanEnabled() const{
return _isEndless;
}
/** Returns the average height over the whole surface (in local space)*/
inline float getSurfaceHeight( void ) const {
return _averageHeight;
}
/** Returns the maximum height over the whole surface (in local space)*/
inline float getMaximumHeight( void ) const {
return _maxHeight;
}
/**
* Enable/Disable choppy wave geometry.
* Dirties geometry by default, pass dirty=false to dirty yourself later.
*/
inline void setIsChoppy(bool isChoppy, bool dirty = true){
_isChoppy = isChoppy;
if (dirty) _isDirty = true;
}
inline bool isChoppy(void) const{
return _isChoppy;
}
/**
* Change the choppy factor.
* Dirties geometry by default, pass dirty=false to dirty yourself later.
*/
inline void setChoppyFactor(float choppyFactor, bool dirty = true){
_choppyFactor = choppyFactor;
if (dirty) _isDirty = true;
}
inline float getChoppyFactor() const{
return _choppyFactor;
}
/**
* Tweak the wave scale factor.
* Typically a very small value: ~1e-8.
* Dirties geometry by default, pass dirty=false to dirty yourself later.
*/
inline void setWaveScaleFactor( float scale, bool dirty = true ){
_waveScale = scale;
if (dirty) _isDirty = true;
}
inline float getWaveScaleFactor( void ) const {
return _waveScale;
}
/**
* Change the wind direction.
* Dirties geometry by default, pass dirty=false to dirty yourself later.
*/
inline void setWindDirection(const osg::Vec2f& windDir, bool dirty = true){
_windDirection = windDir;
if (dirty) _isDirty = true;
}
inline osg::Vec2f getWindDirection() const{
return _windDirection;
}
/**
* Change the wind speed.
* Dirties geometry by default, pass dirty=false to dirty yourself later.
*/
inline void setWindSpeed(const float windSpeed, bool dirty = true){
_windSpeed = windSpeed;
if (dirty) _isDirty = true;
}
inline float getWindSpeed() const{
return _windSpeed;
}
inline void setDepth(const float depth, bool dirty = true){
_depth = depth;
if (dirty) _isDirty = true;
}
inline float getDepth() const{
return _depth;
}
/**
* Sets the parameters for a custom noise map for use in the fragment shader.
* @param FFTSize is the size of the FFT grid that will be used and thus the size of the resulting texture. Values must be 2^n.
* Dirties the stateset.
*/
inline void setNoiseMapParams( unsigned int FFTSize,
const osg::Vec2f& windDir,
float windSpeed,
float waveScale,
float tileResolution )
{
_noiseTileSize = FFTSize;
_noiseWindDir = windDir;
_noiseWindSpeed = windSpeed;
_noiseWaveScale = waveScale;
_noiseTileRes = tileResolution;
_isStateDirty = true;
}
/**
* Linear interpolation of 3 RGBA colors.
* @return interpolated color (vec4)
*/
inline osg::Vec4f colorLerp (const osg::Vec4f& c0, const osg::Vec4f& c1, const osg::Vec4f& c2) const
{
return osg::Vec4f(
c1[0]*(1-c0[0]) + c2[0]*c0[0],
c1[1]*(1-c0[1]) + c2[1]*c0[1],
c1[2]*(1-c0[2]) + c2[2]*c0[2],
c1[3]*(1-c0[3]) + c2[3]*c0[3]
);
}
protected:
// --------------------------------------------------------
// OceanDataType
// --------------------------------------------------------
/**
* Data structure to store data needed for animation callback.
*/
class OSGOCEAN_EXPORT OceanDataType: public osg::Referenced
{
private:
osgOcean::FFTOceanTechnique& _oceanSurface;
const unsigned int _NUMFRAMES;
osg::Vec3f _eye;
double _time;
const unsigned int _FPS;
double _msPerFrame;
unsigned int _frame;
double _oldTime;
double _newTime;
public:
OceanDataType( FFTOceanTechnique& ocean, unsigned int numFrames, unsigned int fps );
OceanDataType( const OceanDataType& copy, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY );
inline void setEye( const osg::Vec3f& eye ){ _eye = eye; }
void updateOcean( double simulationTime );
};
public:
// --------------------------------------------------------
// OceanAnimationCallback
// --------------------------------------------------------
/**
* Cull/Update Animation callback. Override its operator() to customize
* how the ocean is updated.
*/
class OSGOCEAN_EXPORT OceanAnimationCallback: public osg::NodeCallback
{
public:
/**
* Override this to be able to call update() with specified dt.
* Don't forget to call traverse(node, nv); as for any update
* callback in OSG.
*/
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
protected:
/**
* Pass simulationTime < 0.0 to update with the real elapsed time,
* else will use specified simulationTime in seconds.
* @see FFTOceanSurface::update();
*/
void update(osg::Node* node, osg::NodeVisitor* nv, double simulationTime = -1.0);
};
/**
* Set a different animation callback than the default one.
*/
void setOceanAnimationCallback(OceanAnimationCallback* callback);
/**
* Get the animation callback.
*/
OceanAnimationCallback* getOceanAnimationCallback();
// --------------------------------------------------------
// EventHandler
// --------------------------------------------------------
/**
* This class overrides OceanTechnique::EventHandler to provide
* support for manipulating this particular subclass of
* OceanTechnique. Note that the method signatures are identical,
* and that the FFTOceanSurface will be accessed through the base
* class OceanTechnique pointer.
*/
class EventHandler : public OceanTechnique::EventHandler
{
public:
EventHandler(FFTOceanTechnique* oceanSurface);
virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa, osg::Object* object, osg::NodeVisitor* nv);
virtual void getUsage(osg::ApplicationUsage& usage) const;
protected:
bool _autoDirty;
};
virtual OceanTechnique::EventHandler* getEventHandler()
{
if (!_eventHandler.valid())
_eventHandler = new FFTOceanTechnique::EventHandler(this);
return _eventHandler.get();
}
};
}

View File

@ -1,81 +0,0 @@
/*
* 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/Vec2f>
#include <osg/Array>
namespace osgOcean
{
/** Implementation of Jerry Tessendorf's FFT Ocean Simulation
* For more information see his paper "Simulating Ocean Water"
* http://graphics.ucsd.edu/courses/rendering/2005/jdewall/tessendorf.pdf
*/
class OSGOCEAN_EXPORT FFTSimulation
{
private:
// Implementation hidden so that clients do not need to depend on the
// FFT library's headers. All calls to FFTSimulation are delegated to
// the private Implementation class.
class Implementation;
Implementation* _implementation;
public:
/** Constructor.
* Provides default parameters for a calm ocean surface.
* Computes base amplitudes and initialises FFT plans and arrays.
* @param fourierSize Size of FFT grid 2^n ie 128,64,32 etc.
* @param windDir Direction of wind.
* @param windSpeed Speed of wind (m/s).
* @param waveScale Wave height modifier.
* @param loopTime Time for animation to repeat (secs).
*/
FFTSimulation(
int fourierSize = 64,
const osg::Vec2f& windDir = osg::Vec2f(1.0f, 1.0f),
float windSpeed = 12.f,
float depth = 1000.f,
float reflectionDamping = 0.35f,
float waveScale = 1e-9,
float tileRes = 256.f,
float loopTime = 10.f
);
/** Destructor.
* Cleans up FFT plans and arrays.
*/
~FFTSimulation(void);
/** Set the current time and computes the current fourier amplitudes */
void setTime(float time);
/** Compute the current height field.
* Executes an FFT transform to convert the current fourier amplitudes to real height values.
* @param heights must be created before passing in. Function will resize and overwrite the contents with current data.
*/
void computeHeights( osg::FloatArray* heights ) const;
/** Compute the (x,y) displacements for choppy wave effect
* Executes two FFT transforms to convert the current fourier amplitudes to real x,y displacements
* @param scaleFactor defines the magnitude of the displacements. Typically a negative value ( -3.0 > val < -1.0 ).
* @param waveDisplacements must be created before passing in. Function will resize and overwrite the contents with the computed displacements.
*/
void computeDisplacements( const float& scaleFactor, osg::Vec2Array* waveDisplacements ) const;
};
}

View File

@ -1,157 +0,0 @@
/*
* 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/ScreenAlignedQuad>
#include <osg/Geode>
#include <osg/Uniform>
#include <osg/Program>
#include <osg/BlendFunc>
#include <osg/Texture>
#include <osgUtil/CullVisitor>
#include <string>
namespace osgOcean
{
/**
* Screen aligned quad used to display the god ray frame buffer.
*/
class OSGOCEAN_EXPORT GodRayBlendSurface : public osg::Geode
{
private:
osg::Vec3 _HGg; /**< Controls degree of forward light scattering. */
osg::Vec3f _sunDir; /**< sun direction */
float _intensity; /**< Intensity tweak */
osg::ref_ptr<osg::StateSet> _stateset;
osg::ref_ptr<osg::Vec3Array> _normalArray; /**< Stores the ray vectors for the view direction at the corners of the screen aligned quad */
public:
/**
* Default Constructor.
*/
GodRayBlendSurface( void );
/**
* Constructor.
* Calls build().
*/
GodRayBlendSurface( const osg::Vec3f& corner, const osg::Vec2f& dims, osg::TextureRectangle* texture );
GodRayBlendSurface( const GodRayBlendSurface &copy,
const osg::CopyOp &copyop = osg::CopyOp::SHALLOW_COPY );
virtual const char* libraryName() const { return "osgOcean"; }
virtual const char* className() const { return "GodRayBlendSurface"; }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const GodRayBlendSurface*>(obj) != 0; }
protected:
~GodRayBlendSurface(void){};
public:
/**
* Removes all drawables and creates and adds quad geometry, program and stateset.
*/
void build( const osg::Vec3f& corner, const osg::Vec2f& dims, osg::TextureRectangle* texture );
/**
* Updates the _normalArray with new view vectors.
*/
void update( const osg::Matrixd& view, const osg::Matrixd& proj );
/**
* Sets the degree of forward light scattering.
*/
inline void setEccentricity( float g )
{
_HGg = osg::Vec3f(1.f-(g*g), 1.f+(g*g), 2.f*g);
if( _stateset.valid() )
_stateset->getUniform("osgOcean_HGg")->set(_HGg);
}
/**
* Blend intensity tweak.
*/
inline void setIntensity( float i )
{
_intensity = i;
if( _stateset.valid() )
_stateset->getUniform("osgOcean_Intensity")->set(_intensity);
}
/**
* Set sun direction
*/
inline void setSunDirection( const osg::Vec3f& sunDir )
{
_sunDir = sunDir;
if( _stateset.valid() )
_stateset->getUniform("osgOcean_SunDir")->set(_sunDir);
}
private:
/**
* Loads the shaders and returns program.
*/
osg::Program* createShader(void);
// ---------------------------------------------
// Callback declarations
// ---------------------------------------------
protected:
/**
* Animation data structure.
*/
class GodRayBlendDataType: public osg::Referenced
{
private:
GodRayBlendSurface& _blendSurface;
osg::Matrixd _view;
osg::Matrixd _projection;
public:
GodRayBlendDataType( GodRayBlendSurface& godRays );
GodRayBlendDataType( const GodRayBlendDataType& copy,
const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY );
inline void setViewMatrix( const osg::Matrixd& viewMatrix ){
_view=viewMatrix;
}
inline void setProjMatrix( const osg::Matrixd& projMatrix ){
_projection=projMatrix;
}
void update( void );
};
/**
* Update/Cull animation callback.
* Cull callback stores view and projection matrices needed for animation.
* Update callback calls parents update function.
* @see GodRayBlendSurface::update().
*/
class GodRayBlendCallback: public osg::NodeCallback
{
public:
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
};
};
}

View File

@ -1,217 +0,0 @@
/*
* 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
};
};
}

View File

@ -1,120 +0,0 @@
/*
* 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/Geometry>
namespace osgOcean
{
/**
* Stores mipmap geometry and associated mipmap level data.
*/
class OSGOCEAN_EXPORT MipmapGeometry : public osg::Geometry
{
public:
enum BORDER_TYPE{ BORDER_X, BORDER_Y, BORDER_XY, BORDER_NONE };
private:
unsigned int _level; /**< Mipmap level 0 is highest level. */
unsigned int _numLevels; /**< Number of mipmap levels in use. */
unsigned int _resolution; /**< Tile size (n^2). */
unsigned int _rowLen; /**< Length of rows. */
unsigned int _colLen; /**< Length of cols. */
unsigned int _startIdx; /**< Start position in vertex array. */
BORDER_TYPE _border; /**< is the patch a border piece. */
public:
/**
* Default constructor.
* Initialises all values to 0.
*/
MipmapGeometry( void );
/**
* Constructor.
* @param level Tile level.
* @param numLevels Number of levels in the mipmap sequence.
* @param startIdx The position of the first vertex in the main vertex array.
* @param border Tiles border type.
*/
MipmapGeometry( unsigned int level,
unsigned int numLevels,
unsigned int startIdx,
BORDER_TYPE border );
MipmapGeometry( const MipmapGeometry& copy, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY );
virtual const char* libraryName() const { return "osgOcean"; }
virtual const char* className() const { return "MipmapGeometry"; }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const MipmapGeometry*>(obj) != 0; }
protected:
~MipmapGeometry( void );
public:
inline unsigned int getLevel( void ) const {
return _level;
}
inline unsigned int getResolution( void ) const {
return _resolution;
}
inline unsigned int getRowLen( void ) const {
return _rowLen;
}
inline unsigned int getColLen( void ) const {
return _colLen;
}
inline BORDER_TYPE getBorder( void ) const {
return _border;
}
/**
* Sets the level of the mipmap tile.
* Automatically updates the resolution, row and column lengths of the tile.
*/
inline void setLevel( unsigned int level )
{
_level = level;
_resolution = level != (_numLevels-1) ? 2 << (_numLevels-(level+2) ) : 1;
_rowLen = _border==BORDER_X || _border==BORDER_XY ? _resolution+1 : _resolution;
_colLen = _border==BORDER_Y || _border==BORDER_XY ? _resolution+1 : _resolution;
}
inline const PrimitiveSetList& getPrimitives( void ) const {
return _primitives;
}
inline unsigned int getIdx( void ) const {
return _startIdx;
}
inline void setIdx( unsigned int idx ) {
_startIdx = idx;
}
inline unsigned int getIndex( unsigned int c, unsigned r )
{
return _startIdx + (c + r * _rowLen);
}
};
}

View File

@ -1,201 +0,0 @@
/*
* 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 <osg/Geometry>
#include <osg/Version>
#include <assert.h>
namespace osgOcean
{
/**
* Custom geometry type used to display mipmapped ocean tiles.
* Will compute and update primitive indices by calling updatePrimitives().
*/
class MipmapGeometryVBO : public osg::Geometry
{
public:
int _numLevels; /**< Number of mipmap levels in use. */
int _level; /**< Mipmap level - 0 is highest level. */
int _levelRight; /**< Level of the tile to the right */
int _levelBelow; /**< Level of the tile below */
unsigned int _maxResolution; /**< Tile size at level 0 */
unsigned int _rowLen; /**< number of elements in a row (_resolution+1) */
unsigned int _resolution; /**< Tile size (n^2). */
unsigned int _resRight; /**< Size of the tile to the right */
unsigned int _resBelow; /**< Size of the tile below */
float _worldSize; /**< Size of the tile in metres */
osg::Vec3f _offset; /**< Tile position in world coords */
PrimitiveSetList _mainBody; /**< Storage for main body primitives */
PrimitiveSetList _rightBorder; /**< Storage for right border primitives */
PrimitiveSetList _belowBorder; /**< Storage for below border primitives */
PrimitiveSetList _cornerPiece; /**< Storage for corner primitives */
public:
/**
* Default constructor.
* Initialises all values to 0.
*/
MipmapGeometryVBO( void );
/**
* Constructor.
* @param numLevels Total number of mipmap levels in use.
* @param worldSize Size of tile in world coords (metres)
*/
MipmapGeometryVBO( unsigned int numLevels, float worldSize );
MipmapGeometryVBO( const MipmapGeometryVBO& copy, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY );
virtual const char* libraryName() const { return "osgOcean"; }
virtual const char* className() const { return "MipmapGeometryVBO"; }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const MipmapGeometryVBO*>(obj) != 0; }
/**
* Updates the tiles primitives if there has been a change in mipmap level.
* @return true if an update has occurred, false if no update was necessary.
*/
bool updatePrimitives( unsigned int level, unsigned int levelRight, unsigned int levelBelow );
inline void initialiseArrays( osg::Array* vertices, osg::Array* normals )
{
if( vertices && normals )
{
setVertexArray( vertices );
setNormalArray( normals );
}
}
protected:
~MipmapGeometryVBO( void );
private:
/**
* Add primitives for the main body
*/
void addMainBody( void );
void addZeroTile( void );
/**
* Add primitives for the bottom border
*/
void addBottomBorder( void );
/**
* Add primitives for the right border
*/
void addRightBorder( void );
/**
* Add primitives for the corner piece
*/
void addCornerPiece( void );
/**
* Add corner piece for a tile of resolution 1 - special case
*/
void addZeroCornerPiece(void);
/**
* Inserts the primitive component lists (border,corner,border) into the main primitive list.
*/
void assignPrimitives(void);
/**
* Checks to see if an update to the primitive set is required based on the position and level of the tile.
*/
bool checkPrimitives( unsigned int level, unsigned int levelRight, unsigned int levelBelow );
/**
* Computes the resolution of a tile based on its mipmap level ID.
*/
inline unsigned int calcResolution( unsigned level, unsigned numLevels ) const {
return level != (numLevels-1) ? 2 << (numLevels-(level+2) ) : 1;
}
/**
* Convenience method for getting the index of an element within the vertex array.
*/
inline unsigned int getIndex( unsigned c, unsigned r ){
int test = c+r*(_maxResolution+1);
assert( test < (int)((_maxResolution+1)*(_maxResolution+1)) );
return c+r*(_maxResolution+1);
}
public:
/**
* Rather than use standard computeBound() this computes the bounding box
* using the offset and the worldSize.
*/
#if OSG_VERSION_LESS_THAN(3,3,2)
osg::BoundingBox computeBound( void ) const;
#else
osg::BoundingBox computeBoundingBox( void ) const;
#endif
/**
* Set the tile offset for shader positioning.
* Calls dirtyBound() on its parents and recomputes recomputes
* the bounding box using a custom computeBound().
*/
inline void setOffset( const osg::Vec3f& offset ){
_offset = offset;
if( getColorArray() ){
osg::Vec4Array* colors = static_cast<osg::Vec4Array*>(getColorArray());
colors->at(0) = osg::Vec4f( _offset.x(), _offset.y(), _offset.z(), 1.f );
}
else{
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back( osg::Vec4f( _offset.x(), _offset.y(), _offset.z(), 1.f ) );
setColorArray(colors);
}
dirtyBound();
#if OSG_VERSION_LESS_THAN(3,3,2)
setBound( computeBound() );
#else
setBound( computeBoundingBox() );
#endif
}
/**
* Sets the level of the mipmap tile.
* Automatically updates the resolution of the tile.
*/
inline void setLevel( unsigned int level )
{
_level = level;
_resolution = calcResolution( level, _numLevels );
_rowLen = _resolution+1;
}
inline int getLevel( void ) const {
return _level;
}
inline int getResolution( void ) const {
return _resolution;
}
inline unsigned int getRowLen( void ) const {
return _rowLen;
}
};
}

View File

@ -1,872 +0,0 @@
/*
* 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 <osgOcean/OceanTechnique>
#include <osgOcean/GodRayBlendSurface>
#include <osgOcean/DistortionSurface>
#include <osgOcean/GodRays>
#include <osgOcean/SiltEffect>
#include <osgOcean/Cylinder>
#include <osg/Group>
#include <osg/Camera>
#include <osg/Texture2D>
#include <osg/TextureRectangle>
#include <osg/Uniform>
#include <osgUtil/CullVisitor>
#include <osg/MatrixTransform>
#include <osg/ClipNode>
#include <osg/ClipPlane>
#include <osgGA/GUIEventHandler>
#include <map>
namespace osgOcean
{
/**
* Controls the render passes required for the ocean scene effects.
* Uses a series of traversal masks to control which passes a child is subjected to.
* @note Requires an \c OceanTechnique to be added.
*/
class OSGOCEAN_EXPORT OceanScene : public osg::Group
{
public:
typedef std::set< osg::observer_ptr<osg::View> > ViewSet;
private:
osg::ref_ptr<OceanTechnique> _oceanSurface;
bool _isDirty;
bool _enableRefractions;
bool _enableReflections;
bool _enableGodRays;
bool _enableSilt;
bool _enableDOF;
bool _enableGlare;
bool _enableDistortion;
bool _enableUnderwaterScattering;
bool _enableDefaultShader;
bool _enableHeightmap;
osg::Vec2s _reflectionTexSize;
osg::Vec2s _refractionTexSize;
osg::Vec2s _screenDims;
int _reflectionUnit;
int _refractionUnit;
int _refractionDepthUnit;
int _heightmapUnit;
float _aboveWaterFogDensity;
osg::Vec4f _aboveWaterFogColor;
float _underwaterFogDensity;
osg::Vec4f _underwaterFogColor;
osg::Vec4f _underwaterDiffuse;
osg::Vec3f _underwaterAttenuation;
osg::Vec3f _sunDirection;
osg::ref_ptr<osg::Camera> _godrayPreRender;
osg::ref_ptr<osg::Camera> _godrayPostRender;
std::vector< osg::ref_ptr<osg::Camera> > _dofPasses;
std::vector< osg::ref_ptr<osg::Camera> > _glarePasses;
osg::ref_ptr<osg::StateSet> _dofStateSet;
osg::ref_ptr<osg::StateSet> _glareStateSet;
osg::ref_ptr<osg::StateSet> _globalStateSet;
osg::ref_ptr<osg::Program> _defaultSceneShader;
osg::ref_ptr<GodRayBlendSurface> _godRayBlendSurface;
osg::ref_ptr<DistortionSurface> _distortionSurface;
osg::ref_ptr<GodRays> _godrays;
osg::ref_ptr<osg::ClipNode> _siltClipNode;
osg::ref_ptr<osg::ClipNode> _reflectionClipNode;
unsigned int _reflectionSceneMask;
unsigned int _refractionSceneMask;
unsigned int _heightmapMask;
unsigned int _surfaceMask;
unsigned int _normalSceneMask;
unsigned int _siltMask;
unsigned int _lightID;
float _dofNear;
float _dofFar;
float _dofFarClamp;
float _dofFocus;
float _glareThreshold;
float _glareAttenuation;
float _eyeHeightReflectionCutoff;
float _eyeHeightRefractionCutoff;
float _surfaceHeight;
osg::ref_ptr<osg::MatrixTransform> _oceanTransform;
osg::ref_ptr<osg::MatrixTransform> _oceanCylinderMT;
osg::ref_ptr<Cylinder> _oceanCylinder;
ViewSet _viewsWithRTTEffectsDisabled;
struct ViewData : public osg::Referenced
{
/// Simple constructor zeroing all variables.
ViewData()
: _dirty( true )
, _cv( NULL )
, _oceanScene( NULL )
, _reflectionCamera(NULL)
, _refractionCamera(NULL)
, _heightmapCamera(NULL)
, _fog(NULL)
, _eyeAboveWaterPreviousFrame(true)
, _globalStateSet(NULL)
, _surfaceStateSet(NULL)
{ };
/// Method called upon ViewData instance to initialize internal variables
virtual void init( OceanScene* oceanScene, osgUtil::CullVisitor* cv );
virtual void updateStateSet( bool eyeAboveWater );
/// Method called by OceanScene to allow ViewData
/// do the hard work computing reflections/refractions for its associated view
virtual void cull( bool eyeAboveWater, bool surfaceVisible );
/// Dirty is called by parent OceanScene to force
/// update of resources after some of them were modified in parent scene
virtual void dirty( bool flag );
/// View's CullVisitor associated with this ViewData instance
osg::observer_ptr< osgUtil::CullVisitor > _cv;
/// Parent OceanScene
osg::observer_ptr< OceanScene > _oceanScene;
/// Mutex used to guard _dirty flag from override in case when parent technique calls
/// dirty() simultaneously with ViewData while it is updating resources inside init method.
OpenThreads::Mutex _mutex;
/// Dirty flag tells this instance to update its resources
bool _dirty;
osg::Matrixf _reflectionMatrix;
osg::ref_ptr<osg::Camera> _reflectionCamera;
osg::ref_ptr<osg::Camera> _refractionCamera;
osg::ref_ptr<osg::Camera> _heightmapCamera;
osg::ref_ptr<osg::Fog> _fog;
bool _eyeAboveWaterPreviousFrame;
osg::ref_ptr<osg::StateSet> _globalStateSet;
osg::ref_ptr<osg::StateSet> _surfaceStateSet;
friend class OceanScene;
};
/// Map of view dependent data per view cull visitor (CVs are used as indices)
/// ViewDependentShadowTechnique uses this map to find VieData for each cull vitior
typedef std::map< osg::observer_ptr< osgUtil::CullVisitor >,
osg::ref_ptr< ViewData > > ViewDataMap;
ViewDataMap _viewDataMap;
/// Mutex used to serialize accesses to ViewDataMap
OpenThreads::Mutex _viewDataMapMutex;
/// Return view dependent data for the cull visitor
OceanScene::ViewData * getViewDependentData( osgUtil::CullVisitor * cv );
/// Define view dependent data for the cull visitor
void setViewDependentData( osgUtil::CullVisitor * cv, OceanScene::ViewData * data );
ViewData * initViewDependentData( osgUtil::CullVisitor *cv, OceanScene::ViewData * vd );
// NOTE: Remember to add new variables to the copy constructor.
public:
OceanScene( void );
OceanScene( OceanTechnique* technique );
OceanScene( const OceanScene& copy, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY );
virtual const char* libraryName() const { return "osgOcean"; }
virtual const char* className() const { return "OceanScene"; }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const OceanScene*>(obj) != 0; }
/// Sets up statesets and render passes based on current settings
/// Called in the update traversal if dirty flag is set.
void init( void );
/// Check if the eye is above water or not.
bool isEyeAboveWater( const osg::Vec3& eye );
/// Set ocean surface height in world space (default is 0.0)
void setOceanSurfaceHeight(float height){
_surfaceHeight = height;
_oceanTransform->setMatrix(osg::Matrix::translate(0,0,_surfaceHeight - _oceanSurface->getSurfaceHeight()));
_isDirty = true;
}
/// Get ocean surface average height in world space.
double getOceanSurfaceHeight() const{
return _surfaceHeight + _oceanSurface->getSurfaceHeight();
}
/// Get height of given (x,y) point in world space. Optionally returns the normal.
float getOceanSurfaceHeightAt(float x, float y, osg::Vec3* normal = 0)
{
return _surfaceHeight +
_oceanSurface->getSurfaceHeightAt(x, y, normal);
}
/// Set the ocean surface world-space position. Note that the (x,y)
/// components of the translation are of no consequence if the ocean
/// surface is infinite, since the surface will follow the eye.
void setOceanSurfaceTransform(const osg::Matrix& transform)
{
_surfaceHeight = transform.getTrans().z();
_oceanTransform->setMatrix(osg::Matrix::translate(transform.getTrans().x(),
transform.getTrans().y(),
transform.getTrans().z() - _oceanSurface->getSurfaceHeight()));
_isDirty = true;
}
/// Returns the world-space position of the ocean surface. Note that
/// the (x,y) components of the translation are of no consequence if
/// the ocean surface is infinite, since the surface will follow the
/// eye.
osg::Matrix getOceanSurfaceTransform() const
{
return osg::Matrix::translate(_oceanTransform->getMatrix().getTrans().x(),
_oceanTransform->getMatrix().getTrans().y(),
_surfaceHeight + _oceanSurface->getSurfaceHeight());
}
/// Set whether the ocean surface is visible or not.
void setOceanVisible(bool visible){
_oceanTransform->setNodeMask( visible ? _normalSceneMask | _surfaceMask : 0 );
}
/// Check whether the ocean surface is visible or not.
bool isOceanVisible() const { return _oceanTransform->getNodeMask() != 0; }
/// Get the ocean cylinder.
osgOcean::Cylinder* getOceanCylinder() const{
return _oceanCylinder.get();
}
/// Get the ocean cylinder's transform node.
osg::MatrixTransform* getOceanCylinderTransform() const{
return _oceanCylinderMT.get();
}
/// Set the size of _oceanCylinder which follows the camera underwater, so that the clear
/// color is not visible past the far plane - it will be the fog color.
/// Height is a positive number which represents depth.
/// Default values are Radius: 1900 and Height: 4000
inline void setCylinderSize( float radius, float height ){
_oceanCylinder->build( radius, height, 16, false, true );
_oceanCylinderMT->setMatrix( osg::Matrixf::translate(osg::Vec3f(0.f,0.f,-height-0.2f)) );
}
/// Get the radius of the ocean cylinder.
inline const float getCylinderRadius( void ) const{
return _oceanCylinder->getRadius();
}
/// Get the height of the ocean cylinder.
inline const float getCylinderHeight( void ) const{
return _oceanCylinder->getHeight();
}
/// Enable/disable RTT effects (reflection, refraction, height map)
/// for the given view.
void enableRTTEffectsForView(osg::View* view, bool enable);
/// Get the list of views where RTT effects (reflection, refraction,
/// height map) are disabled (enabled for all other views).
ViewSet getViewsWithRTTEffectsDisabled() const
{
return _viewsWithRTTEffectsDisabled;
}
/// Enable reflections (one RTT pass when the eye is above the ocean
/// surface).
inline void enableReflections( bool enable ){
_enableReflections = enable;
_isDirty = true;
}
/// Check whether reflections are enabled.
inline bool areReflectionsEnabled() const{
return _enableReflections;
}
/// If the eye is higher than this value above the ocean surface,
/// reflections will not be rendered. Set to a very large value to
/// disable this feature. Default is FLT_MAX.
inline void setEyeHeightReflectionCutoff( float cutoff ){
_eyeHeightReflectionCutoff = cutoff;
}
/// Get the eye height reflection cutoff.
inline float getEyeHeightReflectionCutoff() const{
return _eyeHeightReflectionCutoff;
}
/// Set reflection texture size (must be 2^n)
inline void setReflectionTextureSize( const osg::Vec2s& size ){
if( size.x() != size.y() )
return;
_reflectionTexSize = size;
_isDirty = true;
}
/// Enable refractions (one RTT pass whether the eye is above or
/// below the ocean surface).
inline void enableRefractions( bool enable ){
_enableRefractions = enable;
_isDirty = true;
}
/// Check whether refractions are enabled.
inline bool areRefractionsEnabled() const{
return _enableRefractions;
}
/// If the eye is lower than this value below the ocean surface,
/// refractions will not be rendered. Set to a very large negative
/// value to disable this feature. Default is -FLT_MAX.
inline void setEyeHeightRefractionCutoff( float cutoff ){
_eyeHeightRefractionCutoff = cutoff;
}
/// Get the eye height refraction cutoff.
inline float getEyeHeightRefractionCutoff() const{
return _eyeHeightRefractionCutoff;
}
/// Set refraction texture size (must be 2^n)
inline void setRefractionTextureSize( const osg::Vec2s& size){
if( size.x() != size.y() )
return;
_refractionTexSize = size;
_isDirty = true;
}
/// Enable the height map pass (one RTT pass when the eye is above
/// the ocean surface - uses the same texture size as refractions).
inline void enableHeightmap( bool enable ){
_enableHeightmap = enable;
_isDirty = true;
}
/// Check whether the height map pass is enabled.
inline bool isHeightmapEnabled() const {
return _enableHeightmap;
}
/// Enable underwater God Rays.
inline void enableGodRays( bool enable ){
_enableGodRays = enable;
_isDirty = true;
}
/// Check whether God Rays are enabled.
inline bool areGodRaysEnabled() const{
return _enableGodRays;
}
/// Enable underwater silt.
inline void enableSilt( bool enable ){
_enableSilt = enable;
_isDirty = true;
}
/// Check whether silt is enabled.
inline bool isSiltEnabled() const{
return _enableSilt;
}
/// Sets the current screen size, needed to initialise the God Ray
/// and DOF frame buffers. Default is 1024x768.
inline void setScreenDims( osg::Vec2s size ){
_screenDims = size;
_isDirty = true;
}
/// Set sun direction.
inline void setSunDirection( const osg::Vec3f& sunDir ){
_sunDirection = sunDir;
_isDirty = true;
}
/// Get sun direction.
inline osg::Vec3f getSunDirection() const{
return _sunDirection;
}
/// Enable underwater depth of field.
/// Also enables the use of the default scene shader as the effect
/// requires information stored in the alpha component.
inline void enableUnderwaterDOF( bool enable ){
_enableDOF = enable;
if(enable)
_enableDefaultShader = true;
_isDirty = true;
}
/// Check if underwater depth of field is enabled.
inline bool isUnderwaterDOFEnabled() const{
return _enableDOF;
}
/// Set near DOF blur distance.
inline void setDOFNear( float dofNear ) {
_dofNear = dofNear;
if( _dofStateSet.valid() )
_dofStateSet->getUniform("osgOcean_DOF_Near")->set(_dofNear);
}
/// Get near DOF blur distance.
inline float getDOFNear() const{
return _dofNear;
}
/// Set far DOF blur distance
inline void setDOFFar( float dofFar ) {
_dofFar = dofFar;
if( _dofStateSet.valid() )
_dofStateSet->getUniform("osgOcean_DOF_Far")->set(_dofFar);
}
/// Get far DOF blur distance.
inline float getDOFFar() const{
return _dofFar;
}
/// Set far clamp value.
inline void setDOFFarClamp( float farClamp ){
_dofFarClamp = farClamp;
if( _dofStateSet.valid() )
_dofStateSet->getUniform("osgOcean_DOF_Clamp")->set(_dofFarClamp);
}
/// Get far clamp value.
inline float getDOFFarClamp() const{
return _dofFarClamp;
}
/// Set DOF focal distance.
inline void setDOFFocalDistance( float focus ){
_dofFocus = focus;
if( _dofStateSet.valid() )
_dofStateSet->getUniform("osgOcean_DOF_Focus")->set(_dofFocus);
}
/// Get DOF focal distance.
inline float getDOFFocalDistance() const{
return _dofFocus;
}
/// Enable cross hatch glare.
/// Also enables the use of the default scene shader as the effect
/// requires information stored in the alpha component.
inline void enableGlare( bool flag )
{
_enableGlare = flag;
if(flag)
_enableDefaultShader = true;
_isDirty = true;
}
/// Check if glare is enabled.
inline bool isGlareEnabled() const{
return _enableGlare;
}
/// Set the luminance threshold for glare.
/// Luminance value at which glare appears.
/// Typical range: 0.75 < threshold < 1.0
inline void setGlareThreshold( float threshold )
{
_glareThreshold = threshold;
_isDirty = true;
}
/// Get the luminance threshold for glare.
inline float getGlareThreshold() const{
return _glareThreshold;
}
/// Set the glare attenuation.
/// Controls the rate at which the glare drops off.
/// Typical range: 0.75 < attenuation < 0.95
inline void setGlareAttenuation( float attenuation )
{
_glareAttenuation = attenuation;
_isDirty = true;
}
/// Get the glare attenuation.
inline float getGlareAttenuation() const{
return _glareAttenuation;
}
/// Enable underwater distortion.
inline void enableDistortion( bool flag )
{
_enableDistortion = flag;
_isDirty = true;
}
/// Check if underwater distortion is enabled.
inline bool isDistortionEnabled() const{
return _enableDistortion;
}
/// Enable underwater scattering.
inline void enableUnderwaterScattering( bool flag )
{
_enableUnderwaterScattering = flag;
_isDirty = true;
}
/// Check whether underwater scattering is enabled.
inline bool isUnderwaterScatteringEnabled() const{
return _enableUnderwaterScattering;
}
/// Set the ocean technique.
inline void setOceanTechnique( OceanTechnique* surface ){
if( _oceanSurface.valid() )
_oceanTransform->removeChild( _oceanSurface.get() );
_oceanSurface = surface;
if (_oceanSurface.valid())
{
_oceanSurface->setNodeMask( _surfaceMask );
_oceanTransform->addChild( _oceanSurface.get() );
}
_isDirty = true;
}
/// Get the current ocean technique.
inline OceanTechnique* getOceanTechnique( void ) {
return _oceanSurface.get();
}
/// Get the node mask for the reflected scene.
inline unsigned int getReflectedSceneMask( void ) const{
return _reflectionSceneMask;
}
/// Get the node mask for the refracted scene.
inline unsigned int getRefractedSceneMask( void ) const{
return _refractionSceneMask;
}
/// Get the node mask for the height map (generally terrain).
inline unsigned int getHeightmapMask( void ) const{
return _heightmapMask;
}
/// Get the node mask for the ocean surface.
inline unsigned int getOceanSurfaceMask( void ) const{
return _surfaceMask;
}
/// Get the node mask for the scene.
inline unsigned int getNormalSceneMask( void ) const{
return _normalSceneMask;
}
/// Set the ID of the light source that should be used to light the ocean.
inline void setLightID( unsigned int id ){
_lightID = id;
_isDirty = true;
}
/// Sets the fogging params for the above water scene.
/// EXP fog
inline void setAboveWaterFog( float density, const osg::Vec4f& color )
{
_aboveWaterFogDensity = density;
_aboveWaterFogColor = color;
const float LOG2E = 1.442695;
if( _globalStateSet.valid() ){
_globalStateSet->getUniform("osgOcean_AboveWaterFogDensity")->set(-_aboveWaterFogDensity*_aboveWaterFogDensity*LOG2E);
_globalStateSet->getUniform("osgOcean_AboveWaterFogColor")->set(color);
}
_isDirty = true;
}
/// Get the above water fog density.
inline float getAboveWaterFogDensity() const
{
return _aboveWaterFogDensity;
}
/// Get the above water fog color.
inline osg::Vec4f getAboveWaterFogColor() const
{
return _aboveWaterFogColor;
}
/// Sets the fogging params for the underwater scene.
/// EXP2 fog
inline void setUnderwaterFog( float density, const osg::Vec4f& color )
{
_underwaterFogDensity = density;
_underwaterFogColor = color;
_oceanCylinder->setColor(_underwaterFogColor);
const float LOG2E = 1.442695;
if( _globalStateSet.valid() ){
_globalStateSet->getUniform("osgOcean_UnderwaterFogDensity")->set(-_underwaterFogDensity*_underwaterFogDensity*LOG2E);
_globalStateSet->getUniform("osgOcean_UnderwaterFogColor")->set(_underwaterFogColor);
}
_isDirty = true;
}
/// Get the underwater fog density.
inline float getUnderwaterFogDensity() const
{
return _underwaterFogDensity;
}
/// Get the underwater fog color.
inline osg::Vec4f getUnderwaterFogColor() const
{
return _underwaterFogColor;
}
/// Changes the color of diffuse light used underwater.
/// @note Should be computing this from physical calculations. For
/// the moment this is tweaked by hand.
/// see: http://citeseer.ist.psu.edu/cache/papers/cs/26265/http:zSzzSzwww.cs.sunysb.eduzSz~ashzSzwaterCGF.pdf/
void setUnderwaterDiffuse( const osg::Vec4f& diffuse )
{
_underwaterDiffuse = diffuse;
_isDirty = true;
}
/// Get the color of the diffuse light underwater.
osg::Vec4f getUnderwaterDiffuse() const
{
return _underwaterDiffuse;
}
/// Change the attenuation of light underwater.
/// @note Should be computing this from physical calculations. For
///the moment this is tweaked by hand.
/// see: http://citeseer.ist.psu.edu/cache/papers/cs/26265/http:zSzzSzwww.cs.sunysb.eduzSz~ashzSzwaterCGF.pdf/
void setUnderwaterAttenuation( const osg::Vec3f& attenuation )
{
_underwaterAttenuation = attenuation;
_isDirty = true;
}
/// Get the attenuation of light underwater.
osg::Vec3f getUnderwaterAttenuation() const
{
return _underwaterAttenuation;
}
/// Override the default scene shader for custom shaders.
/// If custom shaders are required for individual nodes add them
/// before adding to the OceanScene.
void setDefaultSceneShader( osg::Program* program )
{
_defaultSceneShader = program;
_isDirty = true;
}
/// Enable/Disable the use of the default scene shader.
/// This shader is required for the glare, and DOF effects as they
/// require information stored in the alpha component.
/// It also controls the above/below water fogging and lighting.
/// Enabling glare or DOF will automatically enable the shader.
void setUseDefaultSceneShader( bool enable )
{
_enableDefaultShader = enable;
}
/// Add a new path from which to search for library textures.
/// Updates osgDB::Registry's data file path
inline void addAlternativeTexturePath( const std::string& path )
{
osgDB::Registry::instance()->getDataFilePathList().push_back(path);
}
/// Add a new path from which to search for library shaders.
/// Updates osgDB::Registry's data file path
inline void addAlternativeShaderPath( const std::string& path )
{
osgDB::Registry::instance()->getDataFilePathList().push_back(path);
}
/// Base class for the OceanScene event handler. Subclasses of
/// OceanScene can subclass this to provide support for
/// manipulating their particular properties, calling the base class
/// handle() to inherit the base class's events (or not as desired).
/// If subclasses subclass this handler, they need to override
/// getEventHandler() in order for it to return the right concrete
/// event handler instance.
class EventHandler : public osgGA::GUIEventHandler
{
public:
EventHandler(OceanScene* oceanScene);
virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor*);
virtual void getUsage(osg::ApplicationUsage& usage) const;
protected:
OceanScene* _oceanScene;
};
/// Virtual constructor for OceanScene::EventHandler - override in
/// derived classes to return subclass-specific handler if needed.
virtual EventHandler* getEventHandler()
{
if (!_eventHandler.valid())
_eventHandler = new EventHandler(this);
return _eventHandler.get();
}
private:
osg::Texture2D* createTexture2D( const osg::Vec2s& size, GLint format );
osg::TextureRectangle* createTextureRectangle( const osg::Vec2s& size, GLint format );
/// Override OSG traversal function in order to do custom rendering.
void traverse(osg::NodeVisitor& nv);
/// Main cull traversal.
/// Renders main scene, surface, silt.
void cull( osgUtil::CullVisitor& cv, bool eyeAboveWater, bool surfaceVisible );
/// Render to texture passes for reflection/refractions/height map/god rays.
void preRenderCull( osgUtil::CullVisitor& cv, bool eyeAboveWater, bool surfaceVisible );
/// Post render passes for DOF/god rays.
void postRenderCull( osgUtil::CullVisitor& cv, bool eyeAboveWater, bool surfaceVisible );
/// Update god ray geometry and screen quad.
void update(osg::NodeVisitor& nv);
/// Post render pass for god rays. */
osg::Camera* godrayFinalPass( void );
/// Downsample (1/4 original size) pass for depth of field and glare effect.
/// colorBuffer refers to the main frame buffer color image
/// auxBuffer refers to the luminance buffer (glare) or depth buffer (dof).
osg::Camera* downsamplePass(
osg::TextureRectangle* colorBuffer,
osg::TextureRectangle* auxBuffer,
osg::TextureRectangle* outputTexture,
bool isGlareEffect );
/// Gaussian blur passes for the depth of field effect.
/// One pass is required for each axis.
osg::Camera* gaussianPass( osg::TextureRectangle* inputTexture, osg::TextureRectangle* outputTexture, bool isXAxis );
/// Combine original FBO with downsampled blur image.
osg::Camera* dofCombinerPass(
osg::TextureRectangle* fullscreenTexture,
osg::TextureRectangle* fullDepthTexture,
osg::TextureRectangle* blurTexture,
osg::TextureRectangle* outputTexture );
/// Post render pass displays combined DOF buffer
osg::Camera* dofFinalPass( osg::TextureRectangle* combinedTexture );
/// Post render pass blends glare texture into main
osg::Camera* glareCombinerPass(
osg::TextureRectangle* fullscreenTexture,
osg::TextureRectangle* glareTexture1,
osg::TextureRectangle* glareTexture2,
osg::TextureRectangle* glareTexture3,
osg::TextureRectangle* glareTexture4 );
/// Pre render pass adds streak filter to image
osg::Camera* glarePass(osg::TextureRectangle* streakInput,
osg::TextureRectangle* steakOutput,
int pass,
osg::Vec2f direction );
/// Sets up a camera for a render to FBO pass.
osg::Camera* renderToTexturePass( osg::Texture* textureBuffer );
/// Sets up a camera for a render MRT FBO pass.
osg::Camera* multipleRenderTargetPass(
osg::Texture* texture0, osg::Camera::BufferComponent buffer0,
osg::Texture* texture1, osg::Camera::BufferComponent buffer1 );
/// Create geometry for a screen aligned quad.
osg::Geode* createScreenQuad( const osg::Vec2s& dims, const osg::Vec2s& texSize );
osg::Program* createDefaultSceneShader( void );
/// Add the default resource paths to osgDB::Registry.
/// Checks if already present.
/// paths: resources/textures and resources/shaders.
void addResourcePaths(void);
protected:
osg::ref_ptr<EventHandler> _eventHandler;
~OceanScene( void );
class CameraCullCallback : public osg::NodeCallback
{
public:
CameraCullCallback(OceanScene* oceanScene);
virtual void operator()(osg::Node*, osg::NodeVisitor* nv);
protected:
OceanScene* _oceanScene;
};
class PrerenderCameraCullCallback : public osg::NodeCallback
{
public:
PrerenderCameraCullCallback(OceanScene* oceanScene);
virtual void operator()(osg::Node*, osg::NodeVisitor* nv);
protected:
OceanScene* _oceanScene;
};
};
}

View File

@ -1,125 +0,0 @@
/*
* 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 <osgUtil/CullVisitor>
#include <osgGA/GUIEventHandler>
namespace osgOcean
{
class OSGOCEAN_EXPORT OceanTechnique : public osg::Geode
{
public:
OceanTechnique( void );
OceanTechnique( const OceanTechnique& copy, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY );
virtual const char* libraryName() const { return "osgOcean"; }
virtual const char* className() const { return "OceanTechnique"; }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const OceanTechnique*>(obj) != 0; }
virtual void build( void );
virtual void stopAnimation( void ){
_isAnimating = false;
}
virtual void startAnimation( void ){
_isAnimating = true;
}
bool isAnimating( void ) const{
return _isAnimating;
}
/**
* Returns the average height over the whole surface (in local space)
*/
virtual float getSurfaceHeight(void) const;
/**
* Returns the height at the given point (in local space). If the
* address of a Vec3f is passed in the normal argument, the normal at
* that position will be calculated and stored in it.
*/
virtual float getSurfaceHeightAt(float x, float y, osg::Vec3f* normal = NULL) = 0;
/**
* Returns the maximum height over the whole surface (in local space)
*/
virtual float getMaximumHeight(void) const;
inline bool isDirty(void) const{
return _isDirty;
}
inline void dirty(void){
_isDirty=true;
}
/**
* Check if the ocean surface is visible or not. Basic test is very
* simple, subclasses can do a better test.
*/
bool isVisible( osgUtil::CullVisitor& cv, bool eyeAboveWater );
/** Base class for the OceanTechnique event handler. Subclasses of
* OceanTechnique can subclass this to provide support for
* manipulating their particular properties, calling the base class
* handle() to inherit the base class's events (or not as desired).
* If subclasses subclass this handler, they need to override
* getEventHandler() in order for it to return the right concrete
* event handler instance.
*/
class EventHandler : public osgGA::GUIEventHandler
{
public:
EventHandler(OceanTechnique* oceanSurface);
virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa, osg::Object*, osg::NodeVisitor*);
/** Get the keyboard and mouse usage of this manipulator.*/
virtual void getUsage(osg::ApplicationUsage& usage) const;
protected:
OceanTechnique* _oceanSurface;
};
/** Virtual constructor for OceanTechnique::EventHandler - override in
* derived classes to return subclass-specific handler if needed.
*/
virtual EventHandler* getEventHandler()
{
if (!_eventHandler.valid())
_eventHandler = new EventHandler(this);
return _eventHandler.get();
}
protected:
virtual ~OceanTechnique(void){};
/**
* Add the default resource paths to osgDB::Registry.
* Checks if already present.
* paths: resources/textures and resources/shaders.
*/
virtual void addResourcePaths(void);
protected:
bool _isDirty;
bool _isAnimating;
osg::ref_ptr<EventHandler> _eventHandler;
};
}

View File

@ -1,175 +0,0 @@
/*
* 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/Array>
#include <osg/Math>
#include <osg/Notify>
#include <osg/Texture2D>
#include <osg/Image>
namespace osgOcean
{
/**
* Stores vertices and normals for the geomipmp levels.
*/
class OSGOCEAN_EXPORT OceanTile
{
private:
unsigned int _resolution; /**< FFT Size (2^n). */
unsigned int _rowLength; /**< Row length the FFT size with skirt (N+1). */
unsigned int _numVertices; /**< Total number of vertices _rowLength^2. */
osg::ref_ptr<osg::Vec3Array> _vertices; /**< Vertex array. */
osg::ref_ptr<osg::Vec3Array> _normals; /**< Normal array. */
float _spacing; /**< Vertex spacing. */
float _maxDelta; /**< Max change in height between levels */
float _averageHeight; /**< Average height (z) of vertices */
float _maxHeight; /**< Maximum height (z) of vertices */
bool _useVBO; /**< Add relative position to tile placement */
public:
/**
* Default constructor.
* Initialises values to 0.
*/
OceanTile( void );
/**
* Constructor.
* Copies heights into _vertices adding an extra row and column as a skirt, size: (N+1)*(N+1).
* Data from the first row and column are copied into the last column and row.
* Computes average height and normals of tile. Displacements are optional.
*/
OceanTile( osg::FloatArray* heights,
const unsigned int resolution,
const float spacing,
osg::Vec2Array* displacements = NULL,
bool useVBO = false);
/**
* Down sampling constructor.
* Down samples the passed OceanTile data and populates _vertices adding a skirt.
* Down sampled vertices are averages of the surrounding 4 vertices.
*/
OceanTile( const OceanTile& tile,
unsigned int resolution,
const float spacing );
/**
* Copy constructor.
*/
OceanTile( const OceanTile& copy );
OceanTile& operator=(const OceanTile& rhs);
~OceanTile( void );
/**
* Creates a DOT3 normal map based on the heightfield.
* @return osg::Texture2D (size: _tileResolution*_tileResolution).
*/
osg::ref_ptr<osg::Texture2D> createNormalMap( void );
inline osg::Vec3Array *getVertices( void ) const
{
return _vertices.get();
}
inline osg::Vec3Array *getNormals( void ) const
{
return _normals.get();
}
inline const osg::Vec3f& getVertex( unsigned int x, unsigned int y ) const {
return _vertices->at( x + y * _rowLength );
}
inline const osg::Vec3f& getVertex( unsigned int v ) const{
return _vertices->at(v);
}
inline const osg::Vec3f& getNormal( unsigned int x, unsigned int y ) const{
return _normals->at( x + y * _rowLength );
}
inline const osg::Vec3f& getNormal( unsigned int n ) const{
return _normals->at(n);
}
inline const unsigned int& getNumVertices( void ) const{
return _numVertices;
}
inline const unsigned int& getResolution( void ) const{
return _resolution;
}
inline const unsigned int& getRowLen( void ) const {
return _rowLength;
}
inline const float& getSpacing( void ) const {
return _spacing;
}
inline const float getMaxDelta( void ) const {
return _maxDelta;
}
inline const float getAverageHeight(void) const{
return _averageHeight;
}
inline const float getMaximumHeight(void) const{
return _maxHeight;
}
inline const bool getUseVBO(void) const {
return _useVBO;
}
float biLinearInterp(float x, float y ) const;
osg::Vec3f normalBiLinearInterp(float x, float y ) const;
private:
/** Compute normals for an N+2 x N+2 grid to ensure continuous normals around the edges.
* Using first row as last row and first column as last column.
* Discards first row and column when storing internally.
*/
void computeNormals( void );
/** Computes the maximum difference in height between vertices from differant mipmap levels.
* Not used at the moment as the geometry data is constantly changing due to the animation.
* It may be possible to use an average delta value to make the mipmapping smoother.
* More info: http://www.flipcode.com/archives/article_geomipmaps.pdf
*/
void computeMaxDelta( void );
/** Bilinear interpolation between 4 hi-res points and a lower level counter part.
* Not used at the moment.
* @see computeMaxDelta();
*/
float biLinearInterp(int lx, int hx, int ly, int hy, int tx, int ty ) const;
/** Convenience method for computing array position. */
inline unsigned int array_pos( unsigned int x, unsigned int y, unsigned int rowLen )
{
return x + y * rowLen;
}
};
}

View File

@ -1,68 +0,0 @@
/*
* 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 <stdlib.h>
#include <cmath>
namespace osgOcean
{
/**
* A selection of random number generator utility functions
**/
namespace RandUtils
{
/** uniformly distributed random int (0 -> RAND_MAX) */
inline static int myRand( void )
{
return rand();
}
/** uniformly distributed random number (0 -> 1) */
inline float unitRand( void )
{
return (float)myRand()/RAND_MAX;
}
/** uniformly distributed random number (min -> max) */
inline float rangedRand( float min, float max )
{
return min + unitRand() * (max - min);
}
/** Gaussian distributed random number pair
* http://www.taygeta.com/random/gaussian.html
*/
inline void gaussianRand( float& a, float& b )
{
float x1, x2, length2;
do {
x1 = rangedRand(-1.f,1.f);
x2 = rangedRand(-1.f,1.f);
length2 = x1 * x1 + x2 * x2;
}
while ( length2 >= 1.f );
length2 = sqrt( (-2.f * log( length2 ) ) / length2 );
a = x1 * length2;
b = x2 * length2;
}
}
}

View File

@ -1,39 +0,0 @@
/*
* 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/Geometry>
#include <osg/TextureRectangle>
namespace osgOcean
{
class OSGOCEAN_EXPORT ScreenAlignedQuad : public osg::Geometry
{
public:
ScreenAlignedQuad( void );
ScreenAlignedQuad( const osg::Vec3f& corner, const osg::Vec2f& dims, const osg::Vec2s& textureSize );
ScreenAlignedQuad( const osg::Vec3f& corner, const osg::Vec2f& dims, osg::TextureRectangle* texture );
ScreenAlignedQuad( const ScreenAlignedQuad &copy, const osg::CopyOp &copyop = osg::CopyOp::SHALLOW_COPY );
virtual void build( const osg::Vec3f& corner, const osg::Vec2f& dims, const osg::Vec2s& textureSize );
virtual void build( const osg::Vec3f& corner, const osg::Vec2f& dims, osg::TextureRectangle* texture );
protected:
virtual ~ScreenAlignedQuad(void){};
};
}

View File

@ -1,78 +0,0 @@
/*
* 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/Program>
#include <map>
#include <sstream>
namespace osgOcean
{
class OSGOCEAN_EXPORT ShaderManager
{
private:
typedef std::map<const std::string, std::string> GlobalDefinitions;
GlobalDefinitions _globalDefinitions;
bool _shadersEnabled;
public:
static ShaderManager& instance();
/** Set a definition that will be added as a #define to the top of every
* shader loaded through subsequent calls to createProgram() .
*/
template<typename T>
void setGlobalDefinition(const std::string& name, const T& value)
{
std::ostringstream valStr;
valStr << value;
_globalDefinitions[name] = valStr.str();
}
/** Get the value of a global definition that was previously set using
* setGlobalDefinition().
*/
std::string getGlobalDefiniton(const std::string& name);
/** Creates a shader program. Will try to load the filenames first, and if
* not found will fall back to using the given shader source strings.
*/
osg::Program* createProgram( const std::string& name,
const std::string& vertexFilename,
const std::string& fragmentFilename,
const std::string& vertexSrc,
const std::string& fragmentSrc );
/// Check if shaders are globally enabled or not.
bool areShadersEnabled() const { return _shadersEnabled; }
/// Globally enable or disable shaders for osgOcean.
void enableShaders(bool enable) { _shadersEnabled = enable; }
private:
// private so clients can't call it, they have to call instance().
ShaderManager();
// No definition, copy and assignment is illegal.
ShaderManager(const ShaderManager&);
ShaderManager& operator=(const ShaderManager&);
std::string buildGlobalDefinitionsList(const std::string& name);
};
}

View File

@ -1,243 +0,0 @@
/*
* 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/Group>
#include <osg/BoundingBox>
#include <osg/Fog>
#include <osg/Geometry>
#include <osg/Drawable>
#include <osgUtil/CullVisitor>
#include <osg/GL>
namespace osgOcean
{
class OSGOCEAN_EXPORT SiltEffect : public osg::Node
{
public:
SiltEffect();
SiltEffect(const SiltEffect& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
virtual const char* libraryName() const { return "osgOcean"; }
virtual const char* className() const { return "SiltEffect"; }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const SiltEffect*>(obj) != 0; }
virtual void accept(osg::NodeVisitor& nv) { if (nv.validNodeMask(*this)) { nv.pushOntoNodePath(this); nv.apply(*this); nv.popFromNodePath(); } }
virtual void traverse(osg::NodeVisitor& nv);
void setIntensity(float intensity);
void setMaximumParticleDensity(float density) { if (_maximumParticleDensity==density) return; _maximumParticleDensity = density; _dirty = true;}
float setMaximumParticleDensity() const { return _maximumParticleDensity; }
void setWind(const osg::Vec3& wind) { _wind = wind; }
const osg::Vec3& getWind() const { return _wind; }
void setPosition(const osg::Vec3& position) { _origin = position; }
const osg::Vec3& getPosition() const { return _origin; }
void setCellSize(const osg::Vec3& cellSize) { if (_cellSize==cellSize) return; _cellSize = cellSize; _dirty = true; }
const osg::Vec3& getCellSize() const { return _cellSize; }
void setParticleSpeed(float particleSpeed) { if (_particleSpeed==particleSpeed) return; _particleSpeed = particleSpeed; _dirty = true; }
float getParticleSpeed() const { return _particleSpeed; }
void setParticleSize(float particleSize) { if (_particleSize==particleSize) return; _particleSize = particleSize; _dirty = true;}
float getParticleSize() const { return _particleSize; }
void setParticleColor(const osg::Vec4& color) { if (_particleColor==color) return; _particleColor = color; _dirty = true;}
const osg::Vec4& getParticleColor() const { return _particleColor; }
void setNearTransition(float nearTransition) { _nearTransition = nearTransition; }
float getNearTransition() const { return _nearTransition; }
void setFarTransition(float farTransition) { _farTransition = farTransition; }
float getFarTransition() const { return _farTransition; }
void setFog(osg::Fog* fog) { _fog = fog; }
osg::Fog* getFog() { return _fog.get(); }
const osg::Fog* getFog() const { return _fog.get(); }
osg::Geometry* getQuadGeometry() { return _quadGeometry.get(); }
osg::StateSet* getQuadStateSet() { return _quadStateSet.get(); }
osg::Geometry* getPointGeometry() { return _pointGeometry.get(); }
osg::StateSet* getPointStateSet() { return _pointStateSet.get(); }
/** Internal drawable used to render batches of cells.*/
class OSGOCEAN_EXPORT SiltDrawable : public osg::Drawable
{
public:
SiltDrawable();
SiltDrawable(const SiltDrawable& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
META_Object(osgOcean, SiltDrawable);
virtual bool supports(const osg::PrimitiveFunctor&) const { return false; }
virtual void accept(osg::PrimitiveFunctor&) const {}
virtual bool supports(const osg::PrimitiveIndexFunctor&) const { return false; }
virtual void accept(osg::PrimitiveIndexFunctor&) const {}
void setGeometry(osg::Geometry* geom) { _geometry = geom; }
osg::Geometry* getGeometry() { return _geometry.get(); }
const osg::Geometry* getGeometry() const { return _geometry.get(); }
void setDrawType(GLenum type) { _drawType = type; }
GLenum getDrawType() const { return _drawType; }
void setNumberOfVertices(unsigned int numVertices) { _numberOfVertices = numVertices; }
unsigned int getNumberOfVertices() const { return _numberOfVertices; }
virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
struct Cell
{
Cell(int in_i, int in_j, int in_k):
i(in_i), j(in_j), k(in_k) {}
inline bool operator < (const Cell& rhs) const
{
if (i<rhs.i) return true;
if (i>rhs.i) return false;
if (j<rhs.j) return true;
if (j>rhs.j) return false;
if (k<rhs.k) return true;
if (k>rhs.k) return false;
return false;
}
int i;
int j;
int k;
};
struct DepthMatrixStartTime
{
inline bool operator < (const DepthMatrixStartTime& rhs) const
{
return depth < rhs.depth;
}
float depth;
float startTime;
osg::Matrix modelview;
};
typedef std::map< Cell, DepthMatrixStartTime > CellMatrixMap;
struct LessFunctor
{
inline bool operator () (const CellMatrixMap::value_type* lhs,const CellMatrixMap::value_type* rhs) const
{
return (*lhs).second<(*rhs).second;
}
};
CellMatrixMap& getCurrentCellMatrixMap() { return _currentCellMatrixMap; }
CellMatrixMap& getPreviousCellMatrixMap() { return _previousCellMatrixMap; }
inline void newFrame()
{
_previousCellMatrixMap.swap(_currentCellMatrixMap);
_currentCellMatrixMap.clear();
}
protected:
virtual ~SiltDrawable() {}
osg::ref_ptr<osg::Geometry> _geometry;
mutable CellMatrixMap _currentCellMatrixMap;
mutable CellMatrixMap _previousCellMatrixMap;
GLenum _drawType;
unsigned int _numberOfVertices;
};
protected:
virtual ~SiltEffect() {}
void compileGLObjects(osg::RenderInfo& renderInfo) const;
void update();
void createGeometry(unsigned int numParticles,
osg::Geometry* quad_geometry,
osg::Geometry* point_geometry);
void setUpGeometries(unsigned int numParticles);
struct SiltDrawableSet
{
osg::ref_ptr<SiltDrawable> _quadSiltDrawable;
osg::ref_ptr<SiltDrawable> _pointSiltDrawable;
};
void cull(SiltDrawableSet& pds, osgUtil::CullVisitor* cv) const;
bool build(const osg::Vec3 eyeLocal, int i, int j, int k, float startTime, SiltDrawableSet& pds, osg::Polytope& frustum, osgUtil::CullVisitor* cv) const;
// parameters
bool _dirty;
osg::Vec3 _wind;
float _particleSpeed;
float _particleSize;
osg::Vec4 _particleColor;
float _maximumParticleDensity;
osg::Vec3 _cellSize;
float _nearTransition;
float _farTransition;
osg::ref_ptr<osg::Fog> _fog;
osg::ref_ptr<osg::Uniform> _inversePeriodUniform;
osg::ref_ptr<osg::Uniform> _particleSizeUniform;
osg::ref_ptr<osg::Uniform> _particleColorUniform;
typedef std::pair< osg::NodeVisitor*, osg::NodePath > ViewIdentifier;
typedef std::map< ViewIdentifier, SiltDrawableSet > ViewDrawableMap;
OpenThreads::Mutex _mutex;
ViewDrawableMap _viewDrawableMap;
osg::ref_ptr<osg::Geometry> _quadGeometry;
osg::ref_ptr<osg::StateSet> _quadStateSet;
osg::ref_ptr<osg::Geometry> _pointGeometry;
osg::ref_ptr<osg::StateSet> _pointStateSet;
// cache variables.
float _period;
osg::Vec3 _origin;
osg::Vec3 _du;
osg::Vec3 _dv;
osg::Vec3 _dw;
osg::Vec3 _inverse_du;
osg::Vec3 _inverse_dv;
osg::Vec3 _inverse_dw;
};
}

View File

@ -1,38 +0,0 @@
/*
* 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.
*/
#ifndef OSGOCEAN_VERSION
#define OSGOCEAN_VERSION
#include <osgOcean/Export>
extern "C" {
#define OSGOCEAN_VERSION_MAJOR 1
#define OSGOCEAN_VERSION_MINOR 0
#define OSGOCEAN_VERSION_PATCH 1
#define OSGOCEAN_VERSION_RELEASE OSGOCEAN_VERSION_PATCH
#define OSGOCEAN_VERSION_REVISION 0
extern OSGOCEAN_EXPORT const char* osgOceanGetVersion();
extern OSGOCEAN_EXPORT const char* osgOceanGetLibraryName();
}
#endif

View File

@ -1,87 +0,0 @@
/*
* 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 <vector>
#include <cmath>
#include <stdlib.h>
#include <osg/Array>
#include <osg/Math>
namespace osgOcean
{
class OSGOCEAN_EXPORT WaterTrochoids
{
private:
static const int NUM_WAVES = 16;
// Wave data structure
struct Wave {
float A; // amplitude
float w; // frequency
float kx,ky; // wave vector components
float kmod; // wave vector module
float phi0; // phase at time 0
float phase; // current phase
float Ainvk; // amplitude/K module
};
std::vector<Wave> _waves;
// Parameters used for the waves initialization
float _amplitude; // base amplitude (must be <1.0 or they loop over themselves)
float _amplitudeMul; // amplitude multiplier
float _lambda0; // base wavelength
float _lambdaMul; // wavelength multiplier
float _direction; // main waves direction
float _angleDev; // deviation from main direction
public:
WaterTrochoids( void );
WaterTrochoids( const WaterTrochoids& copy );
WaterTrochoids(float amplitude,
float amplitudeMul,
float baseWavelen,
float wavelenMul,
float direction,
float angleDev );
~WaterTrochoids( void );
// create base waves
void createWaves( void );
// update waves
void updateWaves( float time );
// pack waves for vertex shader
void packWaves( osg::FloatArray* constant ) const;
private:
inline float nextRandomDouble(float lBound, float uBound)
{
static int seed = 0;
srand(seed);
seed++;
return (float)rand()/(float)RAND_MAX * (uBound - lBound) + lBound;
}
};
}

Binary file not shown.