/*===========================================================================*\ * * * OpenFlipper * * Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen * * www.openflipper.org * * * *--------------------------------------------------------------------------- * * This file is part of OpenFlipper. * * * * OpenFlipper is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * * published by the Free Software Foundation, either version 3 of * * the License, or (at your option) any later version with the * * following exceptions: * * * * If other files instantiate templates or use macros * * or inline functions from this file, or you compile this file and * * link it with other files to produce an executable, this file does * * not by itself cause the resulting executable to be covered by the * * GNU Lesser General Public License. This exception does not however * * invalidate any other reasons why the executable file might be * * covered by the GNU Lesser General Public License. * * * * OpenFlipper is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Lesser General Public License for more details. * * * * You should have received a copy of the GNU LesserGeneral Public * * License along with OpenFlipper. If not, * * see . * * * \*===========================================================================*/ #pragma once #include #include #include #include #include class DepthPeeling : public QObject, BaseInterface, RenderInterface, LoggingInterface, ACG::IRenderer { Q_OBJECT Q_INTERFACES(BaseInterface) Q_INTERFACES(RenderInterface) Q_INTERFACES(LoggingInterface) signals: // LoggingInterface void log(Logtype _type, QString _message); void log(QString _message); public: DepthPeeling(); ~DepthPeeling(); QString name() { return (QString("DepthPeeling Plugin")); }; QString description( ) { return (QString(tr("DepthPeeling Rendering Pipeline (Alpha Version!)"))); }; /// overide addRenderObject function to include OIT check void addRenderObject(ACG::RenderObject* _renderObject); public slots: QString version() { return QString("1.0"); }; QString renderObjectsInfo(bool _outputShaderInfo) { return dumpCurrentRenderObjectsToString(&sortedObjects_[0],_outputShaderInfo); }; private slots: //BaseInterface void initializePlugin(); void exit(){} // RenderInterface void render(ACG::GLState* _glState, Viewer::ViewerProperties& _properties); QString rendererName() {return QString("Alpha_Version_DepthPeeling");} void supportedDrawModes(ACG::SceneGraph::DrawModes::DrawMode& _mode) {_mode = ACG::SceneGraph::DrawModes::DEFAULT;} QString checkOpenGL(); private: /// peel the scene from front to back, one layer per pass void renderFrontPeeling(ACG::GLState* _glState, Viewer::ViewerProperties& _properties); /// peel the scene with dual depth peeling, two layers per pass void renderDualPeeling(ACG::GLState* _glState, Viewer::ViewerProperties& _properties); /// draw a projected quad in [-1, -1] - [1, 1] range void drawProjQuad(GLSL::Program* _prog); /// vbo containing a quad in projection space GLuint screenQuadVBO_; ACG::VertexDeclaration* screenQuadDecl_; // single layer depth peeling struct PeelLayer { /// target framebuffer for colorTex and depthBuf GLuint fbo; /// color rendertarget GLuint colorTex; /// hardware depth buffer GLuint depthBuf; /// depth-buffer rendertarget GLuint depthTex; // encountered gpu-model specific problems when reading from depthBuf directly }; /// blends one depth-layer into the current scene target GLSL::Program* peelBlend_; /// final copy into back-buffer GLSL::Program* peelFinal_; /** Copy depth-texture of first layer into hardware z-buffer. This is needed for post-processing or renderobjects with low priority. */ GLSL::Program* peelDepthCopy_; /// occlusion query determining end of peeling (last layer) GLuint peelQueryID_; /// dual depth peeling shaders GLSL::Program* peelBlendDual_; GLSL::Program* peelFinalDual_; /// Collection of framebuffers for each viewport struct ViewerResources { ViewerResources(); /// viewer window width unsigned int glWidth_; /// viewer window height unsigned int glHeight_; // depth peeling textures /// ping pong between two consecutive layers PeelLayer peelTargets_[2]; GLuint peelBlendTex_; GLuint peelBlendFbo_; // dual depth peeling textures // ping-pong buffer for (depth, front, back) targets GLuint dualDepthTex_[2]; // float2: (-minDepth, maxDepth) GLuint dualFrontTex_[2]; // rgba: color of front-peeled layer GLuint dualBackTex_[2]; // rgba: color of back-peeled layer GLuint dualBlendTex_; // rgb: color accumulation buffer GLuint dualFbo_; // targets: {depth0, front0, back0, depth1, front1, back1, blend} }; /// Allocate framebuffers and load shaders for depth-peeling. void initDepthPeeling(); /// Allocate framebuffers and load shaders for dual-depth-peeling. void initDualDepthPeeling(); /// Change viewport size for allocated rendertargets. void updateViewerResources(bool _dualPeeling, int _viewerId, unsigned int _newWidth, unsigned int _newHeight); /** * Stores framebuffer resources for each viewport. * Mapping: viewerID -> ViewerResources */ std::map viewerRes_; // debug functions // GLSL::Program* dbgProg_; // // void dbgDrawTex(GLuint _texID); };