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
IRenderer.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 #include <ACG/GL/acg_glew.hh>
51 #include <cstdio>
52 #include <cstring>
53 #include <iostream>
54 #include <QFile>
55 #include <QTextStream>
56
57 #include <ACG/GL/gl.hh>
58
59 #include <ACG/GL/IRenderer.hh>
60
61 #include <ACG/GL/VertexDeclaration.hh>
62 #include <ACG/GL/GLError.hh>
63
64 #include <ACG/GL/ShaderCache.hh>
65 #include <ACG/GL/ScreenQuad.hh>
66 #include <ACG/GL/FBO.hh>
67 #include <ACG/GL/globjects.hh>
68
69
70
71 namespace ACG
72 {
73
74 IRenderer::IRenderer()
75 : numLights_(0),
76 renderObjects_(0),
77 depthMapUsed_(false),
78 curViewerID_(0),
79 prevFbo_(0),
80 prevDrawBuffer_(GL_BACK),
81 prevFboSaved_(false),
82 depthCopyShader_(0),
83 errorDetectionLevel_(1),
84 enableLineThicknessGL42_(false)
85 {
86 prevViewport_[0] = 0;
87 prevViewport_[1] = 0;
88 prevViewport_[2] = 0;
89 prevViewport_[3] = 0;
90
91 // set global ambient scale to default OpenGL value
92 globalLightModelAmbient_ = ACG::Vec3f(0.2f, 0.2f, 0.2f);
93 }
94
95
96 IRenderer::~IRenderer()
97 {
98 delete depthCopyShader_;
99
100 // free depth map fbos
101 for (std::map<int, ACG::FBO*>::iterator it = depthMaps_.begin(); it != depthMaps_.end(); ++it)
102 delete it->second;
103 }
104
105 void IRenderer::addRenderObject(ACG::RenderObject* _renderObject)
106 {
107 // avoid null-ptr access
108 if (!_renderObject->debugName)
109 _renderObject->debugName = "<unnamed>";
110
111 if (_renderObject->name.empty())
112 _renderObject->name = _renderObject->debugName;
113
114 // do some more checks for error detection
115 if (!_renderObject->vertexDecl && !_renderObject->vertexArrayObject)
116 std::cout << "error: missing vertex declaration in renderobject: " << _renderObject->debugName << std::endl;
117 else
118 {
119 if (errorDetectionLevel_ > 0)
120 {
121 // commonly encountered rendering errors
122
123 if (!_renderObject->numIndices)
124 std::cout << "warning: numIndices is 0 in renderobject: " << _renderObject->debugName << std::endl;
125
126 // Why is my object invisible/black?
127 if (!_renderObject->depthWrite &&
128 !_renderObject->colorWriteMask[0] && !_renderObject->colorWriteMask[1] &&
129 !_renderObject->colorWriteMask[2] && !_renderObject->colorWriteMask[3])
130 std::cout << "warning: depth write and color write disabled in renderobject: " << _renderObject->debugName << std::endl;
131
132 if (errorDetectionLevel_ > 1 && _renderObject->shaderDesc.shadeMode == SG_SHADE_UNLIT)
133 {
134 if (_renderObject->emissive.max() < 1e-3f)
135 std::cout << "warning: unlit object rendered with black emissive color: " << _renderObject->debugName << std::endl;
136 else
137 {
138 // rendering with clear color
139
140 float clearColor[4];
141 glGetFloatv(GL_COLOR_CLEAR_VALUE, clearColor);
142
143 if (checkEpsilon(clearColor[0] - _renderObject->emissive[0]) &&
144 checkEpsilon(clearColor[1] - _renderObject->emissive[1]) &&
145 checkEpsilon(clearColor[2] - _renderObject->emissive[2]))
146 {
147 std::cout << "warning: unlit object rendered with clear color as emissive color: " << _renderObject->debugName << std::endl;
148 std::cout << " Should this be intentional, disable color writing instead via obj->glColorMask(0,0,0,0)" << std::endl;
149 }
150 }
151 }
152
153 if (_renderObject->textures().size())
154 {
155 // Why are my textures sampled as black?
156
157 // mipmap enabled, but no mipmap chain provided?
158
159 for (std::map<size_t,RenderObject::Texture>::const_iterator it = _renderObject->textures().begin();
160 it != _renderObject->textures().end(); ++it)
161 {
162 #ifdef GL_ARB_texture_buffer_object
163 if (it->second.type == GL_TEXTURE_BUFFER)
164 continue; // skip texture buffers, for which testing for mipmaps would generate an error
165 #endif
166
167 glBindTexture(it->second.type, it->second.id);
168
169 GLint minFilter = GL_NONE;
170 glGetTexParameteriv(it->second.type, GL_TEXTURE_MIN_FILTER, &minFilter);
171
172 if (minFilter == GL_NEAREST_MIPMAP_LINEAR ||
173 minFilter == GL_NEAREST_MIPMAP_NEAREST ||
174 minFilter == GL_LINEAR_MIPMAP_LINEAR ||
175 minFilter == GL_LINEAR_MIPMAP_NEAREST)
176 {
177 GLint maxLevel = 0;
178 glGetTexParameteriv(it->second.type, GL_TEXTURE_MAX_LEVEL, &maxLevel);
179
180 GLint texWidth = 0;
181 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &texWidth);
182
183 GLint maxLod = -1;
184 for (GLint lod = 0; lod < maxLevel && maxLod < 0; ++lod)
185 {
186 GLint lodWidth;
187 glGetTexLevelParameteriv(GL_TEXTURE_2D, lod, GL_TEXTURE_WIDTH, &lodWidth);
188
189 if (lodWidth <= 0 || lodWidth == GL_INVALID_VALUE)
190 maxLod = lod-1;
191 }
192
193 if (maxLod <= 0 && texWidth > 1)
194 {
195 std::cout << "warning: texture is sampled with mipmapping, but no mipchain is present: " << _renderObject->debugName << " texid: " << it->second.id << std::endl;
196 std::cout << " automatically disabling mipmapping!!" << std::endl;
197
198 GLint correctedFilter = GL_LINEAR;
199
200 if (minFilter == GL_NEAREST_MIPMAP_LINEAR ||
201 minFilter == GL_LINEAR_MIPMAP_LINEAR)
202 correctedFilter = GL_LINEAR;
203 else
204 correctedFilter = GL_NEAREST;
205
206 glTexParameteri(it->second.type, GL_TEXTURE_MIN_FILTER, correctedFilter);
207 }
208 }
209 }
210
211 }
212
213 if (errorDetectionLevel_ > 1)
214 {
215 // Why is there nothing written to the depth-buffer?
216 // this might very well be intentional, so put it in higher level
217
218 if (_renderObject->depthWrite && !_renderObject->depthTest)
219 {
220 std::cout << "warning: trying to write to depth buffer with depth-testing disabled does not work in: " << _renderObject->debugName << std::endl;
221 std::cout << " If depth-writing was intended, enable depth-testing and set depth-func to GL_ALWAYS" << std::endl;
222 }
223 }
224
225 if (!_renderObject->vertexArrayObject)
226 {
227 // Why are there gl errors and/or nothing gets drawn?
228 if (_renderObject->shaderDesc.shadeMode != SG_SHADE_UNLIT)
229 {
230 // check for normals
231 if (!_renderObject->vertexDecl->findElementByUsage(VERTEX_USAGE_NORMAL))
232 std::cout << "warning: missing normals for lighting in renderobject: " << _renderObject->debugName << std::endl
233 << " Set shadeMode to SG_SHADE_UNLIT or provide normals!" << std::endl;
234 }
235
236 if (_renderObject->shaderDesc.textured())
237 {
238 // check for texcoords
239 if (!_renderObject->vertexDecl->findElementByUsage(VERTEX_USAGE_TEXCOORD))
240 std::cout << "warning: missing texcoords for textured mode in renderobject: " << _renderObject->debugName << std::endl;
241 }
242
243 if (_renderObject->shaderDesc.vertexColors)
244 {
245 // check for vertex colors
246 if (!_renderObject->vertexDecl->findElementByUsage(VERTEX_USAGE_COLOR))
247 std::cout << "warning: missing colors for vertexcolor mode in renderobject: " << _renderObject->debugName << std::endl;
248 }
249 }
250
251
252 // Why is alpha blending not work?
253 if (fabsf(_renderObject->alpha - 1.0f) > 1e-3f && !(_renderObject->alphaTest || _renderObject->blending))
254 std::cout << "warning: alpha value != 1 but no alpha blending or testing enabled in renderobject: " << _renderObject->debugName << std::endl;
255
256
257 #ifdef GL_ARB_tessellation_shader
258 // Trying to render with tessellation shaders?
259 const bool tessellationActive = !_renderObject->shaderDesc.tessControlTemplateFile.isEmpty() || !_renderObject->shaderDesc.tessEvaluationTemplateFile.isEmpty();
260 bool tryToFixPatchInfo = false;
261 if (tessellationActive && _renderObject->primitiveMode != GL_PATCHES)
262 {
263 std::cout << "error: tessellation shaders are not used with GL_PATCHES primitiveType in renderobject: " << _renderObject->debugName << std::endl;
264 tryToFixPatchInfo = true;
265 }
266
267 if (tessellationActive && !_renderObject->patchVertices)
268 {
269 std::cout << "error: undefined patch size for tessellation in renderobject: " << _renderObject->debugName << std::endl;
270 tryToFixPatchInfo = true;
271 }
272
273 if (tryToFixPatchInfo)
274 {
275 if (_renderObject->primitiveMode == GL_POINTS)
276 {
277 _renderObject->primitiveMode = GL_PATCHES;
278 _renderObject->patchVertices = 1;
279 std::cout << "warning: attempting to draw with patchVertices = 1 for tessellation in renderobject: " << _renderObject->debugName << std::endl;
280 }
281 else if (_renderObject->primitiveMode == GL_LINES)
282 {
283 _renderObject->primitiveMode = GL_PATCHES;
284 _renderObject->patchVertices = 2;
285 std::cout << "warning: attempting to draw with patchVertices = 2 for tessellation in renderobject: " << _renderObject->debugName << std::endl;
286 }
287 else if (_renderObject->primitiveMode == GL_TRIANGLES)
288 {
289 _renderObject->primitiveMode = GL_PATCHES;
290 _renderObject->patchVertices = 3;
291 std::cout << "warning: attempting to draw with patchVertices = 3 for tessellation in renderobject: " << _renderObject->debugName << std::endl;
292 }
293 else if (_renderObject->primitiveMode == GL_QUADS)
294 {
295 _renderObject->primitiveMode = GL_PATCHES;
296 _renderObject->patchVertices = 4;
297 std::cout << "warning: attempting to draw with patchVertices = 4 for tessellation in renderobject: " << _renderObject->debugName << std::endl;
298 }
299 }
300
301 #endif
302 }
303
304
305 renderObjects_.push_back(*_renderObject);
306
307
308 ACG::RenderObject* p = &renderObjects_.back();
309
310 if (!p->shaderDesc.numLights)
311 p->shaderDesc.numLights = numLights_;
312
313 else if (p->shaderDesc.numLights < 0 || p->shaderDesc.numLights >= SG_MAX_SHADER_LIGHTS)
314 p->shaderDesc.numLights = 0;
315
316 p->internalFlags_ = 0;
317
318 // precompile shader
319 #ifdef GL_VERSION_3_2
320 GLSL::Program* shaderProg = ACG::ShaderCache::getInstance()->getProgram(&p->shaderDesc);
321 #endif
322
323
324 // check primitive type and geometry shader
325 if (errorDetectionLevel_ > 1 && p->shaderDesc.geometryTemplateFile.length())
326 {
327 #ifdef GL_VERSION_3_2
328 GLint geomInputType = 0;
329 glGetProgramiv(shaderProg->getProgramId(), GL_GEOMETRY_INPUT_TYPE, &geomInputType);
330
331
332 if (geomInputType != GLint(p->primitiveMode))
333 {
334
335 switch (geomInputType)
336 {
337 case GL_POINTS: std::cout << "warning: primitive mode is incompatible with points-geometryshader in renderobject: " << _renderObject->debugName << std::endl; break;
338
339 case GL_LINES:
340 {
341 if (p->primitiveMode != GL_LINE_STRIP && p->primitiveMode != GL_LINE_LOOP)
342 std::cout << "warning: primitive mode is incompatible with lines-geometryshader in renderobject: " << _renderObject->debugName << std::endl;
343 } break;
344
345 case GL_LINES_ADJACENCY:
346 {
347 if (p->primitiveMode != GL_LINE_STRIP_ADJACENCY)
348 std::cout << "warning: primitive mode is incompatible with lines_adjacency-geometryshader in renderobject: " << _renderObject->debugName << std::endl;
349 } break;
350
351 case GL_TRIANGLES:
352 {
353 if (p->primitiveMode != GL_TRIANGLE_STRIP && p->primitiveMode != GL_TRIANGLE_FAN)
354 std::cout << "warning: primitive mode is incompatible with triangles-geometryshader in renderobject: " << _renderObject->debugName << std::endl;
355 } break;
356
357 case GL_TRIANGLES_ADJACENCY:
358 {
359 if (p->primitiveMode != GL_TRIANGLE_STRIP_ADJACENCY)
360 std::cout << "warning: primitive mode is incompatible with triangles_adjacency-geometryshader in renderobject: " << _renderObject->debugName << std::endl;
361 } break;
362
363 default: std::cout << "warning: unknown input_type for geometryshader in renderobject: " << _renderObject->debugName << std::endl;
364 }
365
366
367
368 }
369
370
371 #else
372 if (_renderObject->isDefaultLineObject())
373 {
374 if (_renderObject->primitiveMode != GL_LINES && _renderObject->primitiveMode != GL_LINE_STRIP && _renderObject->primitiveMode != GL_LINE_LOOP)
375 std::cout << "warning: primitive mode is incompatible with lines-geometryshader in renderobject: " << _renderObject->debugName << std::endl;
376 }
377 else if (_renderObject->isDefaultPointObject())
378 {
379 if (_renderObject->primitiveMode != GL_POINTS)
380 std::cout << "warning: primitive mode is incompatible with points-geometryshader in renderobject: " << _renderObject->debugName << std::endl;
381 }
382 #endif
383 }
384
385 }
386 }
387
388
389
390
391 void IRenderer::collectRenderObjects( ACG::GLState* _glState, ACG::SceneGraph::DrawModes::DrawMode _drawMode, ACG::SceneGraph::BaseNode* _sceneGraphRoot )
392 {
393 // collect light sources
394 // collectLightNodes(_sceneGraphRoot);
395 numLights_ = 0; // reset light counter
396
397 // // flush render objects
398 // for (size_t i = 0; i < renderObjects_.size(); ++i)
399 // {
400 // renderObjects_[i].uniformPool_.clear();
401 // }
402 renderObjects_.resize(0);
403
404
405 // default material needed
406 ACG::SceneGraph::Material defMat;
407 defMat.baseColor(ACG::Vec4f(0.0f, 0.0f, 0.0f, 1.0f));
408 defMat.ambientColor(ACG::Vec4f(0.2f, 0.2f, 0.2f, 1.0f));
409 defMat.diffuseColor(ACG::Vec4f(0.6f, 0.6f, 0.6f, 1.0f));
410 defMat.specularColor(ACG::Vec4f(0.0f, 0.0f, 0.0f, 1.0f));
411 defMat.shininess(1.0f);
412 // defMat.alphaValue(1.0f);
413
414 // collect renderables
415 traverseRenderableNodes(_glState, _drawMode, _sceneGraphRoot, &defMat);
416 }
417
418
419
420
421
422 void IRenderer::traverseRenderableNodes( ACG::GLState* _glState, ACG::SceneGraph::DrawModes::DrawMode _drawMode, ACG::SceneGraph::BaseNode* _node, const ACG::SceneGraph::Material* _mat )
423 {
424 if (_node)
425 {
426 ACG::SceneGraph::BaseNode::StatusMode status(_node->status());
427
428 ACG::SceneGraph::DrawModes::DrawMode nodeDM = _node->drawMode();
429
430 if (nodeDM == ACG::SceneGraph::DrawModes::DEFAULT)
431 nodeDM = _drawMode;
432
433
434 // If the subtree is hidden, ignore this node and its children while rendering
435 if (status != ACG::SceneGraph::BaseNode::HideSubtree)
436 {
437
438 if ( _node->status() != ACG::SceneGraph::BaseNode::HideNode )
439 _node->enter(*_glState, nodeDM);
440
441
442 // fetch material (Node itself can be a material node, so we have to
443 // set that in front of the nodes own rendering
444 ACG::SceneGraph::MaterialNode* matNode = dynamic_cast<ACG::SceneGraph::MaterialNode*>(_node);
445 if (matNode)
446 _mat = &matNode->material();
447
448 if (_node->status() != ACG::SceneGraph::BaseNode::HideNode)
449 _node->getRenderObjects(this, *_glState, nodeDM, _mat);
450
451 // Process children?
452 if (status != ACG::SceneGraph::BaseNode::HideChildren)
453 {
454
455 ACG::SceneGraph::BaseNode::ChildIter cIt, cEnd(_node->childrenEnd());
456
457 // Process all children which are not second pass
458 for (cIt = _node->childrenBegin(); cIt != cEnd; ++cIt)
459 if (~(*cIt)->traverseMode() & ACG::SceneGraph::BaseNode::SecondPass)
460 traverseRenderableNodes( _glState, _drawMode, *cIt, _mat);
461
462 // Process all children which are second pass
463 for (cIt = _node->childrenBegin(); cIt != cEnd; ++cIt)
464 if ((*cIt)->traverseMode() & ACG::SceneGraph::BaseNode::SecondPass)
465 traverseRenderableNodes( _glState, _drawMode, *cIt, _mat);
466
467 }
468
469
470 if (_node->status() != ACG::SceneGraph::BaseNode::HideNode )
471 _node->leave(*_glState, nodeDM);
472 }
473 }
474 }
475
476
477 int IRenderer::cmpPriority(const void* _a, const void* _b)
478 {
479 const ACG::RenderObject* a = *(const ACG::RenderObject**)_a;
480 const ACG::RenderObject* b = *(const ACG::RenderObject**)_b;
481
482 return a->priority - b->priority;
483 }
484
485
486 void IRenderer::prepareRenderingPipeline(ACG::GLState* _glState, ACG::SceneGraph::DrawModes::DrawMode _drawMode, ACG::SceneGraph::BaseNode* _scenegraphRoot)
487 {
488 // grab view transform from glstate
489 viewMatrix_ = _glState->modelview();
490 camPosWS_ = Vec3f( viewMatrix_(0,3), viewMatrix_(1,3), viewMatrix_(2,3) );
491 camDirWS_ = Vec3f( viewMatrix_(0,2), viewMatrix_(1,2), -viewMatrix_(2,2) ); // mind the z flip
492
493 // printf("pos: %f %f %f\ndir: %f %f %f\n", camPosWS_[0], camPosWS_[1], camPosWS_[2],
494 // camDirWS_[0], camDirWS_[1], camDirWS_[2]);
495
496 // First, all render objects get collected.
497 collectRenderObjects(_glState, _drawMode, _scenegraphRoot);
498
499 // Check if there is anything to render
500 if (renderObjects_.empty())
501 return;
502
503 // ==========================================================
504 // Sort renderable objects based on their priority
505 // Filter for overlay, lines etc.
506 // ==========================================================
507
508 const size_t numRenderObjects = getNumRenderObjects(),
509 numOverlayObjects = getNumOverlayObjects(),
510 numLineObjects = getNumLineGL42Objects();
511
512 // sort for priority
513 if (sortedObjects_.size() < numRenderObjects)
514 sortedObjects_.resize(numRenderObjects);
515
516 if (overlayObjects_.size() < numOverlayObjects)
517 overlayObjects_.resize(numOverlayObjects);
518
519 if (lineGL42Objects_.size() < numLineObjects)
520 lineGL42Objects_.resize(numLineObjects);
521
522 // init sorted objects array
523 size_t sceneObjectOffset = 0, overlayObjectOffset = 0, lineObjectOffset = 0;
524 for (size_t i = 0; i < renderObjects_.size(); ++i)
525 {
526 if (renderObjects_[i].overlay)
527 overlayObjects_[overlayObjectOffset++] = &renderObjects_[i];
528 else if (enableLineThicknessGL42_ && numLineObjects && renderObjects_[i].isDefaultLineObject())
529 {
530 renderObjects_[i].shaderDesc.geometryTemplateFile = "Wireframe/gl42/geometry.tpl";
531 renderObjects_[i].shaderDesc.fragmentTemplateFile = "Wireframe/gl42/fragment.tpl";
532
533 // disable color write to fbo, but allow RenderObject to control depth write
534 renderObjects_[i].glColorMask(0,0,0,0);
535
536 // sortedObjects_[sceneObjectOffset++] = &renderObjects_[i];
537 lineGL42Objects_[lineObjectOffset++] = &renderObjects_[i];
538 }
539 else
540 sortedObjects_[sceneObjectOffset++] = &renderObjects_[i];
541 }
542
543 sortRenderObjects();
544
545
546 // ---------------------------
547 // Initialize the render state
548 // ---------------------------
549 // gl cleanup
550
551 glDisableClientState(GL_VERTEX_ARRAY);
552 glDisableClientState(GL_COLOR_ARRAY);
553 glDisableClientState(GL_NORMAL_ARRAY);
554 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
555 glDisableClientState(GL_INDEX_ARRAY);
556
557
558 glEnable(GL_CULL_FACE);
559 glEnable(GL_DEPTH_TEST);
560 glDepthFunc(GL_LESS);
561 glDepthMask(GL_TRUE);
562
563 // save active fbo and viewport
564 saveInputFbo();
565
566
567 // get global ambient factor
568 GLfloat lightModelAmbient[4];
569 glGetFloatv(GL_LIGHT_MODEL_AMBIENT, lightModelAmbient);
570 globalLightModelAmbient_ = ACG::Vec3f(lightModelAmbient[0], lightModelAmbient[1], lightModelAmbient[2]);
571
572
573 // search list of render object for objects requiring the scene depth map
574 bool requiresSceneDepths = false;
575
576 for (size_t i = 0; i < renderObjects_.size(); ++i)
577 {
578 if (renderObjects_[i].depthMapUniformName)
579 requiresSceneDepths = true;
580 }
581
582 // render scene depth map
583 if (requiresSceneDepths)
584 renderDepthMap(curViewerID_, _glState->viewport_width(), _glState->viewport_height());
585 }
586
587
588
589 void IRenderer::finishRenderingPipeline(bool _drawOverlay)
590 {
591 #ifdef GL_ARB_vertex_array_object
592 glBindVertexArray(0);
593 #endif
594
595 // draw thick lines
596 if (enableLineThicknessGL42_)
597 renderLineThicknessGL42();
598
599 if (_drawOverlay)
600 {
601 const int numOverlayObj = getNumOverlayObjects();
602 // two-pass overlay rendering:
603 // 1. clear depth buffer at pixels of overlay objects
604 // 2. render overlay with correct depth-testing
605
606 // 1. pass: clear depth to max value at overlay footprint
607 for (int i = 0; i < numOverlayObj; ++i)
608 {
609 RenderObject* obj = getOverlayRenderObject(i);
610
611 if (obj->depthTest && obj->depthFunc != GL_ALWAYS)
612 {
613 float depthMax = 1.0f;
614
615 if (obj->depthFunc == GL_GREATER || obj->depthFunc == GL_GEQUAL)
616 depthMax = 0.0f;
617
618 // save depth setting of renderobject
619 Vec2f depthRange = obj->depthRange;
620 bool depthWrite = obj->depthWrite;
621 GLenum depthFunc = obj->depthFunc;
622
623 // reset depth to maximal distance by using depth range
624 obj->depthRange = Vec2f(depthMax, depthMax);
625 obj->depthWrite = true;
626 obj->depthFunc = GL_ALWAYS;
627
628 renderObject(obj);
629
630 // restore depth setting
631 obj->depthRange = depthRange;
632 obj->depthWrite = depthWrite;
633 obj->depthFunc = depthFunc;
634 }
635
636 }
637
638 // 2. render overlay with correct depth-testing
639 for (int i = 0; i < numOverlayObj; ++i)
640 {
641 RenderObject* obj = getOverlayRenderObject(i);
642 renderObject(obj);
643 }
644
645 }
646
647 #ifdef GL_ARB_vertex_array_object
648 glBindVertexArray(0);
649 #endif
650
651 glDepthMask(1);
652 glColorMask(1,1,1,1);
653
654 glUseProgram(0);
655
656 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
657 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
658
659 // Renderer check:
660 // Print a warning if the currently active fbo / viewport is not the same as the saved fbo.
661 // Restore to previous fbo and viewport if not done already.
662
663 GLint curFbo;
664 GLint curViewport[4];
665 GLint curDrawBuf;
666 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &curFbo);
667 glGetIntegerv(GL_VIEWPORT, curViewport);
668 glGetIntegerv(GL_DRAW_BUFFER, &curDrawBuf);
669
670 if (curFbo != prevFbo_)
671 {
672 std::cout << "warning: input and output fbo are not the same in renderer implementation" << std::endl;
673 restoreInputFbo();
674 }
675
676 if (curDrawBuf != prevDrawBuffer_)
677 {
678 std::cout << "warning: input and output draw-buffer are not the same in renderer implementation" << std::endl;
679 restoreInputFbo();
680 }
681
682 if (curViewport[0] != prevViewport_[0] ||
683 curViewport[1] != prevViewport_[1] ||
684 curViewport[2] != prevViewport_[2] ||
685 curViewport[3] != prevViewport_[3])
686 {
687 std::cout << "warning: input and output viewport are not the same in renderer implementation" << std::endl;
688 restoreInputFbo();
689 }
690 }
691
692
693 void IRenderer::saveInputFbo()
694 {
695 // save active fbo
696 saveActiveFbo(&prevFbo_, prevViewport_, &prevDrawBuffer_);
697 prevFboSaved_ = true;
698 }
699
700 void IRenderer::restoreInputFbo()
701 {
702 if (prevFboSaved_)
703 restoreFbo(prevFbo_, prevViewport_, prevDrawBuffer_);
704 }
705
706 void IRenderer::saveActiveFbo( GLint* _outFboId, GLint* _outViewport, GLint* _outDrawBuffer ) const
707 {
708 // save active fbo
709 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, _outFboId);
710 glGetIntegerv(GL_VIEWPORT, _outViewport);
711 glGetIntegerv(GL_DRAW_BUFFER, _outDrawBuffer);
712 }
713
714 void IRenderer::restoreFbo( GLint _fboId, const GLint* _outViewport, GLint _drawBuffer ) const
715 {
716 glBindFramebuffer(GL_FRAMEBUFFER, _fboId);
717 glDrawBuffer(_drawBuffer);
718 glViewport(_outViewport[0], _outViewport[1], _outViewport[2], _outViewport[3]);
719 }
720
721 void IRenderer::clearInputFbo( const ACG::Vec4f& clearColor )
722 {
723 glClearColor(clearColor[0], clearColor[1], clearColor[2], 1.0f);
724
725 // glClear will affect the whole back buffer, not only the area in viewport.
726 // Temporarily use glScissor to only clear the viewport area in the back buffer.
727 if (!prevFboSaved_)
728 {
729 GLint oldViewport[4];
730 glGetIntegerv(GL_VIEWPORT, oldViewport);
731 glScissor(oldViewport[0], oldViewport[1], oldViewport[2], oldViewport[3]);
732 }
733 else
734 glScissor(prevViewport_[0], prevViewport_[1], prevViewport_[2], prevViewport_[3]);
735
736 glEnable(GL_SCISSOR_TEST);
737 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
738
739 // disable scissors again, draw calls only affect the area in glViewport anyway
740 glDisable(GL_SCISSOR_TEST);
741 }
742
743
744 void IRenderer::sortRenderObjects()
745 {
746 if (!sortedObjects_.empty())
747 qsort(&sortedObjects_[0], getNumRenderObjects(), sizeof(ACG::RenderObject*), cmpPriority);
748 if (!overlayObjects_.empty())
749 qsort(&overlayObjects_[0], getNumOverlayObjects(), sizeof(ACG::RenderObject*), cmpPriority);
750 }
751
752
753
754 void IRenderer::bindObjectVBO(ACG::RenderObject* _obj,
755 GLSL::Program* _prog)
756 {
757 _prog->use();
758
759
760 #ifdef GL_ARB_vertex_array_object
761 glBindVertexArray(_obj->vertexArrayObject);
762 #endif
763
764 if (!_obj->vertexArrayObject)
765 {
767 // NOTE:
768 // always bind buffers before glVertexAttribPointer calls!!
769 // freeze in glDrawElements guaranteed (with no error message whatsoever)
770 glBindBufferARB(GL_ARRAY_BUFFER_ARB, _obj->vertexBuffer);
771 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, _obj->indexBuffer);
772
773
774 // activate vertex declaration
775 _obj->vertexDecl->activateShaderPipeline(_prog);
776
777 }
778 }
779
780
781 void IRenderer::bindObjectUniforms( ACG::RenderObject* _obj, GLSL::Program* _prog )
782 {
783 // transforms
784 ACG::GLMatrixf mvp = _obj->proj * _obj->modelview;
785 ACG::GLMatrixf mvIT = _obj->modelview;
786 mvIT.invert();
787 mvIT.transpose();
788
789 _prog->setUniform("g_mWVP", mvp);
790 _prog->setUniform("g_mWV", _obj->modelview);
791 _prog->setUniformMat3("g_mWVIT", mvIT);
792 _prog->setUniform("g_mP", _obj->proj);
793
794 _prog->setUniform("g_vCamPos", camPosWS_);
795 _prog->setUniform("g_vCamDir", camDirWS_);
796
797 // material
798
799 _prog->setUniform("g_cEmissive", _obj->emissive);
800
801 _prog->setUniform("g_cDiffuse", _obj->diffuse);
802 _prog->setUniform("g_cAmbient", _obj->ambient);
803 _prog->setUniform("g_cSpecular", _obj->specular);
804
805 ACG::Vec4f materialParams(_obj->shininess, _obj->alpha, 0.0f, 0.0f);
806 _prog->setUniform("g_vMaterial", materialParams);
807
808 _prog->setUniform("g_cLightModelAmbient", globalLightModelAmbient_);
809
810 // Additional Uniforms defined in the render Object
811 if ( !_obj->uniformPool_.empty() )
812 _obj->uniformPool_.bind(_prog);
813
814 // textures:
815
816 // maybe consider using bindless textures some time in the future
817 // to get rid of the old and problematic glActiveTexture(), glBindTexture() state machine usage:
818 // https://www.opengl.org/registry/specs/ARB/bindless_texture.txt
819
820 int maxTextureStage = 0;
821 for (std::map<size_t,RenderObject::Texture>::const_iterator iter = _obj->textures().begin();
822 iter != _obj->textures().end();++iter)
823 {
824 //check for valid texture id
825 const size_t texture_stage = iter->first;
826 const RenderObject::Texture tex = iter->second;
827 if (!tex.id)
828 continue;
829
830 glActiveTexture(GL_TEXTURE0 + (GLenum)texture_stage);
831 glBindTexture(iter->second.type, tex.id);
832 _prog->setUniform(QString("g_Texture%1").arg(texture_stage).toStdString().c_str(), (int)texture_stage);
833
834 maxTextureStage = std::max(maxTextureStage, (int)texture_stage);
835 }
836
837
838 // scene depth texture
839 if (_obj->depthMapUniformName)
840 {
841 // bind to (hopefully) unused texture stage
842 int depthMapSlot = maxTextureStage + 1;
843
844 _prog->setUniform(_obj->depthMapUniformName, depthMapSlot);
845 glActiveTexture(GL_TEXTURE0 + depthMapSlot);
846 glBindTexture(GL_TEXTURE_2D, depthMaps_[curViewerID_]->getAttachment(GL_COLOR_ATTACHMENT0));
847 }
848
849
850 // lights
851 for (int i = 0; i < numLights_; ++i)
852 {
853 LightData* lgt = lights_ + i;
854
855 char szUniformName[256];
856
857 sprintf(szUniformName, "g_cLightDiffuse_%d", i);
858 _prog->setUniform(szUniformName, lgt->diffuse);
859
860 sprintf(szUniformName, "g_cLightAmbient_%d", i);
861 _prog->setUniform(szUniformName, lgt->ambient);
862
863 sprintf(szUniformName, "g_cLightSpecular_%d", i);
864 _prog->setUniform(szUniformName, lgt->specular);
865
866
867 if (lgt->ltype == ACG::SG_LIGHT_POINT || lgt->ltype == ACG::SG_LIGHT_SPOT)
868 {
869 sprintf(szUniformName, "g_vLightPos_%d", i);
870 _prog->setUniform(szUniformName, lgt->pos);
871
872 sprintf(szUniformName, "g_vLightAtten_%d", i);
873 _prog->setUniform(szUniformName, lgt->atten);
874 }
875
876 if (lgt->ltype == ACG::SG_LIGHT_DIRECTIONAL || lgt->ltype == ACG::SG_LIGHT_SPOT)
877 {
878 sprintf(szUniformName, "g_vLightDir_%d", i);
879 _prog->setUniform(szUniformName, lgt->dir);
880 }
881
882 if (lgt->ltype == ACG::SG_LIGHT_SPOT)
883 {
884 sprintf(szUniformName, "g_vLightAngleExp_%d", i);
885 _prog->setUniform(szUniformName, lgt->spotCutoffExponent);
886 }
887 }
888 }
889
890 void IRenderer::bindObjectRenderStates(ACG::RenderObject* _obj)
891 {
892 if (_obj->culling)
893 glEnable(GL_CULL_FACE);
894 else
895 glDisable(GL_CULL_FACE);
896
897 if (_obj->blending)
898 glEnable(GL_BLEND);
899 else
900 glDisable(GL_BLEND);
901
902 if (_obj->alphaTest)
903 {
904 glEnable(GL_ALPHA_TEST);
905 glAlphaFunc(_obj->alphaFunc, _obj->alphaRef);
906 }
907 else
908 glDisable(GL_ALPHA_TEST);
909
910 if (_obj->depthTest)
911 glEnable(GL_DEPTH_TEST);
912 else
913 glDisable(GL_DEPTH_TEST);
914
915
916 glDepthMask(_obj->depthWrite ? GL_TRUE : GL_FALSE);
917
918 glColorMask(_obj->colorWriteMask[0], _obj->colorWriteMask[1], _obj->colorWriteMask[2], _obj->colorWriteMask[3]);
919
920 glDepthFunc(_obj->depthFunc);
921
922 glDepthRange(_obj->depthRange[0], _obj->depthRange[1]);
923
924 // ACG::GLState::shadeModel(_obj->shadeModel);
925
926 ACG::GLState::blendFunc(_obj->blendSrc, _obj->blendDest);
927 }
928
929 void IRenderer::drawObject(ACG::RenderObject* _obj)
930 {
931 if (_obj->numIndices)
932 {
933 // indexed drawing?
934 bool noIndices = true;
935 if (_obj->indexBuffer || _obj->sysmemIndexBuffer)
936 noIndices = false;
937
938 glPolygonMode(GL_FRONT_AND_BACK, _obj->fillMode);
939
940 // tessellation info
941 bool tessellationActive = !(_obj->shaderDesc.tessControlTemplateFile.isEmpty() && _obj->shaderDesc.tessEvaluationTemplateFile.isEmpty());
942 #ifdef GL_ARB_tessellation_shader
943 if (tessellationActive)
944 {
945 glPatchParameteri(GL_PATCH_VERTICES, _obj->patchVertices);
946
947 if (_obj->shaderDesc.tessControlTemplateFile.isEmpty())
948 {
949 glPatchParameterfv(GL_PATCH_DEFAULT_INNER_LEVEL, _obj->patchDefaultInnerLevel.data());
950 glPatchParameterfv(GL_PATCH_DEFAULT_OUTER_LEVEL, _obj->patchDefaultOuterLevel.data());
951 }
952 }
953 #else
954 if (tessellationActive)
955 std::cout << "error: tessellation shaders cannot be used with the outdated glew version" << std::endl;
956 #endif
957
958 if (noIndices) {
959 if (_obj->numInstances <= 0)
960 glDrawArrays(_obj->primitiveMode, _obj->indexOffset, _obj->numIndices);
961 else
962 glDrawArraysInstanced(_obj->primitiveMode, _obj->indexOffset, _obj->numIndices, _obj->numInstances);
963 }
964 else
965 {
966 // ------------------------------------------
967 // index offset stuff not tested
968 int indexSize = 0;
969 switch (_obj->indexType)
970 {
971 case GL_UNSIGNED_INT: indexSize = 4; break;
972 case GL_UNSIGNED_SHORT: indexSize = 2; break;
973 default: indexSize = 1; break;
974 }
975
976 if (_obj->numInstances <= 0)
977 glDrawElements(_obj->primitiveMode, _obj->numIndices, _obj->indexType,
978 ((const char*)_obj->sysmemIndexBuffer) + _obj->indexOffset * indexSize);
979 else
980 glDrawElementsInstanced(_obj->primitiveMode, _obj->numIndices, _obj->indexType,
981 ((const char*)_obj->sysmemIndexBuffer) + _obj->indexOffset * indexSize, _obj->numInstances);
982 }
983 }
984 }
985
986 void IRenderer::renderObject(ACG::RenderObject* _obj,
987 GLSL::Program* _prog,
988 bool _constRenderStates,
989 const std::vector<unsigned int>* _shaderModifiers)
990 {
991 // select shader from cache
992 GLSL::Program* prog = _prog ? _prog : ACG::ShaderCache::getInstance()->getProgram(&_obj->shaderDesc, _shaderModifiers);
993
994
995 bindObjectVBO(_obj, prog);
996
997 // ---------------------------------------
998 // set shader uniforms
999
1000 bindObjectUniforms(_obj, prog);
1001
1002 // render states
1003
1004 if (!_constRenderStates)
1005 bindObjectRenderStates(_obj);
1006
1007 // ----------------------------
1008 // OpenGL draw call
1009
1010 drawObject(_obj);
1011
1012
1013 ACG::glCheckErrors();
1014
1015 if (_obj->vertexDecl)
1016 {
1017 // deactivate vertex declaration to avoid errors
1018 _obj->vertexDecl->deactivateShaderPipeline(prog);
1019 }
1020
1021
1022 #ifdef GL_ARB_vertex_array_object
1023 if (_obj->vertexArrayObject)
1024 glBindVertexArray(0);
1025 #endif
1026
1027 }
1028
1029
1030 void IRenderer::addLight(const LightData& _light)
1031 {
1032 if (numLights_ < SG_MAX_SHADER_LIGHTS)
1033 {
1034 lights_[numLights_] = _light;
1035
1036 // normalize direction
1037 if (_light.ltype != SG_LIGHT_POINT)
1038 lights_[numLights_].dir.normalize();
1039
1040 ++numLights_;
1041 }
1042 }
1043
1044
1045 int IRenderer::getNumRenderObjects() const
1046 {
1047 int n = 0;
1048 for (size_t i = 0; i < renderObjects_.size(); ++i)
1049 if (!renderObjects_[i].overlay && !(renderObjects_[i].isDefaultLineObject() && enableLineThicknessGL42_))
1050 // if (!renderObjects_[i].overlay)
1051 ++n;
1052
1053 return n;
1054 }
1055
1056 int IRenderer::getNumOverlayObjects() const
1057 {
1058 int n = 0;
1059 for (size_t i = 0; i < renderObjects_.size(); ++i)
1060 if (renderObjects_[i].overlay)
1061 ++n;
1062
1063 return n;
1064 }
1065
1066 int IRenderer::getNumLineGL42Objects() const
1067 {
1068 int n = 0;
1069
1070 if (enableLineThicknessGL42_)
1071 {
1072 for (size_t i = 0; i < renderObjects_.size(); ++i)
1073 if (renderObjects_[i].isDefaultLineObject())
1074 ++n;
1075 }
1076
1077 return n;
1078 }
1079
1080 int IRenderer::getNumLights() const
1081 {
1082 return numLights_;
1083 }
1084
1085
1086 ACG::RenderObject* IRenderer::getRenderObject( int i )
1087 {
1088 if (sortedObjects_.empty())
1089 return &renderObjects_[i];
1090
1091 return sortedObjects_[i];
1092 }
1093
1094 ACG::RenderObject* IRenderer::getOverlayRenderObject( int i )
1095 {
1096 if (overlayObjects_.empty())
1097 return &renderObjects_[i];
1098
1099 return overlayObjects_[i];
1100 }
1101
1102 ACG::RenderObject* IRenderer::getLineGL42RenderObject( int i )
1103 {
1104 if (lineGL42Objects_.empty())
1105 return 0;
1106
1107 return lineGL42Objects_[i];
1108 }
1109
1110 IRenderer::LightData* IRenderer::getLight( int i )
1111 {
1112 return &lights_[i];
1113 }
1114
1115
1116 void IRenderer::dumpRenderObjectsToFile(const char* _fileName, ACG::RenderObject** _sortedList) const
1117 {
1118 QFile fileOut(_fileName);
1119 if (fileOut.open(QFile::WriteOnly | QFile::Truncate))
1120 {
1121 QTextStream outStrm(&fileOut);
1122 for (int i = 0; i < getNumRenderObjects(); ++i)
1123 {
1124 if (_sortedList)
1125 outStrm << "\n" << _sortedList[i]->toString();
1126 else
1127 outStrm << "\n" << renderObjects_[i].toString();
1128 }
1129
1130 fileOut.close();
1131 }
1132 }
1133
1134
1135 QString IRenderer::dumpCurrentRenderObjectsToString(ACG::RenderObject** _list, bool _outputShaders, std::vector<ACG::ShaderModifier*>* _modifiers) {
1136
1137 QString objectString;
1138
1139 QTextStream outStrm(&objectString);
1140
1141 for (int i = 0; i < getNumRenderObjects(); ++i)
1142 {
1143 const RenderObject* obj = _list ? _list[i] : &renderObjects_[i];
1144
1145 if (obj) {
1146 outStrm << "\n" << obj->toString();
1147
1148 if ( _outputShaders ) {
1149
1150 outStrm << "\n";
1151
1152 outStrm << obj->shaderDesc.toString();
1153
1154 ShaderProgGenerator progGen(&(obj->shaderDesc), _modifiers);
1155
1156 outStrm << "\n---------------------vertex-shader--------------------\n\n";
1157 for (int i = 0; i < progGen.getVertexShaderCode().size(); ++i)
1158 outStrm << progGen.getVertexShaderCode()[i] << "\n";
1159 outStrm << "\n---------------------end-vertex-shader--------------------\n\n";
1160
1161 if (progGen.hasTessControlShader())
1162 {
1163 outStrm << "\n---------------------tesscontrol-shader--------------------\n\n";
1164 for (int i = 0; i < progGen.getTessControlShaderCode().size(); ++i)
1165 outStrm << progGen.getTessControlShaderCode()[i] << "\n";
1166 outStrm << "\n---------------------end-tesscontrol-shader--------------------\n\n";
1167 }
1168
1169 if (progGen.hasTessControlShader())
1170 {
1171 outStrm << "\n---------------------tesseval-shader--------------------\n\n";
1172 if (progGen.hasTessEvaluationShader())
1173 for (int i = 0; i < progGen.getTessEvaluationShaderCode().size(); ++i)
1174 outStrm << progGen.getTessEvaluationShaderCode()[i] << "\n";
1175 outStrm << "\n---------------------end-tesseval-shader--------------------\n\n";
1176 }
1177
1178 if (progGen.hasGeometryShader())
1179 {
1180 outStrm << "\n---------------------geometry-shader--------------------\n\n";
1181 for (int i = 0; i < progGen.getGeometryShaderCode().size(); ++i)
1182 outStrm << progGen.getGeometryShaderCode()[i] << "\n";
1183 outStrm << "\n---------------------end-geometry-shader--------------------\n\n";
1184 }
1185
1186
1187 outStrm << "\n---------------------fragment-shader--------------------\n\n";
1188 for (int i = 0; i < progGen.getFragmentShaderCode().size(); ++i)
1189 outStrm << progGen.getFragmentShaderCode()[i] << "\n";
1190 outStrm << "\n---------------------end-fragment-shader--------------------\n\n";
1191 }
1192
1193 }
1194
1195 }
1196
1197 return objectString;
1198 }
1199
1200 void IRenderer::copyDepthToBackBuffer( GLuint _depthTex, float _scale /*= 1.0f*/ )
1201 {
1202 if (!_depthTex) return;
1203
1204 if (!depthCopyShader_)
1205 depthCopyShader_ = GLSL::loadProgram("ScreenQuad/screenquad.glsl", "ScreenQuad/depth_copy.glsl");
1206
1207
1208 if (depthCopyShader_)
1209 {
1210 // save important opengl states
1211 GLint curFbo;
1212 GLint curViewport[4];
1213 GLint curDrawBuffer;
1214 saveActiveFbo(&curFbo, curViewport, &curDrawBuffer);
1215
1216 GLboolean colorMask[4], depthMask;
1217 glGetBooleanv(GL_COLOR_WRITEMASK, colorMask);
1218 glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
1219
1220 GLboolean depthTestEnable;
1221 GLint depthFunc;
1222 glGetBooleanv(GL_DEPTH_TEST, &depthTestEnable);
1223 glGetIntegerv(GL_DEPTH_FUNC, &depthFunc);
1224
1225 // write to depth buffer of input fbo
1226 restoreInputFbo();
1227
1228 depthCopyShader_->use();
1229 depthCopyShader_->setUniform("offset", ACG::Vec2f(0.0f, 0.0f));
1230 depthCopyShader_->setUniform("size", ACG::Vec2f(1.0f, 1.0f));
1231 depthCopyShader_->setUniform("DepthTex", 0); // depth tex at texture slot 0
1232 depthCopyShader_->setUniform("DepthSign", _scale);
1233
1234 // write to depth buffer only, disable writing to color buffer
1235 glColorMask(0,0,0,0);
1236 glDepthMask(1);
1237
1238 // depth test enabled + pass always
1239 glEnable(GL_DEPTH_TEST);
1240 glDepthFunc(GL_ALWAYS);
1241
1242 glActiveTexture(GL_TEXTURE0);
1243 glBindTexture(GL_TEXTURE_2D, _depthTex);
1244
1245 ACG::ScreenQuad::draw(depthCopyShader_);
1246
1247
1248 // restore important opengl states
1249
1250 restoreFbo(curFbo, curViewport, curDrawBuffer);
1251
1252 glColorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
1253 glDepthMask(depthMask);
1254
1255 if (!depthTestEnable)
1256 glDisable(GL_DEPTH_TEST);
1257
1258 if (depthFunc != GL_ALWAYS)
1259 glDepthFunc(depthFunc);
1260
1261 glBindTexture(GL_TEXTURE_2D, 0);
1262 }
1263 }
1264
1265
1266 // depth map computation with a modifier
1267
1268 IRenderer::DepthMapPass IRenderer::DepthMapPass::instance;
1269
1270 void IRenderer::DepthMapPass::modifyFragmentEndCode(QStringList* _code)
1271 {
1272 _code->push_back("outFragment = gl_FragCoord.zzzz;");
1273 }
1274
1275 void IRenderer::renderDepthMap(int _viewerID, int _width, int _height)
1276 {
1277 ACG::FBO* fbo = depthMaps_[_viewerID];
1278
1279 // setup fbo for depth map
1280 if (!fbo)
1281 {
1282 fbo = depthMaps_[_viewerID] = new ACG::FBO();
1283
1284 fbo->bind();
1285 fbo->attachTexture2D(GL_COLOR_ATTACHMENT0, _width, _height, GL_R32F, GL_RED);
1286 fbo->addDepthBuffer(_width, _height);
1287 }
1288 else
1289 {
1290 fbo->bind();
1291 fbo->resize(_width, _height);
1292 }
1293
1294 // make sure modifier is registered
1295 ACG::ShaderProgGenerator::registerModifier(&DepthMapPass::instance);
1296
1297 /* note:
1298 It is possible to directly read the depth buffer if it was attached as a texture.
1299 Then, we would disable the color write mask and just write to the depth buffer in this function.
1300
1301 However, doing this has shown that the actual depth values written to the depth buffer highly depend on the gpu driver.
1302 Or, at least sampling from a texture with format GL_DEPTH_COMPONENT returns driver dependent values.
1303 For instance, in the amd-gl driver sampling the depth texture returns the value of gl_FragDepth (as expected).
1304 But in the nvidia driver, sampling directly from the depth buffer returns something different!
1305
1306 Therefore we render the value of gl_FragDepth to a custom floating-point texture bound to a color slot in order to get driver independent behavior.
1307 */
1308
1309 fbo->bind();
1310 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1311 glViewport(0, 0, _width, _height);
1312
1313 // set depth to max
1314 glColorMask(1,1,1,1);
1315 glDepthMask(1);
1316
1317 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
1318 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1319
1320 // render z-prepass
1321 for (int i = 0; i < getNumRenderObjects(); ++i)
1322 {
1323 RenderObject* obj = getRenderObject(i);
1324
1325 if (obj->inZPrePass)
1326 {
1327 // apply depth map modifier to get the depth pass shader
1328 GLSL::Program* depthPassShader = ShaderCache::getInstance()->getProgram(&obj->shaderDesc, DepthMapPass::instance);
1329
1330 // temporarily prevent read/write access to the same texture (the depth map)
1331 const char* depthMapUniformName = obj->depthMapUniformName;
1332 obj->depthMapUniformName = 0;
1333
1334 if (depthMapUniformName)
1335 {
1336 depthPassShader->use();
1337 depthPassShader->setUniform(depthMapUniformName, 0);
1338 glActiveTexture(GL_TEXTURE0);
1339 glBindTexture(GL_TEXTURE_2D, 0);
1340 }
1341
1342 // we are interested in the depth value only, so temporarily modify the write mask to allow writing to the red channel
1343 // (for instance, an object might not write a color value, but a depth value)
1344 const GLboolean redWriteMask = obj->colorWriteMask[0];
1345 obj->colorWriteMask[0] = obj->depthWrite;
1346
1347 renderObject(obj, depthPassShader);
1348
1349 // reset modified render object states
1350 obj->depthMapUniformName = depthMapUniformName;
1351 obj->colorWriteMask[0]= redWriteMask;
1352 }
1353 }
1354
1355 // restore input fbo state
1356
1357 fbo->unbind();
1358
1359 restoreInputFbo();
1360 }
1361
1362
1363 void IRenderer::setViewerID(int _viewerID)
1364 {
1365 curViewerID_ = _viewerID;
1366 }
1367
1368
1369 void IRenderer::renderLineThicknessGL42()
1370 {
1371 #ifdef GL_ARB_shader_image_load_store
1372 // quad extrusion has depth clipping issue
1373 // GL4.2 method: manually rasterize thick lines into load/store texture, thereby avoiding clipping
1374
1375 // experimental technique, needs some improvements for rasterization
1376 /* possible improvement:
1377 0. init depth buffer with scene objects
1378 1. extract visible line object (startpos, endpos) into imageBuffer after depth-test in fragment shader
1379 1a. line segment id can be found via atomic counter in geometry shader
1380 1b. use imageAtomicMin/max to find start and end pixel pos of each line segment
1381 atomic ops work with uint only, thus each segment has 4 texels in the imageBuffer, offsets are segmentID * 4 + {0,1,2,3}
1382 2. read imageBuffer in geometry shader and do usual quad extrusion, now without depth testing
1383 => get hw rasterization and msaa
1384 */
1385
1386 // using image2D does not work: texture always reads 0, even with glGetTexImage2D
1387 // imageBuffer works
1388 // - check with different gpu
1389
1390 const int numLines = getNumLineGL42Objects();
1391
1392 // configs
1393 const bool useBufferTexture = true; // imageBuffer or image2D
1394 const bool useIntegerTexture = true; // color as R32U or RGBA32F
1395
1396
1397
1398 if (numLines)
1399 {
1400
1401 // macro configs for shader
1402 QStringList macros;
1403
1404 if (useBufferTexture)
1405 macros.push_back("#define IMAGE_BUFFER");
1406 if (useIntegerTexture)
1407 macros.push_back("#define FMT_UINT");
1408
1409
1410 // get random access write buffer
1411 // 32bit uint per viewport pixel, stores rgba8
1412 Texture2D* lineColorImg2D = 0;
1413 TextureBuffer* lineColorImgBuf = 0;
1414
1415 GLsizei w = prevViewport_[2], h = prevViewport_[3];
1416 GLsizei lineBPP = useIntegerTexture ? 4 : 16; // bytes per pixel
1417
1418
1419 if (useBufferTexture)
1420 {
1421 lineColorImgBuf = dynamic_cast<TextureBuffer*>(lineColorBuffers_[curViewerID_]);
1422
1423 if (!lineColorImgBuf)
1424 {
1425 lineColorImgBuf = new TextureBuffer(GL_TEXTURE0);
1426 lineColorBuffers_[curViewerID_] = lineColorImgBuf;
1427 }
1428
1429 // resize
1430 if (lineColorImgBuf->getBufferSize() != w * h * lineBPP)
1431 lineColorImgBuf->setBufferData(w*h*lineBPP, 0, GL_R32UI, GL_DYNAMIC_DRAW);
1432 }
1433 else
1434 {
1435 lineColorImg2D = dynamic_cast<Texture2D*>(lineColorBuffers_[curViewerID_]);
1436
1437 if (!lineColorImg2D)
1438 {
1439 // allocate and store in map
1440 lineColorImg2D = new Texture2D(GL_TEXTURE0);
1441 lineColorBuffers_[curViewerID_] = lineColorImg2D;
1442 }
1443
1444 // resize
1445 if (lineColorImg2D->getWidth() != w || lineColorImg2D->getHeight() != h)
1446 lineColorImg2D->setData(0,
1447 useIntegerTexture ? GL_R32UI : GL_RGBA32F,
1448 w, h,
1449 useIntegerTexture ? GL_RED_INTEGER : GL_RGBA,
1450 useIntegerTexture ? GL_UNSIGNED_INT : GL_FLOAT,
1451 0);
1452 }
1453
1454
1455
1456
1457
1458 glViewport(0, 0, w, h);
1459
1460
1461
1462 // ---------------------------
1463 // clear line color buffer
1464
1465 glColorMask(0,0,0,0);
1466 glDepthMask(0);
1467 glDisable(GL_DEPTH_TEST);
1468
1469 // image binding is set to slot 0 in shader already
1470 if (useBufferTexture)
1471 lineColorImgBuf->bindAsImage(0, GL_WRITE_ONLY);
1472 else
1473 lineColorImg2D->bindAsImage(0, GL_WRITE_ONLY);
1474
1475 GLSL::Program* shaderClear = ShaderCache::getInstance()->getProgram("ScreenQuad/screenquad.glsl", "Wireframe/gl42/clear.glsl", &macros);
1476
1477 shaderClear->use();
1478 // shaderClear->setUniform("offset", Vec2f(0,0));
1479 // shaderClear->setUniform("size", Vec2f(1,1));
1480 shaderClear->setUniform("screenSize", Vec2f(w,h));
1481
1482 ScreenQuad::draw(shaderClear);
1483
1484 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
1485 // GLDebug::dumpTexture2D(lineColorBuf->id(), 0, lineColorBuf->getFormat(), lineColorBuf->getType(), lineBPP*w*h, "c:/dbg/lines_clear.dds");
1486 // GLDebug::dumpBufferData(GL_TEXTURE_BUFFER, lineColorBuf2->getBufferId(), "c:/dbg/lines_clear.bin");
1487
1488 // ---------------------------
1489 // 1. pass
1490 // render into line color buffer via imageStore,
1491
1492 for (int i = 0; i < numLines; ++i)
1493 {
1494 RenderObject* obj = getLineGL42RenderObject(i);
1495
1496 renderObject(obj);
1497 }
1498
1499 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
1500 // GLDebug::dumpTexture2D(lineColorBuf->id(), 0, lineColorBuf->getFormat(), lineColorBuf->getType(), lineBPP*w*h, "c:/dbg/lines_image.dds");
1501 // GLDebug::dumpBufferData(GL_TEXTURE_BUFFER, lineColorBuf2->getBufferId(), "c:/dbg/lines_image.bin");
1502
1503
1504 // ---------------------------
1505 // 2. pass
1506 // composition of line colors and fbo
1507
1508 restoreInputFbo();
1509
1510 // image binding is set to slot 0 in shader already
1511 if (useBufferTexture)
1512 lineColorImgBuf->bindAsImage(0, GL_READ_ONLY);
1513 else
1514 lineColorImg2D->bindAsImage(0, GL_READ_ONLY);
1515
1516
1517 glColorMask(1,1,1,1);
1518 glDisable(GL_DEPTH_TEST);
1519
1520 // enable alpha blending
1521 glEnable(GL_BLEND);
1522 ACG::GLState::blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1523
1524 GLSL::Program* shaderComposite = ShaderCache::getInstance()->getProgram("ScreenQuad/screenquad.glsl", "Wireframe/gl42/composite.glsl", &macros);
1525
1526 shaderComposite->use();
1527 // shaderComposite->setUniform("offset", Vec2f(0,0));
1528 // shaderComposite->setUniform("size", Vec2f(1,1));
1529 shaderComposite->setUniform("screenSize", Vec2f(w,h));
1530
1531 ScreenQuad::draw(shaderComposite);
1532
1533
1534 }
1535 #endif
1536 }
1537
1538 void IRenderer::setLineThicknessRenderingGL42( bool _enable )
1539 {
1540 if (Texture::supportsImageLoadStore() && Texture::supportsTextureBuffer())
1541 enableLineThicknessGL42_ = _enable;
1542 }
1543
1544 void IRenderer::setErrorDetectionLevel( int _level )
1545 {
1546 errorDetectionLevel_ = std::max(_level, 0); // clamp to [0,n]
1547 }
1548
1549 int IRenderer::getErrorDetectionLevel() const
1550 {
1551 return errorDetectionLevel_;
1552 }
1553
1554 } // namespace ACG end
1555
ACG::VertexDeclaration::deactivateShaderPipeline
void deactivateShaderPipeline(GLSL::Program *_prog) const
Definition: VertexDeclaration.cc:476
ACG::RenderObject::indexBuffer
GLuint indexBuffer
Use vertex array object.
Definition: RenderObject.hh:169
ACG::RenderObject::shaderDesc
ShaderGenDesc shaderDesc
Drawmode and other shader params.
Definition: RenderObject.hh:232
ACG::RenderObject::depthRange
Vec2f depthRange
glDepthRange: (znear, zmax)
Definition: RenderObject.hh:256
ACG::ShaderProgGenerator::getVertexShaderCode
const QStringList & getVertexShaderCode()
Returns generated vertex shader code.
Definition: ShaderGenerator.cc:2203
ACG
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
ACG::SceneGraph::BaseNode
Definition: BaseNode.hh:135
ACG::SceneGraph::Material::specularColor
void specularColor(const Vec4f &_s)
set the specular color
Definition: MaterialNode.hh:182
ACG::VERTEX_USAGE_NORMAL
"inNormal"
Definition: VertexDeclaration.hh:72
ACG::SceneGraph::DrawModes::DEFAULT
DrawMode DEFAULT
use the default (global) draw mode and not the node's own.
Definition: DrawModes.cc:78
ACG::FBO::attachTexture2D
void attachTexture2D(GLenum _attachment, GLsizei _width, GLsizei _height, GLuint _internalFmt, GLenum _format, GLint _wrapMode=GL_CLAMP, GLint _minFilter=GL_NEAREST, GLint _magFilter=GL_NEAREST)
function to attach a texture to fbo
Definition: FBO.cc:200
ACG::RenderObject::alphaFunc
GLenum alphaFunc
GL_LESS, GL_LEQUAL, GL_GREATER ..
Definition: RenderObject.hh:250
ACG::RenderObject::isDefaultLineObject
bool isDefaultLineObject() const
Test if the object is rendered with one of the default line thickness methods.
Definition: RenderObject.cc:455
ACG::ShaderProgGenerator::getFragmentShaderCode
const QStringList & getFragmentShaderCode()
Returns generated fragment shader code.
Definition: ShaderGenerator.cc:2223
ACG::RenderObject
Interface class between scenegraph and renderer.
Definition: RenderObject.hh:105
ACG::RenderObject::blendDest
GLenum blendDest
glBlendFunc: GL_SRC_ALPHA, GL_ZERO, GL_ONE, GL_ONE_MINUS_SRC_ALPHA ...
Definition: RenderObject.hh:254
ACG::ShaderProgGenerator
Definition: ShaderGenerator.hh:1152
ACG::VERTEX_USAGE_TEXCOORD
"inTexCoord"
Definition: VertexDeclaration.hh:73
ACG::IRenderer::depthCopyShader_
GLSL::Program * depthCopyShader_
shader copies depth of the first front layer to the back buffer
Definition: IRenderer.hh:503
ACG::ScreenQuad::draw
static void draw(GLSL::Program *_prog=0)
Draw the screen quad.
Definition: ScreenQuad.cc:147
ACG::ShaderProgGenerator::getTessEvaluationShaderCode
const QStringList & getTessEvaluationShaderCode()
Returns generated tessellation control shader code.
Definition: ShaderGenerator.cc:2213
ACG::IRenderer::errorDetectionLevel_
int errorDetectionLevel_
error-detection level for checking render objects
Definition: IRenderer.hh:506
GLSL::loadProgram
GLSL::PtrProgram loadProgram(const char *vertexShaderFile, const char *tessControlShaderFile, const char *tessEvaluationShaderFile, const char *geometryShaderFile, const char *fragmentShaderFile, const GLSL::StringList *macros, bool verbose)
Definition: GLSLShader.cc:1082
ACG::SceneGraph::BaseNode::HideSubtree
Hide this node and its children.
Definition: BaseNode.hh:374
ACG::FBO
Definition: FBO.hh:83
ACG::RenderObject::toString
QString toString() const
Definition: RenderObject.cc:228
ACG::RenderObject::vertexBuffer
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
Definition: RenderObject.hh:169
ACG::RenderObject::internalFlags_
unsigned int internalFlags_
may be used internally by the renderer
Definition: RenderObject.hh:357
ACG::RenderObject::depthFunc
GLenum depthFunc
GL_LESS, GL_LEQUAL, GL_GREATER ..
Definition: RenderObject.hh:247
ACG::SceneGraph::BaseNode::childrenBegin
ChildIter childrenBegin()
Returns: begin-iterator of children.
Definition: BaseNode.hh:270
ACG::ShaderProgGenerator::registerModifier
static unsigned int registerModifier(ShaderModifier *_modifier)
Shader modifiers have to be registered before they can be used. They also must remain allocated for t...
Definition: ShaderGenerator.cc:2412
ACG::SceneGraph::BaseNode::enter
virtual void enter(GLState &, const DrawModes::DrawMode &)
Definition: BaseNode.hh:182
ACG::Texture2D
Definition: globjects.hh:400
ACG::RenderObject::vertexArrayObject
GLuint vertexArrayObject
Use vertex array object.
Definition: RenderObject.hh:165
ACG::GLState::modelview
const GLMatrixd & modelview() const
get modelview matrix
Definition: GLState.hh:794
ACG::VertexDeclaration::activateShaderPipeline
void activateShaderPipeline(GLSL::Program *_prog) const
Definition: VertexDeclaration.cc:424
ACG::SceneGraph::BaseNode::getRenderObjects
virtual void getRenderObjects(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawMode, const Material *_mat)
Deferred draw call with shader based renderer.
Definition: BaseNode.hh:212
ACG::GLState
Definition: GLState.hh:220
ACG::ShaderGenDesc::toString
QString toString() const
convert ShaderGenDesc to string format for debugging
Definition: ShaderGenerator.cc:2688
ACG::FBO::addDepthBuffer
void addDepthBuffer(GLuint _width, GLuint _height)
function to add a depth renderbuffer to the fbo
Definition: FBO.cc:343
ACG::SceneGraph::Material::diffuseColor
void diffuseColor(const Vec4f &_d)
set the diffuse color.
Definition: MaterialNode.hh:177
ACG::RenderObject::sysmemIndexBuffer
const void * sysmemIndexBuffer
Use system memory index buffer.
Definition: RenderObject.hh:180
ACG::ShaderCache::getProgram
GLSL::Program * getProgram(const ShaderGenDesc *_desc, const std::vector< unsigned int > &_mods)
Query a dynamically generated program from cache.
Definition: ShaderCache.cc:108
ACG::ShaderProgGenerator::hasTessControlShader
bool hasTessControlShader() const
check whether there is a tess-control shader present
Definition: ShaderGenerator.cc:2452
GLSL::Program::use
void use()
Enables the program object for using.
Definition: GLSLShader.cc:351
ACG::SceneGraph::BaseNode::ChildIter
std::list< BaseNode * >::iterator ChildIter
allows to iterate over children
Definition: BaseNode.hh:262
ACG::RenderObject::vertexDecl
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
Definition: RenderObject.hh:215
ACG::GLMatrixT< float >
ACG::SceneGraph::DrawModes::DrawMode
Specifies a DrawMode.
Definition: DrawModes.hh:294
GLSL::Program::getProgramId
GLuint getProgramId()
Returns opengl id.
Definition: GLSLShader.cc:382
ACG::GLState::viewport_width
int viewport_width() const
get viewport width
Definition: GLState.hh:825
ACG::FBO::resize
void resize(GLsizei _width, GLsizei _height, bool _forceResize=false)
resize function (if textures created by this class)
Definition: FBO.cc:543
ACG::RenderObject::primitiveMode
GLenum primitiveMode
Primitive type.
Definition: RenderObject.hh:189
ACG::GLState::blendFunc
static void blendFunc(GLenum _sfactor, GLenum _dfactor)
replaces glBlendFunc, supports locking
Definition: GLState.hh:314
ACG::RenderObject::numIndices
unsigned int numIndices
Number indices to render.
Definition: RenderObject.hh:195
ACG::SceneGraph::BaseNode::HideChildren
Draw this node, but hide children.
Definition: BaseNode.hh:372
ACG::RenderObject::diffuse
Vec3f diffuse
material definitions
Definition: RenderObject.hh:267
ACG::RenderObject::name
std::string name
Name for logging.
Definition: RenderObject.hh:128
ACG::Vec3f
VectorT< float, 3 > Vec3f
Definition: VectorT.hh:125
ACG::VERTEX_USAGE_COLOR
"inColor"
Definition: VertexDeclaration.hh:74
ACG::SceneGraph::MaterialNode::material
ACG::SceneGraph::Material & material()
Get material object reference.
Definition: MaterialNode.hh:543
ACG::SceneGraph::BaseNode::SecondPass
Draw node in second pass.
Definition: BaseNode.hh:421
ACG::SceneGraph::BaseNode::StatusMode
StatusMode
Status modi.
Definition: BaseNode.hh:365
ACG::SceneGraph::BaseNode::drawMode
DrawModes::DrawMode drawMode() const
Return the own draw modes of this node.
Definition: BaseNode.hh:406
ACG::IRenderer::numLights_
int numLights_
Number of Lights.
Definition: IRenderer.hh:449
OpenMesh::VectorT
Definition: Vector11T.hh:83
ACG::SceneGraph::BaseNode::status
StatusMode status() const
Get node's status.
Definition: BaseNode.hh:377
ACG::SceneGraph::Material::ambientColor
void ambientColor(const Vec4f &_a)
set the ambient color.
Definition: MaterialNode.hh:172
ACG::IRenderer::depthMaps_
std::map< int, ACG::FBO * > depthMaps_
Definition: IRenderer.hh:473
ACG::IRenderer::addRenderObject
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
Definition: IRenderer.cc:105
ACG::ShaderCache::getInstance
static ShaderCache * getInstance()
Return instance of the ShaderCache singleton.
Definition: ShaderCache.cc:90
ACG::glCheckErrors
void glCheckErrors()
Definition: GLError.hh:105
ACG::RenderObject::Texture
Texture to be used.
Definition: RenderObject.hh:306
ACG::IRenderer::renderObjects_
std::vector< ACG::RenderObject > renderObjects_
array of renderobjects, filled by addRenderObject()
Definition: IRenderer.hh:459
ACG::SceneGraph::Material::baseColor
void baseColor(const Vec4f &_c)
set the base color
Definition: MaterialNode.hh:167
GLSL::Program::setUniform
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
Definition: GLSLShader.cc:391
ACG::ShaderProgGenerator::hasTessEvaluationShader
bool hasTessEvaluationShader() const
check whether there is a tess-evaluation shader present
Definition: ShaderGenerator.cc:2457
GLSL::Program
GLSL program class.
Definition: GLSLShader.hh:217
ACG::RenderObject::numInstances
GLsizei numInstances
Definition: RenderObject.hh:211
ACG::VertexDeclaration::findElementByUsage
const VertexElement * findElementByUsage(VERTEX_USAGE _usage) const
Definition: VertexDeclaration.cc:519
ACG::ShaderProgGenerator::getGeometryShaderCode
const QStringList & getGeometryShaderCode()
Returns generated tessellation evaluation shader code.
Definition: ShaderGenerator.cc:2218
ACG::RenderObject::modelview
GLMatrixd modelview
Modelview transform.
Definition: RenderObject.hh:145
GLSL::UniformPool::empty
bool empty() const
returns if the pool is empty
Definition: UniformPool.cc:95
ACG::SceneGraph::BaseNode::HideNode
Hide this node, but draw children.
Definition: BaseNode.hh:370
ACG::Matrix4x4T::transpose
void transpose()
transpose matrix
Definition: Matrix4x4T.cc:272
ACG::RenderObject::depthMapUniformName
const char * depthMapUniformName
Uniform name of the depth map in the used shader.
Definition: RenderObject.hh:295
ACG::RenderObject::indexType
GLenum indexType
Index element type.
Definition: RenderObject.hh:204
ACG::SceneGraph::Material
Definition: MaterialNode.hh:85
ACG::RenderObject::indexOffset
unsigned int indexOffset
Offset to first index in the index buffer or vertex buffer respectively.
Definition: RenderObject.hh:198
ACG::IRenderer::DepthMapPass
Definition: IRenderer.hh:340
ACG::IRenderer::LightData
Definition: IRenderer.hh:110
ACG::RenderObject::priority
int priority
Priority to allow sorting of objects.
Definition: RenderObject.hh:123
ACG::RenderObject::isDefaultPointObject
bool isDefaultPointObject() const
Test if the object is rendered with one of the default point extension methods.
Definition: RenderObject.cc:476
ACG::SceneGraph::Material::shininess
void shininess(float _s)
set shininess
Definition: MaterialNode.hh:201
ACG::SceneGraph::MaterialNode
Definition: MaterialNode.hh:321
GLSL::UniformPool::bind
void bind(PtrProgram _prog) const
Send all stored uniforms to program.
Definition: UniformPool.cc:103
ACG::FBO::unbind
void unbind()
unbind fbo, go to normal rendering mode
Definition: FBO.cc:474
ACG::ShaderProgGenerator::getTessControlShaderCode
const QStringList & getTessControlShaderCode()
Returns generated vertex shader code.
Definition: ShaderGenerator.cc:2208
ACG::Matrix4x4T::invert
bool invert()
matrix inversion (returns true on success)
Definition: Matrix4x4T.cc:297
ACG::GLState::viewport_height
int viewport_height() const
get viewport height
Definition: GLState.hh:827
ACG::ShaderProgGenerator::hasGeometryShader
bool hasGeometryShader() const
check whether there is a geometry shader present
Definition: ShaderGenerator.cc:2447
ACG::RenderObject::inZPrePass
bool inZPrePass
Specify whether this object should be rendered in a z-prepass.
Definition: RenderObject.hh:284
ACG::SceneGraph::BaseNode::childrenEnd
ChildIter childrenEnd()
Returns: end-iterator of children.
Definition: BaseNode.hh:274
GLSL::Program::setUniformMat3
void setUniformMat3(const char *_name, const ACG::GLMatrixf &_value, bool _transposed=false)
Set 3x3fMatrix uniform to specified value.
Definition: GLSLShader.cc:669
ACG::RenderObject::patchVertices
unsigned int patchVertices
patch size if primitiveMode is GL_PATCHES for rendering with tessellation shaders ...
Definition: RenderObject.hh:192
ACG::FBO::bind
bool bind()
bind the fbo and sets it as rendertarget
Definition: FBO.cc:451
ACG::TextureBuffer
Definition: globjects.hh:522
ACG::SceneGraph::BaseNode::leave
virtual void leave(GLState &, const DrawModes::DrawMode &)
Definition: BaseNode.hh:217
ACG::RenderObject::proj
GLMatrixd proj
Projection transform.
Definition: RenderObject.hh:148