diff --git a/src/fgt/decorate_shadow/decorate_shader.h b/src/fgt/decorate_shadow/decorate_shader.h index dbbebf278..17572541f 100644 --- a/src/fgt/decorate_shadow/decorate_shader.h +++ b/src/fgt/decorate_shadow/decorate_shader.h @@ -29,6 +29,7 @@ #include #include +#define BLUR_COEF 0.4 class DecorateShader { @@ -98,7 +99,7 @@ protected: img.mirrored().save("./_depthMapTXT.png", "PNG"); } - void printColorMap(GLuint map){ + void printColorMap(GLuint map, const QString &fname){ if (!this->_initOk) return; @@ -118,7 +119,8 @@ protected: delete[] tempBuf; - img.mirrored().save("./_depthMapTXT.png", "PNG"); + img.mirrored().save(fname, "PNG"); + //img.save(fname, "PNG"); } diff --git a/src/fgt/decorate_shadow/shader/ssao/blur.frag b/src/fgt/decorate_shadow/shader/ssao/blur.frag new file mode 100644 index 000000000..fccc8d621 --- /dev/null +++ b/src/fgt/decorate_shadow/shader/ssao/blur.frag @@ -0,0 +1,21 @@ +uniform sampler2D scene; +uniform vec2 scale; +void main() { + vec4 color = vec4(vec3(0.0), 1.0); + + color += texture2D( scene, gl_TexCoord[0].st + vec2( -3.0 * scale.x, -3.0 * scale.y ) ) * 0.015625; + color += texture2D( scene, gl_TexCoord[0].st + vec2( -2.0 * scale.x, -2.0 * scale.y ) )*0.09375; + color += texture2D( scene, gl_TexCoord[0].st + vec2( -1.0 * scale.x, -1.0 * scale.y) )*0.234375; + color += texture2D( scene, gl_TexCoord[0].st + vec2( 0.0 , 0.0) )*0.3125; + color += texture2D( scene, gl_TexCoord[0].st + vec2( 1.0 * scale.x, 1.0 * scale.y ) )*0.234375; + color += texture2D( scene, gl_TexCoord[0].st + vec2( 2.0 * scale.x, 2.0 * scale.y ) )*0.09375; + color += texture2D( scene, gl_TexCoord[0].st + vec2( 3.0 * scale.x, 3.0 * scale.y ) ) * 0.015625; + + + //gl_FragColor = color;//vec4(color.xyz, (0.5 - color.x)); + if(scale.y == 0.0) + gl_FragColor = color;//vec4(color.xyz, 0.5); + else + gl_FragColor = vec4(color.xyz, 0.5); + +} \ No newline at end of file diff --git a/src/fgt/decorate_shadow/shader/ssao/blur.vert b/src/fgt/decorate_shadow/shader/ssao/blur.vert new file mode 100644 index 000000000..5da395dfd --- /dev/null +++ b/src/fgt/decorate_shadow/shader/ssao/blur.vert @@ -0,0 +1,4 @@ +void main(){ + gl_Position = ftransform(); + gl_TexCoord[0] = gl_MultiTexCoord0; +} \ No newline at end of file diff --git a/src/fgt/decorate_shadow/shader/ssao/normalMap.frag b/src/fgt/decorate_shadow/shader/ssao/normalMap.frag new file mode 100644 index 000000000..146d40dd2 --- /dev/null +++ b/src/fgt/decorate_shadow/shader/ssao/normalMap.frag @@ -0,0 +1,13 @@ +varying vec3 normal; +varying vec4 point; +//varying float depth; + +void main(){ + float depth = point.z;// / point.w; + depth = depth * 0.5 + 0.5; + + //gl_FragColor = vec4(normal, 1.0); + //gl_FragColor = vec4(vec3(depth), 1.0); + + gl_FragColor = vec4(vec3(normal), depth); +} \ No newline at end of file diff --git a/src/fgt/decorate_shadow/shader/ssao/normalMap.vert b/src/fgt/decorate_shadow/shader/ssao/normalMap.vert new file mode 100644 index 000000000..4e50da551 --- /dev/null +++ b/src/fgt/decorate_shadow/shader/ssao/normalMap.vert @@ -0,0 +1,20 @@ +/*uniform float farPlane; +uniform float nearPlane; +uniform float diag;*/ + +varying vec3 normal; +varying vec4 point; +//varying float depth; + +void main(){ + normal = normalize(gl_NormalMatrix * gl_Normal); + + gl_Position = ftransform(); + point = gl_Position; + + //depth = gl_Position.z; + //depth = (gl_Position.z + nearPlane) / farPlane; + //depth = (gl_Position.z/ farPlane) + nearPlane; + //depth = (gl_Position.z * (nearPlane * farPlane/ nearPlane + farPlane))// + (nearPlane);// + nearPlane); + //depth = gl_Position / diag; +} diff --git a/src/fgt/decorate_shadow/shader/ssao/ssao.frag b/src/fgt/decorate_shadow/shader/ssao/ssao.frag new file mode 100644 index 000000000..3b800cc83 --- /dev/null +++ b/src/fgt/decorate_shadow/shader/ssao/ssao.frag @@ -0,0 +1,61 @@ +uniform sampler2D rnm; +uniform sampler2D normalMap; + +varying vec2 uv; + +const float totStrength = 1.38; +const float strength = 0.07; +const float offset = 18.0; +const float falloff = 0.000002; +const float rad = 0.006; +#define SAMPLES 10 // 10 is good +const float invSamples = -1.38/10.0; + +void main(void) +{ + // these are the random vectors inside a unit sphere + vec3 pSphere[10] = vec3[](vec3(-0.010735935, 0.01647018, 0.0062425877),vec3(-0.06533369, 0.3647007, -0.13746321),vec3(-0.6539235, -0.016726388, -0.53000957),vec3(0.40958285, 0.0052428036, -0.5591124),vec3(-0.1465366, 0.09899267, 0.15571679),vec3(-0.44122112, -0.5458797, 0.04912532),vec3(0.03755566, -0.10961345, -0.33040273),vec3(0.019100213, 0.29652783, 0.066237666),vec3(0.8765323, 0.011236004, 0.28265962),vec3(0.29264435, -0.40794238, 0.15964167)); + + // grab a normal for reflecting the sample rays later on + vec3 fres = normalize((texture2D(rnm,uv*offset).xyz*2.0) - vec3(1.0)); + + vec4 currentPixelSample = texture2D(normalMap,uv); + + float currentPixelDepth = currentPixelSample.a; + + // current fragment coords in screen space + vec3 ep = vec3(uv.xy,currentPixelDepth); + // get the normal of current fragment + vec3 norm = currentPixelSample.xyz; + + float bl = 0.0; + // adjust for the depth ( not shure if this is good..) + float radD = rad/currentPixelDepth; + + //vec3 ray, se, occNorm; + float occluderDepth, depthDifference; + vec4 occluderFragment; + vec3 ray; + for(int i=0; i < SAMPLES; ++i) + { + // get a vector (randomized inside of a sphere with radius 1.0) from a texture and reflect it + ray = radD*reflect(pSphere[i],fres); + + // get the depth of the occluder fragment + occluderFragment = texture2D(normalMap,ep.xy + sign(dot(ray,norm) )*ray.xy); + // if depthDifference is negative = occluder is behind current fragment + depthDifference = currentPixelDepth-occluderFragment.a; + + // calculate the difference between the normals as a weight + // the falloff equation, starts at falloff and is kind of 1/x^2 falling + bl += step(falloff,depthDifference)*(1.0-dot(occluderFragment.xyz,norm))*(1.0-smoothstep(falloff,strength,depthDifference)); + } + + // output the result + //gl_FragColor.r = 1.0+bl*invSamples; + + float ao = 1.0+bl*invSamples; + gl_FragColor = vec4(vec3(ao), 1.0); + //gl_FragColor = 1.0; + +} \ No newline at end of file diff --git a/src/fgt/decorate_shadow/shader/ssao/ssao.vert b/src/fgt/decorate_shadow/shader/ssao/ssao.vert new file mode 100644 index 000000000..f51fa7752 --- /dev/null +++ b/src/fgt/decorate_shadow/shader/ssao/ssao.vert @@ -0,0 +1,13 @@ +uniform mat4 mvpl; + +varying vec2 uv; + +void main(void) +{ + //gl_Position = ftransform(); + gl_Position = mvpl * gl_Vertex; + gl_Position = sign( gl_Position ); + + // Texture coordinate for screen aligned (in correct range): + uv = (vec2( gl_Position.x, gl_Position.y ) + vec2( 1.0 ) ) * 0.5; +} \ No newline at end of file diff --git a/src/fgt/decorate_shadow/ssao.cpp b/src/fgt/decorate_shadow/ssao.cpp new file mode 100644 index 000000000..c6b33896c --- /dev/null +++ b/src/fgt/decorate_shadow/ssao.cpp @@ -0,0 +1,508 @@ +#include "ssao.h" + +SSAO::SSAO():DecorateShader() +{ + this->_depth = 0; + + this->_normalMap = 0; + this->_normalMapFrag = 0; + this->_normalMapVert = 0; + this->_normalMapShaderProgram = 0; + + this->_ssao= 0; + this->_ssaoVert = 0; + this->_ssaoFrag = 0; + this->_ssaoShaderProgram = 0; + + this->_blurH = 0; +// this->_blurV = 0; + this->_blurVert = 0; + this->_blurFrag = 0; + this->_blurShaderProgram = 0; + this->_fbo = 0; +} + +SSAO::~SSAO(){ + glDetachShader(this->_normalMapShaderProgram, this->_normalMapVert); + glDetachShader(this->_normalMapShaderProgram, this->_normalMapFrag); + + glDeleteShader(this->_normalMapVert); + glDeleteShader(this->_normalMapFrag); + glDeleteProgram(this->_normalMapShaderProgram); + + glDetachShader(this->_ssaoShaderProgram, this->_ssaoVert); + glDetachShader(this->_ssaoShaderProgram, this->_ssaoFrag); + + glDeleteShader(this->_ssaoVert); + glDeleteShader(this->_ssaoFrag); + glDeleteProgram(this->_ssaoShaderProgram); + + 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->_normalMap)); + glDeleteTexturesEXT(1, &(this->_ssao)); + + glDeleteTexturesEXT(1, &(this->_blurH)); + // glDeleteTexturesEXT(1, &(this->_blurV)); + glDeleteFramebuffersEXT(1, &_fbo); +} + +bool SSAO::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 SSAO::runShader(MeshModel& m, GLArea* gla){ + /***********************************************************/ + //GENERAZIONE SHADOW MAP + /***********************************************************/ +// glEnable(GL_POLYGON_OFFSET_FILL); +// glPolygonOffset(1.0, 1.0); +GLfloat g_mModelView[16]; + GLfloat g_mProjection[16]; + vcg::Box3f bb = m.cm.bbox; + vcg::Point3f center; + center = bb.Center(); + + float diag = bb.Diag(); + + 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(); + glLoadIdentity(); + + 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); + + this->bind(); + glUseProgram(this->_normalMapShaderProgram); + + /*GLuint farLoc = glGetUniformLocation(this->_normalMapShaderProgram, "farPlane"); + glUniform1f(farLoc, gla->farPlane); + + GLuint nearLoc = glGetUniformLocation(this->_normalMapShaderProgram, "nearPlane"); + glUniform1f(nearLoc, gla->nearPlane); + + GLuint diagLoc = glGetUniformLocation(this->_normalMapShaderProgram, "diag"); + glUniform1f(diagLoc, m.cm.bbox.Diag()); +*/ + + 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->printColorMap(this->_normalMap, "_normalMap.png"); + //this->unbind(); + glUseProgram(0); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + /***********************************************************/ + //SSAO 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->_ssaoShaderProgram); + + GLuint matrixLoc = glGetUniformLocation(this->_ssaoShaderProgram, "mvpl"); + glUniformMatrix4fv(matrixLoc, 1, 0, mvpl.V()); + + glEnable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, this->_noise); + GLuint noiseloc = glGetUniformLocation(this->_ssaoShaderProgram, "rnm"); + glUniform1i(noiseloc, 0); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, this->_normalMap); + GLuint loc = glGetUniformLocation(this->_ssaoShaderProgram, "normalMap"); + glUniform1i(loc, 1); + + + glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + m.Render(rm.drawMode, vcg::GLW::CMNone, vcg::GLW::TMNone); + + this->printColorMap(this->_ssao, "_ssao1.png"); + //this->unbind(); + glUseProgram(0); + +/****************************************************************************************/ +// BLURRING +/****************************************************************************************/ + //Preparing to draw quad + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(-(this->_texSize/2), + this->_texSize/2, + -(this->_texSize/2), + this->_texSize/2, + -(this->_texSize/2), + this->_texSize/2); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + //vcg::Point3f t = track.tra; + //glTranslated(0,0,t[2]); + glTranslated(0,0,-1); + /***********************************************************/ + //BLURRING horizontal + /***********************************************************/ + glUseProgram(this->_blurShaderProgram); + + GLfloat scale = 1/(this->_texSize * BLUR_COEF);// * SHADOW_COEF); + //GLfloat scale = (1/(this->_texSize)) * BLUR_COEF * SHADOW_COEF; + GLuint scaleLoc = glGetUniformLocation(this->_blurShaderProgram, "scale"); + glUniform2f(scaleLoc, scale, 0.0); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, this->_ssao); + loc = glGetUniformLocation(this->_blurShaderProgram, "scene"); + glUniform1i(loc, 0); + + glDrawBuffer(GL_COLOR_ATTACHMENT2_EXT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + 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(); + + this->printColorMap(this->_blurH, "./_blurOrizzontale.png"); + this->unbind(); + + + /***********************************************************/ + //BLURRING vertical + /***********************************************************/ + glUniform2f(scaleLoc, 0.0, scale); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable(GL_DEPTH_TEST); + + glBindTexture(GL_TEXTURE_2D, this->_blurH); + loc = glGetUniformLocation(this->_blurShaderProgram, "scene"); + glUniform1i(loc, 0); + + 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(); + + + //glDepthFunc((GLenum)depthFuncOld); + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + glUseProgram(0); + + + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + +/****************************************************************************************/ +// BLURRING END +/****************************************************************************************/ + + int error = glGetError(); +} + +bool SSAO::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); + + glGenTextures(1, &this->_normalMap); + glBindTexture(GL_TEXTURE_2D, this->_normalMap); + 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->_normalMap, 0); + + glGenTextures(1, &this->_ssao); + glBindTexture(GL_TEXTURE_2D, this->_ssao); + 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_ATTACHMENT1_EXT, GL_TEXTURE_2D, this->_ssao, 0); + + + //genero la texture di blur orizzontale. + glGenTextures(1, &this->_blurH); + glBindTexture(GL_TEXTURE_2D, this->_blurH); + 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 orizzontale + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_2D, this->_blurH, 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->_normalMap, this->_ssao, this->_blurH}; + GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2}; + glDrawBuffersARB(3, drawBuffers); + + this->loadNoiseTxt(); + + int err = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + _initOk = (err == GL_FRAMEBUFFER_COMPLETE_EXT); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + return _initOk; +} + +void SSAO::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 SSAO::unbind() +{ + if (!_initOk) + return; + + glPopAttrib(); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + //glDeleteFramebuffersEXT(1, &_fbo); +} + +bool SSAO::compileAndLink(){ + QFile* normalVert = new QFile(MainWindowInterface::getBaseDirPath() + QString("/../fgt/decorate_shadow/shader/ssao/normalMap.vert")); + QFile* normalFrag = new QFile(MainWindowInterface::getBaseDirPath() + QString("/../fgt/decorate_shadow/shader/ssao/normalMap.frag")); + + QFile* ssaoVert = new QFile(MainWindowInterface::getBaseDirPath() + QString("/../fgt/decorate_shadow/shader/ssao/ssao.vert")); + QFile* ssaoFrag = new QFile(MainWindowInterface::getBaseDirPath() + QString("/../fgt/decorate_shadow/shader/ssao/ssao.frag")); + + QFile* blurVert = new QFile(MainWindowInterface::getBaseDirPath() + QString("/../fgt/decorate_shadow/shader/ssao/blur.vert")); + QFile* blurFrag = new QFile(MainWindowInterface::getBaseDirPath() + QString("/../fgt/decorate_shadow/shader/ssao/blur.frag")); + + normalVert->open(QIODevice::ReadOnly | QIODevice::Text); + normalFrag->open(QIODevice::ReadOnly | QIODevice::Text); + + ssaoVert->open(QIODevice::ReadOnly | QIODevice::Text); + ssaoFrag->open(QIODevice::ReadOnly | QIODevice::Text); + + blurVert->open(QIODevice::ReadOnly | QIODevice::Text); + blurFrag->open(QIODevice::ReadOnly | QIODevice::Text); + + QByteArray bArray = normalVert->readAll(); + GLint ShaderLen = (GLint) bArray.length(); + GLubyte* ShaderSource = (GLubyte *)bArray.data(); + + normalVert->close(); + + this->_normalMapVert= glCreateShader(GL_VERTEX_SHADER); + glShaderSource(this->_normalMapVert, 1, (const GLchar **)&ShaderSource, &ShaderLen); + glCompileShader(this->_normalMapVert); + if(!this->printShaderInfoLog(this->_normalMapVert)) + return false; + + bArray = normalFrag->readAll(); + ShaderLen = (GLint) bArray.length(); + ShaderSource = (GLubyte *)bArray.data(); + + normalFrag->close(); + + this->_normalMapFrag = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(this->_normalMapFrag, 1, (const GLchar **)&ShaderSource, &ShaderLen); + glCompileShader(_normalMapFrag); + if(!this->printShaderInfoLog(this->_normalMapFrag)) + return false; + + this->_normalMapShaderProgram = glCreateProgram(); + glAttachShader(this->_normalMapShaderProgram, this->_normalMapVert); + glAttachShader(this->_normalMapShaderProgram, this->_normalMapFrag); + glLinkProgram(this->_normalMapShaderProgram); + if(!this->printProgramInfoLog(this->_normalMapShaderProgram)) + return false; + + + bArray = ssaoVert->readAll(); + ShaderLen = (GLint) bArray.length(); + ShaderSource = (GLubyte *)bArray.data(); + + ssaoVert->close(); + + this->_ssaoVert= glCreateShader(GL_VERTEX_SHADER); + glShaderSource(this->_ssaoVert, 1, (const GLchar **)&ShaderSource, &ShaderLen); + glCompileShader(this->_ssaoVert); + if(!this->printShaderInfoLog(this->_ssaoVert)) + return false; + + bArray = ssaoFrag->readAll(); + ShaderLen = (GLint) bArray.length(); + ShaderSource = (GLubyte *)bArray.data(); + + ssaoFrag->close(); + + this->_ssaoFrag= glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(this->_ssaoFrag, 1, (const GLchar **)&ShaderSource, &ShaderLen); + glCompileShader(this->_ssaoFrag); + if(!this->printShaderInfoLog(this->_ssaoFrag)) + return false; + + this->_ssaoShaderProgram = glCreateProgram(); + glAttachShader(this->_ssaoShaderProgram, this->_ssaoVert); + glAttachShader(this->_ssaoShaderProgram, this->_ssaoFrag); + glLinkProgram(this->_ssaoShaderProgram); + if(!this->printProgramInfoLog(this->_ssaoShaderProgram)) + 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; +} + +bool SSAO::loadNoiseTxt(){ + + QImage image = QImage(); + QString textureName = QString("./noise.png"); + //fileName = textureName; + if (QFile(textureName).exists()) + { + image = QImage(textureName); + //int bestW = pow(2.0,floor(::log(double(image.width()))/::log(2.0))); + //int bestH = pow(2.0,floor(::log(double(image.height()))/::log(2.0))); + //QImage imgGL = image.scaled(bestW,bestH,Qt::IgnoreAspectRatio,Qt::SmoothTransformation); + QImage tmpGL = QGLWidget::convertToGLFormat(image); + image = QImage(tmpGL); + } + // Creates The Texture + glGenTextures(1, &(this->_noise)); + glBindTexture(GL_TEXTURE_2D, this->_noise); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, NOISE_WIDTH , NOISE_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, image.bits()); + + return true; +} diff --git a/src/fgt/decorate_shadow/ssao.h b/src/fgt/decorate_shadow/ssao.h new file mode 100644 index 000000000..3fdbd1b91 --- /dev/null +++ b/src/fgt/decorate_shadow/ssao.h @@ -0,0 +1,74 @@ +/**************************************************************************** +* MeshLab o o * +* A versatile mesh processing toolbox o o * +* _ O _ * +* Copyright(C) 2005 \/)\/ * +* Visual Computing Lab /\/| * +* ISTI - Italian National Research Council | * +* \ * +* All rights reserved. * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program 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 General Public License (http://www.gnu.org/licenses/gpl.txt) * +* for more details. * +* * +****************************************************************************/ + +#ifndef SSAO_H +#define SSAO_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NOISE_WIDTH 64 +#define NOISE_HEIGHT 64 + +class SSAO : public DecorateShader +{ + +public: + SSAO(); + ~SSAO(); + + bool init(); + void runShader(MeshModel&, GLArea*); + +private: + bool compileAndLink(); + bool setup(); + void bind(); + void unbind(); + bool loadNoiseTxt(); + + GLuint _normalMap; + GLuint _ssao; + GLuint _noise; + GLuint _blurH; + //GLuint _blurV; + + GLuint _depth; + + GLuint _fbo; + GLuint _normalMapShaderProgram; + GLuint _normalMapVert, _normalMapFrag; + GLuint _ssaoShaderProgram; + GLuint _ssaoVert, _ssaoFrag; + GLuint _blurShaderProgram; + GLuint _blurVert, _blurFrag; +}; + +#endif // SSAO_H diff --git a/src/fgt/decorate_shadow/variance_shadow_mapping_blur.cpp b/src/fgt/decorate_shadow/variance_shadow_mapping_blur.cpp index 2f15f3cb5..198e1cb1a 100644 --- a/src/fgt/decorate_shadow/variance_shadow_mapping_blur.cpp +++ b/src/fgt/decorate_shadow/variance_shadow_mapping_blur.cpp @@ -190,7 +190,7 @@ void VarianceShadowMappingBlur::runShader(MeshModel& m, GLArea* gla){ /***********************************************************/ glUseProgram(this->_blurShaderProgram); - GLfloat scale = 1/(diag * BLUR_COEF);// * SHADOW_COEF); + GLfloat scale = 1/(this->_texSize * BLUR_COEF);// * SHADOW_COEF); //GLfloat scale = (1/(this->_texSize)) * BLUR_COEF * SHADOW_COEF; GLuint scaleLoc = glGetUniformLocation(this->_blurShaderProgram, "scale"); glUniform2f(scaleLoc, scale, 0.0); diff --git a/src/fgt/decorate_shadow/variance_shadow_mapping_blur.h b/src/fgt/decorate_shadow/variance_shadow_mapping_blur.h index 7447f6121..f5c6dc056 100644 --- a/src/fgt/decorate_shadow/variance_shadow_mapping_blur.h +++ b/src/fgt/decorate_shadow/variance_shadow_mapping_blur.h @@ -11,7 +11,7 @@ #include #include -#define BLUR_COEF 0.4 + #define SHADOW_COEF 0.95 class VarianceShadowMappingBlur : public DecorateShader