mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-20 11:26:11 +00:00
first draft of variance shadow mapping with and without blur.
some problems in variance shadow mapping due to blur texture mapping and blending.
This commit is contained in:
parent
f46e925e47
commit
c46fd9ef92
@ -35,9 +35,8 @@ class DecorateShader
|
||||
public:
|
||||
DecorateShader(){
|
||||
this->_initOk = false;
|
||||
this->_texSize = 512;
|
||||
this->_texSize = 1024;
|
||||
this->_shadowMap = 0;
|
||||
// this->_color_tex = 0;
|
||||
}
|
||||
|
||||
//virtual ~DecorateShader();
|
||||
@ -49,7 +48,6 @@ protected:
|
||||
bool _initOk;
|
||||
int _texSize;
|
||||
GLuint _shadowMap;
|
||||
// GLuint _color_tex;
|
||||
|
||||
virtual bool compileAndLink() = 0;
|
||||
virtual bool setup() = 0;
|
||||
|
||||
@ -29,10 +29,11 @@ const QString DecorateShadowPlugin::Info(QAction *action)
|
||||
{
|
||||
switch(ID(action))
|
||||
{
|
||||
case DP_SHOW_AO_DEPTH_TRICK : return tr("Enable ambient occlusion trick");
|
||||
case DP_SHOW_SIMPLE_SHADOW: return tr("Enable simple shadow");
|
||||
case DP_SHOW_SSAO: return tr("Enable SSAO");
|
||||
case DP_SHOW_VSM_SHADOW : return tr("Enable variance shadow mapping");
|
||||
case DP_SHOW_AO_DEPTH_TRICK : return tr("Enable ambient occlusion trick");
|
||||
case DP_SHOW_SIMPLE_SHADOW: return tr("Enable simple shadow");
|
||||
case DP_SHOW_SSAO: return tr("Enable SSAO");
|
||||
case DP_SHOW_VSM_SHADOW : return tr("Enable variance shadow mapping");
|
||||
case DP_SHOW_VSM_SHADOW_BLUR : return tr("Enable variance shadow mapping with blur");
|
||||
}
|
||||
assert(0);
|
||||
return QString();
|
||||
@ -60,9 +61,10 @@ const QString DecorateShadowPlugin::ST(FilterIDType filter) const
|
||||
switch(filter)
|
||||
{
|
||||
case DP_SHOW_AO_DEPTH_TRICK : return QString("AO depth trick");
|
||||
case DP_SHOW_SIMPLE_SHADOW : return QString("simple shadow");
|
||||
case DP_SHOW_SIMPLE_SHADOW : return QString("Simple shadow");
|
||||
case DP_SHOW_SSAO : return QString("SSAO");
|
||||
case DP_SHOW_VSM_SHADOW : return QString("VSM");
|
||||
case DP_SHOW_VSM_SHADOW : return QString("Variance shadow mapping");
|
||||
case DP_SHOW_VSM_SHADOW_BLUR : return QString("Variance shadow mapping blur");
|
||||
default: assert(0);
|
||||
}
|
||||
return QString("error!");
|
||||
@ -74,6 +76,15 @@ bool DecorateShadowPlugin::StartDecorate(QAction* action, MeshModel& m, GLArea*
|
||||
result = this->_decorator = new ShadowMapping();
|
||||
}
|
||||
|
||||
if(action->text() == ST(DP_SHOW_VSM_SHADOW)){
|
||||
result = this->_decorator = new VarianceShadowMapping();
|
||||
}
|
||||
|
||||
if(action->text() == ST(DP_SHOW_VSM_SHADOW_BLUR)){
|
||||
result = this->_decorator = new VarianceShadowMappingBlur();
|
||||
}
|
||||
|
||||
|
||||
result = this->_decorator->init();
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -37,6 +37,8 @@
|
||||
//#include <wrap/gl/addons.h>
|
||||
#include "decorate_shader.h"
|
||||
#include "shadow_mapping.h"
|
||||
#include "variance_shadow_mapping.h"
|
||||
#include "variance_shadow_mapping_blur.h"
|
||||
|
||||
class DecorateShadowPlugin : public QObject, public MeshDecorateInterface
|
||||
{
|
||||
@ -47,6 +49,7 @@ class DecorateShadowPlugin : public QObject, public MeshDecorateInterface
|
||||
enum {
|
||||
DP_SHOW_SIMPLE_SHADOW,
|
||||
DP_SHOW_VSM_SHADOW,
|
||||
DP_SHOW_VSM_SHADOW_BLUR,
|
||||
DP_SHOW_AO_DEPTH_TRICK,
|
||||
DP_SHOW_SSAO
|
||||
};
|
||||
@ -57,8 +60,10 @@ public:
|
||||
|
||||
DecorateShadowPlugin()
|
||||
{
|
||||
typeList <<
|
||||
DP_SHOW_SIMPLE_SHADOW ;
|
||||
typeList <<
|
||||
DP_SHOW_SIMPLE_SHADOW <<
|
||||
DP_SHOW_VSM_SHADOW <<
|
||||
DP_SHOW_VSM_SHADOW_BLUR;
|
||||
|
||||
FilterIDType tt;
|
||||
foreach(tt , types()){
|
||||
@ -68,7 +73,6 @@ public:
|
||||
foreach(ap,actionList){
|
||||
ap->setCheckable(true);
|
||||
}
|
||||
//this->_sm = new ShadowMapping();
|
||||
}
|
||||
|
||||
QList<QAction *> actions () const {return actionList;}
|
||||
@ -77,7 +81,6 @@ public:
|
||||
virtual void initGlobalParameterSet(QAction *, FilterParameterSet * /*globalparam*/);
|
||||
private:
|
||||
DecorateShader* _decorator;
|
||||
ShadowMapping* _sm;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -3,11 +3,15 @@ QT += opengl
|
||||
HEADERS = decorate_shadow.h \
|
||||
shadow_mapping.h \
|
||||
../../../../vcglib/wrap/gui/trackball.h \
|
||||
decorate_shader.h
|
||||
decorate_shader.h \
|
||||
variance_shadow_mapping.h \
|
||||
variance_shadow_mapping_blur.h
|
||||
SOURCES = decorate_shadow.cpp \
|
||||
shadow_mapping.cpp \
|
||||
../../meshlab/filterparameter.cpp \
|
||||
$$GLEWCODE \
|
||||
../../../../vcglib/wrap/gui/trackball.cpp \
|
||||
../../../../vcglib/wrap/gui/trackmode.cpp
|
||||
../../../../vcglib/wrap/gui/trackmode.cpp \
|
||||
variance_shadow_mapping.cpp \
|
||||
variance_shadow_mapping_blur.cpp
|
||||
TARGET = decorate_shadow
|
||||
|
||||
@ -7,72 +7,8 @@ void main(){
|
||||
//shadow2DProj fa automaticamente la divisione prospettica..al momento siamo in ortografica e nn serve
|
||||
shadowCoord.xyz = shadowCoord.xyz * 0.5 + 0.5;
|
||||
float sh = shadow2D(shadowMap, shadowCoord.xyz).x;
|
||||
if (sh > 0.95)
|
||||
if (sh > 0.4)
|
||||
discard;
|
||||
//else
|
||||
gl_FragColor = vec4(vec3(0.0), 1.0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
uniform mat4 mvpl;
|
||||
|
||||
|
||||
const float w = 0.5;
|
||||
float pcf()
|
||||
{
|
||||
float texel = 1.0/width;
|
||||
vec4 depths;
|
||||
vec4 ProjCoord = gl_TexCoord[0];
|
||||
depths[0] = texture2D(shadowMap, ProjCoord.st/ProjCoord.q + texel*vec2(-w, -w)).r;
|
||||
depths[1] = texture2D(shadowMap, ProjCoord.st/ProjCoord.q + texel*vec2(+w, -w)).r;
|
||||
depths[2] = texture2D(shadowMap, ProjCoord.st/ProjCoord.q + texel*vec2(-w, +w)).r;
|
||||
depths[3] = texture2D(shadowMap, ProjCoord.st/ProjCoord.q + texel*vec2(+w, +w)).r;
|
||||
|
||||
float r = ProjCoord.p / ProjCoord.q;
|
||||
vec4 inShadow = vec4(lessThanEqual(vec4(r,r,r,r), depths+0.011));
|
||||
return dot(inShadow, vec4(0.25, 0.25, 0.25, 0.25));
|
||||
}
|
||||
|
||||
|
||||
void main(void)
|
||||
{
|
||||
|
||||
|
||||
// normalize vectors for lighting
|
||||
vec3 nNormal = normalize(normalVec);
|
||||
vec3 nLight = normalize(lightVec.xyz);
|
||||
vec3 nView = normalize(viewVec);
|
||||
|
||||
|
||||
// diffuse and specular contribution
|
||||
float diffuse = clamp(dot(nLight, nNormal), 0.0, 1.0);
|
||||
float specular = pow(clamp(dot(reflect(-nView, nNormal), nLight), 0.0, 1.0), 16.0);
|
||||
//apply viewport transform to current frag distance from light
|
||||
float depth = (lightDepth/2.0 + 0.5 );
|
||||
// retrieve stored depth from depthmap
|
||||
// this is the same as:
|
||||
//float sDepth = texture2D(shadowMap, gl_TexCoord[1].st/gl_TexCoord[1].q).r;
|
||||
float sDepth = texture2DProj(shadowMap, gl_TexCoord[0]).q ;
|
||||
|
||||
// compare distances to determine if fragment should be
|
||||
// lit or shadowed
|
||||
float shadow = (lightDepth < sDepth)? 1.0 : 0.0;
|
||||
|
||||
vec4 Ka = gl_LightSource[0].ambient;
|
||||
vec4 Kd = gl_LightSource[0].diffuse;
|
||||
vec4 Ks = gl_LightSource[0].specular;
|
||||
|
||||
// if fragment is shadowed, do not add specular and diffuse
|
||||
// contribution
|
||||
if(shadow == 0.0)
|
||||
gl_FragColor = (Ka + (Kd * diffuse + Ks * specular));
|
||||
else
|
||||
gl_FragColor = vec4(vec3(0.0), 1.0);
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
gl_FragColor = vec4(sh);
|
||||
}
|
||||
16
src/fgt/decorate_shadow/shader/vsm/depthVSM.frag
Normal file
16
src/fgt/decorate_shadow/shader/vsm/depthVSM.frag
Normal file
@ -0,0 +1,16 @@
|
||||
varying vec4 point;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
float depth = point.z;// / point.w;
|
||||
depth = depth * 0.5 + 0.5;
|
||||
|
||||
float moment1 = depth;
|
||||
float moment2 = depth * depth;
|
||||
|
||||
float dx = dFdx(depth);
|
||||
float dy = dFdy(depth);
|
||||
moment2 += 0.25 * (dx * dx + dy * dy);
|
||||
|
||||
gl_FragColor = vec4(moment1, moment2 , 0.0, 1.0);
|
||||
}
|
||||
6
src/fgt/decorate_shadow/shader/vsm/depthVSM.vert
Normal file
6
src/fgt/decorate_shadow/shader/vsm/depthVSM.vert
Normal file
@ -0,0 +1,6 @@
|
||||
varying vec4 point;
|
||||
|
||||
void main(){
|
||||
gl_Position = ftransform();
|
||||
point = gl_Position;
|
||||
}
|
||||
33
src/fgt/decorate_shadow/shader/vsm/objectVSM.frag
Normal file
33
src/fgt/decorate_shadow/shader/vsm/objectVSM.frag
Normal file
@ -0,0 +1,33 @@
|
||||
uniform mat4 mvpl;
|
||||
uniform sampler2D shadowMap;
|
||||
uniform float texSize;
|
||||
varying vec4 shadowCoord;
|
||||
|
||||
|
||||
vec4 shadowCoordPostW;
|
||||
float chebyshevUpperBound( float distance) {
|
||||
// We retrive the two moments previously stored (depth and depth*depth)
|
||||
vec2 moments = texture2D(shadowMap,shadowCoordPostW.xy).rb;
|
||||
// Surface is fully lit. as the current fragment is before the light occluder
|
||||
if (distance <= moments.x)
|
||||
return 1.0 ;
|
||||
|
||||
float variance = moments.y - (moments.x*moments.x);
|
||||
//variance = max(variance,0.00002);
|
||||
variance = max(variance,0.000195);
|
||||
float d = distance - moments.x;
|
||||
float p_max = variance / (variance + d*d);
|
||||
return p_max;
|
||||
}
|
||||
|
||||
void main() {
|
||||
shadowCoordPostW = shadowCoord / shadowCoord.w;
|
||||
shadowCoordPostW = shadowCoordPostW * 0.5 + 0.5;
|
||||
float shadow = chebyshevUpperBound(shadowCoordPostW.z);
|
||||
|
||||
vec4 kd = gl_LightSource[0].diffuse;
|
||||
if (shadow > 0.4)
|
||||
discard;
|
||||
|
||||
gl_FragColor = vec4(vec3(shadow), 1.0);
|
||||
}
|
||||
6
src/fgt/decorate_shadow/shader/vsm/objectVSM.vert
Normal file
6
src/fgt/decorate_shadow/shader/vsm/objectVSM.vert
Normal file
@ -0,0 +1,6 @@
|
||||
uniform mat4 mvpl;
|
||||
varying vec4 shadowCoord;
|
||||
void main() {
|
||||
shadowCoord= mvpl * gl_Vertex;
|
||||
gl_Position = ftransform();
|
||||
}
|
||||
@ -40,7 +40,7 @@ ShadowMapping::~ShadowMapping(){
|
||||
glDeleteShader(this->_objectFrag);
|
||||
glDeleteProgram(this->_objectShaderProgram);
|
||||
|
||||
//glDeleteTextures(1, &(this->_color_tex));
|
||||
//glDeleteTextures(1, &(this->_color_tex));
|
||||
glDeleteTextures(1, &(this->_shadowMap));
|
||||
|
||||
glDeleteFramebuffersEXT(1, &_fbo);
|
||||
@ -124,7 +124,7 @@ void ShadowMapping::runShader(MeshModel& m, GLArea* gla){
|
||||
RenderMode rm = gla->getCurrentRenderMode();
|
||||
m.Render(rm.drawMode, rm.colorMode, rm.textureMode);
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
this->getShadowMap();
|
||||
//this->getShadowMap();
|
||||
this->unbind();
|
||||
// glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
|
||||
|
||||
@ -167,20 +167,8 @@ bool ShadowMapping::setup()
|
||||
if (_initOk)
|
||||
return true;
|
||||
|
||||
|
||||
//COLOR
|
||||
/*glGenTextures(1, &(this->_color_tex));
|
||||
glBindTexture(GL_TEXTURE_2D, this->_color_tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, this->_texSize, this->_texSize, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
|
||||
*/
|
||||
|
||||
|
||||
/*DEPTH*/
|
||||
glGenTextures(1, &this->_shadowMap);
|
||||
/*DEPTH*/
|
||||
glGenTextures(1, &this->_shadowMap);
|
||||
glBindTexture(GL_TEXTURE_2D, this->_shadowMap);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
@ -192,24 +180,24 @@ bool ShadowMapping::setup()
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, this->_texSize, this->_texSize, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, this->_texSize, this->_texSize, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
||||
|
||||
glGenFramebuffersEXT(1, &_fbo);
|
||||
glGenFramebuffersEXT(1, &_fbo);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo);
|
||||
|
||||
//depth
|
||||
//depth
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, this->_shadowMap, 0);
|
||||
|
||||
//color
|
||||
//glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, this->_color_tex, 0/*mipmap level*/);
|
||||
|
||||
//cosi specifichi che il colore non importa, che il fbo non ha niente sull'attachment colore
|
||||
|
||||
//color
|
||||
//glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, this->_color_tex, 0/*mipmap level*/);
|
||||
|
||||
//cosi specifichi che il colore non importa, che il fbo non ha niente sull'attachment colore
|
||||
GLenum drawBuffers[] = {GL_NONE};
|
||||
glDrawBuffersARB(1, drawBuffers);
|
||||
|
||||
glReadBuffer(GL_NONE);
|
||||
|
||||
int err = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
glReadBuffer(GL_NONE);
|
||||
|
||||
int err = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
_initOk = (err == GL_FRAMEBUFFER_COMPLETE_EXT);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
return _initOk;
|
||||
@ -223,7 +211,7 @@ void ShadowMapping::bind()
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo);
|
||||
glPushAttrib(GL_VIEWPORT_BIT);
|
||||
glViewport(0, 0, this->_texSize, this->_texSize);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void ShadowMapping::unbind()
|
||||
@ -253,6 +241,8 @@ bool ShadowMapping::compileAndLink(){
|
||||
if(!this->printShaderInfoLog(this->_objectVert))
|
||||
return false;
|
||||
|
||||
objVert->close();
|
||||
|
||||
bArray = objFrag->readAll();
|
||||
ShaderLen = (GLint) bArray.length();
|
||||
ShaderSource = (GLubyte *)bArray.data();
|
||||
@ -263,6 +253,8 @@ bool ShadowMapping::compileAndLink(){
|
||||
if(!this->printShaderInfoLog(this->_objectFrag))
|
||||
return false;
|
||||
|
||||
objFrag->close();
|
||||
|
||||
this->_objectShaderProgram = glCreateProgram();
|
||||
glAttachShader(this->_objectShaderProgram, this->_objectVert);
|
||||
glAttachShader(this->_objectShaderProgram, this->_objectFrag);
|
||||
|
||||
291
src/fgt/decorate_shadow/variance_shadow_mapping.cpp
Normal file
291
src/fgt/decorate_shadow/variance_shadow_mapping.cpp
Normal file
@ -0,0 +1,291 @@
|
||||
#include "variance_shadow_mapping.h"
|
||||
|
||||
VarianceShadowMapping::VarianceShadowMapping():DecorateShader()
|
||||
{
|
||||
this->_depth = 0;
|
||||
|
||||
this->_depthVert = 0;
|
||||
this->_depthFrag = 0;
|
||||
this->_depthShaderProgram = 0;
|
||||
this->_objectVert = 0;
|
||||
this->_objectFrag = 0;
|
||||
this->_objectShaderProgram = 0;
|
||||
this->_fbo = 0;
|
||||
}
|
||||
|
||||
VarianceShadowMapping::~VarianceShadowMapping(){
|
||||
glDetachShader(this->_depthShaderProgram, this->_depthVert);
|
||||
glDetachShader(this->_depthShaderProgram, this->_depthFrag);
|
||||
|
||||
glDeleteShader(this->_depthVert);
|
||||
glDeleteShader(this->_depthFrag);
|
||||
glDeleteProgram(this->_depthShaderProgram);
|
||||
|
||||
glDetachShader(this->_objectShaderProgram, this->_objectVert);
|
||||
glDetachShader(this->_objectShaderProgram, this->_objectFrag);
|
||||
|
||||
glDeleteShader(this->_objectVert);
|
||||
glDeleteShader(this->_objectFrag);
|
||||
glDeleteProgram(this->_objectShaderProgram);
|
||||
|
||||
glDeleteFramebuffersEXT(1, &(this->_depth));
|
||||
glDeleteTexturesEXT(1, &(this->_shadowMap));
|
||||
glDeleteFramebuffersEXT(1, &_fbo);
|
||||
}
|
||||
|
||||
bool VarianceShadowMapping::init()
|
||||
{
|
||||
GLenum err = glewInit();
|
||||
if (!GLEW_OK == err){
|
||||
QMessageBox msgBox;
|
||||
msgBox.setIcon(QMessageBox::Warning);
|
||||
msgBox.setWindowTitle("GLEW init failure");
|
||||
msgBox.setText(QString("Init GLEW failed."));
|
||||
int ret = msgBox.exec();
|
||||
return false;
|
||||
}
|
||||
if(!this->setup()){
|
||||
QMessageBox msgBox;
|
||||
msgBox.setIcon(QMessageBox::Warning);
|
||||
msgBox.setWindowTitle("FBO Setup failure");
|
||||
msgBox.setText(QString("Failed in creating a Frame Buffer Object."));
|
||||
int ret = msgBox.exec();
|
||||
return false;
|
||||
}
|
||||
return compileAndLink();
|
||||
}
|
||||
|
||||
void VarianceShadowMapping::runShader(MeshModel& m, GLArea* gla){
|
||||
vcg::Box3f bb = m.cm.bbox;
|
||||
vcg::Point3f center;
|
||||
center = bb.Center();
|
||||
|
||||
GLfloat g_mModelView[16];
|
||||
GLfloat g_mProjection[16];
|
||||
|
||||
int diag = bb.Diag();
|
||||
|
||||
GLfloat lP[4];
|
||||
glGetLightfv(GL_LIGHT0, GL_POSITION, lP);
|
||||
vcg::Point3f light = -vcg::Point3f(lP[0],lP[1],lP[2]);
|
||||
|
||||
vcg::Matrix44f tm = gla->trackball.Matrix();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
glLoadIdentity();
|
||||
glOrtho(-(diag/2),
|
||||
diag/2,
|
||||
-(diag/2),
|
||||
diag/2,
|
||||
-(diag/2),
|
||||
diag/2);
|
||||
|
||||
glGetFloatv(GL_PROJECTION_MATRIX, g_mProjection);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
glPushMatrix();
|
||||
vcg::Point3f u, v;
|
||||
//mi seleziona automaticamente un upvector che mi eviti casi degeneri...
|
||||
//nel caso vada bene 010 sceglie quello
|
||||
vcg::GetUV(light, u, v, vcg::Point3f(0,-1,0));
|
||||
glLoadIdentity();
|
||||
gluLookAt(0, 0, 0, light[0], light[1], light[2], v[0], v[1], v[2]);
|
||||
|
||||
//get the rotation matrix from the trackball
|
||||
vcg::Matrix44f rotation;
|
||||
vcg::Similarityf track = gla->trackball.track;
|
||||
track.rot.ToMatrix(rotation);
|
||||
glMultMatrixf(rotation.transpose().V());
|
||||
|
||||
//traslate the model in the center
|
||||
glTranslatef(-center[0],-center[1],-center[2]);
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, g_mModelView);
|
||||
|
||||
|
||||
/***********************************************************/
|
||||
//GENERAZIONE SHADOW MAP
|
||||
/***********************************************************/
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(1.0, 1.0);
|
||||
|
||||
|
||||
this->bind();
|
||||
glUseProgram(this->_depthShaderProgram);
|
||||
RenderMode rm = gla->getCurrentRenderMode();
|
||||
m.Render(rm.drawMode, vcg::GLW::CMNone, vcg::GLW::TMNone);
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
this->unbind();
|
||||
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
/***********************************************************/
|
||||
//OBJECT PASS
|
||||
/***********************************************************/
|
||||
GLint depthFuncOld;
|
||||
glGetIntegerv(GL_DEPTH_FUNC, &depthFuncOld);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
vcg::Matrix44f mvpl = (vcg::Matrix44f(g_mProjection).transpose() * vcg::Matrix44f(g_mModelView).transpose()).transpose();
|
||||
glUseProgram(this->_objectShaderProgram);
|
||||
|
||||
GLuint matrixLoc = glGetUniformLocation(this->_objectShaderProgram, "mvpl");
|
||||
glUniformMatrix4fv(matrixLoc, 1, 0, mvpl.V());
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, this->_shadowMap);
|
||||
|
||||
GLuint loc = glGetUniformLocation(this->_objectShaderProgram, "shadowMap");
|
||||
glUniform1i(loc, 0);
|
||||
m.Render(rm.drawMode, rm.colorMode, rm.textureMode);
|
||||
glDepthFunc((GLenum)depthFuncOld);
|
||||
glUseProgram(0);
|
||||
|
||||
int error = glGetError();
|
||||
}
|
||||
|
||||
bool VarianceShadowMapping::setup()
|
||||
{
|
||||
if (!GLEW_EXT_framebuffer_object) {
|
||||
qWarning("FBO not supported!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_initOk)
|
||||
return true;
|
||||
|
||||
//genero il frame buffer object
|
||||
glGenFramebuffersEXT(1, &_fbo);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo);
|
||||
|
||||
//genero la texture di colore che sara la mia variance shadow map.
|
||||
glGenTextures(1, &this->_shadowMap);
|
||||
glBindTexture(GL_TEXTURE_2D, this->_shadowMap);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->_texSize, this->_texSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
//attacco al FBO la texture di colore
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, this->_shadowMap, 0);
|
||||
|
||||
//genero il render buffer per il depth buffer
|
||||
glGenRenderbuffersEXT(1, &(this->_depth));
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, this->_depth);
|
||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, this->_texSize, this->_texSize);
|
||||
|
||||
//e il depth buffer
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, this->_depth);
|
||||
|
||||
|
||||
int err = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
_initOk = (err == GL_FRAMEBUFFER_COMPLETE_EXT);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
return _initOk;
|
||||
}
|
||||
|
||||
void VarianceShadowMapping::bind()
|
||||
{
|
||||
assert(_initOk);
|
||||
|
||||
glClearDepth(1.0);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo);
|
||||
glPushAttrib(GL_VIEWPORT_BIT);
|
||||
glViewport(0, 0, this->_texSize, this->_texSize);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void VarianceShadowMapping::unbind()
|
||||
{
|
||||
if (!_initOk)
|
||||
return;
|
||||
|
||||
glPopAttrib();
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
//glDeleteFramebuffersEXT(1, &_fbo);
|
||||
}
|
||||
|
||||
bool VarianceShadowMapping::compileAndLink(){
|
||||
QFile* depthVert = new QFile(MainWindowInterface::getBaseDirPath() + QString("/../fgt/decorate_shadow/shader/vsm/depthVSM.vert"));
|
||||
QFile* depthFrag = new QFile(MainWindowInterface::getBaseDirPath() + QString("/../fgt/decorate_shadow/shader/vsm/depthVSM.frag"));
|
||||
QFile* objVert = new QFile(MainWindowInterface::getBaseDirPath() + QString("/../fgt/decorate_shadow/shader/vsm/objectVSM.vert"));
|
||||
QFile* objFrag = new QFile(MainWindowInterface::getBaseDirPath() + QString("/../fgt/decorate_shadow/shader/vsm/objectVSM.frag"));
|
||||
|
||||
depthVert->open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
depthFrag->open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
|
||||
objVert->open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
objFrag->open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
|
||||
QByteArray bArray = depthVert->readAll();
|
||||
GLint ShaderLen = (GLint) bArray.length();
|
||||
GLubyte* ShaderSource = (GLubyte *)bArray.data();
|
||||
|
||||
this->_depthVert= glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(this->_depthVert, 1, (const GLchar **)&ShaderSource, &ShaderLen);
|
||||
glCompileShader(this->_depthVert);
|
||||
if(!this->printShaderInfoLog(this->_depthVert))
|
||||
return false;
|
||||
|
||||
depthVert->close();
|
||||
|
||||
bArray = depthFrag->readAll();
|
||||
ShaderLen = (GLint) bArray.length();
|
||||
ShaderSource = (GLubyte *)bArray.data();
|
||||
|
||||
this->_depthFrag = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(this->_depthFrag, 1, (const GLchar **)&ShaderSource, &ShaderLen);
|
||||
glCompileShader(this->_depthFrag);
|
||||
if(!this->printShaderInfoLog(this->_depthFrag))
|
||||
return false;
|
||||
|
||||
depthFrag->close();
|
||||
|
||||
this->_depthShaderProgram = glCreateProgram();
|
||||
glAttachShader(this->_depthShaderProgram, this->_depthVert);
|
||||
glAttachShader(this->_depthShaderProgram, this->_depthFrag);
|
||||
glLinkProgram(this->_depthShaderProgram);
|
||||
if(!this->printProgramInfoLog(this->_depthShaderProgram))
|
||||
return false;
|
||||
|
||||
|
||||
bArray = objVert->readAll();
|
||||
ShaderLen = (GLint) bArray.length();
|
||||
ShaderSource = (GLubyte *)bArray.data();
|
||||
|
||||
this->_objectVert= glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(this->_objectVert, 1, (const GLchar **)&ShaderSource, &ShaderLen);
|
||||
glCompileShader(this->_objectVert);
|
||||
if(!this->printShaderInfoLog(this->_objectVert))
|
||||
return false;
|
||||
|
||||
objVert->close();
|
||||
|
||||
bArray = objFrag->readAll();
|
||||
ShaderLen = (GLint) bArray.length();
|
||||
ShaderSource = (GLubyte *)bArray.data();
|
||||
|
||||
this->_objectFrag= glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(this->_objectFrag, 1, (const GLchar **)&ShaderSource, &ShaderLen);
|
||||
glCompileShader(this->_objectFrag);
|
||||
if(!this->printShaderInfoLog(this->_objectFrag))
|
||||
return false;
|
||||
|
||||
objFrag->close();
|
||||
|
||||
this->_objectShaderProgram = glCreateProgram();
|
||||
glAttachShader(this->_objectShaderProgram, this->_objectVert);
|
||||
glAttachShader(this->_objectShaderProgram, this->_objectFrag);
|
||||
glLinkProgram(this->_objectShaderProgram);
|
||||
if(!this->printProgramInfoLog(this->_objectShaderProgram))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
43
src/fgt/decorate_shadow/variance_shadow_mapping.h
Normal file
43
src/fgt/decorate_shadow/variance_shadow_mapping.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef VARIANCE_SHADOW_MAPPING_H
|
||||
#define VARIANCE_SHADOW_MAPPING_H
|
||||
|
||||
#include <cassert>
|
||||
#include <QString>
|
||||
#include <QImage>
|
||||
#include <QFile>
|
||||
#include <GL/glew.h>
|
||||
#include <meshlab/interfaces.h>
|
||||
#include <meshlab/meshmodel.h>
|
||||
#include <meshlab/glarea.h>
|
||||
#include <decorate_shader.h>
|
||||
|
||||
#define BLUR_COEF 0.25
|
||||
#define SHADOW_COEF 0.5
|
||||
|
||||
class VarianceShadowMapping : public DecorateShader
|
||||
{
|
||||
|
||||
public:
|
||||
VarianceShadowMapping();
|
||||
~VarianceShadowMapping();
|
||||
|
||||
bool init();
|
||||
void runShader(MeshModel&, GLArea*);
|
||||
|
||||
private:
|
||||
bool compileAndLink();
|
||||
bool setup();
|
||||
void bind();
|
||||
void unbind();
|
||||
|
||||
GLuint _depth;
|
||||
|
||||
GLuint _fbo;
|
||||
GLuint _objectShaderProgram;
|
||||
GLuint _objectVert, _objectFrag;
|
||||
GLuint _depthShaderProgram;
|
||||
GLuint _depthVert, _depthFrag;
|
||||
};
|
||||
|
||||
|
||||
#endif // VARIANCE_SHADOW_MAPPING_H
|
||||
470
src/fgt/decorate_shadow/variance_shadow_mapping_blur.cpp
Normal file
470
src/fgt/decorate_shadow/variance_shadow_mapping_blur.cpp
Normal file
@ -0,0 +1,470 @@
|
||||
#include "variance_shadow_mapping_blur.h"
|
||||
|
||||
VarianceShadowMappingBlur::VarianceShadowMappingBlur():DecorateShader()
|
||||
{
|
||||
this->_depth = 0;
|
||||
this->_blur = 0;
|
||||
|
||||
this->_depthVert = 0;
|
||||
this->_depthFrag = 0;
|
||||
this->_depthShaderProgram = 0;
|
||||
this->_objectVert = 0;
|
||||
this->_objectFrag = 0;
|
||||
this->_objectShaderProgram = 0;
|
||||
this->_blurVert = 0;
|
||||
this->_blurFrag = 0;
|
||||
this->_blurShaderProgram = 0;
|
||||
this->_fbo = 0;
|
||||
}
|
||||
|
||||
VarianceShadowMappingBlur::~VarianceShadowMappingBlur(){
|
||||
glDetachShader(this->_depthShaderProgram, this->_depthVert);
|
||||
glDetachShader(this->_depthShaderProgram, this->_depthFrag);
|
||||
|
||||
glDeleteShader(this->_depthVert);
|
||||
glDeleteShader(this->_depthFrag);
|
||||
glDeleteProgram(this->_depthShaderProgram);
|
||||
|
||||
glDetachShader(this->_objectShaderProgram, this->_objectVert);
|
||||
glDetachShader(this->_objectShaderProgram, this->_objectFrag);
|
||||
|
||||
glDeleteShader(this->_objectVert);
|
||||
glDeleteShader(this->_objectFrag);
|
||||
glDeleteProgram(this->_objectShaderProgram);
|
||||
|
||||
glDetachShader(this->_blurShaderProgram, this->_blurVert);
|
||||
glDetachShader(this->_blurShaderProgram, this->_blurFrag);
|
||||
|
||||
glDeleteShader(this->_blurVert);
|
||||
glDeleteShader(this->_blurFrag);
|
||||
glDeleteProgram(this->_blurShaderProgram);
|
||||
|
||||
glDeleteFramebuffersEXT(1, &(this->_depth));
|
||||
glDeleteTexturesEXT(1, &(this->_shadowMap));
|
||||
glDeleteTexturesEXT(1, &(this->_blur));
|
||||
glDeleteFramebuffersEXT(1, &_fbo);
|
||||
}
|
||||
|
||||
bool VarianceShadowMappingBlur::init()
|
||||
{
|
||||
GLenum err = glewInit();
|
||||
if (!GLEW_OK == err){
|
||||
QMessageBox msgBox;
|
||||
msgBox.setIcon(QMessageBox::Warning);
|
||||
msgBox.setWindowTitle("GLEW init failure");
|
||||
msgBox.setText(QString("Init GLEW failed."));
|
||||
int ret = msgBox.exec();
|
||||
return false;
|
||||
}
|
||||
if(!this->setup()){
|
||||
QMessageBox msgBox;
|
||||
msgBox.setIcon(QMessageBox::Warning);
|
||||
msgBox.setWindowTitle("FBO Setup failure");
|
||||
msgBox.setText(QString("Failed in creating a Frame Buffer Object."));
|
||||
int ret = msgBox.exec();
|
||||
return false;
|
||||
}
|
||||
return compileAndLink();
|
||||
}
|
||||
|
||||
void VarianceShadowMappingBlur::runShader(MeshModel& m, GLArea* gla){
|
||||
vcg::Box3f bb = m.cm.bbox;
|
||||
vcg::Point3f center;
|
||||
center = bb.Center();
|
||||
|
||||
GLfloat g_mModelView[16];
|
||||
GLfloat g_mProjection[16];
|
||||
|
||||
int diag = bb.Diag();
|
||||
|
||||
GLfloat lP[4];
|
||||
glGetLightfv(GL_LIGHT0, GL_POSITION, lP);
|
||||
vcg::Point3f light = -vcg::Point3f(lP[0],lP[1],lP[2]);
|
||||
|
||||
vcg::Matrix44f tm = gla->trackball.Matrix();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
glLoadIdentity();
|
||||
glOrtho(-(diag/2),
|
||||
diag/2,
|
||||
-(diag/2),
|
||||
diag/2,
|
||||
-(diag/2),
|
||||
diag/2);
|
||||
|
||||
glGetFloatv(GL_PROJECTION_MATRIX, g_mProjection);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
glPushMatrix();
|
||||
vcg::Point3f u, v;
|
||||
//mi seleziona automaticamente un upvector che mi eviti casi degeneri...nel caso vada bene 010 sceglie quello
|
||||
vcg::GetUV(light, u, v, vcg::Point3f(0,-1,0));
|
||||
glLoadIdentity();
|
||||
gluLookAt(0, 0, 0, light[0], light[1], light[2], v[0], v[1], v[2]);
|
||||
|
||||
//get the rotation matrix from the trackball
|
||||
vcg::Matrix44f rotation;
|
||||
vcg::Similarityf track = gla->trackball.track;
|
||||
track.rot.ToMatrix(rotation);
|
||||
glMultMatrixf(rotation.transpose().V());
|
||||
|
||||
//traslate the model in the center
|
||||
glTranslatef(-center[0],-center[1],-center[2]);
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, g_mModelView);
|
||||
|
||||
|
||||
/***********************************************************/
|
||||
//GENERAZIONE SHADOW MAP
|
||||
/***********************************************************/
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(1.0, 1.0);
|
||||
|
||||
|
||||
this->bind();
|
||||
glUseProgram(this->_depthShaderProgram);
|
||||
RenderMode rm = gla->getCurrentRenderMode();
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
m.Render(rm.drawMode, vcg::GLW::CMNone, vcg::GLW::TMNone);
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
//this->getShadowMap();
|
||||
//glUseProgram(0);
|
||||
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
/***********************************************************/
|
||||
//OBJECT PASS
|
||||
/***********************************************************/
|
||||
GLint depthFuncOld;
|
||||
glGetIntegerv(GL_DEPTH_FUNC, &depthFuncOld);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
vcg::Matrix44f mvpl = (vcg::Matrix44f(g_mProjection).transpose() * vcg::Matrix44f(g_mModelView).transpose()).transpose();
|
||||
glUseProgram(this->_objectShaderProgram);
|
||||
|
||||
GLuint matrixLoc = glGetUniformLocation(this->_objectShaderProgram, "mvpl");
|
||||
glUniformMatrix4fv(matrixLoc, 1, 0, mvpl.V());
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, this->_shadowMap);
|
||||
|
||||
|
||||
GLuint loc = glGetUniformLocation(this->_objectShaderProgram, "shadowMap");
|
||||
glUniform1i(loc, 0);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
m.Render(rm.drawMode, rm.colorMode, rm.textureMode);
|
||||
|
||||
//this->getBlur();
|
||||
this->unbind();
|
||||
glDepthFunc((GLenum)depthFuncOld);
|
||||
glUseProgram(0);
|
||||
|
||||
/***********************************************************/
|
||||
//BLURRING
|
||||
/***********************************************************/
|
||||
glUseProgram(this->_blurShaderProgram);
|
||||
|
||||
//GLfloat scale = 1/(diag * BLUR_COEF * SHADOW_COEF);
|
||||
GLfloat scale = (1/(this->_texSize)) * BLUR_COEF * SHADOW_COEF;
|
||||
|
||||
GLuint scaleLoc = glGetUniformLocation(this->_blurShaderProgram, "scale");
|
||||
//glUniform2f(scaleLoc, 0.0, 0.0);
|
||||
glUniform2f(scaleLoc, scale, scale);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
//glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, this->_blur);
|
||||
loc = glGetUniformLocation(this->_blurShaderProgram, "scene");
|
||||
glUniform1i(loc, 0);
|
||||
|
||||
//Preparing to draw quad
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
/*glOrtho(-(diag/2),
|
||||
diag/2,
|
||||
-(diag/2),
|
||||
diag/2,
|
||||
-(diag/2),
|
||||
diag/2);*/
|
||||
glOrtho(-(this->_texSize/2),
|
||||
this->_texSize/2,
|
||||
-(this->_texSize/2),
|
||||
this->_texSize/2,
|
||||
-(this->_texSize/2),
|
||||
this->_texSize/2);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
//glTranslated(0,0,-(diag/2));
|
||||
glTranslated(0,0,-5);
|
||||
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2d(0,0);glVertex3f(-this->_texSize/2,-this->_texSize/2,0);
|
||||
glTexCoord2d(1,0);glVertex3f(this->_texSize/2,-this->_texSize/2,0);
|
||||
glTexCoord2d(1,1);glVertex3f(this->_texSize/2,this->_texSize/2,0);
|
||||
glTexCoord2d(0,1);glVertex3f(-this->_texSize/2,this->_texSize/2,0);
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
|
||||
//m.Render(rm.drawMode, rm.colorMode, rm.textureMode);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_BLEND);
|
||||
glUseProgram(0);
|
||||
|
||||
int error = glGetError();
|
||||
}
|
||||
|
||||
bool VarianceShadowMappingBlur::setup()
|
||||
{
|
||||
if (!GLEW_EXT_framebuffer_object) {
|
||||
qWarning("FBO not supported!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_initOk)
|
||||
return true;
|
||||
|
||||
//genero il frame buffer object
|
||||
glGenFramebuffersEXT(1, &_fbo);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo);
|
||||
|
||||
//genero la texture di colore che sara la mia variance shadow map.
|
||||
glGenTextures(1, &this->_shadowMap);
|
||||
glBindTexture(GL_TEXTURE_2D, this->_shadowMap);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F_ARB, this->_texSize, this->_texSize, 0, GL_RGB, GL_FLOAT, NULL);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->_texSize, this->_texSize, 0, GL_RGBA, GL_FLOAT, NULL);
|
||||
//attacco al FBO la texture di colore
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, this->_shadowMap, 0);
|
||||
|
||||
//genero la texture di blur.
|
||||
glGenTextures(1, &this->_blur);
|
||||
glBindTexture(GL_TEXTURE_2D, this->_blur);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F_ARB, this->_texSize, this->_texSize, 0, GL_RGB, GL_FLOAT, NULL);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->_texSize, this->_texSize, 0, GL_RGBA, GL_FLOAT, NULL);
|
||||
//e la texture per il blur
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, this->_blur, 0);
|
||||
|
||||
//genero il render buffer per il depth buffer
|
||||
glGenRenderbuffersEXT(1, &(this->_depth));
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, this->_depth);
|
||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, this->_texSize, this->_texSize);
|
||||
|
||||
//e il depth buffer
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, this->_depth);
|
||||
GLenum drawBuffers[] = {this->_shadowMap, this->_blur};
|
||||
glDrawBuffersARB(2, drawBuffers);
|
||||
|
||||
int err = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
_initOk = (err == GL_FRAMEBUFFER_COMPLETE_EXT);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
return _initOk;
|
||||
}
|
||||
|
||||
void VarianceShadowMappingBlur::bind()
|
||||
{
|
||||
assert(_initOk);
|
||||
|
||||
glClearDepth(1.0);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo);
|
||||
glPushAttrib(GL_VIEWPORT_BIT);
|
||||
glViewport(0, 0, this->_texSize, this->_texSize);
|
||||
//glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void VarianceShadowMappingBlur::unbind()
|
||||
{
|
||||
if (!_initOk)
|
||||
return;
|
||||
|
||||
glPopAttrib();
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
//glDeleteFramebuffersEXT(1, &_fbo);
|
||||
}
|
||||
|
||||
bool VarianceShadowMappingBlur::compileAndLink(){
|
||||
QFile* depthVert = new QFile(MainWindowInterface::getBaseDirPath() + QString("/../fgt/decorate_shadow/shader/vsmb/depthVSM.vert"));
|
||||
QFile* depthFrag = new QFile(MainWindowInterface::getBaseDirPath() + QString("/../fgt/decorate_shadow/shader/vsmb/depthVSM.frag"));
|
||||
QFile* objVert = new QFile(MainWindowInterface::getBaseDirPath() + QString("/../fgt/decorate_shadow/shader/vsmb/objectVSM.vert"));
|
||||
QFile* objFrag = new QFile(MainWindowInterface::getBaseDirPath() + QString("/../fgt/decorate_shadow/shader/vsmb/objectVSM.frag"));
|
||||
QFile* blurVert = new QFile(MainWindowInterface::getBaseDirPath() + QString("/../fgt/decorate_shadow/shader/vsmb/blurVSM.vert"));
|
||||
QFile* blurFrag = new QFile(MainWindowInterface::getBaseDirPath() + QString("/../fgt/decorate_shadow/shader/vsmb/blurVSM.frag"));
|
||||
|
||||
depthVert->open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
depthFrag->open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
|
||||
objVert->open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
objFrag->open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
|
||||
blurVert->open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
blurFrag->open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
|
||||
QByteArray bArray = depthVert->readAll();
|
||||
GLint ShaderLen = (GLint) bArray.length();
|
||||
GLubyte* ShaderSource = (GLubyte *)bArray.data();
|
||||
|
||||
depthVert->close();
|
||||
|
||||
this->_depthVert= glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(this->_depthVert, 1, (const GLchar **)&ShaderSource, &ShaderLen);
|
||||
glCompileShader(this->_depthVert);
|
||||
if(!this->printShaderInfoLog(this->_depthVert))
|
||||
return false;
|
||||
|
||||
bArray = depthFrag->readAll();
|
||||
ShaderLen = (GLint) bArray.length();
|
||||
ShaderSource = (GLubyte *)bArray.data();
|
||||
|
||||
depthFrag->close();
|
||||
|
||||
this->_depthFrag = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(this->_depthFrag, 1, (const GLchar **)&ShaderSource, &ShaderLen);
|
||||
glCompileShader(this->_depthFrag);
|
||||
if(!this->printShaderInfoLog(this->_depthFrag))
|
||||
return false;
|
||||
|
||||
this->_depthShaderProgram = glCreateProgram();
|
||||
glAttachShader(this->_depthShaderProgram, this->_depthVert);
|
||||
glAttachShader(this->_depthShaderProgram, this->_depthFrag);
|
||||
glLinkProgram(this->_depthShaderProgram);
|
||||
if(!this->printProgramInfoLog(this->_depthShaderProgram))
|
||||
return false;
|
||||
|
||||
|
||||
bArray = objVert->readAll();
|
||||
ShaderLen = (GLint) bArray.length();
|
||||
ShaderSource = (GLubyte *)bArray.data();
|
||||
|
||||
objVert->close();
|
||||
|
||||
this->_objectVert= glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(this->_objectVert, 1, (const GLchar **)&ShaderSource, &ShaderLen);
|
||||
glCompileShader(this->_objectVert);
|
||||
if(!this->printShaderInfoLog(this->_objectVert))
|
||||
return false;
|
||||
|
||||
bArray = objFrag->readAll();
|
||||
ShaderLen = (GLint) bArray.length();
|
||||
ShaderSource = (GLubyte *)bArray.data();
|
||||
|
||||
objFrag->close();
|
||||
|
||||
this->_objectFrag= glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(this->_objectFrag, 1, (const GLchar **)&ShaderSource, &ShaderLen);
|
||||
glCompileShader(this->_objectFrag);
|
||||
if(!this->printShaderInfoLog(this->_objectFrag))
|
||||
return false;
|
||||
|
||||
this->_objectShaderProgram = glCreateProgram();
|
||||
glAttachShader(this->_objectShaderProgram, this->_objectVert);
|
||||
glAttachShader(this->_objectShaderProgram, this->_objectFrag);
|
||||
glLinkProgram(this->_objectShaderProgram);
|
||||
if(!this->printProgramInfoLog(this->_objectShaderProgram))
|
||||
return false;
|
||||
|
||||
bArray = blurVert->readAll();
|
||||
ShaderLen = (GLint) bArray.length();
|
||||
ShaderSource = (GLubyte *)bArray.data();
|
||||
|
||||
blurVert->close();
|
||||
|
||||
this->_blurVert = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(this->_blurVert, 1, (const GLchar **)&ShaderSource, &ShaderLen);
|
||||
glCompileShader(this->_blurVert);
|
||||
if(!this->printShaderInfoLog(this->_blurVert))
|
||||
return false;
|
||||
|
||||
bArray = blurFrag->readAll();
|
||||
ShaderLen = (GLint) bArray.length();
|
||||
ShaderSource = (GLubyte *)bArray.data();
|
||||
|
||||
blurFrag->close();
|
||||
|
||||
this->_blurFrag= glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(this->_blurFrag, 1, (const GLchar **)&ShaderSource, &ShaderLen);
|
||||
glCompileShader(this->_blurFrag);
|
||||
if(!this->printShaderInfoLog(this->_blurFrag))
|
||||
return false;
|
||||
|
||||
this->_blurShaderProgram = glCreateProgram();
|
||||
glAttachShader(this->_blurShaderProgram, this->_blurVert);
|
||||
glAttachShader(this->_blurShaderProgram, this->_blurFrag);
|
||||
glLinkProgram(this->_blurShaderProgram);
|
||||
if(!this->printProgramInfoLog(this->_blurShaderProgram))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VarianceShadowMappingBlur::getBlur()
|
||||
{
|
||||
if (!this->_initOk)
|
||||
return;
|
||||
|
||||
QImage img(this->_texSize, this->_texSize, QImage::Format_RGB32);
|
||||
|
||||
unsigned char *tempBuf = new unsigned char[this->_texSize * this->_texSize * 3];
|
||||
unsigned char *tempBufPtr = tempBuf;
|
||||
glBindTexture(GL_TEXTURE_2D, this->_blur);
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, tempBufPtr);
|
||||
for (int i = 0; i < this->_texSize; ++i) {
|
||||
QRgb *scanLine = (QRgb*)img.scanLine(i);
|
||||
for (int j = 0; j < this->_texSize; ++j) {
|
||||
scanLine[j] = qRgb(tempBufPtr[0], tempBufPtr[1], tempBufPtr[2]);
|
||||
tempBufPtr += 3;
|
||||
}
|
||||
}
|
||||
|
||||
delete[] tempBuf;
|
||||
|
||||
img.mirrored().save("./_vsm_blurTXT.png", "PNG");
|
||||
}
|
||||
|
||||
void VarianceShadowMappingBlur::getShadowMap(){
|
||||
if (!this->_initOk)
|
||||
return;
|
||||
|
||||
QImage img(this->_texSize, this->_texSize, QImage::Format_RGB32);
|
||||
|
||||
unsigned char *tempBuf = new unsigned char[this->_texSize * this->_texSize * 3];
|
||||
unsigned char *tempBufPtr = tempBuf;
|
||||
glBindTexture(GL_TEXTURE_2D, this->_shadowMap);
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, tempBufPtr);
|
||||
for (int i = 0; i < this->_texSize; ++i) {
|
||||
QRgb *scanLine = (QRgb*)img.scanLine(i);
|
||||
for (int j = 0; j < this->_texSize; ++j) {
|
||||
scanLine[j] = qRgb(tempBufPtr[0], tempBufPtr[1], tempBufPtr[2]);
|
||||
tempBufPtr += 3;
|
||||
}
|
||||
}
|
||||
|
||||
delete[] tempBuf;
|
||||
img.mirrored().save("./_shadowMapTXT.png", "PNG");
|
||||
}
|
||||
|
||||
47
src/fgt/decorate_shadow/variance_shadow_mapping_blur.h
Normal file
47
src/fgt/decorate_shadow/variance_shadow_mapping_blur.h
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef VARIANCE_SHADOW_MAPPING_BLUR_H
|
||||
#define VARIANCE_SHADOW_MAPPING_BLUR_H
|
||||
|
||||
#include <cassert>
|
||||
#include <QString>
|
||||
#include <QImage>
|
||||
#include <QFile>
|
||||
#include <GL/glew.h>
|
||||
#include <meshlab/interfaces.h>
|
||||
#include <meshlab/meshmodel.h>
|
||||
#include <meshlab/glarea.h>
|
||||
#include <decorate_shader.h>
|
||||
|
||||
#define BLUR_COEF 0.25
|
||||
#define SHADOW_COEF 0.5
|
||||
|
||||
class VarianceShadowMappingBlur : public DecorateShader
|
||||
{
|
||||
|
||||
public:
|
||||
VarianceShadowMappingBlur();
|
||||
~VarianceShadowMappingBlur();
|
||||
|
||||
bool init();
|
||||
void runShader(MeshModel&, GLArea*);
|
||||
|
||||
private:
|
||||
bool compileAndLink();
|
||||
bool setup();
|
||||
void bind();
|
||||
void unbind();
|
||||
void getBlur();
|
||||
void getShadowMap();
|
||||
|
||||
GLuint _depth;
|
||||
GLuint _blur;
|
||||
|
||||
GLuint _fbo;
|
||||
GLuint _objectShaderProgram;
|
||||
GLuint _objectVert, _objectFrag;
|
||||
GLuint _depthShaderProgram;
|
||||
GLuint _depthVert, _depthFrag;
|
||||
GLuint _blurShaderProgram;
|
||||
GLuint _blurVert, _blurFrag;
|
||||
};
|
||||
|
||||
#endif // VARIANCE_SHADOW_MAPPING_BLUR_H
|
||||
Loading…
x
Reference in New Issue
Block a user