source: swollen_viewer/swollen/watersurface.cpp @ 2869

Last change on this file since 2869 was 116, checked in by darran, 19 years ago
  • distro20050627
  • functioning record/playback/save. Can't yet replay from movie.swm
  • image capture not yet implemented.
File size: 5.1 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   _dirtydata = 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   // default is steep culling on
51   _culling = true;
52   _dirtyculling = true;  // will force culling ...
53
54
55   // environment map
56   osg::Texture2D* texture = new osg::Texture2D;
57   texture->setDataVariance(osg::Object::DYNAMIC);
58   texture->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,0.5f));
59   texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
60   std::string* envmap = new std::string( _sww->getSwollenDir() + std::string("/") + std::string("envmap.jpg") );
61   texture->setImage(osgDB::readImageFile( envmap->c_str() ));
62   _stateset->setTextureAttributeAndModes( 1, texture, osg::StateAttribute::ON );
63   _stateset->setMode( GL_LIGHTING, osg::StateAttribute::ON );
64
65   // surface transparency
66   osg::BlendFunc* osgBlendFunc = new osg::BlendFunc();
67   osgBlendFunc->setFunction(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA);
68   _stateset->setAttribute(osgBlendFunc);
69   _stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
70   _stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
71
72   // discard pixels with an alpha value below threshold
73   osg::AlphaFunc* alphaFunc = new osg::AlphaFunc;
74   alphaFunc->setFunction( osg::AlphaFunc::GREATER, DEF_ALPHA_THRESHOLD );
75   _stateset->setAttributeAndModes( alphaFunc, osg::StateAttribute::ON );
76
77   // automatically generate texture coords
78   osg::TexGen* texgen = new osg::TexGen;
79   texgen->setMode( osg::TexGen::SPHERE_MAP );
80
81   osg::TexEnv* texenv = new osg::TexEnv;
82   texenv->setMode( osg::TexEnv::DECAL );
83   //texenv->setMode( osg::TexEnv::BLEND );
84   texenv->setColor( osg::Vec4(0.6f,0.6f,0.6f,0.2f) );
85   _stateset->setTextureAttributeAndModes( 1, texgen, osg::StateAttribute::ON );
86   _stateset->setTextureAttribute( 1, texenv );
87
88}
89
90
91
92WaterSurface::~WaterSurface()
93{
94}
95
96
97
98void WaterSurface::setTimeStep(unsigned int ts)
99{
100   if( ts != _timestep )
101   {
102      _timestep = ts;
103      _dirtydata = true;
104   }
105}
106
107
108void WaterSurface::setWireframe(bool value)
109{
110   if( value != _wireframe )
111   {
112      _wireframe = value;
113      _dirtywireframe = true;
114   }
115}
116
117void WaterSurface::setCulling(bool value)
118{
119   if( value != _culling )
120   {
121      _culling = value;
122      _dirtyculling = true;
123      _dirtydata = true;
124   }
125}
126
127
128void WaterSurface::update()
129{
130
131   if( _dirtyculling )
132   {
133      _sww->setCulling( _culling );
134      _dirtyculling = false;
135   }
136
137   if( _dirtydata )
138   {
139      // delete if exists
140      if( _geom->getNumPrimitiveSets() )
141         _geom->removePrimitiveSet(0);  // reference counting does actual delete
142
143      // local reference to raw height field data
144      osg::ref_ptr<osg::Vec3Array> vertices = _sww->getStageVertexArray(_timestep);
145      osg::ref_ptr<osg::Vec3Array> vertexnormals = _sww->getStageVertexNormalArray();
146      osg::ref_ptr<osg::Vec4Array> colors = _sww->getStageColorArray();
147
148      // geometry
149      _geom->setVertexArray( vertices.get() );
150      _geom->addPrimitiveSet( _sww->getBedslopeIndexArray().get() );
151
152      // per vertex colors (we only modulate the alpha for transparency)
153      _geom->setColorArray( colors.get() );
154      _geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
155
156      // normals
157      _geom->setNormalArray( vertexnormals.get() );
158      _geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
159
160      // osgUtil::TriStripVisitor* optimize = new osgUtil::TriStripVisitor();
161      // optimize->stripify( *_geom );
162
163      // water surface corresponding to _timestep is now (re)loaded ...
164      _dirtydata = false;
165   }
166
167
168   if( _dirtywireframe )
169   {
170      osg::PolygonMode* polyModeObj = 
171         dynamic_cast<osg::PolygonMode*>(_stateset->getAttribute(osg::StateAttribute::POLYGONMODE));
172
173      if (!polyModeObj) 
174      {
175         polyModeObj = new osg::PolygonMode;
176         _stateset->setAttribute(polyModeObj);
177      }
178
179      switch( _wireframe )
180      {
181         case true :
182            polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE);
183            break;
184
185         case false :
186            polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::FILL);
187            break;
188      }
189
190      // desired wireframe mode now loaded ...
191      _dirtywireframe = false;
192
193   }
194
195
196}
Note: See TracBrowser for help on using the repository browser.