43 #include <ACG/GL/acg_glew.hh>
45 #include "DeferredShading.hh"
49 #include <ACG/GL/ShaderCache.hh>
50 #include <ACG/GL/ScreenQuad.hh>
51 #include <ACG/GL/GLError.hh>
52 #include <ACG/QtWidgets/QtColorChooserButton.hh>
56 #define GBUFFER_INCLUDE_FILE "DeferredShading/GBufferAccess.glsl"
58 #define SCREENQUAD_VERTEXSHADER_FILE "DeferredShading/screenquad.glsl"
60 #define PASS_EMISSIVE_FILE "DeferredShading/pass_emissive.glsl"
61 #define PASS_EMISSIVE_MS_FILE "DeferredShading/pass_emissiveMS.glsl"
63 #define PASS_DIRECTIONAL_FILE "DeferredShading/pass_directional.glsl"
64 #define PASS_DIRECTIONAL_MS_FILE "DeferredShading/pass_directionalMS.glsl"
65 #define PASS_POINT_FILE "DeferredShading/pass_point.glsl"
66 #define PASS_POINT_MS_FILE "DeferredShading/pass_pointMS.glsl"
67 #define PASS_SPOT_FILE "DeferredShading/pass_spot.glsl"
68 #define PASS_SPOT_MS_FILE "DeferredShading/pass_spotMS.glsl"
70 #define PASS_BACKGROUND_FILE "DeferredShading/pass_background.glsl"
76 _shader->
addOutput(
"vec3 outVertexNormal");
77 _shader->
addOutput(
"vec4 outVertexPosVS");
88 _shader->
addInput(
"vec3 outVertexNormal");
89 _shader->
addInput(
"vec4 outVertexPosVS");
99 _code->push_back(
"outVertexPosVS = sg_vPosVS;");
100 _code->push_back(
"outVertexNormal = g_mWVIT * inNormal;");
104 _code->push_back(
"outFragment = WritePositionVS(outVertexPosVS, materialID);");
105 _code->push_back(
"outNormal = WriteNormalVS(outVertexNormal);");
124 DeferredShading::DeferredShading()
125 : progEmissive_(0), progEmissiveMS_(0),
127 progDirectional_(0), progDirectionalMS_(0),
128 progPoint_(0), progPointMS_(0),
129 progSpot_(0), progSpotMS_(0)
136 DeferredShading::~DeferredShading() {
149 void DeferredShading::initializePlugin() {
154 std::vector<ACG::ShaderModifier*> modifiers;
155 modifiers.push_back(&DeferredShadingInitPass::instance);
161 #ifdef GL_ARB_texture_buffer_object
174 materialBufferData_[0] =
ACG::Vec3f(.0f,.0f,.0f);
175 materialBufferData_[1] =
ACG::Vec3f(.0f,.0f,.0f);
176 materialBufferData_[2] =
ACG::Vec3f(.0f,.0f,.0f);
177 materialBufferData_[3] =
ACG::Vec3f(.0f,.0f,.0f);
178 materialBufferData_[4] =
ACG::Vec3f(1.0f,1.0f,0.0f);
181 int offset = (i + 1) * 5;
192 materialBuffer_.setBufferData(matBufSize, &materialBufferData_[0], GL_RGB32F, GL_DYNAMIC_DRAW);
200 glColorMask(1,1,1,1);
203 viewRes->scene_->bind();
208 const GLenum colorTarget[2] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
211 for (
int i = 0; i < 2; ++i) {
212 glDrawBuffer(colorTarget[i]);
214 ACG::Vec4f clearColor(0.0f, 0.0f, 0.0f, 0.0f);
216 glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
217 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
221 glDrawBuffers(2, colorTarget);
255 if (matProj(0,0) == 0.0)
259 if (objName.compare(
"MeshNode") == 0)
264 const ACG::Vec2f clipPlanes(
float(matProj(2,3) / (matProj(2,2) - 1.0)),
float(matProj(2,3) / (matProj(2,2) + 1.0)));
266 viewRes->scene_->unbind();
273 ACG::MSFilterWeights filterWeights(numSamples_);
274 filterWeights.asTextureBuffer(filterWeightsBuffer_);
287 glColorMask(1,1,1,1);
293 glEnable(GL_DEPTH_TEST);
294 glDepthFunc(GL_ALWAYS);
298 glBlendFunc(GL_ONE, GL_ONE);
316 passShader->
setUniform(
"projParams",
ACG::Vec4f(matProj(0,0), matProj(1,1), matProj(2,2), matProj(2,3)) );
317 passShader->
setUniform(
"clipPlanes", clipPlanes);
320 passShader->
setUniform(
"numSamples", numSamples_);
321 passShader->
setUniform(
"samplerFilterWeights", 7);
323 filterWeightsBuffer_.bind(GL_TEXTURE7);
326 materialBuffer_.bind(GL_TEXTURE6);
328 for (
int i = 1; i >= 0; --i){
329 glActiveTexture(GL_TEXTURE0 + i);
331 glBindTexture(numSamples_ ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D, viewRes->scene_->getAttachment(GL_COLOR_ATTACHMENT0 + i));
341 for (
int lightID = 0; lightID <
numLights_; ++lightID) {
342 const LightData* lgt =
lights_ + lightID;
347 if (lgt->ltype == ACG::SG_LIGHT_DIRECTIONAL)
349 else if (lgt->ltype == ACG::SG_LIGHT_SPOT)
363 passShader->
setUniform(
"lightAtten", lgt->atten);
365 if (lgt->ltype == ACG::SG_LIGHT_SPOT) {
366 passShader->
setUniform(
"lightSpotDir", lgt->dir);
367 passShader->
setUniform(
"lightSpotParam", lgt->spotCutoffExponent);
371 passShader->
setUniform(
"lightAmbient", lgt->ambient);
372 passShader->
setUniform(
"lightDiffuse", lgt->diffuse);
373 passShader->
setUniform(
"lightSpecular", lgt->specular);
375 passShader->
setUniform(
"projParams",
ACG::Vec4f(matProj(0,0), matProj(1,1), matProj(2,2), matProj(2,3)) );
376 passShader->
setUniform(
"clipPlanes", clipPlanes);
380 passShader->
setUniform(
"numSamples", numSamples_);
381 passShader->
setUniform(
"samplerFilterWeights", 7);
383 filterWeightsBuffer_.bind(GL_TEXTURE7);
386 materialBuffer_.bind(GL_TEXTURE6);
388 for (
int i = 1; i >= 0; --i){
389 glActiveTexture(GL_TEXTURE0 + i);
391 glBindTexture(numSamples_ ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D, viewRes->scene_->getAttachment(GL_COLOR_ATTACHMENT0 + i));
401 glDepthFunc(GL_LEQUAL);
411 glDepthFunc(GL_LESS);
413 glBlendFunc(GL_ONE, GL_ZERO);
427 void DeferredShading::reloadShaders() {
428 const int numShaders = 9;
439 const char* shaderFiles[numShaders] =
441 PASS_EMISSIVE_FILE, PASS_EMISSIVE_MS_FILE,
442 PASS_BACKGROUND_FILE,
443 PASS_DIRECTIONAL_FILE, PASS_DIRECTIONAL_MS_FILE,
444 PASS_POINT_FILE, PASS_POINT_MS_FILE,
445 PASS_SPOT_FILE, PASS_SPOT_MS_FILE,
448 for (
int i = 0; i < numShaders; ++i){
452 delete *(ptrShaders[i]);
453 *(ptrShaders[i]) = prog;
458 void DeferredShading::ViewerResources::resize(
int _newWidth,
int _newHeight,
int& _numSamples ) {
459 if (!_newHeight || !_newWidth)
return;
471 scene_->
attachTexture2D(GL_COLOR_ATTACHMENT0, _newWidth, _newHeight, GL_RG32F, GL_RG);
472 scene_->
attachTexture2D(GL_COLOR_ATTACHMENT1, _newWidth, _newHeight, GL_RGB, GL_RGB);
479 scene_->
resize(_newWidth, _newHeight);
483 void DeferredShading::slotMSAASelection( QAction * _action) {
484 if ( _action->text() ==
"0x MSAA") {
486 }
else if ( _action->text() ==
"2x MSAA") {
488 }
else if ( _action->text() ==
"4x MSAA") {
490 }
else if ( _action->text() ==
"8x MSAA") {
493 std::cerr <<
"Error : optionHandling unable to find MSAA selection!!! " << _action->text().toStdString() << std::endl;
502 #if QT_VERSION < 0x050000
void modifyFragmentEndCode(QStringList *_code)
Append code the the fragment shader.
int viewport_width() const
get viewport width
GLSL::Program * progSpot_
spot lighting pass
void clear()
sets all elements to zero
static void draw(GLSL::Program *_prog=0)
Draw the screen quad.
virtual void finishRenderingPipeline(bool _drawOverlay=true)
Draw overlay objects and reset OpenGL state.
GLSL::Program * progBackground_
background color pass
int numLights_
Number of Lights.
std::map< int, ViewerResources > viewerRes_
void link()
Links the shader objects to the program.
LightData lights_[SG_MAX_SHADER_LIGHTS]
Light sources ( Filled by addLight() )
bool replaceDefaultLightingCode()
Specify whether this modifier replaces or extends the default lighting code.
static ShaderCache * getInstance()
Return instance of the ShaderCache singleton.
void init()
function to generate the framebuffer object
void modifyFragmentIO(ACG::ShaderGenerator *_shader)
Add your own inputs/outputs to the fragment shader.
std::vector< ACG::RenderObject * > sortedObjects_
sorted list of renderobjects without overlay objects (sorted in rendering order)
virtual QString dumpCurrentRenderObjectsToString(ACG::RenderObject **_list=0, bool _outputShaders=false, std::vector< ACG::ShaderModifier * > *_modifiers=0)
Outputs the current render objects to the string.
GLSL::Program * progEmissive_
emissive color pass
GLsizei getMultisamplingCount() const
get number of samples
int viewerId()
Get the id of the viewer this viewerproperties belongs to.
void bindFragDataLocation(unsigned int _index, const char *_name)
Bind fragment output data to name.
static void setShaderDir(QString _dir)
void addOutput(const QString &_output)
Add one GLSL output specifier.
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
void modifyLightingCode(QStringList *_code, int _lightId, ACG::ShaderGenLightType _lightType)
Modify the default lighting code of the shader generator.
GLSL::Program * progDirectionalMS_
directional lighting pass with multisampling
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
void addInput(const QString &_input)
Add one GLSL input specifier.
GLsizei setMultisampling(GLsizei _samples, GLboolean _fixedsamplelocations=GL_TRUE)
void addIncludeFile(QString _fileName)
Imports another shader, same as #include.
GLSL::Program * progEmissiveMS_
emissive color pass with multisampling
VectorT< float, 3 > Vec3f
virtual void renderObject(ACG::RenderObject *_obj, GLSL::Program *_prog=0, bool _constRenderStates=false, const std::vector< unsigned int > *_shaderModifiers=0)
Render one renderobject.
GLSL::Program * getProgram(const ShaderGenDesc *_desc, const std::vector< unsigned int > &_mods)
Query a dynamically generated program from cache.
virtual void clearInputFbo(const ACG::Vec4f &_clearColor)
Clear input Fbo.
void modifyVertexIO(ACG::ShaderGenerator *_shader)
Add your own inputs/outputs to the vertex shader.
void addDepthBuffer(GLuint _width, GLuint _height)
function to add a depth renderbuffer to the fbo
QString renderObjectsInfo(bool _outputShaderInfo)
Return a qstring of the current render objects.
int viewport_height() const
get viewport height
GLSL::Program * progPoint_
point lighting pass
int getNumRenderObjects() const
Get the number of collected render objects (not including overlay objects or gl4.2 line objects) ...
GLSL::Program * progPointMS_
point lighting pass with multisampling
GLSL::Program * progSpotMS_
spot lighting pass with multisampling
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.
void addUniform(QString _uniform, QString _comment="")
Add one GLSL uniform specifier.
static QString getShaderDir()
void modifyVertexEndCode(QStringList *_code)
Append code the the vertex shader.
void drawMode(ACG::SceneGraph::DrawModes::DrawMode _mode)
set draw mode (No test if this mode is available!)
GLSL::Program * progDirectional_
directional lighting pass
int getFragDataLocation(const char *_name)
Get location of the fragment data output.
void use()
Enables the program object for using.
virtual void restoreInputFbo()
Restore the previously saved input Fbo configuration (fbo id + viewport)
static unsigned int registerModifier(ShaderModifier *_modifier)
Shader modifiers have to be registered before they can be used. They also must remain allocated for t...
void resize(GLsizei _width, GLsizei _height, bool _forceResize=false)
resize function (if textures created by this class)
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node
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 disable()
Resets to standard rendering pipeline.
ACG::Vec4f backgroundColor()
Get current background color.