50 #include <ACG/GL/acg_glew.hh>
55 #include <QTextStream>
57 #include <ACG/GL/gl.hh>
59 #include <ACG/GL/IRenderer.hh>
61 #include <ACG/GL/VertexDeclaration.hh>
62 #include <ACG/GL/GLError.hh>
64 #include <ACG/GL/ShaderCache.hh>
65 #include <ACG/GL/ScreenQuad.hh>
66 #include <ACG/GL/FBO.hh>
67 #include <ACG/GL/globjects.hh>
74 IRenderer::IRenderer()
80 prevDrawBuffer_(GL_BACK),
83 errorDetectionLevel_(1),
84 enableLineThicknessGL42_(false)
92 globalLightModelAmbient_ =
ACG::Vec3f(0.2f, 0.2f, 0.2f);
96 IRenderer::~IRenderer()
108 if (!_renderObject->debugName)
109 _renderObject->debugName =
"<unnamed>";
111 if (_renderObject->
name.empty())
112 _renderObject->
name = _renderObject->debugName;
116 std::cout <<
"error: missing vertex declaration in renderobject: " << _renderObject->debugName << std::endl;
124 std::cout <<
"warning: numIndices is 0 in renderobject: " << _renderObject->debugName << std::endl;
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;
134 if (_renderObject->emissive.max() < 1e-3f)
135 std::cout <<
"warning: unlit object rendered with black emissive color: " << _renderObject->debugName << std::endl;
141 glGetFloatv(GL_COLOR_CLEAR_VALUE, clearColor);
143 if (checkEpsilon(clearColor[0] - _renderObject->emissive[0]) &&
144 checkEpsilon(clearColor[1] - _renderObject->emissive[1]) &&
145 checkEpsilon(clearColor[2] - _renderObject->emissive[2]))
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;
153 if (_renderObject->textures().size())
159 for (std::map<size_t,RenderObject::Texture>::const_iterator it = _renderObject->textures().begin();
160 it != _renderObject->textures().end(); ++it)
162 #ifdef GL_ARB_texture_buffer_object
163 if (it->second.type == GL_TEXTURE_BUFFER)
167 glBindTexture(it->second.type, it->second.id);
169 GLint minFilter = GL_NONE;
170 glGetTexParameteriv(it->second.type, GL_TEXTURE_MIN_FILTER, &minFilter);
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)
178 glGetTexParameteriv(it->second.type, GL_TEXTURE_MAX_LEVEL, &maxLevel);
181 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &texWidth);
184 for (GLint lod = 0; lod < maxLevel && maxLod < 0; ++lod)
187 glGetTexLevelParameteriv(GL_TEXTURE_2D, lod, GL_TEXTURE_WIDTH, &lodWidth);
189 if (lodWidth <= 0 || lodWidth == GL_INVALID_VALUE)
193 if (maxLod <= 0 && texWidth > 1)
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;
198 GLint correctedFilter = GL_LINEAR;
200 if (minFilter == GL_NEAREST_MIPMAP_LINEAR ||
201 minFilter == GL_LINEAR_MIPMAP_LINEAR)
202 correctedFilter = GL_LINEAR;
204 correctedFilter = GL_NEAREST;
206 glTexParameteri(it->second.type, GL_TEXTURE_MIN_FILTER, correctedFilter);
218 if (_renderObject->depthWrite && !_renderObject->depthTest)
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;
228 if (_renderObject->
shaderDesc.shadeMode != SG_SHADE_UNLIT)
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;
240 std::cout <<
"warning: missing texcoords for textured mode in renderobject: " << _renderObject->debugName << std::endl;
247 std::cout <<
"warning: missing colors for vertexcolor mode in renderobject: " << _renderObject->debugName << std::endl;
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;
257 #ifdef GL_ARB_tessellation_shader
259 const bool tessellationActive = !_renderObject->
shaderDesc.tessControlTemplateFile.isEmpty() || !_renderObject->
shaderDesc.tessEvaluationTemplateFile.isEmpty();
260 bool tryToFixPatchInfo =
false;
261 if (tessellationActive && _renderObject->
primitiveMode != GL_PATCHES)
263 std::cout <<
"error: tessellation shaders are not used with GL_PATCHES primitiveType in renderobject: " << _renderObject->debugName << std::endl;
264 tryToFixPatchInfo =
true;
269 std::cout <<
"error: undefined patch size for tessellation in renderobject: " << _renderObject->debugName << std::endl;
270 tryToFixPatchInfo =
true;
273 if (tryToFixPatchInfo)
279 std::cout <<
"warning: attempting to draw with patchVertices = 1 for tessellation in renderobject: " << _renderObject->debugName << std::endl;
285 std::cout <<
"warning: attempting to draw with patchVertices = 2 for tessellation in renderobject: " << _renderObject->debugName << std::endl;
291 std::cout <<
"warning: attempting to draw with patchVertices = 3 for tessellation in renderobject: " << _renderObject->debugName << std::endl;
297 std::cout <<
"warning: attempting to draw with patchVertices = 4 for tessellation in renderobject: " << _renderObject->debugName << std::endl;
319 #ifdef GL_VERSION_3_2
327 #ifdef GL_VERSION_3_2
328 GLint geomInputType = 0;
329 glGetProgramiv(shaderProg->
getProgramId(), GL_GEOMETRY_INPUT_TYPE, &geomInputType);
335 switch (geomInputType)
337 case GL_POINTS: std::cout <<
"warning: primitive mode is incompatible with points-geometryshader in renderobject: " << _renderObject->debugName << std::endl;
break;
342 std::cout <<
"warning: primitive mode is incompatible with lines-geometryshader in renderobject: " << _renderObject->debugName << std::endl;
345 case GL_LINES_ADJACENCY:
348 std::cout <<
"warning: primitive mode is incompatible with lines_adjacency-geometryshader in renderobject: " << _renderObject->debugName << std::endl;
354 std::cout <<
"warning: primitive mode is incompatible with triangles-geometryshader in renderobject: " << _renderObject->debugName << std::endl;
357 case GL_TRIANGLES_ADJACENCY:
360 std::cout <<
"warning: primitive mode is incompatible with triangles_adjacency-geometryshader in renderobject: " << _renderObject->debugName << std::endl;
363 default: std::cout <<
"warning: unknown input_type for geometryshader in renderobject: " << _renderObject->debugName << std::endl;
375 std::cout <<
"warning: primitive mode is incompatible with lines-geometryshader in renderobject: " << _renderObject->debugName << std::endl;
380 std::cout <<
"warning: primitive mode is incompatible with points-geometryshader in renderobject: " << _renderObject->debugName << std::endl;
402 renderObjects_.resize(0);
415 traverseRenderableNodes(_glState, _drawMode, _sceneGraphRoot, &defMat);
439 _node->
enter(*_glState, nodeDM);
460 traverseRenderableNodes( _glState, _drawMode, *cIt, _mat);
465 traverseRenderableNodes( _glState, _drawMode, *cIt, _mat);
471 _node->
leave(*_glState, nodeDM);
477 int IRenderer::cmpPriority(
const void* _a,
const void* _b)
490 camPosWS_ =
Vec3f( viewMatrix_(0,3), viewMatrix_(1,3), viewMatrix_(2,3) );
491 camDirWS_ =
Vec3f( viewMatrix_(0,2), viewMatrix_(1,2), -viewMatrix_(2,2) );
497 collectRenderObjects(_glState, _drawMode, _scenegraphRoot);
500 if (renderObjects_.empty())
508 const size_t numRenderObjects = getNumRenderObjects(),
509 numOverlayObjects = getNumOverlayObjects(),
510 numLineObjects = getNumLineGL42Objects();
513 if (sortedObjects_.size() < numRenderObjects)
514 sortedObjects_.resize(numRenderObjects);
516 if (overlayObjects_.size() < numOverlayObjects)
517 overlayObjects_.resize(numOverlayObjects);
519 if (lineGL42Objects_.size() < numLineObjects)
520 lineGL42Objects_.resize(numLineObjects);
523 size_t sceneObjectOffset = 0, overlayObjectOffset = 0, lineObjectOffset = 0;
524 for (
size_t i = 0; i < renderObjects_.size(); ++i)
526 if (renderObjects_[i].overlay)
527 overlayObjects_[overlayObjectOffset++] = &renderObjects_[i];
528 else if (enableLineThicknessGL42_ && numLineObjects && renderObjects_[i].isDefaultLineObject())
530 renderObjects_[i].shaderDesc.geometryTemplateFile =
"Wireframe/gl42/geometry.tpl";
531 renderObjects_[i].shaderDesc.fragmentTemplateFile =
"Wireframe/gl42/fragment.tpl";
534 renderObjects_[i].glColorMask(0,0,0,0);
537 lineGL42Objects_[lineObjectOffset++] = &renderObjects_[i];
540 sortedObjects_[sceneObjectOffset++] = &renderObjects_[i];
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);
558 glEnable(GL_CULL_FACE);
559 glEnable(GL_DEPTH_TEST);
560 glDepthFunc(GL_LESS);
561 glDepthMask(GL_TRUE);
568 GLfloat lightModelAmbient[4];
569 glGetFloatv(GL_LIGHT_MODEL_AMBIENT, lightModelAmbient);
570 globalLightModelAmbient_ =
ACG::Vec3f(lightModelAmbient[0], lightModelAmbient[1], lightModelAmbient[2]);
574 bool requiresSceneDepths =
false;
576 for (
size_t i = 0; i < renderObjects_.size(); ++i)
578 if (renderObjects_[i].depthMapUniformName)
579 requiresSceneDepths =
true;
583 if (requiresSceneDepths)
589 void IRenderer::finishRenderingPipeline(
bool _drawOverlay)
591 #ifdef GL_ARB_vertex_array_object
592 glBindVertexArray(0);
596 if (enableLineThicknessGL42_)
597 renderLineThicknessGL42();
601 const int numOverlayObj = getNumOverlayObjects();
607 for (
int i = 0; i < numOverlayObj; ++i)
611 if (obj->depthTest && obj->
depthFunc != GL_ALWAYS)
613 float depthMax = 1.0f;
620 bool depthWrite = obj->depthWrite;
625 obj->depthWrite =
true;
632 obj->depthWrite = depthWrite;
639 for (
int i = 0; i < numOverlayObj; ++i)
647 #ifdef GL_ARB_vertex_array_object
648 glBindVertexArray(0);
652 glColorMask(1,1,1,1);
656 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
657 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
664 GLint curViewport[4];
666 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &curFbo);
667 glGetIntegerv(GL_VIEWPORT, curViewport);
668 glGetIntegerv(GL_DRAW_BUFFER, &curDrawBuf);
670 if (curFbo != prevFbo_)
672 std::cout <<
"warning: input and output fbo are not the same in renderer implementation" << std::endl;
676 if (curDrawBuf != prevDrawBuffer_)
678 std::cout <<
"warning: input and output draw-buffer are not the same in renderer implementation" << std::endl;
682 if (curViewport[0] != prevViewport_[0] ||
683 curViewport[1] != prevViewport_[1] ||
684 curViewport[2] != prevViewport_[2] ||
685 curViewport[3] != prevViewport_[3])
687 std::cout <<
"warning: input and output viewport are not the same in renderer implementation" << std::endl;
693 void IRenderer::saveInputFbo()
696 saveActiveFbo(&prevFbo_, prevViewport_, &prevDrawBuffer_);
697 prevFboSaved_ =
true;
700 void IRenderer::restoreInputFbo()
703 restoreFbo(prevFbo_, prevViewport_, prevDrawBuffer_);
706 void IRenderer::saveActiveFbo( GLint* _outFboId, GLint* _outViewport, GLint* _outDrawBuffer )
const
709 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, _outFboId);
710 glGetIntegerv(GL_VIEWPORT, _outViewport);
711 glGetIntegerv(GL_DRAW_BUFFER, _outDrawBuffer);
714 void IRenderer::restoreFbo( GLint _fboId,
const GLint* _outViewport, GLint _drawBuffer )
const
716 glBindFramebuffer(GL_FRAMEBUFFER, _fboId);
717 glDrawBuffer(_drawBuffer);
718 glViewport(_outViewport[0], _outViewport[1], _outViewport[2], _outViewport[3]);
721 void IRenderer::clearInputFbo(
const ACG::Vec4f& clearColor )
723 glClearColor(clearColor[0], clearColor[1], clearColor[2], 1.0f);
729 GLint oldViewport[4];
730 glGetIntegerv(GL_VIEWPORT, oldViewport);
731 glScissor(oldViewport[0], oldViewport[1], oldViewport[2], oldViewport[3]);
734 glScissor(prevViewport_[0], prevViewport_[1], prevViewport_[2], prevViewport_[3]);
736 glEnable(GL_SCISSOR_TEST);
737 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
740 glDisable(GL_SCISSOR_TEST);
744 void IRenderer::sortRenderObjects()
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);
760 #ifdef GL_ARB_vertex_array_object
770 glBindBufferARB(GL_ARRAY_BUFFER_ARB, _obj->
vertexBuffer);
771 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, _obj->
indexBuffer);
799 _prog->
setUniform(
"g_cEmissive", _obj->emissive);
802 _prog->
setUniform(
"g_cAmbient", _obj->ambient);
803 _prog->
setUniform(
"g_cSpecular", _obj->specular);
805 ACG::Vec4f materialParams(_obj->shininess, _obj->alpha, 0.0f, 0.0f);
806 _prog->
setUniform(
"g_vMaterial", materialParams);
808 _prog->
setUniform(
"g_cLightModelAmbient", globalLightModelAmbient_);
811 if ( !_obj->uniformPool_.
empty() )
812 _obj->uniformPool_.
bind(_prog);
820 int maxTextureStage = 0;
821 for (std::map<size_t,RenderObject::Texture>::const_iterator iter = _obj->textures().begin();
822 iter != _obj->textures().end();++iter)
825 const size_t texture_stage = iter->first;
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);
834 maxTextureStage = std::max(maxTextureStage, (
int)texture_stage);
842 int depthMapSlot = maxTextureStage + 1;
845 glActiveTexture(GL_TEXTURE0 + depthMapSlot);
846 glBindTexture(GL_TEXTURE_2D, depthMaps_[curViewerID_]->getAttachment(GL_COLOR_ATTACHMENT0));
851 for (
int i = 0; i < numLights_; ++i)
855 char szUniformName[256];
857 sprintf(szUniformName,
"g_cLightDiffuse_%d", i);
858 _prog->
setUniform(szUniformName, lgt->diffuse);
860 sprintf(szUniformName,
"g_cLightAmbient_%d", i);
861 _prog->
setUniform(szUniformName, lgt->ambient);
863 sprintf(szUniformName,
"g_cLightSpecular_%d", i);
864 _prog->
setUniform(szUniformName, lgt->specular);
867 if (lgt->ltype == ACG::SG_LIGHT_POINT || lgt->ltype == ACG::SG_LIGHT_SPOT)
869 sprintf(szUniformName,
"g_vLightPos_%d", i);
872 sprintf(szUniformName,
"g_vLightAtten_%d", i);
876 if (lgt->ltype == ACG::SG_LIGHT_DIRECTIONAL || lgt->ltype == ACG::SG_LIGHT_SPOT)
878 sprintf(szUniformName,
"g_vLightDir_%d", i);
882 if (lgt->ltype == ACG::SG_LIGHT_SPOT)
884 sprintf(szUniformName,
"g_vLightAngleExp_%d", i);
885 _prog->
setUniform(szUniformName, lgt->spotCutoffExponent);
893 glEnable(GL_CULL_FACE);
895 glDisable(GL_CULL_FACE);
904 glEnable(GL_ALPHA_TEST);
905 glAlphaFunc(_obj->
alphaFunc, _obj->alphaRef);
908 glDisable(GL_ALPHA_TEST);
911 glEnable(GL_DEPTH_TEST);
913 glDisable(GL_DEPTH_TEST);
916 glDepthMask(_obj->depthWrite ? GL_TRUE : GL_FALSE);
918 glColorMask(_obj->colorWriteMask[0], _obj->colorWriteMask[1], _obj->colorWriteMask[2], _obj->colorWriteMask[3]);
934 bool noIndices =
true;
938 glPolygonMode(GL_FRONT_AND_BACK, _obj->fillMode);
941 bool tessellationActive = !(_obj->
shaderDesc.tessControlTemplateFile.isEmpty() && _obj->
shaderDesc.tessEvaluationTemplateFile.isEmpty());
942 #ifdef GL_ARB_tessellation_shader
943 if (tessellationActive)
947 if (_obj->
shaderDesc.tessControlTemplateFile.isEmpty())
949 glPatchParameterfv(GL_PATCH_DEFAULT_INNER_LEVEL, _obj->patchDefaultInnerLevel.data());
950 glPatchParameterfv(GL_PATCH_DEFAULT_OUTER_LEVEL, _obj->patchDefaultOuterLevel.data());
954 if (tessellationActive)
955 std::cout <<
"error: tessellation shaders cannot be used with the outdated glew version" << std::endl;
971 case GL_UNSIGNED_INT: indexSize = 4;
break;
972 case GL_UNSIGNED_SHORT: indexSize = 2;
break;
973 default: indexSize = 1;
break;
988 bool _constRenderStates,
989 const std::vector<unsigned int>* _shaderModifiers)
995 bindObjectVBO(_obj, prog);
1000 bindObjectUniforms(_obj, prog);
1004 if (!_constRenderStates)
1005 bindObjectRenderStates(_obj);
1022 #ifdef GL_ARB_vertex_array_object
1024 glBindVertexArray(0);
1032 if (numLights_ < SG_MAX_SHADER_LIGHTS)
1034 lights_[numLights_] = _light;
1037 if (_light.ltype != SG_LIGHT_POINT)
1038 lights_[numLights_].dir.normalize();
1045 int IRenderer::getNumRenderObjects()
const
1048 for (
size_t i = 0; i < renderObjects_.size(); ++i)
1049 if (!renderObjects_[i].overlay && !(renderObjects_[i].isDefaultLineObject() && enableLineThicknessGL42_))
1056 int IRenderer::getNumOverlayObjects()
const
1059 for (
size_t i = 0; i < renderObjects_.size(); ++i)
1060 if (renderObjects_[i].overlay)
1066 int IRenderer::getNumLineGL42Objects()
const
1070 if (enableLineThicknessGL42_)
1072 for (
size_t i = 0; i < renderObjects_.size(); ++i)
1073 if (renderObjects_[i].isDefaultLineObject())
1080 int IRenderer::getNumLights()
const
1088 if (sortedObjects_.empty())
1089 return &renderObjects_[i];
1091 return sortedObjects_[i];
1096 if (overlayObjects_.empty())
1097 return &renderObjects_[i];
1099 return overlayObjects_[i];
1104 if (lineGL42Objects_.empty())
1107 return lineGL42Objects_[i];
1116 void IRenderer::dumpRenderObjectsToFile(
const char* _fileName,
ACG::RenderObject** _sortedList)
const
1118 QFile fileOut(_fileName);
1119 if (fileOut.open(QFile::WriteOnly | QFile::Truncate))
1121 QTextStream outStrm(&fileOut);
1122 for (
int i = 0; i < getNumRenderObjects(); ++i)
1125 outStrm <<
"\n" << _sortedList[i]->
toString();
1127 outStrm <<
"\n" << renderObjects_[i].toString();
1135 QString IRenderer::dumpCurrentRenderObjectsToString(
ACG::RenderObject** _list,
bool _outputShaders, std::vector<ACG::ShaderModifier*>* _modifiers) {
1137 QString objectString;
1139 QTextStream outStrm(&objectString);
1141 for (
int i = 0; i < getNumRenderObjects(); ++i)
1143 const RenderObject* obj = _list ? _list[i] : &renderObjects_[i];
1146 outStrm <<
"\n" << obj->
toString();
1148 if ( _outputShaders ) {
1156 outStrm <<
"\n---------------------vertex-shader--------------------\n\n";
1159 outStrm <<
"\n---------------------end-vertex-shader--------------------\n\n";
1163 outStrm <<
"\n---------------------tesscontrol-shader--------------------\n\n";
1166 outStrm <<
"\n---------------------end-tesscontrol-shader--------------------\n\n";
1171 outStrm <<
"\n---------------------tesseval-shader--------------------\n\n";
1175 outStrm <<
"\n---------------------end-tesseval-shader--------------------\n\n";
1180 outStrm <<
"\n---------------------geometry-shader--------------------\n\n";
1183 outStrm <<
"\n---------------------end-geometry-shader--------------------\n\n";
1187 outStrm <<
"\n---------------------fragment-shader--------------------\n\n";
1190 outStrm <<
"\n---------------------end-fragment-shader--------------------\n\n";
1197 return objectString;
1200 void IRenderer::copyDepthToBackBuffer( GLuint _depthTex,
float _scale )
1202 if (!_depthTex)
return;
1204 if (!depthCopyShader_)
1205 depthCopyShader_ =
GLSL::loadProgram(
"ScreenQuad/screenquad.glsl",
"ScreenQuad/depth_copy.glsl");
1208 if (depthCopyShader_)
1212 GLint curViewport[4];
1213 GLint curDrawBuffer;
1214 saveActiveFbo(&curFbo, curViewport, &curDrawBuffer);
1216 GLboolean colorMask[4], depthMask;
1217 glGetBooleanv(GL_COLOR_WRITEMASK, colorMask);
1218 glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
1220 GLboolean depthTestEnable;
1222 glGetBooleanv(GL_DEPTH_TEST, &depthTestEnable);
1223 glGetIntegerv(GL_DEPTH_FUNC, &depthFunc);
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);
1232 depthCopyShader_->setUniform(
"DepthSign", _scale);
1235 glColorMask(0,0,0,0);
1239 glEnable(GL_DEPTH_TEST);
1240 glDepthFunc(GL_ALWAYS);
1242 glActiveTexture(GL_TEXTURE0);
1243 glBindTexture(GL_TEXTURE_2D, _depthTex);
1250 restoreFbo(curFbo, curViewport, curDrawBuffer);
1252 glColorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
1253 glDepthMask(depthMask);
1255 if (!depthTestEnable)
1256 glDisable(GL_DEPTH_TEST);
1258 if (depthFunc != GL_ALWAYS)
1259 glDepthFunc(depthFunc);
1261 glBindTexture(GL_TEXTURE_2D, 0);
1270 void IRenderer::DepthMapPass::modifyFragmentEndCode(QStringList* _code)
1272 _code->push_back(
"outFragment = gl_FragCoord.zzzz;");
1275 void IRenderer::renderDepthMap(
int _viewerID,
int _width,
int _height)
1277 ACG::FBO* fbo = depthMaps_[_viewerID];
1282 fbo = depthMaps_[_viewerID] =
new ACG::FBO();
1285 fbo->
attachTexture2D(GL_COLOR_ATTACHMENT0, _width, _height, GL_R32F, GL_RED);
1291 fbo->
resize(_width, _height);
1310 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1311 glViewport(0, 0, _width, _height);
1314 glColorMask(1,1,1,1);
1317 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
1318 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1321 for (
int i = 0; i < getNumRenderObjects(); ++i)
1328 GLSL::Program* depthPassShader = ShaderCache::getInstance()->getProgram(&obj->
shaderDesc, DepthMapPass::instance);
1334 if (depthMapUniformName)
1336 depthPassShader->
use();
1337 depthPassShader->
setUniform(depthMapUniformName, 0);
1338 glActiveTexture(GL_TEXTURE0);
1339 glBindTexture(GL_TEXTURE_2D, 0);
1344 const GLboolean redWriteMask = obj->colorWriteMask[0];
1345 obj->colorWriteMask[0] = obj->depthWrite;
1347 renderObject(obj, depthPassShader);
1351 obj->colorWriteMask[0]= redWriteMask;
1363 void IRenderer::setViewerID(
int _viewerID)
1365 curViewerID_ = _viewerID;
1369 void IRenderer::renderLineThicknessGL42()
1371 #ifdef GL_ARB_shader_image_load_store
1390 const int numLines = getNumLineGL42Objects();
1393 const bool useBufferTexture =
true;
1394 const bool useIntegerTexture =
true;
1404 if (useBufferTexture)
1405 macros.push_back(
"#define IMAGE_BUFFER");
1406 if (useIntegerTexture)
1407 macros.push_back(
"#define FMT_UINT");
1415 GLsizei w = prevViewport_[2], h = prevViewport_[3];
1416 GLsizei lineBPP = useIntegerTexture ? 4 : 16;
1419 if (useBufferTexture)
1421 lineColorImgBuf =
dynamic_cast<TextureBuffer*
>(lineColorBuffers_[curViewerID_]);
1423 if (!lineColorImgBuf)
1426 lineColorBuffers_[curViewerID_] = lineColorImgBuf;
1430 if (lineColorImgBuf->getBufferSize() != w * h * lineBPP)
1431 lineColorImgBuf->setBufferData(w*h*lineBPP, 0, GL_R32UI, GL_DYNAMIC_DRAW);
1435 lineColorImg2D =
dynamic_cast<Texture2D*
>(lineColorBuffers_[curViewerID_]);
1437 if (!lineColorImg2D)
1440 lineColorImg2D =
new Texture2D(GL_TEXTURE0);
1441 lineColorBuffers_[curViewerID_] = lineColorImg2D;
1445 if (lineColorImg2D->getWidth() != w || lineColorImg2D->getHeight() != h)
1446 lineColorImg2D->setData(0,
1447 useIntegerTexture ? GL_R32UI : GL_RGBA32F,
1449 useIntegerTexture ? GL_RED_INTEGER : GL_RGBA,
1450 useIntegerTexture ? GL_UNSIGNED_INT : GL_FLOAT,
1458 glViewport(0, 0, w, h);
1465 glColorMask(0,0,0,0);
1467 glDisable(GL_DEPTH_TEST);
1470 if (useBufferTexture)
1471 lineColorImgBuf->bindAsImage(0, GL_WRITE_ONLY);
1473 lineColorImg2D->bindAsImage(0, GL_WRITE_ONLY);
1475 GLSL::Program* shaderClear = ShaderCache::getInstance()->getProgram(
"ScreenQuad/screenquad.glsl",
"Wireframe/gl42/clear.glsl", ¯os);
1482 ScreenQuad::draw(shaderClear);
1484 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
1492 for (
int i = 0; i < numLines; ++i)
1494 RenderObject* obj = getLineGL42RenderObject(i);
1499 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
1511 if (useBufferTexture)
1512 lineColorImgBuf->bindAsImage(0, GL_READ_ONLY);
1514 lineColorImg2D->bindAsImage(0, GL_READ_ONLY);
1517 glColorMask(1,1,1,1);
1518 glDisable(GL_DEPTH_TEST);
1524 GLSL::Program* shaderComposite = ShaderCache::getInstance()->getProgram(
"ScreenQuad/screenquad.glsl",
"Wireframe/gl42/composite.glsl", ¯os);
1526 shaderComposite->
use();
1531 ScreenQuad::draw(shaderComposite);
1538 void IRenderer::setLineThicknessRenderingGL42(
bool _enable )
1540 if (Texture::supportsImageLoadStore() && Texture::supportsTextureBuffer())
1541 enableLineThicknessGL42_ = _enable;
1544 void IRenderer::setErrorDetectionLevel(
int _level )
1546 errorDetectionLevel_ = std::max(_level, 0);
1549 int IRenderer::getErrorDetectionLevel()
const
1551 return errorDetectionLevel_;
void deactivateShaderPipeline(GLSL::Program *_prog) const
GLuint indexBuffer
Use vertex array object.
ShaderGenDesc shaderDesc
Drawmode and other shader params.
Vec2f depthRange
glDepthRange: (znear, zmax)
const QStringList & getVertexShaderCode()
Returns generated vertex shader code.
Namespace providing different geometric functions concerning angles.
void specularColor(const Vec4f &_s)
set the specular color
DrawMode DEFAULT
use the default (global) draw mode and not the node's own.
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
GLenum alphaFunc
GL_LESS, GL_LEQUAL, GL_GREATER ..
bool isDefaultLineObject() const
Test if the object is rendered with one of the default line thickness methods.
const QStringList & getFragmentShaderCode()
Returns generated fragment shader code.
Interface class between scenegraph and renderer.
GLenum blendDest
glBlendFunc: GL_SRC_ALPHA, GL_ZERO, GL_ONE, GL_ONE_MINUS_SRC_ALPHA ...
GLSL::Program * depthCopyShader_
shader copies depth of the first front layer to the back buffer
static void draw(GLSL::Program *_prog=0)
Draw the screen quad.
const QStringList & getTessEvaluationShaderCode()
Returns generated tessellation control shader code.
int errorDetectionLevel_
error-detection level for checking render objects
GLSL::PtrProgram loadProgram(const char *vertexShaderFile, const char *tessControlShaderFile, const char *tessEvaluationShaderFile, const char *geometryShaderFile, const char *fragmentShaderFile, const GLSL::StringList *macros, bool verbose)
Hide this node and its children.
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
unsigned int internalFlags_
may be used internally by the renderer
GLenum depthFunc
GL_LESS, GL_LEQUAL, GL_GREATER ..
ChildIter childrenBegin()
Returns: begin-iterator of children.
static unsigned int registerModifier(ShaderModifier *_modifier)
Shader modifiers have to be registered before they can be used. They also must remain allocated for t...
virtual void enter(GLState &, const DrawModes::DrawMode &)
GLuint vertexArrayObject
Use vertex array object.
const GLMatrixd & modelview() const
get modelview matrix
void activateShaderPipeline(GLSL::Program *_prog) const
virtual void getRenderObjects(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawMode, const Material *_mat)
Deferred draw call with shader based renderer.
QString toString() const
convert ShaderGenDesc to string format for debugging
void addDepthBuffer(GLuint _width, GLuint _height)
function to add a depth renderbuffer to the fbo
void diffuseColor(const Vec4f &_d)
set the diffuse color.
const void * sysmemIndexBuffer
Use system memory index buffer.
GLSL::Program * getProgram(const ShaderGenDesc *_desc, const std::vector< unsigned int > &_mods)
Query a dynamically generated program from cache.
bool hasTessControlShader() const
check whether there is a tess-control shader present
void use()
Enables the program object for using.
std::list< BaseNode * >::iterator ChildIter
allows to iterate over children
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
GLuint getProgramId()
Returns opengl id.
int viewport_width() const
get viewport width
void resize(GLsizei _width, GLsizei _height, bool _forceResize=false)
resize function (if textures created by this class)
GLenum primitiveMode
Primitive type.
static void blendFunc(GLenum _sfactor, GLenum _dfactor)
replaces glBlendFunc, supports locking
unsigned int numIndices
Number indices to render.
Draw this node, but hide children.
Vec3f diffuse
material definitions
std::string name
Name for logging.
VectorT< float, 3 > Vec3f
ACG::SceneGraph::Material & material()
Get material object reference.
Draw node in second pass.
DrawModes::DrawMode drawMode() const
Return the own draw modes of this node.
int numLights_
Number of Lights.
StatusMode status() const
Get node's status.
void ambientColor(const Vec4f &_a)
set the ambient color.
std::map< int, ACG::FBO * > depthMaps_
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
static ShaderCache * getInstance()
Return instance of the ShaderCache singleton.
std::vector< ACG::RenderObject > renderObjects_
array of renderobjects, filled by addRenderObject()
void baseColor(const Vec4f &_c)
set the base color
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
bool hasTessEvaluationShader() const
check whether there is a tess-evaluation shader present
const VertexElement * findElementByUsage(VERTEX_USAGE _usage) const
const QStringList & getGeometryShaderCode()
Returns generated tessellation evaluation shader code.
GLMatrixd modelview
Modelview transform.
bool empty() const
returns if the pool is empty
Hide this node, but draw children.
void transpose()
transpose matrix
const char * depthMapUniformName
Uniform name of the depth map in the used shader.
GLenum indexType
Index element type.
unsigned int indexOffset
Offset to first index in the index buffer or vertex buffer respectively.
int priority
Priority to allow sorting of objects.
bool isDefaultPointObject() const
Test if the object is rendered with one of the default point extension methods.
void shininess(float _s)
set shininess
void bind(PtrProgram _prog) const
Send all stored uniforms to program.
void unbind()
unbind fbo, go to normal rendering mode
const QStringList & getTessControlShaderCode()
Returns generated vertex shader code.
bool invert()
matrix inversion (returns true on success)
int viewport_height() const
get viewport height
bool hasGeometryShader() const
check whether there is a geometry shader present
bool inZPrePass
Specify whether this object should be rendered in a z-prepass.
ChildIter childrenEnd()
Returns: end-iterator of children.
void setUniformMat3(const char *_name, const ACG::GLMatrixf &_value, bool _transposed=false)
Set 3x3fMatrix uniform to specified value.
unsigned int patchVertices
patch size if primitiveMode is GL_PATCHES for rendering with tessellation shaders ...
bool bind()
bind the fbo and sets it as rendertarget
virtual void leave(GLState &, const DrawModes::DrawMode &)
GLMatrixd proj
Projection transform.