OpenWalnut  1.5.0dev
WMTemplateColormapping.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
26 // This is a tutorial on how to use the WGEColormapping interface. This tutorial also includes some shader files in the shaders subdirectory. You
27 // will be referred to them later.
28 //
29 // You will need the knowledge of these tutorials before you can go on:
30 // * WMTemplate
31 // * WMTemplateShaders
32 //
33 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
34 
35 #include <memory>
36 #include <string>
37 
38 #include <osg/StateAttribute>
39 
40 #include "WDemoGeometry.h"
41 #include "WMTemplateColormapping.h"
42 #include "core/graphicsEngine/WGEColormapping.h" // <- this is the awesome new header you will need
43 #include "core/graphicsEngine/WGEManagedGroupNode.h"
44 #include "core/graphicsEngine/WGERequirement.h"
45 #include "core/graphicsEngine/WGETexture.h"
46 #include "core/graphicsEngine/shaders/WGEShader.h"
47 #include "core/kernel/WKernel.h"
48 
49 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
50 // All the basic setup ... Refer to WMTemplate.cpp if you do not understand these commands.
51 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
52 
54  : WModule()
55 {
56 }
57 
59 {
60 }
61 
62 std::shared_ptr< WModule > WMTemplateColormapping::factory() const
63 {
64  // NOTE: Refer to WMTemplate.cpp if you do not understand these commands.
65  return std::shared_ptr< WModule >( new WMTemplateColormapping() );
66 }
67 
68 const std::string WMTemplateColormapping::getName() const
69 {
70  // NOTE: Refer to WMTemplate.cpp if you do not understand these commands.
71  return "Template Colormapping";
72 }
73 
74 const std::string WMTemplateColormapping::getDescription() const
75 {
76  // NOTE: Refer to WMTemplate.cpp if you do not understand these commands.
77  return "Show how to use colormapping in your modules.";
78 }
79 
81 {
82  // NOTE: Refer to WMTemplate.cpp if you do not understand these commands.
83 
84  // We do not need any connectors. Have a look at WMTemplate.cpp if you want to know what this means.
86 }
87 
89 {
90  // NOTE: Refer to WMTemplate.cpp if you do not understand these commands.
91 
92  m_propCondition = std::shared_ptr< WCondition >( new WCondition() );
93 
95 }
96 
98 {
99  // NOTE: Refer to WMTemplate.cpp if you do not understand these commands.
100 
101  // We need graphics to draw anything:
102  m_requirements.push_back( new WGERequirement() );
103 }
104 
105 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
106 // ATTENTION: now it gets interesting ...
107 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
108 
110 {
111  m_moduleState.setResetable( true, true );
113 
114  // Now, we can mark the module ready.
115  ready();
116 
117  // This tutorial is about applying the global colormapping to your geometry. So, if you write a module which creates some geometry, you might
118  // want to be able to map other datasets onto this surface. The WGEColormapping interface is made for exactly this. It consists of a C++ part
119  // and a quite complex GLSL part. But before we start, here are some important facts.
120  //
121  // In OpenWalnut, most 3D scalar or vectorial datasets can be used as colormaps. The data module automatically registers compatible datasets
122  // to the global colormapper. If you create data for your own, you can use the Colormapping module to register data. Each supported
123  // WDataSetSingle instance has a method getTexture() that returns the data as OpenGL compatible texture. As these texture were derived from
124  // WGETexture they already provide a lot of comfortable features. You have learned them in the WMTemplateShaders tutorial. These textures
125  // also store their transformation matrix and set them automatically to the right texture unit as texture matrix. So, the colormapper ensures
126  // that the colormap only appears on the surface parts that intersect with the bounding volume of the original dataset!
127  //
128  // This means, you can use either global colormapping, which usually is recommended or you can use an input dataset's texture and bind it to
129  // your state. This tutorial shows the global method as binding a texture was already shown in the shader tutorial. In GLSL, we then use the
130  // GLSL colormapping implementation to actually color each fragment.
131  // To run this module, you need to create a colormap (or load a dataset). An easy way is to add a Scalar Dataset Creator module and attach a
132  // Colormapper module to it! Ensure that the colormap-data overlaps with our geometry ... i.e. somewhere in the box defined by
133  // 0,0,0 to 100,100,50.
134 
135  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
136  // 1. Setup some geometry.
137  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
138 
139  osg::ref_ptr< WGEGroupNode > rootNode = new WGEGroupNode();
140 
141  // Add Scene
142  WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( rootNode );
143 
144  // Now we can add your demo geometry:
145  osg::ref_ptr< osg::Node > spheres = WDemoGeometry::createSphereGeometry();
146  osg::ref_ptr< osg::Node > plane = WDemoGeometry::createPlaneGeometry();
147 
148  // Allow blending here? Yes. We need it later.
149  plane->getOrCreateStateSet()->setMode( GL_BLEND, osg::StateAttribute::ON );
150  plane->getOrCreateStateSet()->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
151 
152  // To see our new geometry we need to add it to the group of ours:
153  rootNode->insert( spheres );
154  rootNode->insert( plane );
155 
156  // Allow blending, since colormaps might contain transparency.
157  rootNode->getOrCreateStateSet()->setMode( GL_BLEND, osg::StateAttribute::ON );
158 
159  // We use some shaders too:
160  osg::ref_ptr< WGEShader > globalShader(
161  new WGEShader(
162  "WMTemplateColormapping", // shader name prefix
163  m_localPath // where to search?
164  )
165  );
166  globalShader->apply( rootNode );
167 
168  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
169  // 2. Setup some the colormapper
170  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
171 
172  // Colormapping? One call!
173  WGEColormapping::apply( rootNode, // Apply to all our nodes
174  globalShader // Tell the colormapper which shader is bound to the node
175  );
176 
177  // This was easy! You tell the colormapper on which node you want to bind it and the corresponding shader. The shader is needed as the
178  // colormapper sets several defines to the shader.
179 
180  // Now we can switch over to the shader: WMTemplateColormapping-vertex.glsl!
181 
182  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
183  // 3. ... do stuff.
184  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
185 
186  // You already know this module loop code.
187 
188  // Now the remaining module code. In our case, this is empty.
189  while( !m_shutdownFlag() )
190  {
192  if( m_shutdownFlag() )
193  {
194  break;
195  }
196  }
197 
198  // Never miss to clean up. Especially remove your OSG nodes. Everything else you add to these nodes will be removed automatically.
199  debugLog() << "Shutting down ...";
200  WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->remove( rootNode );
201 }
202 
virtual void wait() const
Wait for the condition.
void setResetable(bool resetable=true, bool autoReset=true)
Sets the resetable flag.
virtual void add(std::shared_ptr< WCondition > condition)
Adds another condition to the set of conditions to wait for.
Class to encapsulate boost::condition_variable_any.
Definition: WCondition.h:42
static void apply(osg::ref_ptr< osg::Node > node, WMatrix4d preTransform=WMatrix4d::identity(), osg::ref_ptr< WGEShader > shader=osg::ref_ptr< WGEShader >(), size_t startTexUnit=0)
Apply the colormapping to the specified node.
Class to wrap around the osg Group node and providing a thread safe add/removal mechanism.
Definition: WGEGroupNode.h:48
This requirement ensures an up and running WGE.
Class encapsulating the OSG Program class for a more convenient way of adding and modifying shader.
Definition: WGEShader.h:48
static WKernel * getRunningKernel()
Returns pointer to the currently running kernel.
Definition: WKernel.cpp:117
std::shared_ptr< WGraphicsEngine > getGraphicsEngine() const
Returns pointer to currently running instance of graphics engine.
Definition: WKernel.cpp:122
virtual void moduleMain()
Entry point after loading the module.
virtual void requirements()
Initialize requirements for this module.
virtual ~WMTemplateColormapping()
Destructor.
virtual const std::string getDescription() const
Gives back a description of this module.
std::shared_ptr< WCondition > m_propCondition
A condition for property updates.
virtual const std::string getName() const
Gives back the name of this module.
virtual void properties()
Initialize the properties for this module.
virtual void connectors()
Initialize the connectors this module is using.
virtual std::shared_ptr< WModule > factory() const
Due to the prototype design pattern used to build modules, this method returns a new instance of this...
Class representing a single module of OpenWalnut.
Definition: WModule.h:72
boost::filesystem::path m_localPath
The path where the module binary resides in.
Definition: WModule.h:734
Requirements m_requirements
The list of requirements.
Definition: WModule.h:754
virtual void properties()
Initialize properties in this function.
Definition: WModule.cpp:212
wlog::WStreamedLogger debugLog() const
Logger instance for comfortable debug logging.
Definition: WModule.cpp:575
void ready()
Call this whenever your module is ready and can react on property changes.
Definition: WModule.cpp:505
WConditionSet m_moduleState
The internal state of the module.
Definition: WModule.h:703
virtual void connectors()
Initialize connectors in this function.
Definition: WModule.cpp:208
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.
osg::ref_ptr< osg::Node > createSphereGeometry()
Create several spheres.
osg::ref_ptr< osg::Node > createPlaneGeometry()
Create a plane.