From 1f66d948de19910c4299a18077a1424256275037 Mon Sep 17 00:00:00 2001 From: ansgar <ansgar@5a81b35b-ba03-0410-adc8-b2c5c5119f08> Date: Sat, 1 May 2010 18:04:17 +0000 Subject: [PATCH] some more scene fx refactoring git-svn-id: https://dng.biozentrum.unibas.ch/svn/openstructure/branches/new_gfx@2147 5a81b35b-ba03-0410-adc8-b2c5c5119f08 --- modules/gfx/src/CMakeLists.txt | 5 +- modules/gfx/src/impl/scene_fx.cc | 259 ++++++++++++++++ modules/gfx/src/impl/scene_fx.hh | 45 +++ modules/gfx/src/scene.cc | 280 +----------------- modules/gfx/src/scene.hh | 9 +- modules/gfx/src/shader.cc | 23 +- modules/gfx/src/shader.hh | 3 + modules/gfx/src/shader/amboccl_fs.glsl | 6 + .../{convolute1_vs.glsl => quadpp_vs.glsl} | 0 9 files changed, 359 insertions(+), 271 deletions(-) create mode 100644 modules/gfx/src/impl/scene_fx.cc create mode 100644 modules/gfx/src/impl/scene_fx.hh create mode 100644 modules/gfx/src/shader/amboccl_fs.glsl rename modules/gfx/src/shader/{convolute1_vs.glsl => quadpp_vs.glsl} (100%) diff --git a/modules/gfx/src/CMakeLists.txt b/modules/gfx/src/CMakeLists.txt index 8de2ae86c..1e17c9008 100644 --- a/modules/gfx/src/CMakeLists.txt +++ b/modules/gfx/src/CMakeLists.txt @@ -192,6 +192,8 @@ if (USE_SHADER) message("Compiling with Shader Support") list(APPEND OST_GFX_SOURCES shader.cc) list(APPEND OST_GFX_HEADERS shader.hh) + list(APPEND OST_GFX_SOURCES impl/scene_fx.cc) + list(APPEND OST_GFX_IMPL_HEADERS scene_fx.hh) if (NOT APPLE) set(OST_GLEW_HEADERS glew.h @@ -240,8 +242,9 @@ if (USE_SHADER) shader/fast_sphere_vs.glsl shader/fast_sphere_fs.glsl shader/outline_vs.glsl - shader/convolute1_vs.glsl + shader/quadpp_vs.glsl shader/convolute1_fs.glsl + shader/amboccl_fs.glsl ) copy_if_different("./" "${SHARED_DATA_PATH}/shader" "${SHADER_FILES}" "SHADER_TARGETS" ost_gfx) diff --git a/modules/gfx/src/impl/scene_fx.cc b/modules/gfx/src/impl/scene_fx.cc new file mode 100644 index 000000000..7e6d8033f --- /dev/null +++ b/modules/gfx/src/impl/scene_fx.cc @@ -0,0 +1,259 @@ +#include "scene_fx.hh" + +#include <ost/gfx/gfx_node.hh> +#include <ost/gfx/shader.hh> +#include <ost/gfx/scene.hh> + +namespace ost { namespace gfx { namespace impl { + +void prep_shadow_map(Scene& scene, GLuint texunit, GLuint texid, uint quality) +{ + GLint smap_size=256 << quality; + + // modelview transform for the lightsource pov + mol::Transform ltrans(scene.GetTransform()); + ltrans.SetRot(scene.GetLightRot()*scene.GetTransform().GetRot()); + + // calculate encompassing box for ortho projection + geom::AlignedCuboid bb=scene.GetBoundingBox(ltrans); + geom::Vec3 tmin=bb.GetMin(); + geom::Vec3 tmax=bb.GetMax(); + + // render pass 1 - without shadows + + // turn shadowing off for subsequent rendering + Shader::Instance().SetShadowMapping(false,0); + + // save overall gl settings + glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT); + // maximize rendering for depth-only information + glDisable(GL_LIGHTING); + glDisable(GL_FOG); + glDisable(GL_COLOR_MATERIAL); + glDisable(GL_NORMALIZE); + glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); + + // render scene with only depth components + // seen from the light's perspective + glViewport(0,0,smap_size,smap_size); + glClear(GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(tmin[0],tmax[0],tmin[1],tmax[1],-tmax[2],-tmin[2]); + //glFrustum(tmin[0],tmax[0],tmin[1],tmax[1],-tmax[2],-tmin[2]); + float glpmat[16]; + glGetv(GL_PROJECTION_MATRIX, glpmat); + geom::Mat4 pmat(Transpose(geom::Mat4(glpmat))); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glMultMatrix(ltrans.GetTransposedMatrix().Data()); + + // only render non-transparent objects for the shadow map + scene.GetRootNode()->RenderGL(DEPTH_RENDER_PASS); + + // now get the shadow map + glActiveTexture(GL_TEXTURE0+texunit); + glBindTexture(GL_TEXTURE_2D, texid); + + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, + 0,0, smap_size,smap_size, 0); + + // all of the following texture and shader params need to be moved + // to a one-time initialization place + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + // assign tex unit 0 to shadow map + Shader::Instance().SetShadowMapping(true,texunit); + + // restore settings + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + glPopAttrib(); + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); + + glEnable(GL_TEXTURE_2D); + + // set up appropriate texture matrix + geom::Mat4 bias(0.5,0.0,0.0,0.5, + 0.0,0.5,0.0,0.5, + 0.0,0.0,0.5,0.5, + 0.0,0.0,0.0,1.0); + + geom::Mat4 texm = bias*pmat*ltrans.GetMatrix(); + + glMatrixMode(GL_TEXTURE); + // make explicit object instead of temporary to avoid potential crash with Data() + geom::Mat4 ttmp=Transpose(texm); + glLoadMatrix(ttmp.Data()); + glMatrixMode(GL_MODELVIEW); +} + +void prep_amb_occlusion(Scene& scene, GLuint texunit, GLuint texid) +{ +} + +void prep_depth_darkening(Scene& scene, GLuint texunit, GLuint texid) +{ + Viewport vp=scene.GetViewport(); + prep_depth_map(scene,vp.width/2,vp.height/2,texunit,texid); + + // kernel is static for now, inside the convolution shader + + // now convolute the depth map with the kernel + Shader::Instance().PushProgram(); + Shader::Instance().Activate("convolute1"); + GLuint cpr=Shader::Instance().GetCurrentProgram(); + // assign tex units + glUniform1i(glGetUniformLocation(cpr,"data"),1); + glUniform1i(glGetUniformLocation(cpr,"vp_width"),vp.width/2); + glUniform1i(glGetUniformLocation(cpr,"vp_height"),vp.height/2); + + // set up viewport filling quad to run the fragment shader + draw_screen_quad(vp.width/2,vp.height/2,texunit, texid); + + Shader::Instance().PopProgram(); + + // mode 1, tex unit 1 + Shader::Instance().SetDepthMapping(1,texunit); +} + +void prep_depth_map(Scene& scene, unsigned int width, unsigned int height,GLuint texunit, GLuint texid) +{ + // render pass 1 - without shadows + Shader::Instance().SetShadowMapping(false,0); + // save overall gl settings + glPushAttrib(GL_ENABLE_BIT | GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT); + // maximize rendering for depth-only information + glDisable(GL_LIGHTING); + glDisable(GL_FOG); + glDisable(GL_COLOR_MATERIAL); + glDisable(GL_NORMALIZE); + glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); + + // render scene with only depth components + glClear(GL_DEPTH_BUFFER_BIT); + glViewport(0,0,width,height); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glMultMatrix(scene.GetTransform().GetTransposedMatrix().Data()); + scene.GetRootNode()->RenderGL(DEPTH_RENDER_PASS); + + // now get the depth map + glActiveTexture(texunit); + glBindTexture(GL_TEXTURE_2D, texid); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0,0, width, height, 0); + + // restore settings + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glPopAttrib(); + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); +} + +void draw_screen_quad(unsigned int w, unsigned int h, GLuint gltex, GLuint tex_id) +{ + glPushAttrib(GL_ENABLE_BIT | GL_VIEWPORT_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_FOG_BIT); + + // setup + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glDisable(GL_COLOR_MATERIAL); + glDisable(GL_FOG); + glDisable(GL_CULL_FACE); + glDisable(GL_BLEND); + glDisable(GL_LINE_SMOOTH); + glDisable(GL_POINT_SMOOTH); + glClear(GL_COLOR_BUFFER_BIT); + glViewport(0,0,w,h); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0,1,0,1,-1,1); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // draw + glColor3f(1.0,0.0,1.0); + glBegin(GL_QUADS); + glTexCoord2f(0.0,0.0); + glVertex2f(0.0,0.0); + glTexCoord2f(0.0,1.0); + glVertex2f(0.0,1.0); + glTexCoord2f(1.0,1.0); + glVertex2f(1.0,1.0); + glTexCoord2f(1.0,0.0); + glVertex2f(1.0,0.0); + glEnd(); + + // grab the result + glEnable(GL_TEXTURE_2D); + glActiveTexture(gltex); + glBindTexture(GL_TEXTURE_2D, tex_id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0,0, w, h, 0); + + // restore settings + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glPopAttrib(); +} + +// this debug code draws the given texture across the complete screen +void draw_debug_tex(unsigned int w, unsigned int h, GLuint texid) +{ + glPushAttrib(GL_ALL_ATTRIB_BITS); + Shader::Instance().PushProgram(); + + Shader::Instance().Activate(""); + glViewport(0,0,w,h); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0,1,0,1,-1,1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glColor3f(1.0,0.0,1.0); + glEnable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texid); + glBegin(GL_QUADS); + glTexCoord2f(0.0,0.0); + glVertex2f(0.01,0.01); + glTexCoord2f(0.0,1.0); + glVertex2f(0.01,0.99); + glTexCoord2f(1.0,1.0); + glVertex2f(0.99,0.99); + glTexCoord2f(1.0,0.0); + glVertex2f(0.99,0.01); + glEnd(); + glPopAttrib(); + Shader::Instance().PopProgram(); +} + + +}}} // ns diff --git a/modules/gfx/src/impl/scene_fx.hh b/modules/gfx/src/impl/scene_fx.hh new file mode 100644 index 000000000..5c407e8be --- /dev/null +++ b/modules/gfx/src/impl/scene_fx.hh @@ -0,0 +1,45 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2010 by the OpenStructure authors +// +// This library 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.0 of the License, or (at your option) +// any later version. +// This library 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 Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +#ifndef OST_SCENE_FX_HH +#define OST_SCENE_FX_HH + +#include <ost/gfx/gl_helper.hh> + +/* + low level code for scene shading effects + + Author: Ansgar Philippsen +*/ + +namespace ost { namespace gfx { + +class Scene; + +namespace impl { + +void prep_shadow_map(Scene& scene, GLuint texunit, GLuint texid, uint quality); +void prep_depth_darkening(Scene& scene, GLuint texunit, GLuint texid); +void prep_amb_occlusion(Scene& scene, GLuint texunit, GLuint texid); +void prep_depth_map(Scene& scene, uint, uint, GLuint texunit, GLuint texid); +void draw_screen_quad(unsigned int w, unsigned int h, GLuint texunit, GLuint texid); +void draw_debug_tex(unsigned int w, unsigned int h, GLuint texid); + +}}} // ns + +#endif diff --git a/modules/gfx/src/scene.cc b/modules/gfx/src/scene.cc index 181120438..5a8222295 100644 --- a/modules/gfx/src/scene.cc +++ b/modules/gfx/src/scene.cc @@ -54,6 +54,7 @@ #if OST_SHADER_SUPPORT_ENABLED # include "shader.hh" +# include "impl/scene_fx.hh" #endif using boost::bind; @@ -112,6 +113,7 @@ Scene::Scene(): shadow_quality_(1), shadow_tex_id_(), depth_dark_flag_(false), + amb_occl_flag_(false), depth_tex_id_(), kernel_tex_id_(), scene_tex_id_(), @@ -186,6 +188,13 @@ void Scene::SetDepthDarkening(bool f) RequestRedraw(); } +void Scene::SetAmbientOcclusion(bool f) +{ + amb_occl_flag_=f; + // the redraw routine will deal with the Shader + RequestRedraw(); +} + void Scene::SetShadingMode(const std::string& smode) { @@ -498,13 +507,18 @@ void Scene::RenderGL() if(auto_autoslab_) Autoslab(false, false); #if OST_SHADER_SUPPORT_ENABLED + if(amb_occl_flag_) { + impl::prep_amb_occlusion(*this,GL_TEXTURE1, depth_tex_id_); + } else { + Shader::Instance().SetOcclusionMapping(0,0); + } if(depth_dark_flag_) { - prep_depth_darkening(); + impl::prep_depth_darkening(*this,GL_TEXTURE1, depth_tex_id_); } else { Shader::Instance().SetDepthMapping(0,0); } if(shadow_flag_) { - prep_shadow_map(); + impl::prep_shadow_map(*this,GL_TEXTURE0,shadow_tex_id_,shadow_quality_); } else { Shader::Instance().SetShadowMapping(0,0); } @@ -1571,268 +1585,6 @@ void Scene::update_fog() glFogf(GL_FOG_END,zfar_+ffar_); } -namespace { - - void draw_screen_quad(unsigned int w, unsigned int h, GLuint gltex, GLuint tex_id) - { - glPushAttrib(GL_ENABLE_BIT | GL_VIEWPORT_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_FOG_BIT); - - // setup - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - glDisable(GL_COLOR_MATERIAL); - glDisable(GL_FOG); - glDisable(GL_CULL_FACE); - glDisable(GL_BLEND); - glDisable(GL_LINE_SMOOTH); - glDisable(GL_POINT_SMOOTH); - glClear(GL_COLOR_BUFFER_BIT); - glViewport(0,0,w,h); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0,1,0,1,-1,1); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - // draw - glColor3f(1.0,0.0,1.0); - glBegin(GL_QUADS); - glTexCoord2f(0.0,0.0); - glVertex2f(0.0,0.0); - glTexCoord2f(0.0,1.0); - glVertex2f(0.0,1.0); - glTexCoord2f(1.0,1.0); - glVertex2f(1.0,1.0); - glTexCoord2f(1.0,0.0); - glVertex2f(1.0,0.0); - glEnd(); - - // grab the result - glEnable(GL_TEXTURE_2D); - glActiveTexture(gltex); - glBindTexture(GL_TEXTURE_2D, tex_id); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0,0, w, h, 0); - - // restore settings - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glPopAttrib(); - } - - // this debug code draws the given texture across the complete screen - void draw_debug_tex(unsigned int w, unsigned int h, GLuint tex_id) - { - glPushAttrib(GL_ALL_ATTRIB_BITS); - Shader::Instance().PushProgram(); - - Shader::Instance().Activate(""); - glViewport(0,0,w,h); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0,1,0,1,-1,1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glColor3f(1.0,0.0,1.0); - glEnable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, tex_id); - glBegin(GL_QUADS); - glTexCoord2f(0.0,0.0); - glVertex2f(0.01,0.01); - glTexCoord2f(0.0,1.0); - glVertex2f(0.01,0.99); - glTexCoord2f(1.0,1.0); - glVertex2f(0.99,0.99); - glTexCoord2f(1.0,0.0); - glVertex2f(0.99,0.01); - glEnd(); - glPopAttrib(); - Shader::Instance().PopProgram(); - } -} - -void Scene::prep_shadow_map() -{ -#if OST_SHADER_SUPPORT_ENABLED - GLint smap_size=256 << shadow_quality_; - - // modelview transform for the lightsource pov - mol::Transform ltrans(transform_); - ltrans.SetRot(light_rot_*transform_.GetRot()); - - // calculate encompassing box for ortho projection - geom::AlignedCuboid bb=this->GetBoundingBox(ltrans); - const Vec3& tmin=bb.GetMin(); - const Vec3& tmax=bb.GetMax(); - - // render pass 1 - without shadows - - // turn shadowing off for subsequent rendering - Shader::Instance().SetShadowMapping(false,0); - - // save overall gl settings - glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT); - // maximize rendering for depth-only information - glDisable(GL_LIGHTING); - glDisable(GL_FOG); - glDisable(GL_COLOR_MATERIAL); - glDisable(GL_NORMALIZE); - glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); - - // render scene with only depth components - // seen from the light's perspective - glViewport(0,0,smap_size,smap_size); - glClear(GL_DEPTH_BUFFER_BIT); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(tmin[0],tmax[0],tmin[1],tmax[1],-tmax[2],-tmin[2]); - //glFrustum(tmin[0],tmax[0],tmin[1],tmax[1],-tmax[2],-tmin[2]); - float glpmat[16]; - glGetv(GL_PROJECTION_MATRIX, glpmat); - Mat4 pmat(Transpose(Mat4(glpmat))); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glMultMatrix(ltrans.GetTransposedMatrix().Data()); - - // only render non-transparent objects for the shadow map - root_node_->RenderGL(DEPTH_RENDER_PASS); - - // now get the shadow map - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, shadow_tex_id_); - - glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, - 0,0, smap_size,smap_size, 0); - - // all of the following texture and shader params need to be moved - // to a one-time initialization place - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - - // assign tex unit 0 to shadow map - Shader::Instance().SetShadowMapping(true,0); - - // restore settings - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - - glPopAttrib(); - glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); - - glEnable(GL_TEXTURE_2D); - - // set up appropriate texture matrix - Mat4 bias(0.5,0.0,0.0,0.5, - 0.0,0.5,0.0,0.5, - 0.0,0.0,0.5,0.5, - 0.0,0.0,0.0,1.0); - - Mat4 texm = bias*pmat*ltrans.GetMatrix(); - - glMatrixMode(GL_TEXTURE); - // make explicit object instead of temporary to avoid potential crash with Data() - Mat4 ttmp=Transpose(texm); - glLoadMatrix(ttmp.Data()); - glMatrixMode(GL_MODELVIEW); -#endif -} - -void Scene::prep_depth_darkening() -{ -#if OST_SHADER_SUPPORT_ENABLED - prep_depth_map(vp_width_/2,vp_height_/2); - // in unit 1, bound to depth_tex_id_ - - // kernel is static for now, inside the convolution shader - - // now convolute the depth map with the kernel - Shader::Instance().PushProgram(); - Shader::Instance().Activate("convolute1"); - GLuint cpr=Shader::Instance().GetCurrentProgram(); - // assign tex units - glUniform1i(glGetUniformLocation(cpr,"data"),1); - glUniform1i(glGetUniformLocation(cpr,"vp_width"),vp_width_/2); - glUniform1i(glGetUniformLocation(cpr,"vp_height"),vp_height_/2); - - // set up viewport filling quad to run the fragment shader - draw_screen_quad(vp_width_/2,vp_height_/2,GL_TEXTURE1, depth_tex_id_); - - Shader::Instance().PopProgram(); - - // mode 1, tex unit 1 - Shader::Instance().SetDepthMapping(1,1); - -#endif -} - -// returns the depth map in texture 1 -// bound to depth_tex_id_ -void Scene::prep_depth_map(unsigned int w, unsigned int h) -{ -#if OST_SHADER_SUPPORT_ENABLED - unsigned int vp_width2=w; - unsigned int vp_height2=h; - - // render pass 1 - without shadows - Shader::Instance().SetShadowMapping(false,0); - // save overall gl settings - glPushAttrib(GL_ENABLE_BIT); - // maximize rendering for depth-only information - glDisable(GL_LIGHTING); - glDisable(GL_FOG); - glDisable(GL_COLOR_MATERIAL); - glDisable(GL_NORMALIZE); - glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); - - // render scene with only depth components - glClear(GL_DEPTH_BUFFER_BIT); - glViewport(0,0,vp_width2,vp_height2); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glMultMatrix(transform_.GetTransposedMatrix().Data()); - root_node_->RenderGL(DEPTH_RENDER_PASS); - - // now get the depth map - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, depth_tex_id_); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, - 0,0, vp_width2, vp_height2, 0); - - // restore settings - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glPopAttrib(); - glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); - glViewport(0,0,vp_width_,vp_height_); - -#endif -} namespace { class DirtyAll: public GfxNodeVisitor diff --git a/modules/gfx/src/scene.hh b/modules/gfx/src/scene.hh index 142b4c942..f35920a83 100644 --- a/modules/gfx/src/scene.hh +++ b/modules/gfx/src/scene.hh @@ -112,6 +112,8 @@ class DLLEXPORT_OST_GFX Scene { void SetShadowQuality(int q); void SetDepthDarkening(bool f); + + void SetAmbientOcclusion(bool f); /// \brief select shading mode /// one of fallback, basic, default, hf, toon1, toon2 @@ -356,6 +358,9 @@ class DLLEXPORT_OST_GFX Scene { void RenderText(const TextPrim& t); + geom::Vec3 GetLightDir() const {return light_dir_;} + geom::Mat3 GetLightRot() const {return light_rot_;} + protected: friend class GfxObj; friend class GfxNode; @@ -408,6 +413,7 @@ private: int shadow_quality_; GLuint shadow_tex_id_; bool depth_dark_flag_; + bool amb_occl_flag_; GLuint depth_tex_id_; GLuint kernel_tex_id_; GLuint scene_tex_id_; @@ -437,9 +443,6 @@ private: void set_near(float n); void set_far(float f); void update_fog(); - void prep_shadow_map(); - void prep_depth_darkening(); - void prep_depth_map(uint,uint); void flag_all_dirty(); void prep_glyphs(); void prep_blur(); diff --git a/modules/gfx/src/shader.cc b/modules/gfx/src/shader.cc index 982306a52..a3940c457 100644 --- a/modules/gfx/src/shader.cc +++ b/modules/gfx/src/shader.cc @@ -148,8 +148,9 @@ void Shader::Setup() {"fast_sphere_vs.glsl", GL_VERTEX_SHADER}, {"fast_sphere_fs.glsl", GL_FRAGMENT_SHADER}, {"outline_vs.glsl", GL_VERTEX_SHADER}, - {"convolute1_vs.glsl", GL_VERTEX_SHADER}, - {"convolute1_fs.glsl", GL_FRAGMENT_SHADER} + {"quadpp_vs.glsl", GL_VERTEX_SHADER}, + {"convolute1_fs.glsl", GL_FRAGMENT_SHADER}, + {"amboccl_fs.glsl", GL_FRAGMENT_SHADER} ////////////////////////////////////////////////////////////////// }; @@ -252,11 +253,18 @@ void Shader::Setup() } // convolute1 shader shader_program_list.clear(); - shader_program_list.push_back(shader_code_map_["convolute1_vs.glsl"]); + shader_program_list.push_back(shader_code_map_["quadpp.glsl"]); shader_program_list.push_back(shader_code_map_["convolute1_fs.glsl"]); if(link_shader(shader_program_list,"convolute1",shader_program_id)) { shader_program_map_["convolute1"]=shader_program_id; } + // amb occl shader + shader_program_list.clear(); + shader_program_list.push_back(shader_code_map_["quadpp.glsl"]); + shader_program_list.push_back(shader_code_map_["amboccl_fs.glsl"]); + if(link_shader(shader_program_list,"amboccl",shader_program_id)) { + shader_program_map_["amboccl"]=shader_program_id; + } valid_=true; } @@ -328,6 +336,15 @@ void Shader::SetShadowMapping(bool flag, GLuint texid) UpdateState(); } +void Shader::SetOcclusionMapping(bool flag, GLuint texid) +{ + occl_flag_=flag; + if(flag) { + occl_map_id_=texid; + } + UpdateState(); +} + void Shader::SetDepthMapping(int mode, GLuint texid) { depth_mode_=mode; diff --git a/modules/gfx/src/shader.hh b/modules/gfx/src/shader.hh index 32ea8d129..b8938108f 100644 --- a/modules/gfx/src/shader.hh +++ b/modules/gfx/src/shader.hh @@ -55,6 +55,7 @@ public: void SetShadowMapping(bool flag, GLuint texid); void SetDepthMapping(int mode, GLuint texid); + void SetOcclusionMapping(bool flag, GLuint texid); private: Shader(); @@ -67,6 +68,8 @@ private: GLuint shadow_map_id_; int depth_mode_; GLuint depth_map_id_; + bool occl_flag_; + GLuint occl_map_id_; std::stack<String> program_stack_; diff --git a/modules/gfx/src/shader/amboccl_fs.glsl b/modules/gfx/src/shader/amboccl_fs.glsl new file mode 100644 index 000000000..44ad2220d --- /dev/null +++ b/modules/gfx/src/shader/amboccl_fs.glsl @@ -0,0 +1,6 @@ +uniform sampler2D data; + +void main() +{ + gl_FragColor=texture2D(data,gl_TexCoord[0].xy); +} diff --git a/modules/gfx/src/shader/convolute1_vs.glsl b/modules/gfx/src/shader/quadpp_vs.glsl similarity index 100% rename from modules/gfx/src/shader/convolute1_vs.glsl rename to modules/gfx/src/shader/quadpp_vs.glsl -- GitLab