Developer Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
ShaderNode.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $Author$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49
50
51
52
53 //=============================================================================
54 //
55 // CLASS ShaderNode - IMPLEMENTATION
56 //
57 //=============================================================================
58
59
60 //== INCLUDES =================================================================
61
62
63 #include "ShaderNode.hh"
64
65
66 //== NAMESPACES ===============================================================
67
68 namespace ACG {
69 namespace SceneGraph {
70
71
72 //== IMPLEMENTATION ==========================================================
73
74
75 ShaderNode::ShaderNode( BaseNode* _parent,
76 const std::string& _name)
77 : BaseNode(_parent, _name),
78 shaderDir_("")
79 {
80 }
81
82 ShaderNode::~ShaderNode() {
83 for ( std::map<size_t,ShaderInfo>::iterator it = shaders.begin(); it != shaders.end(); ++it) {
84 if ( it->second.initialized ) {
85
86 if ( it->second.program != 0 )
87 delete it->second.program;
88
89 if ( it->second.vertexShader != 0 )
90 delete it->second.vertexShader;
91
92 if ( it->second.fragmentShader != 0 )
93 delete it->second.fragmentShader;
94 }
95 }
96 }
97
98 //----------------------------------------------------------------------------
99 bool
100 ShaderNode::
101 hasShader( DrawModes::DrawMode _drawmode, bool _pick ) {
102
103 if ( !_drawmode.isAtomic() ) {
104 std::cerr << "hasShader: Error, draw mode not atomic!" << std::endl;
105 return false;
106 }
107
108 std::map<size_t,ShaderInfo>::iterator it;
109
110 if ( _pick ) {
111 it = pickShaders.find(_drawmode.getIndex());
112 if ( it == pickShaders.end() )
113 return false;
114 } else {
115 it = shaders.find(_drawmode.getIndex());
116 if ( it == shaders.end() )
117 return false;
118 }
119
120 return it->second.initialized;
121 }
122
123 //----------------------------------------------------------------------------
124
125
126 void
127 ShaderNode::enter(GLState& /*_state*/, const DrawModes::DrawMode& _drawmode )
128 {
129 for ( std::map<size_t,ShaderInfo>::iterator it = shaders.begin(); it != shaders.end(); ++it) {
130 if ( _drawmode.containsAtomicDrawMode(it->first) && it->second.initialized ) {
131 it->second.program->use();
132 }
133 }
134 }
135
136 //----------------------------------------------------------------------------
137
138 void
139 ShaderNode::enterPick(GLState& /*_state*/, PickTarget /*_target*/, const DrawModes::DrawMode& _drawmode )
140 {
141 for ( std::map<size_t,ShaderInfo>::iterator it = pickShaders.begin(); it != pickShaders.end(); ++it) {
142 if ( _drawmode.containsAtomicDrawMode(it->first) && it->second.initialized ) {
143 it->second.program->use();
144 }
145 }
146 }
147
148 //----------------------------------------------------------------------------
149 std::string
150 ShaderNode::vertexShaderName(DrawModes::DrawMode _drawmode, bool _pick) {
151
152 if ( !_drawmode.isAtomic() ) {
153 std::cerr << "vertexShaderName: Error, draw mode not atomic!" << std::endl;
154 return std::string("");
155 }
156
157 std::map<size_t,ShaderInfo>::iterator it;
158
159 if ( _pick ) {
160 it = pickShaders.find(_drawmode.getIndex());
161 if ( it == pickShaders.end() )
162 return std::string("");
163 } else {
164 it = shaders.find(_drawmode.getIndex());
165 if ( it == shaders.end() )
166 return std::string("");
167 }
168
169 if ( it->second.initialized )
170 return it->second.vertexShaderFile;
171
172 return std::string("");
173 }
174
175 //----------------------------------------------------------------------------
176 std::string
177 ShaderNode::fragmentShaderName(DrawModes::DrawMode _drawmode, bool _pick) {
178
179 if ( !_drawmode.isAtomic() ) {
180 std::cerr << "fragmentShaderName: Error, draw mode not atomic!" << std::endl;
181 return std::string("");
182 }
183
184 std::map<size_t,ShaderInfo>::iterator it;
185
186 if ( _pick ) {
187 it = pickShaders.find(_drawmode.getIndex());
188 if ( it == pickShaders.end() )
189 return std::string("");
190 } else {
191 it = shaders.find(_drawmode.getIndex());
192 if ( it == shaders.end() )
193 return std::string("");
194 }
195
196 if ( it->second.initialized )
197 return it->second.fragmentShaderFile;
198
199 return std::string("");
200 }
201
202
203 //----------------------------------------------------------------------------
204
205
206 void ShaderNode::leave(GLState& /*_state*/, const DrawModes::DrawMode& _drawmode )
207 {
208 for ( std::map<size_t,ShaderInfo>::iterator it = shaders.begin(); it != shaders.end(); ++it)
209 if ( _drawmode.containsAtomicDrawMode(it->first) && it->second.initialized )
210 it->second.program->disable();
211 }
212
213 //----------------------------------------------------------------------------
214
215
216 void ShaderNode::leavePick(GLState& /*_state*/, PickTarget /*_target*/, const DrawModes::DrawMode& _drawmode )
217 {
218 for ( std::map<size_t,ShaderInfo>::iterator it = pickShaders.begin(); it != pickShaders.end(); ++it)
219 if ( _drawmode.containsAtomicDrawMode(it->first) && it->second.initialized )
220 it->second.program->disable();
221 }
222
223 //----------------------------------------------------------------------------
224
226 GLSL::PtrProgram
227 ShaderNode::
228 getShader( DrawModes::DrawMode _drawmode, bool _pick ) {
229
230 if ( !_drawmode.isAtomic() ) {
231 std::cerr << "getShader: Error, draw mode not atomic!" << std::endl;
232 return 0;
233 }
234
235 std::map<size_t,ShaderInfo>::iterator it;
236
237 if ( _pick ) {
238 it = pickShaders.find(_drawmode.getIndex());
239
240 if ( it == pickShaders.end() )
241 return 0;
242
243 if ( it->second.initialized )
244 return it->second.program;
245 else
246 return 0;
247
248 } else {
249 it = shaders.find(_drawmode.getIndex());
250
251 if ( it == shaders.end() )
252 return 0;
253
254 if ( it->second.initialized )
255 return it->second.program;
256 else
257 return 0;
258 }
259
260 // No shader found for this mode
261 return 0;
262 }
263
264 //----------------------------------------------------------------------------
265
266 void
267 ShaderNode::
268 disableShader (DrawModes::DrawMode _drawmode) {
269
270
271 if ( !_drawmode.isAtomic() ) {
272 std::cerr << "disableShader: Error, draw mode not atomic!" << std::endl;
273 return;
274 }
275
276 size_t index = _drawmode.getIndex();
277
278 // Cleanup old shaders for this mode, if they exist
279 if ( shaders[index].initialized ) {
280 if ( shaders[index].program != 0 )
281 delete shaders[index].program;
282
283 if ( shaders[index].vertexShader != 0 )
284 delete shaders[index].vertexShader;
285
286 if ( shaders[index].fragmentShader != 0 )
287 delete shaders[index].fragmentShader;
288
289 shaders[index].initialized = false;
290 }
291 }
292
293 //----------------------------------------------------------------------------
294
295 void
296 ShaderNode::
297 setShader( DrawModes::DrawMode _drawmode ,
298 std::string _vertexShader,
299 std::string _fragmentShader,
300 std::string _pickVertexShader,
301 std::string _pickFragmentShader) {
302
303 if ( !ACG::openGLVersion(2,0) ) {
304 std::cerr << "Shaders not supported with OpenGL Version less than 2.0" << std::endl;
305 return;
306 }
307
308 if ( shaderDir_ == "" ) {
309 std::cerr << "No shader dir set for shadernode. Unable to load shaders!" << std::endl;
310 return;
311 }
312
313 if ( !_drawmode.isAtomic() ) {
314 std::cerr << "setShader: Error, draw mode not atomic!" << std::endl;
315 return;
316 }
317
318 disableShader (_drawmode);
319 size_t index = _drawmode.getIndex();
320
321 shaders[index].vertexShaderFile = shaderDir_ + _vertexShader;
322 shaders[index].fragmentShaderFile = shaderDir_ + _fragmentShader;
323
324 const char* vertexShaderFilePath = shaders[index].vertexShaderFile.c_str();
325 const char* fragmentShaderFilePath = shaders[index].fragmentShaderFile.c_str();
326 shaders[index].vertexShader = GLSL::loadVertexShader(vertexShaderFilePath);
327 shaders[index].fragmentShader = GLSL::loadFragmentShader(fragmentShaderFilePath);
328 shaders[index].program = GLSL::PtrProgram(new GLSL::Program());
329
330 if ( (shaders[index].vertexShader == 0) ||
331 (shaders[index].fragmentShader == 0) ||
332 (shaders[index].program == 0) ) {
333 std::cerr << "Unable to load shaders" << shaders[index].vertexShaderFile <<
334 " or " << shaders[index].fragmentShaderFile << std::endl;
335 shaders[index].vertexShader = 0;
336 shaders[index].fragmentShader = 0;
337 shaders[index].program = 0;
338 shaders[index].initialized = false;
339 return;
340 }
341
342 shaders[index].program->attach(shaders[index].vertexShader);
343 shaders[index].program->attach(shaders[index].fragmentShader);
344 shaders[index].program->link();
345
346 shaders[index].initialized = true;
347
348
349 // Cleanup old shaders for this mode, if they exist
350 if ( pickShaders[index].initialized ) {
351 if ( pickShaders[index].program != 0 )
352 delete pickShaders[index].program;
353
354 if ( pickShaders[index].vertexShader != 0 )
355 delete pickShaders[index].vertexShader;
356
357 if ( pickShaders[index].fragmentShader != 0 )
358 delete pickShaders[index].fragmentShader;
359
360 pickShaders[index].initialized = false;
361 }
362
363 if (_pickVertexShader.length () > 0 && _pickFragmentShader.length () > 0)
364 {
365 pickShaders[index].vertexShaderFile = shaderDir_ + _pickVertexShader;
366 pickShaders[index].fragmentShaderFile = shaderDir_ + _pickFragmentShader;
367
368 const char* vertexShaderFilePath = pickShaders[index].vertexShaderFile.c_str();
369 const char* fragmentShaderFilePath = pickShaders[index].fragmentShaderFile.c_str();
370 pickShaders[index].vertexShader = GLSL::loadVertexShader(vertexShaderFilePath);
371 pickShaders[index].fragmentShader = GLSL::loadFragmentShader(fragmentShaderFilePath);
372 pickShaders[index].program = GLSL::PtrProgram(new GLSL::Program());
373
374 if ( (pickShaders[index].vertexShader == 0) ||
375 (pickShaders[index].fragmentShader == 0) ||
376 (pickShaders[index].program == 0) ) {
377 std::cerr << "Unable to load pick shaders" << pickShaders[index].vertexShaderFile <<
378 " or " << pickShaders[index].fragmentShaderFile << std::endl;
379 pickShaders[index].vertexShader = 0;
380 pickShaders[index].fragmentShader = 0;
381 pickShaders[index].program = 0;
382 pickShaders[index].initialized = false;
383 return;
384 }
385
386 pickShaders[index].program->attach(pickShaders[index].vertexShader);
387 pickShaders[index].program->attach(pickShaders[index].fragmentShader);
388 pickShaders[index].program->link();
389
390 pickShaders[index].initialized = true;
391 }
392 }
393
394 //----------------------------------------------------------------------------
395
396 void
397 ShaderNode::
398 setShaderDir( std::string _shaderDir) {
399 shaderDir_ = _shaderDir;
400 }
401
402 DrawModes::DrawMode
403 ShaderNode::
404 availableDrawModes() const
405 {
406 DrawModes::DrawMode drawModes(DrawModes::NONE);
407
408 for ( std::map<size_t,ShaderInfo>::const_iterator it = shaders.begin(); it != shaders.end(); ++it) {
409 // If the shader for this drawmode is initialized, this node supports the given draw mode.
410 // Then we add it to the list of supported draw modes
411 if ( it->second.initialized) {
412 drawModes |= DrawModes::DrawMode(it->first);
413 }
414 }
415
416 return drawModes;
417
418 }
419
420 //=============================================================================
421 } // namespace SceneGraph
422 } // namespace ACG
423 //=============================================================================
ACG::SceneGraph::ShaderNode::enter
void enter(GLState &, const DrawModes::DrawMode &_drawmode)
set shader
Definition: ShaderNode.cc:127
ACG::SceneGraph::ShaderNode::hasShader
bool hasShader(DrawModes::DrawMode _drawmode, bool _pick=false)
Check if a shader is available for the given drawMode.
Definition: ShaderNode.cc:101
ACG
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
ACG::SceneGraph::DrawModes::DrawMode::getIndex
size_t getIndex() const
get an index of the current drawMode
ACG::SceneGraph::BaseNode
Definition: BaseNode.hh:135
ACG::SceneGraph::GLSL::Program
GLSL program class.
Definition: MeshNode2T.cc:217
ACG::SceneGraph::PickTarget
PickTarget
What target to use for picking.
Definition: BaseNode.hh:99
ACG::SceneGraph::DrawModes::DrawMode::containsAtomicDrawMode
bool containsAtomicDrawMode(DrawMode _atomicDrawMode) const
Check whether an Atomic DrawMode is active in this draw Mode.
ACG::SceneGraph::ShaderNode::disableShader
void disableShader(DrawModes::DrawMode _drawmode)
Definition: ShaderNode.cc:268
ACG::SceneGraph::ShaderNode::~ShaderNode
virtual ~ShaderNode()
Destructor.
Definition: ShaderNode.cc:82
ACG::SceneGraph::GLSL::loadVertexShader
GLSL::PtrVertexShader ACGDLLEXPORT loadVertexShader(const char *name, const GLSL::StringList *macros=0, bool verbose=true)
Loads, compiles and installs a new vertex shader.
Definition: GLSLShader.cc:975
ACG::openGLVersion
bool openGLVersion(const int _major, const int _minor)
Definition: gl.cc:95
ACG::GLState
Definition: GLState.hh:220
ACG::SceneGraph::ShaderNode::setShader
void setShader(DrawModes::DrawMode _drawmode, std::string _vertexShader, std::string _fragmentShader, std::string _pickVertexShader="", std::string _pickFragmentShader="")
Definition: ShaderNode.cc:297
ACG::SceneGraph::ShaderNode::leavePick
void leavePick(GLState &, PickTarget _target, const DrawModes::DrawMode &_drawmode)
disable shader
Definition: ShaderNode.cc:216
ACG::SceneGraph::DrawModes::DrawMode
Specifies a DrawMode.
Definition: DrawModes.hh:294
ACG::SceneGraph::ShaderNode::enterPick
void enterPick(GLState &, PickTarget _target, const DrawModes::DrawMode &_drawmode)
set shader
Definition: ShaderNode.cc:139
ACG::SceneGraph::ShaderNode::getShader
GLSL::PtrProgram getShader(DrawModes::DrawMode _drawmode, bool _pick=false)
Get the shader for the given drawMode.
Definition: ShaderNode.cc:228
ACG::SceneGraph::ShaderNode::setShaderDir
void setShaderDir(std::string _shaderDir)
Sets the shader dir.
Definition: ShaderNode.cc:398
ACG::SceneGraph::DrawModes::DrawMode::isAtomic
bool isAtomic() const
Check if this is an atomic draw Mode.
ACG::SceneGraph::ShaderNode::ShaderNode
ShaderNode(BaseNode *_parent=0, const std::string &_name="<ShaderNode>")
Default constructor. Applies all properties.
Definition: ShaderNode.cc:75
ACG::SceneGraph::GLSL::loadFragmentShader
GLSL::PtrFragmentShader ACGDLLEXPORT loadFragmentShader(const char *name, const GLSL::StringList *macros=0, bool verbose=true)
Loads, compiles and installs a new vertex shader.
Definition: GLSLShader.cc:989
ACG::SceneGraph::ShaderNode::leave
void leave(GLState &, const DrawModes::DrawMode &_drawmode)
disable shader
Definition: ShaderNode.cc:206
ACG::SceneGraph::DrawModes::NONE
DrawMode NONE
not a valid draw mode
Definition: DrawModes.cc:77
ACG::SceneGraph::ShaderNode::availableDrawModes
DrawModes::DrawMode availableDrawModes() const
return available draw modes
Definition: ShaderNode.cc:404