Developer Documentation
Loading...
Searching...
No Matches
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
45
46
47//=============================================================================
48//
49// CLASS ShaderNode - IMPLEMENTATION
50//
51//=============================================================================
52
53
54//== INCLUDES =================================================================
55
56
57#include "ShaderNode.hh"
58
59
60//== NAMESPACES ===============================================================
61
62namespace ACG {
63namespace SceneGraph {
64
65
66//== IMPLEMENTATION ==========================================================
67
68
70 const std::string& _name)
71 : BaseNode(_parent, _name),
72 shaderDir_("")
73{
74}
75
77 for ( std::map<size_t,ShaderInfo>::iterator it = shaders.begin(); it != shaders.end(); ++it) {
78 if ( it->second.initialized ) {
79
80 if ( it->second.program != 0 )
81 delete it->second.program;
82
83 if ( it->second.vertexShader != 0 )
84 delete it->second.vertexShader;
85
86 if ( it->second.fragmentShader != 0 )
87 delete it->second.fragmentShader;
88 }
89 }
90}
91
92//----------------------------------------------------------------------------
93bool
95hasShader( DrawModes::DrawMode _drawmode, bool _pick ) {
96
97 if ( !_drawmode.isAtomic() ) {
98 std::cerr << "hasShader: Error, draw mode not atomic!" << std::endl;
99 return false;
100 }
101
102 std::map<size_t,ShaderInfo>::iterator it;
103
104 if ( _pick ) {
105 it = pickShaders.find(_drawmode.getIndex());
106 if ( it == pickShaders.end() )
107 return false;
108 } else {
109 it = shaders.find(_drawmode.getIndex());
110 if ( it == shaders.end() )
111 return false;
112 }
113
114 return it->second.initialized;
115}
116
117//----------------------------------------------------------------------------
118
119
120void
121ShaderNode::enter(GLState& /*_state*/, const DrawModes::DrawMode& _drawmode )
122{
123 for ( std::map<size_t,ShaderInfo>::iterator it = shaders.begin(); it != shaders.end(); ++it) {
124 if ( _drawmode.containsAtomicDrawMode(DrawModes::DrawMode(it->first)) && it->second.initialized ) {
125 it->second.program->use();
126 }
127 }
128}
129
130//----------------------------------------------------------------------------
131
132void
133ShaderNode::enterPick(GLState& /*_state*/, PickTarget /*_target*/, const DrawModes::DrawMode& _drawmode )
134{
135 for ( std::map<size_t,ShaderInfo>::iterator it = pickShaders.begin(); it != pickShaders.end(); ++it) {
136 if ( _drawmode.containsAtomicDrawMode(DrawModes::DrawMode(it->first)) && it->second.initialized ) {
137 it->second.program->use();
138 }
139 }
140}
141
142//----------------------------------------------------------------------------
143std::string
144ShaderNode::vertexShaderName(DrawModes::DrawMode _drawmode, bool _pick) {
145
146 if ( !_drawmode.isAtomic() ) {
147 std::cerr << "vertexShaderName: Error, draw mode not atomic!" << std::endl;
148 return std::string("");
149 }
150
151 std::map<size_t,ShaderInfo>::iterator it;
152
153 if ( _pick ) {
154 it = pickShaders.find(_drawmode.getIndex());
155 if ( it == pickShaders.end() )
156 return std::string("");
157 } else {
158 it = shaders.find(_drawmode.getIndex());
159 if ( it == shaders.end() )
160 return std::string("");
161 }
162
163 if ( it->second.initialized )
164 return it->second.vertexShaderFile;
165
166 return std::string("");
167}
168
169//----------------------------------------------------------------------------
170std::string
171ShaderNode::fragmentShaderName(DrawModes::DrawMode _drawmode, bool _pick) {
172
173 if ( !_drawmode.isAtomic() ) {
174 std::cerr << "fragmentShaderName: Error, draw mode not atomic!" << std::endl;
175 return std::string("");
176 }
177
178 std::map<size_t,ShaderInfo>::iterator it;
179
180 if ( _pick ) {
181 it = pickShaders.find(_drawmode.getIndex());
182 if ( it == pickShaders.end() )
183 return std::string("");
184 } else {
185 it = shaders.find(_drawmode.getIndex());
186 if ( it == shaders.end() )
187 return std::string("");
188 }
189
190 if ( it->second.initialized )
191 return it->second.fragmentShaderFile;
192
193 return std::string("");
194}
195
196
197//----------------------------------------------------------------------------
198
199
200void ShaderNode::leave(GLState& /*_state*/, const DrawModes::DrawMode& _drawmode )
201{
202 for ( std::map<size_t,ShaderInfo>::iterator it = shaders.begin(); it != shaders.end(); ++it)
203 if ( _drawmode.containsAtomicDrawMode(DrawModes::DrawMode(it->first)) && it->second.initialized )
204 it->second.program->disable();
205}
206
207//----------------------------------------------------------------------------
208
209
210void ShaderNode::leavePick(GLState& /*_state*/, PickTarget /*_target*/, const DrawModes::DrawMode& _drawmode )
211{
212 for ( std::map<size_t,ShaderInfo>::iterator it = pickShaders.begin(); it != pickShaders.end(); ++it)
213 if ( _drawmode.containsAtomicDrawMode(DrawModes::DrawMode(it->first)) && it->second.initialized )
214 it->second.program->disable();
215}
216
217//----------------------------------------------------------------------------
218
222getShader( DrawModes::DrawMode _drawmode, bool _pick ) {
223
224 if ( !_drawmode.isAtomic() ) {
225 std::cerr << "getShader: Error, draw mode not atomic!" << std::endl;
226 return 0;
227 }
228
229 std::map<size_t,ShaderInfo>::iterator it;
230
231 if ( _pick ) {
232 it = pickShaders.find(_drawmode.getIndex());
233
234 if ( it == pickShaders.end() )
235 return 0;
236
237 if ( it->second.initialized )
238 return it->second.program;
239 else
240 return 0;
241
242 } else {
243 it = shaders.find(_drawmode.getIndex());
244
245 if ( it == shaders.end() )
246 return 0;
247
248 if ( it->second.initialized )
249 return it->second.program;
250 else
251 return 0;
252 }
253
254 // No shader found for this mode
255 return 0;
256}
257
258//----------------------------------------------------------------------------
259
260void
263
264
265 if ( !_drawmode.isAtomic() ) {
266 std::cerr << "disableShader: Error, draw mode not atomic!" << std::endl;
267 return;
268 }
269
270 size_t index = _drawmode.getIndex();
271
272 // Cleanup old shaders for this mode, if they exist
273 if ( shaders[index].initialized ) {
274 if ( shaders[index].program != 0 )
275 delete shaders[index].program;
276
277 if ( shaders[index].vertexShader != 0 )
278 delete shaders[index].vertexShader;
279
280 if ( shaders[index].fragmentShader != 0 )
281 delete shaders[index].fragmentShader;
282
283 shaders[index].initialized = false;
284 }
285}
286
287//----------------------------------------------------------------------------
288
289void
292 const std::string& _vertexShader,
293 const std::string& _fragmentShader,
294 std::string _pickVertexShader,
295 std::string _pickFragmentShader) {
296
297 if ( !ACG::openGLVersion(2,0) ) {
298 std::cerr << "Shaders not supported with OpenGL Version less than 2.0" << std::endl;
299 return;
300 }
301
302 if ( shaderDir_ == "" ) {
303 std::cerr << "No shader dir set for shadernode. Unable to load shaders!" << std::endl;
304 return;
305 }
306
307 if ( !_drawmode.isAtomic() ) {
308 std::cerr << "setShader: Error, draw mode not atomic!" << std::endl;
309 return;
310 }
311
312 disableShader (_drawmode);
313 size_t index = _drawmode.getIndex();
314
315 shaders[index].vertexShaderFile = shaderDir_ + _vertexShader;
316 shaders[index].fragmentShaderFile = shaderDir_ + _fragmentShader;
317
318 const char* vertexShaderFilePath = shaders[index].vertexShaderFile.c_str();
319 const char* fragmentShaderFilePath = shaders[index].fragmentShaderFile.c_str();
320 shaders[index].vertexShader = GLSL::loadVertexShader(vertexShaderFilePath);
321 shaders[index].fragmentShader = GLSL::loadFragmentShader(fragmentShaderFilePath);
322 shaders[index].program = GLSL::PtrProgram(new GLSL::Program());
323
324 if ( (shaders[index].vertexShader == 0) ||
325 (shaders[index].fragmentShader == 0) ||
326 (shaders[index].program == 0) ) {
327 std::cerr << "Unable to load shaders" << shaders[index].vertexShaderFile <<
328 " or " << shaders[index].fragmentShaderFile << std::endl;
329 shaders[index].vertexShader = 0;
330 shaders[index].fragmentShader = 0;
331 shaders[index].program = 0;
332 shaders[index].initialized = false;
333 return;
334 }
335
336 shaders[index].program->attach(shaders[index].vertexShader);
337 shaders[index].program->attach(shaders[index].fragmentShader);
338 shaders[index].program->link();
339
340 shaders[index].initialized = true;
341
342
343 // Cleanup old shaders for this mode, if they exist
344 if ( pickShaders[index].initialized ) {
345 if ( pickShaders[index].program != 0 )
346 delete pickShaders[index].program;
347
348 if ( pickShaders[index].vertexShader != 0 )
349 delete pickShaders[index].vertexShader;
350
351 if ( pickShaders[index].fragmentShader != 0 )
352 delete pickShaders[index].fragmentShader;
353
354 pickShaders[index].initialized = false;
355 }
356
357 if (_pickVertexShader.length () > 0 && _pickFragmentShader.length () > 0)
358 {
359 pickShaders[index].vertexShaderFile = shaderDir_ + _pickVertexShader;
360 pickShaders[index].fragmentShaderFile = shaderDir_ + _pickFragmentShader;
361
362 const char* vertexShaderFilePath2 = pickShaders[index].vertexShaderFile.c_str();
363 const char* fragmentShaderFilePath2 = pickShaders[index].fragmentShaderFile.c_str();
364 pickShaders[index].vertexShader = GLSL::loadVertexShader(vertexShaderFilePath2);
365 pickShaders[index].fragmentShader = GLSL::loadFragmentShader(fragmentShaderFilePath2);
366 pickShaders[index].program = GLSL::PtrProgram(new GLSL::Program());
367
368 if ( (pickShaders[index].vertexShader == 0) ||
369 (pickShaders[index].fragmentShader == 0) ||
370 (pickShaders[index].program == 0) ) {
371 std::cerr << "Unable to load pick shaders" << pickShaders[index].vertexShaderFile <<
372 " or " << pickShaders[index].fragmentShaderFile << std::endl;
373 pickShaders[index].vertexShader = 0;
374 pickShaders[index].fragmentShader = 0;
375 pickShaders[index].program = 0;
376 pickShaders[index].initialized = false;
377 return;
378 }
379
380 pickShaders[index].program->attach(pickShaders[index].vertexShader);
381 pickShaders[index].program->attach(pickShaders[index].fragmentShader);
382 pickShaders[index].program->link();
383
384 pickShaders[index].initialized = true;
385 }
386}
387
388//----------------------------------------------------------------------------
389
390void
392setShaderDir( std::string _shaderDir) {
393 shaderDir_ = _shaderDir;
394}
395
398availableDrawModes() const
399{
401
402 for ( std::map<size_t,ShaderInfo>::const_iterator it = shaders.begin(); it != shaders.end(); ++it) {
403 // If the shader for this drawmode is initialized, this node supports the given draw mode.
404 // Then we add it to the list of supported draw modes
405 if ( it->second.initialized) {
406 drawModes |= DrawModes::DrawMode(it->first);
407 }
408 }
409
410 return drawModes;
411
412}
413
414//=============================================================================
415} // namespace SceneGraph
416} // namespace ACG
417//=============================================================================
size_t getIndex() const
get an index of the current drawMode
Definition DrawModes.cc:424
bool containsAtomicDrawMode(const DrawMode &_atomicDrawMode) const
Check whether an Atomic DrawMode is active in this draw Mode.
Definition DrawModes.cc:510
bool isAtomic() const
Check if this is an atomic draw Mode.
Definition DrawModes.cc:502
void setShaderDir(std::string _shaderDir)
Sets the shader dir.
bool hasShader(DrawModes::DrawMode _drawmode, bool _pick=false)
Check if a shader is available for the given drawMode.
Definition ShaderNode.cc:95
void leavePick(GLState &, PickTarget _target, const DrawModes::DrawMode &_drawmode) override
disable shader
virtual ~ShaderNode()
Destructor.
Definition ShaderNode.cc:76
ShaderNode(BaseNode *_parent=0, const std::string &_name="<ShaderNode>")
Default constructor. Applies all properties.
Definition ShaderNode.cc:69
GLSL::PtrProgram getShader(DrawModes::DrawMode _drawmode, bool _pick=false)
Get the shader for the given drawMode.
void disableShader(DrawModes::DrawMode _drawmode)
DrawModes::DrawMode availableDrawModes() const override
return available draw modes
void leave(GLState &, const DrawModes::DrawMode &_drawmode) override
disable shader
void enter(GLState &, const DrawModes::DrawMode &_drawmode) override
set shader
void enterPick(GLState &, PickTarget _target, const DrawModes::DrawMode &_drawmode) override
set shader
void setShader(DrawModes::DrawMode _drawmode, const std::string &_vertexShader, const std::string &_fragmentShader, std::string _pickVertexShader="", std::string _pickFragmentShader="")
GLSL program class.
DrawMode NONE
not a valid draw mode
Definition DrawModes.cc:71
PickTarget
What target to use for picking.
Definition PickTarget.hh:74
Namespace providing different geometric functions concerning angles.
bool openGLVersion(const int _major, const int _minor, bool _verbose)
Definition gl.cc:129
GLSL::PtrFragmentShader loadFragmentShader(const char *name, const GLSL::StringList *macros, bool verbose)
Loads, compiles and installs a new vertex shader.
GLSL::PtrVertexShader loadVertexShader(const char *name, const GLSL::StringList *macros, bool verbose)
Loads, compiles and installs a new vertex shader.