source: Swollen/swollen/watersurface.cpp @ 115

Last change on this file since 115 was 115, checked in by darran, 19 years ago
File size: 4.8 KB
Line 
1/*
2  WaterSurface class
3
4  An OpenSceneGraph viewer for pyVolution .sww files.
5  copyright (C) 2004 Geoscience Australia
6*/
7
8
9#include <watersurface.h>
10#include <osg/AlphaFunc>
11#include <osg/BlendFunc>
12#include <osg/PolygonMode>
13#include <osg/ShapeDrawable>
14#include <osg/Texture2D>
15#include <osg/TexEnv>
16#include <osg/TexGen>
17
18#include <osgDB/ReadFile>
19//#include <osgUtil/TriStripVisitor>
20
21#define DEF_ALPHA_THRESHOLD 0.05
22
23
24// constructor
25WaterSurface::WaterSurface(SWWReader* sww)
26{
27   // persistent
28   _sww = sww;
29   _node = new osg::Geode;
30   _geom = new osg::Geometry;
31   _stateset = new osg::StateSet;
32
33   // construct local scenegraph hierarchy
34   _node->setName("watersurface");
35   _node->addDrawable(_geom);
36   _node->setStateSet(_stateset);
37
38   _geom->setUseDisplayList( false );
39
40
41   // surface starts on first timestep
42   _timestep = 0;
43   _dirtytimestep = true;  // will force load of watersurface
44
45   // default is filled watersurface
46   _wireframe = false;
47   _dirtywireframe = true;  // will force wireframe refresh
48
49
50
51   // environment map
52   osg::Texture2D* texture = new osg::Texture2D;
53   texture->setDataVariance(osg::Object::DYNAMIC);
54   texture->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,0.5f));
55   texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
56   std::string* envmap = new std::string( _sww->getSwollenDir() + std::string("/") + std::string("envmap.jpg") );
57   texture->setImage(osgDB::readImageFile( envmap->c_str() ));
58   _stateset->setTextureAttributeAndModes( 1, texture, osg::StateAttribute::ON );
59   _stateset->setMode( GL_LIGHTING, osg::StateAttribute::ON );
60
61   // surface transparency
62   osg::BlendFunc* osgBlendFunc = new osg::BlendFunc();
63   osgBlendFunc->setFunction(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA);
64   _stateset->setAttribute(osgBlendFunc);
65   _stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
66   _stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
67
68   // discard pixels with an alpha value below threshold
69   osg::AlphaFunc* alphaFunc = new osg::AlphaFunc;
70   alphaFunc->setFunction( osg::AlphaFunc::GREATER, DEF_ALPHA_THRESHOLD );
71   _stateset->setAttributeAndModes( alphaFunc, osg::StateAttribute::ON );
72
73   // automatically generate texture coords
74   osg::TexGen* texgen = new osg::TexGen;
75   texgen->setMode( osg::TexGen::SPHERE_MAP );
76
77   osg::TexEnv* texenv = new osg::TexEnv;
78   texenv->setMode( osg::TexEnv::DECAL );
79   //texenv->setMode( osg::TexEnv::BLEND );
80   texenv->setColor( osg::Vec4(0.6f,0.6f,0.6f,0.2f) );
81   _stateset->setTextureAttributeAndModes( 1, texgen, osg::StateAttribute::ON );
82   _stateset->setTextureAttribute( 1, texenv );
83
84}
85
86
87
88WaterSurface::~WaterSurface()
89{
90}
91
92
93
94void WaterSurface::setTimeStep(unsigned int ts)
95{
96   if( ts != _timestep )
97   {
98      _timestep = ts;
99      _dirtytimestep = true;
100   }
101}
102
103
104void WaterSurface::toggleWireframe()
105{
106   setWireframe( _wireframe ? false : true );
107}
108
109
110void WaterSurface::setWireframe(bool value)
111{
112   if( value != _wireframe )
113   {
114      _wireframe = value;
115      _dirtywireframe = true;
116   }
117}
118
119
120void WaterSurface::update()
121{
122
123   if( _dirtytimestep )
124   {
125      // delete if exists
126      if( _geom->getNumPrimitiveSets() )
127         _geom->removePrimitiveSet(0);  // reference counting does actual delete
128
129      // local reference to raw height field data
130      osg::ref_ptr<osg::Vec3Array> vertices = _sww->getStageVertexArray(_timestep);
131      osg::ref_ptr<osg::Vec3Array> vertexnormals = _sww->getStageVertexNormalArray();
132      osg::ref_ptr<osg::Vec4Array> colors = _sww->getStageColorArray();
133
134      // geometry
135      _geom->setVertexArray( vertices.get() );
136      _geom->addPrimitiveSet( _sww->getBedslopeIndexArray().get() );
137
138      // per vertex colors (we only modulate the alpha for transparency)
139      _geom->setColorArray( colors.get() );
140      _geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
141
142      // normals
143      _geom->setNormalArray( vertexnormals.get() );
144      _geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
145
146      // osgUtil::TriStripVisitor* optimize = new osgUtil::TriStripVisitor();
147      // optimize->stripify( *_geom );
148
149      // water surface corresponding to _timestep is now loaded ...
150      _dirtytimestep = false;
151   }
152
153
154   if( _dirtywireframe )
155   {
156      osg::PolygonMode* polyModeObj = 
157         dynamic_cast<osg::PolygonMode*>(_stateset->getAttribute(osg::StateAttribute::POLYGONMODE));
158
159      if (!polyModeObj) 
160      {
161         polyModeObj = new osg::PolygonMode;
162         _stateset->setAttribute(polyModeObj);
163      }
164
165      switch( _wireframe )
166      {
167         case true :
168            polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE);
169            break;
170
171         case false :
172            polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::FILL);
173            break;
174      }
175
176      // desired wireframe mode now loaded ...
177      _dirtywireframe = false;
178
179   }
180
181
182}
Note: See TracBrowser for help on using the repository browser.