50 #include <ACG/GL/acg_glew.hh>
56 #include <QTextStream>
58 #include <ACG/GL/gl.hh>
60 #include <ACG/GL/IRenderer.hh>
62 #include <ACG/GL/VertexDeclaration.hh>
63 #include <ACG/GL/GLError.hh>
65 #include <ACG/GL/ShaderCache.hh>
66 #include <ACG/GL/ScreenQuad.hh>
67 #include <ACG/GL/FBO.hh>
68 #include <ACG/GL/globjects.hh>
77 IRenderer::IRenderer()
83 prevDrawBuffer_(GL_BACK),
86 errorDetectionLevel_(1),
87 enableLineThicknessGL42_(false)
95 globalLightModelAmbient_ =
ACG::Vec3f(0.2f, 0.2f, 0.2f);
99 IRenderer::~IRenderer()
111 if (!_renderObject->debugName)
112 _renderObject->debugName =
"<unnamed>";
114 if (_renderObject->
name.empty())
115 _renderObject->
name = _renderObject->debugName;
119 std::cout <<
"error: missing vertex declaration in renderobject: " << _renderObject->debugName << std::endl;
127 std::cout <<
"warning: numIndices is 0 in renderobject: " << _renderObject->debugName << std::endl;
130 if (!_renderObject->depthWrite &&
131 !_renderObject->colorWriteMask[0] && !_renderObject->colorWriteMask[1] &&
132 !_renderObject->colorWriteMask[2] && !_renderObject->colorWriteMask[3])
133 std::cout <<
"warning: depth write and color write disabled in renderobject: " << _renderObject->debugName << std::endl;
137 if (_renderObject->emissive.max() < 1e-3f)
138 std::cout <<
"warning: unlit object rendered with black emissive color: " << _renderObject->debugName << std::endl;
144 glGetFloatv(GL_COLOR_CLEAR_VALUE, clearColor);
146 if (checkEpsilon(clearColor[0] - _renderObject->emissive[0]) &&
147 checkEpsilon(clearColor[1] - _renderObject->emissive[1]) &&
148 checkEpsilon(clearColor[2] - _renderObject->emissive[2]))
150 std::cout <<
"warning: unlit object rendered with clear color as emissive color: " << _renderObject->debugName << std::endl;
151 std::cout <<
" Should this be intentional, disable color writing instead via obj->glColorMask(0,0,0,0)" << std::endl;
156 if (_renderObject->textures().size())
162 for (std::map<size_t,RenderObject::Texture>::const_iterator it = _renderObject->textures().begin();
163 it != _renderObject->textures().end(); ++it)
165 #ifdef GL_ARB_texture_buffer_object
166 if (it->second.type == GL_TEXTURE_BUFFER)
170 glBindTexture(it->second.type, it->second.id);
172 GLint minFilter = GL_NONE;
173 glGetTexParameteriv(it->second.type, GL_TEXTURE_MIN_FILTER, &minFilter);
175 if (minFilter == GL_NEAREST_MIPMAP_LINEAR ||
176 minFilter == GL_NEAREST_MIPMAP_NEAREST ||
177 minFilter == GL_LINEAR_MIPMAP_LINEAR ||
178 minFilter == GL_LINEAR_MIPMAP_NEAREST)
181 glGetTexParameteriv(it->second.type, GL_TEXTURE_MAX_LEVEL, &maxLevel);
184 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &texWidth);
187 for (GLint lod = 0; lod < maxLevel && maxLod < 0; ++lod)
190 glGetTexLevelParameteriv(GL_TEXTURE_2D, lod, GL_TEXTURE_WIDTH, &lodWidth);
192 if (lodWidth <= 0 || lodWidth == GL_INVALID_VALUE)
196 if (maxLod <= 0 && texWidth > 1)
198 std::cout <<
"warning: texture is sampled with mipmapping, but no mipchain is present: " << _renderObject->debugName <<
" texid: " << it->second.id << std::endl;
199 std::cout <<
" automatically disabling mipmapping!!" << std::endl;
201 GLint correctedFilter = GL_LINEAR;
203 if (minFilter == GL_NEAREST_MIPMAP_LINEAR ||
204 minFilter == GL_LINEAR_MIPMAP_LINEAR)
205 correctedFilter = GL_LINEAR;
207 correctedFilter = GL_NEAREST;
209 glTexParameteri(it->second.type, GL_TEXTURE_MIN_FILTER, correctedFilter);
221 if (_renderObject->depthWrite && !_renderObject->depthTest)
223 std::cout <<
"warning: trying to write to depth buffer with depth-testing disabled does not work in: " << _renderObject->debugName << std::endl;
224 std::cout <<
" If depth-writing was intended, enable depth-testing and set depth-func to GL_ALWAYS" << std::endl;
231 if (_renderObject->
shaderDesc.shadeMode != SG_SHADE_UNLIT)
235 std::cout <<
"warning: missing normals for lighting in renderobject: " << _renderObject->debugName << std::endl
236 <<
" Set shadeMode to SG_SHADE_UNLIT or provide normals!" << std::endl;
243 std::cout <<
"warning: missing texcoords for textured mode in renderobject: " << _renderObject->debugName << std::endl;
250 std::cout <<
"warning: missing colors for vertexcolor mode in renderobject: " << _renderObject->debugName << std::endl;
256 if (fabsf(_renderObject->alpha - 1.0f) > 1e-3f && !(_renderObject->alphaTest || _renderObject->blending))
257 std::cout <<
"warning: alpha value != 1 but no alpha blending or testing enabled in renderobject: " << _renderObject->debugName << std::endl;
260 #ifdef GL_ARB_tessellation_shader
262 const bool tessellationActive = !_renderObject->
shaderDesc.tessControlTemplateFile.isEmpty() || !_renderObject->
shaderDesc.tessEvaluationTemplateFile.isEmpty();
263 bool tryToFixPatchInfo =
false;
264 if (tessellationActive && _renderObject->
primitiveMode != GL_PATCHES)
266 std::cout <<
"error: tessellation shaders are not used with GL_PATCHES primitiveType in renderobject: " << _renderObject->debugName << std::endl;
267 tryToFixPatchInfo =
true;
272 std::cout <<
"error: undefined patch size for tessellation in renderobject: " << _renderObject->debugName << std::endl;
273 tryToFixPatchInfo =
true;
276 if (tryToFixPatchInfo)
282 std::cout <<
"warning: attempting to draw with patchVertices = 1 for tessellation in renderobject: " << _renderObject->debugName << std::endl;
288 std::cout <<
"warning: attempting to draw with patchVertices = 2 for tessellation in renderobject: " << _renderObject->debugName << std::endl;
294 std::cout <<
"warning: attempting to draw with patchVertices = 3 for tessellation in renderobject: " << _renderObject->debugName << std::endl;
300 std::cout <<
"warning: attempting to draw with patchVertices = 4 for tessellation in renderobject: " << _renderObject->debugName << std::endl;
315 for (
size_t i = 0; i < numMods; ++i)
330 #ifdef GL_VERSION_3_2
338 #ifdef GL_VERSION_3_2
339 GLint geomInputType = 0;
340 glGetProgramiv(shaderProg->
getProgramId(), GL_GEOMETRY_INPUT_TYPE, &geomInputType);
346 switch (geomInputType)
348 case GL_POINTS: std::cout <<
"warning: primitive mode is incompatible with points-geometryshader in renderobject: " << _renderObject->debugName << std::endl;
break;
353 std::cout <<
"warning: primitive mode is incompatible with lines-geometryshader in renderobject: " << _renderObject->debugName << std::endl;
356 case GL_LINES_ADJACENCY:
359 std::cout <<
"warning: primitive mode is incompatible with lines_adjacency-geometryshader in renderobject: " << _renderObject->debugName << std::endl;
365 std::cout <<
"warning: primitive mode is incompatible with triangles-geometryshader in renderobject: " << _renderObject->debugName << std::endl;
368 case GL_TRIANGLES_ADJACENCY:
371 std::cout <<
"warning: primitive mode is incompatible with triangles_adjacency-geometryshader in renderobject: " << _renderObject->debugName << std::endl;
374 default: std::cout <<
"warning: unknown input_type for geometryshader in renderobject: " << _renderObject->debugName << std::endl;
386 std::cout <<
"warning: primitive mode is incompatible with lines-geometryshader in renderobject: " << _renderObject->debugName << std::endl;
391 std::cout <<
"warning: primitive mode is incompatible with points-geometryshader in renderobject: " << _renderObject->debugName << std::endl;
413 renderObjects_.clear();
415 if (!_sceneGraphRoot)
return;
427 traverseRenderableNodes(_glState, _drawMode, *_sceneGraphRoot, defMat);
433 class ScenegraphTraversalStackEl {
437 node(_node), material(_material),
438 subtree_index_start(0), leave(false) {}
442 size_t subtree_index_start;
449 renderObjectSource_.clear();
450 overlayObjectSource_.clear();
455 std::vector<ScenegraphTraversalStackEl> stack;
458 stack.push_back(ScenegraphTraversalStackEl(&_node, &_mat));
459 while (!stack.empty()) {
460 ScenegraphTraversalStackEl &cur = stack.back();
470 cur.node->enter(
this, *_glState, nodeDM);
472 cur.subtree_index_start = renderObjects_.size();
479 cur.material = &matNode->
material();
482 cur.node->getRenderObjects(
this, *_glState, nodeDM, cur.material);
485 size_t numAddedObjects = renderObjects_.size() - renderObjectSource_.size();
486 renderObjectSource_.insert(renderObjectSource_.end(), numAddedObjects, cur.node);
492 cIt = cur.node->childrenBegin(),
493 cEnd = cur.node->childrenEnd(); cIt != cEnd; ++cIt) {
494 if (((*cIt)->traverseMode() &
497 stack.push_back(ScenegraphTraversalStackEl(*cIt, cur.material));
502 cIt = cur.node->childrenBegin(),
503 cEnd = cur.node->childrenEnd(); cIt != cEnd; ++cIt) {
504 if ((~(*cIt)->traverseMode() &
507 stack.push_back(ScenegraphTraversalStackEl(*cIt, cur.material));
519 renderObjects_.begin() + cur.subtree_index_start,
520 renderObjects_.end());
523 cur.node->leave(
this, *_glState, nodeDM);
533 camPosWS_ =
Vec3f( viewMatrix_(0,3), viewMatrix_(1,3), viewMatrix_(2,3) );
534 camDirWS_ =
Vec3f( viewMatrix_(0,2), viewMatrix_(1,2), -viewMatrix_(2,2) );
540 collectRenderObjects(_glState, _drawMode, _scenegraphRoot);
547 size_t numRenderObjects = 0,
548 numOverlayObjects = 0,
551 for (std::vector<ACG::RenderObject>::const_iterator it = renderObjects_.begin();
552 it != renderObjects_.end(); ++it) {
553 if (!it->overlay && !(it->isDefaultLineObject() && enableLineThicknessGL42_))
557 if (enableLineThicknessGL42_ && it->isDefaultLineObject())
566 sortedObjects_.clear();
567 sortedObjects_.reserve(numRenderObjects);
569 overlayObjects_.clear();
570 overlayObjects_.reserve(numOverlayObjects);
572 lineGL42Objects_.clear();
573 lineGL42Objects_.reserve(numLineObjects);
576 sortListObjects_.clear();
577 sortListObjects_.reserve(numRenderObjects);
579 sortListOverlays_.clear();
580 sortListOverlays_.reserve(numOverlayObjects);
583 for (
size_t i = 0; i < renderObjects_.size(); ++i)
585 if (renderObjects_[i].overlay)
587 overlayObjects_.push_back(&renderObjects_[i]);
588 sortListOverlays_.push_back(i);
590 else if (enableLineThicknessGL42_ && numLineObjects && renderObjects_[i].isDefaultLineObject())
592 renderObjects_[i].shaderDesc.geometryTemplateFile =
"Wireframe/gl42/geometry.tpl";
593 renderObjects_[i].shaderDesc.fragmentTemplateFile =
"Wireframe/gl42/fragment.tpl";
596 renderObjects_[i].glColorMask(0,0,0,0);
599 lineGL42Objects_.push_back(&renderObjects_[i]);
603 sortedObjects_.push_back(&renderObjects_[i]);
604 sortListObjects_.push_back(i);
616 glDisableClientState(GL_VERTEX_ARRAY);
617 glDisableClientState(GL_COLOR_ARRAY);
618 glDisableClientState(GL_NORMAL_ARRAY);
619 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
620 glDisableClientState(GL_INDEX_ARRAY);
623 glEnable(GL_CULL_FACE);
624 glEnable(GL_DEPTH_TEST);
625 glDepthFunc(GL_LESS);
626 glDepthMask(GL_TRUE);
633 GLfloat lightModelAmbient[4];
634 glGetFloatv(GL_LIGHT_MODEL_AMBIENT, lightModelAmbient);
635 globalLightModelAmbient_ =
ACG::Vec3f(lightModelAmbient[0], lightModelAmbient[1], lightModelAmbient[2]);
639 bool requiresSceneDepths =
false;
641 for (
size_t i = 0; i < renderObjects_.size(); ++i)
643 if (renderObjects_[i].depthMapUniformName)
644 requiresSceneDepths =
true;
648 if (requiresSceneDepths)
654 void IRenderer::finishRenderingPipeline(
bool _drawOverlay)
656 #ifdef GL_ARB_vertex_array_object
657 glBindVertexArray(0);
661 if (enableLineThicknessGL42_)
662 renderLineThicknessGL42();
666 const int numOverlayObj = overlayObjects_.size();
672 for (
int i = 0; i < numOverlayObj; ++i)
676 if (obj->depthTest && obj->
depthFunc != GL_ALWAYS)
678 float depthMax = 1.0f;
685 bool depthWrite = obj->depthWrite;
690 obj->depthWrite =
true;
697 obj->depthWrite = depthWrite;
704 for (
int i = 0; i < numOverlayObj; ++i)
712 #ifdef GL_ARB_vertex_array_object
713 glBindVertexArray(0);
716 for (
int i = 0; i < maxClipDistances_; ++i)
717 glDisable(GL_CLIP_DISTANCE0 + i);
720 glColorMask(1,1,1,1);
724 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
725 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
732 GLint curViewport[4];
734 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &curFbo);
735 glGetIntegerv(GL_VIEWPORT, curViewport);
736 glGetIntegerv(GL_DRAW_BUFFER, &curDrawBuf);
738 if (curFbo != prevFbo_)
740 std::cout <<
"warning: input and output fbo are not the same in renderer implementation" << std::endl;
744 if (curDrawBuf != prevDrawBuffer_)
746 std::cout <<
"warning: input and output draw-buffer are not the same in renderer implementation" << std::endl;
750 if (curViewport[0] != prevViewport_[0] ||
751 curViewport[1] != prevViewport_[1] ||
752 curViewport[2] != prevViewport_[2] ||
753 curViewport[3] != prevViewport_[3])
755 std::cout <<
"warning: input and output viewport are not the same in renderer implementation" << std::endl;
761 void IRenderer::saveInputFbo()
764 saveActiveFbo(&prevFbo_, prevViewport_, &prevDrawBuffer_);
765 prevFboSaved_ =
true;
768 void IRenderer::restoreInputFbo()
771 restoreFbo(prevFbo_, prevViewport_, prevDrawBuffer_);
774 void IRenderer::saveActiveFbo( GLint* _outFboId, GLint* _outViewport, GLint* _outDrawBuffer )
const
777 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, _outFboId);
778 glGetIntegerv(GL_VIEWPORT, _outViewport);
779 glGetIntegerv(GL_DRAW_BUFFER, _outDrawBuffer);
782 void IRenderer::restoreFbo( GLint _fboId,
const GLint* _outViewport, GLint _drawBuffer )
const
784 glBindFramebuffer(GL_FRAMEBUFFER, _fboId);
785 glDrawBuffer(_drawBuffer);
786 glViewport(_outViewport[0], _outViewport[1], _outViewport[2], _outViewport[3]);
789 void IRenderer::clearInputFbo(
const ACG::Vec4f& clearColor )
791 glClearColor(clearColor[0], clearColor[1], clearColor[2], 1.0f);
797 GLint oldViewport[4];
798 glGetIntegerv(GL_VIEWPORT, oldViewport);
799 glScissor(oldViewport[0], oldViewport[1], oldViewport[2], oldViewport[3]);
802 glScissor(prevViewport_[0], prevViewport_[1], prevViewport_[2], prevViewport_[3]);
804 glEnable(GL_SCISSOR_TEST);
805 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
808 glDisable(GL_SCISSOR_TEST);
812 struct RenderObjectComparator {
813 RenderObjectComparator(
const std::vector<ACG::RenderObject>& _vec) : vec_(_vec) {
816 bool operator() (
int a,
int b) {
817 return (vec_[a].priority < vec_[b].priority);
820 const std::vector<ACG::RenderObject>& vec_;
824 void IRenderer::sortRenderObjects()
826 size_t numObjs = sortListObjects_.size();
827 size_t numOverlays = sortListOverlays_.size();
829 RenderObjectComparator cmpOp(renderObjects_);
831 std::sort(sortListObjects_.begin(), sortListObjects_.end(), cmpOp);
832 std::sort(sortListOverlays_.begin(), sortListOverlays_.end(), cmpOp);
835 std::vector<ACG::SceneGraph::BaseNode*> temp;
836 renderObjectSource_.swap(temp);
839 renderObjectSource_.resize(numObjs, 0);
840 overlayObjectSource_.resize(numOverlays, 0);
842 for (
size_t i = 0; i < numObjs; ++i)
844 int objID = sortListObjects_[i];
845 sortedObjects_[i] = &renderObjects_[objID];
847 renderObjectSource_[i] = temp[objID];
850 for (
size_t i = 0; i < numOverlays; ++i)
852 int objID = sortListOverlays_[i];
853 overlayObjects_[i] = &renderObjects_[objID];
855 overlayObjectSource_[i] = temp[objID];
867 #ifdef GL_ARB_vertex_array_object
877 glBindBufferARB(GL_ARRAY_BUFFER_ARB, _obj->
vertexBuffer);
878 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, _obj->
indexBuffer);
906 _prog->
setUniform(
"g_cEmissive", _obj->emissive);
909 _prog->
setUniform(
"g_cAmbient", _obj->ambient);
910 _prog->
setUniform(
"g_cSpecular", _obj->specular);
912 ACG::Vec4f materialParams(_obj->shininess, _obj->alpha, 0.0f, 0.0f);
913 _prog->
setUniform(
"g_vMaterial", materialParams);
915 _prog->
setUniform(
"g_cLightModelAmbient", globalLightModelAmbient_);
918 if ( !_obj->uniformPool_.
empty() )
919 _obj->uniformPool_.
bind(_prog);
927 int maxTextureStage = 0;
928 for (std::map<size_t,RenderObject::Texture>::const_iterator iter = _obj->textures().begin();
929 iter != _obj->textures().end();++iter)
932 const size_t texture_stage = iter->first;
937 glActiveTexture(GL_TEXTURE0 + (GLenum)texture_stage);
938 glBindTexture(iter->second.type, tex.id);
939 _prog->
setUniform(QString(
"g_Texture%1").arg(texture_stage).toStdString().c_str(), (
int)texture_stage);
941 maxTextureStage = std::max(maxTextureStage, (
int)texture_stage);
949 int depthMapSlot = maxTextureStage + 1;
952 glActiveTexture(GL_TEXTURE0 + depthMapSlot);
953 glBindTexture(GL_TEXTURE_2D, depthMaps_[curViewerID_]->getAttachment(GL_COLOR_ATTACHMENT0));
958 for (
int i = 0; i < numLights_; ++i)
962 char szUniformName[256];
964 sprintf(szUniformName,
"g_cLightDiffuse_%d", i);
965 _prog->
setUniform(szUniformName, lgt->diffuse);
967 sprintf(szUniformName,
"g_cLightAmbient_%d", i);
968 _prog->
setUniform(szUniformName, lgt->ambient);
970 sprintf(szUniformName,
"g_cLightSpecular_%d", i);
971 _prog->
setUniform(szUniformName, lgt->specular);
974 if (lgt->ltype == ACG::SG_LIGHT_POINT || lgt->ltype == ACG::SG_LIGHT_SPOT)
976 sprintf(szUniformName,
"g_vLightPos_%d", i);
979 sprintf(szUniformName,
"g_vLightAtten_%d", i);
983 if (lgt->ltype == ACG::SG_LIGHT_DIRECTIONAL || lgt->ltype == ACG::SG_LIGHT_SPOT)
985 sprintf(szUniformName,
"g_vLightDir_%d", i);
989 if (lgt->ltype == ACG::SG_LIGHT_SPOT)
991 sprintf(szUniformName,
"g_vLightAngleExp_%d", i);
992 _prog->
setUniform(szUniformName, lgt->spotCutoffExponent);
1000 glEnable(GL_CULL_FACE);
1002 glDisable(GL_CULL_FACE);
1007 glDisable(GL_BLEND);
1009 if (_obj->alphaTest)
1011 glEnable(GL_ALPHA_TEST);
1012 glAlphaFunc(_obj->
alphaFunc, _obj->alphaRef);
1015 glDisable(GL_ALPHA_TEST);
1017 if (_obj->depthTest)
1018 glEnable(GL_DEPTH_TEST);
1020 glDisable(GL_DEPTH_TEST);
1023 glDepthMask(_obj->depthWrite ? GL_TRUE : GL_FALSE);
1025 glColorMask(_obj->colorWriteMask[0], _obj->colorWriteMask[1], _obj->colorWriteMask[2], _obj->colorWriteMask[3]);
1035 if (maxClipDistances_ < 0)
1037 glGetIntegerv(GL_MAX_CLIP_DISTANCES, &maxClipDistances_);
1038 maxClipDistances_ = std::min(maxClipDistances_, 32);
1041 for (
int i = 0; i < maxClipDistances_; ++i)
1043 if (_obj->clipDistanceMask & (1 << i))
1044 glEnable(GL_CLIP_DISTANCE0 + i);
1046 glDisable(GL_CLIP_DISTANCE0 + i);
1055 bool noIndices =
true;
1059 glPolygonMode(GL_FRONT_AND_BACK, _obj->fillMode);
1062 bool tessellationActive = !(_obj->
shaderDesc.tessControlTemplateFile.isEmpty() && _obj->
shaderDesc.tessEvaluationTemplateFile.isEmpty());
1063 #ifdef GL_ARB_tessellation_shader
1064 if (tessellationActive)
1068 if (_obj->
shaderDesc.tessControlTemplateFile.isEmpty())
1070 glPatchParameterfv(GL_PATCH_DEFAULT_INNER_LEVEL, _obj->patchDefaultInnerLevel.data());
1071 glPatchParameterfv(GL_PATCH_DEFAULT_OUTER_LEVEL, _obj->patchDefaultOuterLevel.data());
1075 if (tessellationActive)
1076 std::cout <<
"error: tessellation shaders cannot be used with the outdated glew version" << std::endl;
1092 case GL_UNSIGNED_INT: indexSize = 4;
break;
1093 case GL_UNSIGNED_SHORT: indexSize = 2;
break;
1094 default: indexSize = 1;
break;
1109 bool _constRenderStates,
1110 const std::vector<unsigned int>* _shaderModifiers)
1116 bindObjectVBO(_obj, prog);
1121 bindObjectUniforms(_obj, prog);
1125 if (!_constRenderStates)
1126 bindObjectRenderStates(_obj);
1143 #ifdef GL_ARB_vertex_array_object
1145 glBindVertexArray(0);
1153 if (numLights_ < SG_MAX_SHADER_LIGHTS)
1155 lights_[numLights_] = _light;
1158 if (_light.ltype != SG_LIGHT_POINT)
1159 lights_[numLights_].dir.normalize();
1167 renderObjectModifiers_.push_back(_mod);
1172 for (
int i =
int(renderObjectModifiers_.size()) - 1; i >= 0; --i)
1174 if (renderObjectModifiers_[i] == _mod)
1175 renderObjectModifiers_.erase(renderObjectModifiers_.begin() + i);
1179 int IRenderer::getNumRenderObjects()
const {
1180 return sortedObjects_.size();
1183 int IRenderer::getNumLights()
const
1191 if (sortedObjects_.empty())
1192 return &renderObjects_[i];
1194 return sortedObjects_[i];
1199 if (overlayObjects_.empty())
1200 return &renderObjects_[i];
1202 return overlayObjects_[i];
1208 return renderObjectSource_[i];
1213 return overlayObjectSource_[i];
1219 if (lineGL42Objects_.empty())
1222 return lineGL42Objects_[i];
1231 void IRenderer::dumpRenderObjectsToFile(
const char* _fileName,
ACG::RenderObject** _sortedList)
const
1233 QFile fileOut(_fileName);
1234 if (fileOut.open(QFile::WriteOnly | QFile::Truncate))
1236 QTextStream outStrm(&fileOut);
1237 for (
int i = 0; i < getNumRenderObjects(); ++i)
1240 outStrm <<
"\n" << _sortedList[i]->
toString();
1242 outStrm <<
"\n" << renderObjects_[i].toString();
1250 QString IRenderer::dumpCurrentRenderObjectsToString(
ACG::RenderObject** _list,
bool _outputShaders, std::vector<ACG::ShaderModifier*>* _modifiers) {
1252 QString objectString;
1254 QTextStream outStrm(&objectString);
1256 for (
int i = 0; i < getNumRenderObjects(); ++i)
1258 const RenderObject* obj = _list ? _list[i] : &renderObjects_[i];
1261 outStrm <<
"\n" << obj->
toString();
1263 if ( _outputShaders ) {
1271 outStrm <<
"\n---------------------vertex-shader--------------------\n\n";
1274 outStrm <<
"\n---------------------end-vertex-shader--------------------\n\n";
1278 outStrm <<
"\n---------------------tesscontrol-shader--------------------\n\n";
1281 outStrm <<
"\n---------------------end-tesscontrol-shader--------------------\n\n";
1286 outStrm <<
"\n---------------------tesseval-shader--------------------\n\n";
1290 outStrm <<
"\n---------------------end-tesseval-shader--------------------\n\n";
1295 outStrm <<
"\n---------------------geometry-shader--------------------\n\n";
1298 outStrm <<
"\n---------------------end-geometry-shader--------------------\n\n";
1302 outStrm <<
"\n---------------------fragment-shader--------------------\n\n";
1305 outStrm <<
"\n---------------------end-fragment-shader--------------------\n\n";
1312 return objectString;
1315 void IRenderer::copyDepthToBackBuffer( GLuint _depthTex,
float _scale )
1317 if (!_depthTex)
return;
1319 if (!depthCopyShader_)
1320 depthCopyShader_ =
GLSL::loadProgram(
"ScreenQuad/screenquad.glsl",
"ScreenQuad/depth_copy.glsl");
1323 if (depthCopyShader_)
1327 GLint curViewport[4];
1328 GLint curDrawBuffer;
1329 saveActiveFbo(&curFbo, curViewport, &curDrawBuffer);
1331 GLboolean colorMask[4], depthMask;
1332 glGetBooleanv(GL_COLOR_WRITEMASK, colorMask);
1333 glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
1335 GLboolean depthTestEnable;
1337 glGetBooleanv(GL_DEPTH_TEST, &depthTestEnable);
1338 glGetIntegerv(GL_DEPTH_FUNC, &depthFunc);
1343 depthCopyShader_->use();
1344 depthCopyShader_->setUniform(
"offset",
ACG::Vec2f(0.0f, 0.0f));
1345 depthCopyShader_->setUniform(
"size",
ACG::Vec2f(1.0f, 1.0f));
1346 depthCopyShader_->setUniform(
"DepthTex", 0);
1347 depthCopyShader_->setUniform(
"DepthSign", _scale);
1350 glColorMask(0,0,0,0);
1354 glEnable(GL_DEPTH_TEST);
1355 glDepthFunc(GL_ALWAYS);
1357 glActiveTexture(GL_TEXTURE0);
1358 glBindTexture(GL_TEXTURE_2D, _depthTex);
1365 restoreFbo(curFbo, curViewport, curDrawBuffer);
1367 glColorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
1368 glDepthMask(depthMask);
1370 if (!depthTestEnable)
1371 glDisable(GL_DEPTH_TEST);
1373 if (depthFunc != GL_ALWAYS)
1374 glDepthFunc(depthFunc);
1376 glBindTexture(GL_TEXTURE_2D, 0);
1385 void IRenderer::DepthMapPass::modifyFragmentEndCode(QStringList* _code)
1387 _code->push_back(
"outFragment = gl_FragCoord.zzzz;");
1390 void IRenderer::renderDepthMap(
int _viewerID,
int _width,
int _height)
1392 ACG::FBO* fbo = depthMaps_[_viewerID];
1397 fbo = depthMaps_[_viewerID] =
new ACG::FBO();
1400 fbo->
attachTexture2D(GL_COLOR_ATTACHMENT0, _width, _height, GL_R32F, GL_RED);
1406 fbo->
resize(_width, _height);
1425 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1426 glViewport(0, 0, _width, _height);
1429 glColorMask(1,1,1,1);
1432 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
1433 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1436 for (
int i = 0; i < getNumRenderObjects(); ++i)
1443 GLSL::Program* depthPassShader = ShaderCache::getInstance()->getProgram(&obj->
shaderDesc, DepthMapPass::instance);
1449 if (depthMapUniformName)
1451 depthPassShader->
use();
1452 depthPassShader->
setUniform(depthMapUniformName, 0);
1453 glActiveTexture(GL_TEXTURE0);
1454 glBindTexture(GL_TEXTURE_2D, 0);
1459 const GLboolean redWriteMask = obj->colorWriteMask[0];
1460 obj->colorWriteMask[0] = obj->depthWrite;
1462 renderObject(obj, depthPassShader);
1466 obj->colorWriteMask[0]= redWriteMask;
1478 void IRenderer::setViewerID(
int _viewerID)
1480 curViewerID_ = _viewerID;
1484 void IRenderer::renderLineThicknessGL42()
1486 #ifdef GL_ARB_shader_image_load_store
1505 const int numLines = lineGL42Objects_.size();
1508 const bool useBufferTexture =
true;
1509 const bool useIntegerTexture =
true;
1519 if (useBufferTexture)
1520 macros.push_back(
"#define IMAGE_BUFFER");
1521 if (useIntegerTexture)
1522 macros.push_back(
"#define FMT_UINT");
1530 size_t w =
static_cast<size_t>(prevViewport_[2]), h = static_cast<size_t>(prevViewport_[3]);
1531 size_t lineBPP =
static_cast<size_t>(useIntegerTexture ? 4 : 16);
1534 if (useBufferTexture)
1536 lineColorImgBuf =
dynamic_cast<TextureBuffer*
>(lineColorBuffers_[curViewerID_]);
1538 if (!lineColorImgBuf)
1541 lineColorBuffers_[curViewerID_] = lineColorImgBuf;
1545 if (lineColorImgBuf->getBufferSize() != w * h * lineBPP)
1546 lineColorImgBuf->setBufferData(w*h*lineBPP, 0, GL_R32UI, GL_DYNAMIC_DRAW);
1550 lineColorImg2D =
dynamic_cast<Texture2D*
>(lineColorBuffers_[curViewerID_]);
1552 if (!lineColorImg2D)
1555 lineColorImg2D =
new Texture2D(GL_TEXTURE0);
1556 lineColorBuffers_[curViewerID_] = lineColorImg2D;
1560 if (lineColorImg2D->getWidth() !=
static_cast<int>(w) || lineColorImg2D->getHeight() !=
static_cast<int>(h))
1561 lineColorImg2D->setData(0,
1562 useIntegerTexture ? GL_R32UI : GL_RGBA32F,
1564 useIntegerTexture ? GL_RED_INTEGER : GL_RGBA,
1565 useIntegerTexture ? GL_UNSIGNED_INT : GL_FLOAT,
1573 glViewport(0, 0, w, h);
1580 glColorMask(0,0,0,0);
1582 glDisable(GL_DEPTH_TEST);
1585 if (useBufferTexture)
1586 lineColorImgBuf->bindAsImage(0, GL_WRITE_ONLY);
1588 lineColorImg2D->bindAsImage(0, GL_WRITE_ONLY);
1590 GLSL::Program* shaderClear = ShaderCache::getInstance()->getProgram(
"ScreenQuad/screenquad.glsl",
"Wireframe/gl42/clear.glsl", ¯os);
1597 ScreenQuad::draw(shaderClear);
1599 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
1607 for (
int i = 0; i < numLines; ++i)
1609 RenderObject* obj = getLineGL42RenderObject(i);
1614 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
1626 if (useBufferTexture)
1627 lineColorImgBuf->bindAsImage(0, GL_READ_ONLY);
1629 lineColorImg2D->bindAsImage(0, GL_READ_ONLY);
1632 glColorMask(1,1,1,1);
1633 glDisable(GL_DEPTH_TEST);
1639 GLSL::Program* shaderComposite = ShaderCache::getInstance()->getProgram(
"ScreenQuad/screenquad.glsl",
"Wireframe/gl42/composite.glsl", ¯os);
1641 shaderComposite->
use();
1646 ScreenQuad::draw(shaderComposite);
1653 void IRenderer::setLineThicknessRenderingGL42(
bool _enable )
1655 if (Texture::supportsImageLoadStore() && Texture::supportsTextureBuffer())
1656 enableLineThicknessGL42_ = _enable;
1659 void IRenderer::setErrorDetectionLevel(
int _level )
1661 errorDetectionLevel_ = std::max(_level, 0);
1664 int IRenderer::getErrorDetectionLevel()
const
1666 return errorDetectionLevel_;
bool isDefaultLineObject() const
Test if the object is rendered with one of the default line thickness methods.
GLSL::Program * depthCopyShader_
shader copies depth of the first front layer to the back buffer
int viewport_width() const
get viewport width
bool isDefaultPointObject() const
Test if the object is rendered with one of the default point extension methods.
static void draw(GLSL::Program *_prog=0)
Draw the screen quad.
bool invert()
matrix inversion (returns true on success)
GLenum indexType
Index element type.
void specularColor(const Vec4f &_s)
set the specular color
int numLights_
Number of Lights.
bool hasTessControlShader() const
check whether there is a tess-control shader present
const QStringList & getGeometryShaderCode()
Returns generated tessellation evaluation shader code.
GLenum alphaFunc
GL_LESS, GL_LEQUAL, GL_GREATER ..
void ambientColor(const Vec4f &_a)
set the ambient color.
static ShaderCache * getInstance()
Return instance of the ShaderCache singleton.
Hide this node and its children.
const QStringList & getTessControlShaderCode()
Returns generated vertex shader code.
Namespace providing different geometric functions concerning angles.
std::vector< ACG::RenderObjectModifier * > renderObjectModifiers_
active render object modifiers
GLuint vertexArrayObject
Use vertex array object.
bool empty() const
returns if the pool is empty
GLenum depthFunc
GL_LESS, GL_LEQUAL, GL_GREATER ..
void unbind()
unbind fbo, go to normal rendering mode
bool hasTessEvaluationShader() const
check whether there is a tess-evaluation shader present
unsigned int patchVertices
patch size if primitiveMode is GL_PATCHES for rendering with tessellation shaders ...
bool inZPrePass
Specify whether this object should be rendered in a z-prepass.
const void * sysmemIndexBuffer
Use system memory index buffer.
void setUniformMat3(const char *_name, const ACG::GLMatrixf &_value, bool _transposed=false)
Set 3x3fMatrix uniform to specified value.
void transpose()
transpose matrix
static void blendFunc(GLenum _sfactor, GLenum _dfactor)
replaces glBlendFunc, supports locking
void diffuseColor(const Vec4f &_d)
set the diffuse color.
GLMatrixd proj
Projection transform.
std::vector< BaseNode * >::iterator ChildIter
allows to iterate over children
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
const VertexElement * findElementByUsage(VERTEX_USAGE _usage) const
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
Vec3f diffuse
material definitions
int errorDetectionLevel_
error-detection level for checking render objects
Draw this node, but hide children.
VectorT< float, 3 > Vec3f
Draw node in second pass.
static int maxClipDistances_
max number of clip distance outputs in a vertex shader
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
GLSL::Program * getProgram(const ShaderGenDesc *_desc, const std::vector< unsigned int > &_mods)
Query a dynamically generated program from cache.
GLMatrixd modelview
Modelview transform.
void addDepthBuffer(GLuint _width, GLuint _height)
function to add a depth renderbuffer to the fbo
bool bind()
bind the fbo and sets it as rendertarget
void activateShaderPipeline(GLSL::Program *_prog) const
QString toString() const
convert ShaderGenDesc to string format for debugging
Interface for modifying render objects.
Vec2f depthRange
glDepthRange: (znear, zmax)
std::map< int, ACG::FBO * > depthMaps_
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
const QStringList & getTessEvaluationShaderCode()
Returns generated tessellation control shader code.
void baseColor(const Vec4f &_c)
set the base color
std::vector< ACG::RenderObject > renderObjects_
array of renderobjects, filled by addRenderObject()
std::string name
Name for logging.
int viewport_height() const
get viewport height
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
bool hasGeometryShader() const
check whether there is a geometry shader present
const GLMatrixd & modelview() const
get modelview matrix
void deactivateShaderPipeline(GLSL::Program *_prog) const
Hide this node, but draw children.
unsigned int numIndices
Number indices to render.
GLenum blendDest
glBlendFunc: GL_SRC_ALPHA, GL_ZERO, GL_ONE, GL_ONE_MINUS_SRC_ALPHA ...
unsigned int internalFlags_
may be used internally by the renderer
DrawMode DEFAULT
use the default (global) draw mode and not the node's own.
void shininess(float _s)
set shininess
StatusMode status() const
Get node's status.
const QStringList & getFragmentShaderCode()
Returns generated fragment shader code.
Interface class between scenegraph and renderer.
void use()
Enables the program object for using.
void bind(PtrProgram _prog) const
Send all stored uniforms to program.
const QStringList & getVertexShaderCode()
Returns generated vertex shader code.
GLenum primitiveMode
Primitive type.
static unsigned int registerModifier(ShaderModifier *_modifier)
Shader modifiers have to be registered before they can be used. They also must remain allocated for t...
const char * depthMapUniformName
Uniform name of the depth map in the used shader.
void resize(GLsizei _width, GLsizei _height, bool _forceResize=false)
resize function (if textures created by this class)
GLSL::PtrProgram loadProgram(const char *vertexShaderFile, const char *tessControlShaderFile, const char *tessEvaluationShaderFile, const char *geometryShaderFile, const char *fragmentShaderFile, const GLSL::StringList *macros, bool verbose)
ACG::SceneGraph::Material & material()
Get material object reference.
unsigned int indexOffset
Offset to first index in the index buffer or vertex buffer respectively.
GLuint getProgramId()
Returns opengl id.
GLuint indexBuffer
Use vertex array object.
ShaderGenDesc shaderDesc
Drawmode and other shader params.