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()
101 delete depthCopyShader_;
104 for (std::map<int, ACG::FBO*>::iterator it = depthMaps_.begin(); it != depthMaps_.end(); ++it)
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;
122 if (errorDetectionLevel_ > 0)
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;
135 if (errorDetectionLevel_ > 1 && _renderObject->
shaderDesc.shadeMode == SG_SHADE_UNLIT)
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);
216 if (errorDetectionLevel_ > 1)
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;
308 renderObjects_.push_back(*_renderObject);
314 size_t numMods = renderObjectModifiers_.size();
315 for (
size_t i = 0; i < numMods; ++i)
317 if (renderObjectModifiers_[i])
318 renderObjectModifiers_[i]->apply(p);
330 #ifdef GL_VERSION_3_2 336 if (errorDetectionLevel_ > 1 && p->
shaderDesc.geometryTemplateFile.length())
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;
452 std::vector<ScenegraphTraversalStackEl> stack;
455 stack.push_back(ScenegraphTraversalStackEl(&_node, &_mat));
456 while (!stack.empty()) {
457 ScenegraphTraversalStackEl &cur = stack.back();
467 cur.node->enter(
this, *_glState, nodeDM);
469 cur.subtree_index_start = renderObjects_.size();
476 cur.material = &matNode->
material();
479 cur.node->getRenderObjects(
this, *_glState, nodeDM, cur.material);
485 cIt = cur.node->childrenBegin(),
486 cEnd = cur.node->childrenEnd(); cIt != cEnd; ++cIt) {
487 if (((*cIt)->traverseMode() &
490 stack.push_back(ScenegraphTraversalStackEl(*cIt, cur.material));
495 cIt = cur.node->childrenBegin(),
496 cEnd = cur.node->childrenEnd(); cIt != cEnd; ++cIt) {
497 if ((~(*cIt)->traverseMode() &
500 stack.push_back(ScenegraphTraversalStackEl(*cIt, cur.material));
512 renderObjects_.begin() + cur.subtree_index_start,
513 renderObjects_.end());
516 cur.node->leave(
this, *_glState, nodeDM);
526 camPosWS_ =
Vec3f( viewMatrix_(0,3), viewMatrix_(1,3), viewMatrix_(2,3) );
527 camDirWS_ =
Vec3f( viewMatrix_(0,2), viewMatrix_(1,2), -viewMatrix_(2,2) );
533 collectRenderObjects(_glState, _drawMode, _scenegraphRoot);
540 size_t numRenderObjects = 0,
541 numOverlayObjects = 0,
544 for (std::vector<ACG::RenderObject>::const_iterator it = renderObjects_.begin();
545 it != renderObjects_.end(); ++it) {
546 if (!it->overlay && !(it->isDefaultLineObject() && enableLineThicknessGL42_))
550 if (enableLineThicknessGL42_ && it->isDefaultLineObject())
559 sortedObjects_.clear();
560 sortedObjects_.reserve(numRenderObjects);
562 overlayObjects_.clear();
563 overlayObjects_.reserve(numOverlayObjects);
565 lineGL42Objects_.clear();
566 lineGL42Objects_.reserve(numLineObjects);
569 for (
size_t i = 0; i < renderObjects_.size(); ++i)
571 if (renderObjects_[i].overlay)
572 overlayObjects_.push_back(&renderObjects_[i]);
573 else if (enableLineThicknessGL42_ && numLineObjects && renderObjects_[i].isDefaultLineObject())
575 renderObjects_[i].shaderDesc.geometryTemplateFile =
"Wireframe/gl42/geometry.tpl";
576 renderObjects_[i].shaderDesc.fragmentTemplateFile =
"Wireframe/gl42/fragment.tpl";
579 renderObjects_[i].glColorMask(0,0,0,0);
582 lineGL42Objects_.push_back(&renderObjects_[i]);
585 sortedObjects_.push_back(&renderObjects_[i]);
596 glDisableClientState(GL_VERTEX_ARRAY);
597 glDisableClientState(GL_COLOR_ARRAY);
598 glDisableClientState(GL_NORMAL_ARRAY);
599 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
600 glDisableClientState(GL_INDEX_ARRAY);
603 glEnable(GL_CULL_FACE);
604 glEnable(GL_DEPTH_TEST);
605 glDepthFunc(GL_LESS);
606 glDepthMask(GL_TRUE);
613 GLfloat lightModelAmbient[4];
614 glGetFloatv(GL_LIGHT_MODEL_AMBIENT, lightModelAmbient);
615 globalLightModelAmbient_ =
ACG::Vec3f(lightModelAmbient[0], lightModelAmbient[1], lightModelAmbient[2]);
619 bool requiresSceneDepths =
false;
621 for (
size_t i = 0; i < renderObjects_.size(); ++i)
623 if (renderObjects_[i].depthMapUniformName)
624 requiresSceneDepths =
true;
628 if (requiresSceneDepths)
636 #ifdef GL_ARB_vertex_array_object 637 glBindVertexArray(0);
641 if (enableLineThicknessGL42_)
642 renderLineThicknessGL42();
646 const int numOverlayObj = overlayObjects_.size();
652 for (
int i = 0; i < numOverlayObj; ++i)
656 if (obj->depthTest && obj->
depthFunc != GL_ALWAYS)
658 float depthMax = 1.0f;
665 bool depthWrite = obj->depthWrite;
670 obj->depthWrite =
true;
677 obj->depthWrite = depthWrite;
684 for (
int i = 0; i < numOverlayObj; ++i)
692 #ifdef GL_ARB_vertex_array_object 693 glBindVertexArray(0);
696 for (
int i = 0; i < maxClipDistances_; ++i)
697 glDisable(GL_CLIP_DISTANCE0 + i);
700 glColorMask(1,1,1,1);
704 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
705 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
712 GLint curViewport[4];
714 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &curFbo);
715 glGetIntegerv(GL_VIEWPORT, curViewport);
716 glGetIntegerv(GL_DRAW_BUFFER, &curDrawBuf);
718 if (curFbo != prevFbo_)
720 std::cout <<
"warning: input and output fbo are not the same in renderer implementation" << std::endl;
724 if (curDrawBuf != prevDrawBuffer_)
726 std::cout <<
"warning: input and output draw-buffer are not the same in renderer implementation" << std::endl;
730 if (curViewport[0] != prevViewport_[0] ||
731 curViewport[1] != prevViewport_[1] ||
732 curViewport[2] != prevViewport_[2] ||
733 curViewport[3] != prevViewport_[3])
735 std::cout <<
"warning: input and output viewport are not the same in renderer implementation" << std::endl;
744 saveActiveFbo(&prevFbo_, prevViewport_, &prevDrawBuffer_);
745 prevFboSaved_ =
true;
751 restoreFbo(prevFbo_, prevViewport_, prevDrawBuffer_);
757 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, _outFboId);
758 glGetIntegerv(GL_VIEWPORT, _outViewport);
759 glGetIntegerv(GL_DRAW_BUFFER, _outDrawBuffer);
764 glBindFramebuffer(GL_FRAMEBUFFER, _fboId);
765 glDrawBuffer(_drawBuffer);
766 glViewport(_outViewport[0], _outViewport[1], _outViewport[2], _outViewport[3]);
771 glClearColor(clearColor[0], clearColor[1], clearColor[2], 1.0f);
777 GLint oldViewport[4];
778 glGetIntegerv(GL_VIEWPORT, oldViewport);
779 glScissor(oldViewport[0], oldViewport[1], oldViewport[2], oldViewport[3]);
782 glScissor(prevViewport_[0], prevViewport_[1], prevViewport_[2], prevViewport_[3]);
784 glEnable(GL_SCISSOR_TEST);
785 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
788 glDisable(GL_SCISSOR_TEST);
792 struct RenderObjectComparator {
801 std::sort(sortedObjects_.begin(), sortedObjects_.end(), RenderObjectComparator());
802 std::sort(overlayObjects_.begin(), overlayObjects_.end(), RenderObjectComparator());
813 #ifdef GL_ARB_vertex_array_object 823 glBindBufferARB(GL_ARRAY_BUFFER_ARB, _obj->
vertexBuffer);
824 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, _obj->
indexBuffer);
852 _prog->
setUniform(
"g_cEmissive", _obj->emissive);
855 _prog->
setUniform(
"g_cAmbient", _obj->ambient);
856 _prog->
setUniform(
"g_cSpecular", _obj->specular);
858 ACG::Vec4f materialParams(_obj->shininess, _obj->alpha, 0.0f, 0.0f);
859 _prog->
setUniform(
"g_vMaterial", materialParams);
861 _prog->
setUniform(
"g_cLightModelAmbient", globalLightModelAmbient_);
864 if ( !_obj->uniformPool_.
empty() )
865 _obj->uniformPool_.
bind(_prog);
873 int maxTextureStage = 0;
874 for (std::map<size_t,RenderObject::Texture>::const_iterator iter = _obj->textures().begin();
875 iter != _obj->textures().end();++iter)
878 const size_t texture_stage = iter->first;
883 glActiveTexture(GL_TEXTURE0 + (GLenum)texture_stage);
884 glBindTexture(iter->second.type, tex.id);
885 _prog->
setUniform(QString(
"g_Texture%1").arg(texture_stage).toStdString().c_str(), (
int)texture_stage);
887 maxTextureStage = std::max(maxTextureStage, (
int)texture_stage);
895 int depthMapSlot = maxTextureStage + 1;
898 glActiveTexture(GL_TEXTURE0 + depthMapSlot);
899 glBindTexture(GL_TEXTURE_2D, depthMaps_[curViewerID_]->getAttachment(GL_COLOR_ATTACHMENT0));
904 for (
int i = 0; i < numLights_; ++i)
908 char szUniformName[256];
910 sprintf(szUniformName,
"g_cLightDiffuse_%d", i);
911 _prog->
setUniform(szUniformName, lgt->diffuse);
913 sprintf(szUniformName,
"g_cLightAmbient_%d", i);
914 _prog->
setUniform(szUniformName, lgt->ambient);
916 sprintf(szUniformName,
"g_cLightSpecular_%d", i);
917 _prog->
setUniform(szUniformName, lgt->specular);
920 if (lgt->ltype == ACG::SG_LIGHT_POINT || lgt->ltype == ACG::SG_LIGHT_SPOT)
922 sprintf(szUniformName,
"g_vLightPos_%d", i);
925 sprintf(szUniformName,
"g_vLightAtten_%d", i);
929 if (lgt->ltype == ACG::SG_LIGHT_DIRECTIONAL || lgt->ltype == ACG::SG_LIGHT_SPOT)
931 sprintf(szUniformName,
"g_vLightDir_%d", i);
935 if (lgt->ltype == ACG::SG_LIGHT_SPOT)
937 sprintf(szUniformName,
"g_vLightAngleExp_%d", i);
938 _prog->
setUniform(szUniformName, lgt->spotCutoffExponent);
946 glEnable(GL_CULL_FACE);
948 glDisable(GL_CULL_FACE);
957 glEnable(GL_ALPHA_TEST);
958 glAlphaFunc(_obj->
alphaFunc, _obj->alphaRef);
961 glDisable(GL_ALPHA_TEST);
964 glEnable(GL_DEPTH_TEST);
966 glDisable(GL_DEPTH_TEST);
969 glDepthMask(_obj->depthWrite ? GL_TRUE : GL_FALSE);
971 glColorMask(_obj->colorWriteMask[0], _obj->colorWriteMask[1], _obj->colorWriteMask[2], _obj->colorWriteMask[3]);
981 if (maxClipDistances_ < 0)
983 glGetIntegerv(GL_MAX_CLIP_DISTANCES, &maxClipDistances_);
984 maxClipDistances_ = std::min(maxClipDistances_, 32);
987 for (
int i = 0; i < maxClipDistances_; ++i)
989 if (_obj->clipDistanceMask & (1 << i))
990 glEnable(GL_CLIP_DISTANCE0 + i);
992 glDisable(GL_CLIP_DISTANCE0 + i);
1001 bool noIndices =
true;
1005 glPolygonMode(GL_FRONT_AND_BACK, _obj->fillMode);
1008 bool tessellationActive = !(_obj->
shaderDesc.tessControlTemplateFile.isEmpty() && _obj->
shaderDesc.tessEvaluationTemplateFile.isEmpty());
1009 #ifdef GL_ARB_tessellation_shader 1010 if (tessellationActive)
1014 if (_obj->
shaderDesc.tessControlTemplateFile.isEmpty())
1016 glPatchParameterfv(GL_PATCH_DEFAULT_INNER_LEVEL, _obj->patchDefaultInnerLevel.
data());
1017 glPatchParameterfv(GL_PATCH_DEFAULT_OUTER_LEVEL, _obj->patchDefaultOuterLevel.
data());
1021 if (tessellationActive)
1022 std::cout <<
"error: tessellation shaders cannot be used with the outdated glew version" << std::endl;
1038 case GL_UNSIGNED_INT: indexSize = 4;
break;
1039 case GL_UNSIGNED_SHORT: indexSize = 2;
break;
1040 default: indexSize = 1;
break;
1055 bool _constRenderStates,
1056 const std::vector<unsigned int>* _shaderModifiers)
1062 bindObjectVBO(_obj, prog);
1067 bindObjectUniforms(_obj, prog);
1071 if (!_constRenderStates)
1072 bindObjectRenderStates(_obj);
1089 #ifdef GL_ARB_vertex_array_object 1091 glBindVertexArray(0);
1099 if (numLights_ < SG_MAX_SHADER_LIGHTS)
1101 lights_[numLights_] = _light;
1104 if (_light.ltype != SG_LIGHT_POINT)
1113 renderObjectModifiers_.push_back(_mod);
1118 for (
int i =
int(renderObjectModifiers_.size()) - 1; i >= 0; --i)
1120 if (renderObjectModifiers_[i] == _mod)
1121 renderObjectModifiers_.erase(renderObjectModifiers_.begin() + i);
1126 return sortedObjects_.size();
1137 if (sortedObjects_.empty())
1138 return &renderObjects_[i];
1140 return sortedObjects_[i];
1145 if (overlayObjects_.empty())
1146 return &renderObjects_[i];
1148 return overlayObjects_[i];
1153 if (lineGL42Objects_.empty())
1156 return lineGL42Objects_[i];
1167 QFile fileOut(_fileName);
1168 if (fileOut.open(QFile::WriteOnly | QFile::Truncate))
1170 QTextStream outStrm(&fileOut);
1171 for (
int i = 0; i < getNumRenderObjects(); ++i)
1174 outStrm <<
"\n" << _sortedList[i]->
toString();
1176 outStrm <<
"\n" << renderObjects_[i].toString();
1186 QString objectString;
1188 QTextStream outStrm(&objectString);
1190 for (
int i = 0; i < getNumRenderObjects(); ++i)
1192 const RenderObject* obj = _list ? _list[i] : &renderObjects_[i];
1195 outStrm <<
"\n" << obj->
toString();
1197 if ( _outputShaders ) {
1205 outStrm <<
"\n---------------------vertex-shader--------------------\n\n";
1208 outStrm <<
"\n---------------------end-vertex-shader--------------------\n\n";
1212 outStrm <<
"\n---------------------tesscontrol-shader--------------------\n\n";
1215 outStrm <<
"\n---------------------end-tesscontrol-shader--------------------\n\n";
1220 outStrm <<
"\n---------------------tesseval-shader--------------------\n\n";
1224 outStrm <<
"\n---------------------end-tesseval-shader--------------------\n\n";
1229 outStrm <<
"\n---------------------geometry-shader--------------------\n\n";
1232 outStrm <<
"\n---------------------end-geometry-shader--------------------\n\n";
1236 outStrm <<
"\n---------------------fragment-shader--------------------\n\n";
1239 outStrm <<
"\n---------------------end-fragment-shader--------------------\n\n";
1246 return objectString;
1251 if (!_depthTex)
return;
1253 if (!depthCopyShader_)
1254 depthCopyShader_ =
GLSL::loadProgram(
"ScreenQuad/screenquad.glsl",
"ScreenQuad/depth_copy.glsl");
1257 if (depthCopyShader_)
1261 GLint curViewport[4];
1262 GLint curDrawBuffer;
1263 saveActiveFbo(&curFbo, curViewport, &curDrawBuffer);
1265 GLboolean colorMask[4], depthMask;
1266 glGetBooleanv(GL_COLOR_WRITEMASK, colorMask);
1267 glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
1269 GLboolean depthTestEnable;
1271 glGetBooleanv(GL_DEPTH_TEST, &depthTestEnable);
1272 glGetIntegerv(GL_DEPTH_FUNC, &depthFunc);
1277 depthCopyShader_->use();
1278 depthCopyShader_->setUniform(
"offset",
ACG::Vec2f(0.0f, 0.0f));
1279 depthCopyShader_->setUniform(
"size",
ACG::Vec2f(1.0f, 1.0f));
1280 depthCopyShader_->setUniform(
"DepthTex", 0);
1281 depthCopyShader_->setUniform(
"DepthSign", _scale);
1284 glColorMask(0,0,0,0);
1288 glEnable(GL_DEPTH_TEST);
1289 glDepthFunc(GL_ALWAYS);
1291 glActiveTexture(GL_TEXTURE0);
1292 glBindTexture(GL_TEXTURE_2D, _depthTex);
1299 restoreFbo(curFbo, curViewport, curDrawBuffer);
1301 glColorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
1302 glDepthMask(depthMask);
1304 if (!depthTestEnable)
1305 glDisable(GL_DEPTH_TEST);
1307 if (depthFunc != GL_ALWAYS)
1308 glDepthFunc(depthFunc);
1310 glBindTexture(GL_TEXTURE_2D, 0);
1321 _code->push_back(
"outFragment = gl_FragCoord.zzzz;");
1326 ACG::FBO* fbo = depthMaps_[_viewerID];
1331 fbo = depthMaps_[_viewerID] =
new ACG::FBO();
1334 fbo->
attachTexture2D(GL_COLOR_ATTACHMENT0, _width, _height, GL_R32F, GL_RED);
1340 fbo->
resize(_width, _height);
1359 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1360 glViewport(0, 0, _width, _height);
1363 glColorMask(1,1,1,1);
1366 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
1367 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1370 for (
int i = 0; i < getNumRenderObjects(); ++i)
1383 if (depthMapUniformName)
1385 depthPassShader->
use();
1386 depthPassShader->
setUniform(depthMapUniformName, 0);
1387 glActiveTexture(GL_TEXTURE0);
1388 glBindTexture(GL_TEXTURE_2D, 0);
1393 const GLboolean redWriteMask = obj->colorWriteMask[0];
1394 obj->colorWriteMask[0] = obj->depthWrite;
1396 renderObject(obj, depthPassShader);
1400 obj->colorWriteMask[0]= redWriteMask;
1414 curViewerID_ = _viewerID;
1418 void IRenderer::renderLineThicknessGL42()
1420 #ifdef GL_ARB_shader_image_load_store 1439 const int numLines = lineGL42Objects_.size();
1442 const bool useBufferTexture =
true;
1443 const bool useIntegerTexture =
true;
1453 if (useBufferTexture)
1454 macros.push_back(
"#define IMAGE_BUFFER");
1455 if (useIntegerTexture)
1456 macros.push_back(
"#define FMT_UINT");
1464 GLsizei w = prevViewport_[2], h = prevViewport_[3];
1465 GLsizei lineBPP = useIntegerTexture ? 4 : 16;
1468 if (useBufferTexture)
1470 lineColorImgBuf =
dynamic_cast<TextureBuffer*
>(lineColorBuffers_[curViewerID_]);
1472 if (!lineColorImgBuf)
1475 lineColorBuffers_[curViewerID_] = lineColorImgBuf;
1479 if (lineColorImgBuf->getBufferSize() != w * h * lineBPP)
1480 lineColorImgBuf->setBufferData(w*h*lineBPP, 0, GL_R32UI, GL_DYNAMIC_DRAW);
1484 lineColorImg2D =
dynamic_cast<Texture2D*
>(lineColorBuffers_[curViewerID_]);
1486 if (!lineColorImg2D)
1489 lineColorImg2D =
new Texture2D(GL_TEXTURE0);
1490 lineColorBuffers_[curViewerID_] = lineColorImg2D;
1494 if (lineColorImg2D->getWidth() != w || lineColorImg2D->getHeight() != h)
1495 lineColorImg2D->setData(0,
1496 useIntegerTexture ? GL_R32UI : GL_RGBA32F,
1498 useIntegerTexture ? GL_RED_INTEGER : GL_RGBA,
1499 useIntegerTexture ? GL_UNSIGNED_INT : GL_FLOAT,
1507 glViewport(0, 0, w, h);
1514 glColorMask(0,0,0,0);
1516 glDisable(GL_DEPTH_TEST);
1519 if (useBufferTexture)
1520 lineColorImgBuf->bindAsImage(0, GL_WRITE_ONLY);
1522 lineColorImg2D->bindAsImage(0, GL_WRITE_ONLY);
1533 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
1541 for (
int i = 0; i < numLines; ++i)
1548 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
1560 if (useBufferTexture)
1561 lineColorImgBuf->bindAsImage(0, GL_READ_ONLY);
1563 lineColorImg2D->bindAsImage(0, GL_READ_ONLY);
1566 glColorMask(1,1,1,1);
1567 glDisable(GL_DEPTH_TEST);
1575 shaderComposite->
use();
1589 if (Texture::supportsImageLoadStore() && Texture::supportsTextureBuffer())
1590 enableLineThicknessGL42_ = _enable;
1595 errorDetectionLevel_ = std::max(_level, 0);
1600 return errorDetectionLevel_;
const VertexElement * findElementByUsage(VERTEX_USAGE _usage) const
VectorT< float, 2 > Vec2f
Vec3f diffuse
material definitions
StatusMode status() const
Get node's status.
void specularColor(const Vec4f &_s)
set the specular color
static void draw(GLSL::Program *_prog=0)
Draw the screen quad.
void transpose()
transpose matrix
QString toString() const
convert ShaderGenDesc to string format for debugging
std::vector< BaseNode * >::iterator ChildIter
allows to iterate over children
void activateShaderPipeline(GLSL::Program *_prog) const
DrawMode DEFAULT
use the default (global) draw mode and not the node's own.
virtual void bindObjectVBO(ACG::RenderObject *_obj, GLSL::Program *_prog)
Binding VBOs (First state function)
static ShaderCache * getInstance()
Return instance of the ShaderCache singleton.
ACG::SceneGraph::Material & material()
Get material object reference.
bool bind()
bind the fbo and sets it as rendertarget
GLenum primitiveMode
Primitive type.
virtual void sortRenderObjects()
Sort the renderobjects by priority.
bool isDefaultLineObject() const
Test if the object is rendered with one of the default line thickness methods.
virtual void collectRenderObjects(ACG::GLState *_glState, ACG::SceneGraph::DrawModes::DrawMode _drawMode, ACG::SceneGraph::BaseNode *_sceneGraphRoot)
Traverse the scenegraph to collect render information.
Hide this node and its children.
int priority
Priority to allow sorting of objects.
virtual void renderObject(ACG::RenderObject *_obj, GLSL::Program *_prog=0, bool _constRenderStates=false, const std::vector< unsigned int > *_shaderModifiers=0)
Render one renderobject.
unsigned int internalFlags_
may be used internally by the renderer
GLuint indexBuffer
Use vertex array object.
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
void setUniformMat3(const char *_name, const ACG::GLMatrixf &_value, bool _transposed=false)
Set 3x3fMatrix uniform to specified value.
const void * sysmemIndexBuffer
Use system memory index buffer.
Interface for modifying render objects.
virtual void saveActiveFbo(GLint *_outFboId, GLint *_outViewport, GLint *_outDrawBuffer) const
Save active Fbo configuration (fbo id + viewport)
GLSL::PtrProgram loadProgram(const char *vertexShaderFile, const char *tessControlShaderFile, const char *tessEvaluationShaderFile, const char *geometryShaderFile, const char *fragmentShaderFile, const GLSL::StringList *macros, bool verbose)
void traverseRenderableNodes(ACG::GLState *_glState, ACG::SceneGraph::DrawModes::DrawMode _drawMode, ACG::SceneGraph::BaseNode &_node, const ACG::SceneGraph::Material &_mat)
Scene graph traversal for render object collection.
void baseColor(const Vec4f &_c)
set the base color
GLuint vertexArrayObject
Use vertex array object.
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
int viewport_width() const
get viewport width
GLenum indexType
Index element type.
ACG::RenderObject * getRenderObject(int i)
Get render objects in the sorted list by index (not including overlay objects)
void bind(PtrProgram _prog) const
Send all stored uniforms to program.
const QStringList & getFragmentShaderCode()
Returns generated fragment shader code.
virtual void drawObject(ACG::RenderObject *_obj)
Executes the opengl draw call for one object (Fourth function)
unsigned int patchVertices
patch size if primitiveMode is GL_PATCHES for rendering with tessellation shaders ...
void use()
Enables the program object for using.
static int maxClipDistances_
max number of clip distance outputs in a vertex shader
virtual void copyDepthToBackBuffer(GLuint _depthTex, float _scale=1.0f)
Copy texture to depth buffer.
int getNumLights() const
Get the number of current light sources.
bool hasGeometryShader() const
check whether there is a geometry shader present
Draw this node, but hide children.
unsigned int numIndices
Number indices to render.
GLMatrixd modelview
Modelview transform.
void ambientColor(const Vec4f &_a)
set the ambient color.
GLenum blendDest
glBlendFunc: GL_SRC_ALPHA, GL_ZERO, GL_ONE, GL_ONE_MINUS_SRC_ALPHA ...
VectorT< float, 3 > Vec3f
virtual void removeRenderObjectModifier(RenderObjectModifier *_mod)
Callback for the scenegraph nodes, which removes a render object modifier from the renderer...
unsigned int indexOffset
Offset to first index in the index buffer or vertex buffer respectively.
bool empty() const
returns if the pool is empty
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
void addDepthBuffer(GLuint _width, GLuint _height)
function to add a depth renderbuffer to the fbo
void diffuseColor(const Vec4f &_d)
set the diffuse color.
Hide this node, but draw children.
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
const QStringList & getGeometryShaderCode()
Returns generated tessellation evaluation shader code.
int getNumRenderObjects() const
Get the number of collected render objects (not including overlay objects or gl4.2 line objects) ...
std::string name
Name for logging.
void dumpRenderObjectsToFile(const char *_fileName, ACG::RenderObject **_sortedList=0) const
Debugging function to dump list of render objects into a file.
const QStringList & getVertexShaderCode()
Returns generated vertex shader code.
bool hasTessControlShader() const
check whether there is a tess-control shader present
virtual void restoreFbo(GLint _fboId, const GLint *_outViewport, GLint _drawBuffer) const
Restore a previously saved input Fbo configuration (fbo id + viewport)
ACG::RenderObject * getLineGL42RenderObject(int i)
Get render objects in the sorted list by index (only line objects rendered with gl4.2)
Namespace providing different geometric functions concerning angles.
void deactivateShaderPipeline(GLSL::Program *_prog) const
void setViewerID(int _viewerID)
Set currently active viewer id.
void resize(GLsizei _width, GLsizei _height, bool _forceResize=false)
resize function (if textures created by this class)
const QStringList & getTessEvaluationShaderCode()
Returns generated tessellation control shader code.
int getErrorDetectionLevel() const
Get error detection level.
virtual void renderDepthMap(int _viewerID, int _width, int _height)
Render the depth map of the scene.
GLSL::Program * getProgram(const ShaderGenDesc *_desc, const std::vector< unsigned int > &_mods)
Query a dynamically generated program from cache.
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
LightData * getLight(int i)
Get light by index.
virtual void addLight(const LightData &_light)
Callback for the scenegraph nodes, which send new lights to the renderer via this function...
bool invert()
matrix inversion (returns true on success)
GLenum depthFunc
GL_LESS, GL_LEQUAL, GL_GREATER ..
void setErrorDetectionLevel(int _level)
Control error detection for checking render objects.
Draw node in second pass.
virtual void bindObjectUniforms(ACG::RenderObject *_obj, GLSL::Program *_prog)
Binding Uniforms (Second state function)
void setLineThicknessRenderingGL42(bool _enable)
ACG::RenderObject * getOverlayRenderObject(int i)
Get render objects in the sorted list by index (only overlay objects)
const QStringList & getTessControlShaderCode()
Returns generated vertex shader code.
const char * depthMapUniformName
Uniform name of the depth map in the used shader.
void shininess(float _s)
set shininess
GLenum alphaFunc
GL_LESS, GL_LEQUAL, GL_GREATER ..
bool hasTessEvaluationShader() const
check whether there is a tess-evaluation shader present
const GLMatrixd & modelview() const
get modelview matrix
Scalar max() const
return the maximal component
virtual void finishRenderingPipeline(bool _drawOverlay=true)
Draw overlay objects and reset OpenGL state.
virtual void addRenderObjectModifier(RenderObjectModifier *_mod)
Callback for the scenegraph nodes, which adds a render object modifier to the renderer via this funct...
bool inZPrePass
Specify whether this object should be rendered in a z-prepass.
void modifyFragmentEndCode(QStringList *_code)
Append code the the fragment shader.
virtual void clearInputFbo(const ACG::Vec4f &_clearColor)
Clear input Fbo.
virtual void saveInputFbo()
Save input Fbo configuration (fbo id + viewport)
virtual void prepareRenderingPipeline(ACG::GLState *_glState, ACG::SceneGraph::DrawModes::DrawMode _drawMode, ACG::SceneGraph::BaseNode *_scenegraphRoot)
Prepares renderer and OpenGL for any draw-related calls including.
int viewport_height() const
get viewport height
void unbind()
unbind fbo, go to normal rendering mode
GLMatrixd proj
Projection transform.
Interface class between scenegraph and renderer.
static unsigned int registerModifier(ShaderModifier *_modifier)
Shader modifiers have to be registered before they can be used. They also must remain allocated for t...
bool isDefaultPointObject() const
Test if the object is rendered with one of the default point extension methods.
GLuint getProgramId()
Returns opengl id.
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
ShaderGenDesc shaderDesc
Drawmode and other shader params.
virtual void bindObjectRenderStates(ACG::RenderObject *_obj)
Binding Render state (Third state function)
virtual QString dumpCurrentRenderObjectsToString(ACG::RenderObject **_list=0, bool _outputShaders=false, std::vector< ACG::ShaderModifier * > *_modifiers=0)
Outputs the current render objects to the string.
Scalar * data()
access to Scalar array
Vec2f depthRange
glDepthRange: (znear, zmax)
virtual void restoreInputFbo()
Restore the previously saved input Fbo configuration (fbo id + viewport)
static void blendFunc(GLenum _sfactor, GLenum _dfactor)
replaces glBlendFunc, supports locking