45 #include <ACG/GL/acg_glew.hh> 50 #include <ACG/GL/GLError.hh> 58 SSAOPlugin::SSAOPlugin() :
61 for (
unsigned int i = 0; i < 10; ++i)
64 for (
unsigned int i = 0; i < 6; ++i)
68 SSAOPlugin::~SSAOPlugin()
73 QString SSAOPlugin::checkOpenGL()
76 return QString(
"SSAO rendering-plugin is not yet compatible with Core Profile contexts.");
78 return QString(
"Insufficient OpenGL Version! OpenGL 3.2 or higher required");
82 missing +=
"GL_ARB_vertex_buffer_object extension missing\n";
86 missing +=
"GL_ARB_vertex_program extension missing\n";
90 missing +=
"GL_ARB_texture_float extension missing\n";
93 missing +=
"GL_EXT_framebuffer_object extension missing\n";
99 void SSAOPlugin::initializePlugin()
101 memset(shaders_, 0,
sizeof(shaders_));
102 memset(programs_, 0,
sizeof(programs_));
106 generateSamplingKernel();
113 for (
unsigned int i = 0; i < numSamples_; ++i)
116 for (
int k = 0; k < 3; ++k)
118 unsigned int x = (rand()*rand()*rand()) & RAND_MAX;
119 r[k] = float(x) / float(RAND_MAX);
129 float d = float(i+1) / float(numSamples_);
131 if (d < 0.1f) d = 0.1f;
135 samplingKernel_[i] = r;
141 void SSAOPlugin::exit()
148 QString SSAOPlugin::rendererName() {
149 return QString(
"SSAO Renderer");
169 destroyResources(_viewerId);
188 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
189 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
191 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
192 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
200 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
201 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
203 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
204 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
205 glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, p->
glWidth_, p->
glHeight_, 0, GL_RGB, GL_FLOAT, 0);
211 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
212 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
214 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
215 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
216 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, p->
glWidth_, p->
glHeight_, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
220 for (
int i = 0; i < 2; ++i)
225 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
226 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
228 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
229 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
236 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
237 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
239 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
240 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
241 glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, p->
glWidth_, p->
glHeight_, 0, GL_RGB, GL_FLOAT, 0);
251 glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, p->
glWidth_, p->
glHeight_);
252 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
260 glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, p->
depthBufTex_, 0);
261 glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, p->
sceneNormalTex_, 0);
262 glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_2D, p->
occlusionTex_, 0);
263 glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, p->
depthSSAORenderBuf_);
265 GLenum fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
266 if(fboStatus != GL_FRAMEBUFFER_COMPLETE_EXT)
267 printf(
"SSAO Plugin: ssaoFbo failed to initialize\n");
272 glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, p->
sceneBufTex_, 0);
280 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
282 glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, p->
depthSceneRenderBuf_);
285 glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, p->
depthSSAORenderBuf_);
287 fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
288 if(fboStatus != GL_FRAMEBUFFER_COMPLETE_EXT)
289 printf(
"SSAO Plugin: sceneFbo failed to initialize\n");
294 glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, p->
downsampledTex_, 0);
295 glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, p->
downsampledTmpTex_, 0);
298 fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
299 if(fboStatus != GL_FRAMEBUFFER_COMPLETE_EXT)
300 printf(
"SSAO Plugin: blurFbo failed to initialize\n");
308 const char* ShaderFiles[] = {
"SSAO/init_vertex.glsl",
309 "SSAO/fullscreen_vertex.glsl",
310 "SSAO/init_fragment.glsl",
311 "SSAO/downsampling_fragment.glsl",
312 "SSAO/blur_fragment.glsl",
313 "SSAO/ssao_fragment.glsl",
314 "SSAO/final_fragment.glsl",
315 "SSAO/final_MSAA_vertex.glsl",
316 "SSAO/final_MSAA_fragment.glsl"};
318 for (
int i = 0; i < 9; ++i)
320 QString shaderFile = OpenFlipper::Options::shaderDirStr() + QDir::separator() + QString(ShaderFiles[i]);
322 #ifdef SSAO_SHADER_DEBUG_MODE 325 if (shaders_[i])
continue;
335 log(
LOGERR, QString(ShaderFiles[i]) + QString(
" could not be loaded and compiled"));
341 for (
int i = 0; i < 6; ++i)
343 #ifndef SSAO_SHADER_DEBUG_MODE 355 pr->
attach(shaders_[2]);
break;
357 case PROG_DOWNSAMPLING:
359 pr->
attach(shaders_[3]);
break;
363 pr->
attach(shaders_[4]);
break;
367 pr->
attach(shaders_[5]);
break;
371 pr->
attach(shaders_[6]);
break;
373 case PROG_FINAL_MSAA:
375 pr->
attach(shaders_[8]);
break;
385 glGenTextures(1, &randomVecTex_);
388 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
389 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
391 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
392 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
395 for (
int i = 0; i < 16; ++i)
398 for (
int k = 0; k < 3; ++k)
399 x[k] =
float(rand()) / float(RAND_MAX);
401 float theta = x[0] * 6.2831853f;
402 float phi = x[1] * 6.2831853f;
403 randVecs[i][0] = sinf(phi);
404 randVecs[i][1] = cosf(phi);
405 randVecs[i][2] = sinf(theta);
406 randVecs[i][3] = cosf(theta);
408 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, 4, 4, 0, GL_RGBA, GL_FLOAT, randVecs);
420 for (
unsigned int i = 0; i <
sizeof(programs_) /
sizeof(programs_[0]); ++i)
422 delete programs_[i]; programs_[i] = 0;
425 for (
unsigned int i = 0; i <
sizeof(shaders_) /
sizeof(shaders_[0]); ++i)
431 if (randomVecTex_) glDeleteTextures(1, &randomVecTex_);
435 std::map<int, ViewerResources>::iterator resIt = viewerRes_.begin();
436 for (; resIt != viewerRes_.end(); ++resIt)
437 destroyResources(resIt->first);
477 glVertex2f(x0, y0-h);
478 glVertex2f(x0+w, y0-h);
479 glVertex2f(x0+w, y0);
494 void SSAOPlugin::gaussianBlurPass(
const ViewerResources* _pViewer,
const float* _texelSize,
495 GLenum _targetAttachement, GLuint _srcTexture)
498 const float gaussStDev = 1.0f;
502 float gaussKernel[5];
504 for (
int i = 0; i < 5; ++i)
507 gaussKernel[i] = powf(2.71828f, -
float(i*i)*(_texelSize[0]*_texelSize[0] + _texelSize[1]*_texelSize[1]) /
508 (gaussStDev*gaussStDev));
509 sum += gaussKernel[i];
512 for (
int i = 0; i < 5; ++i)
513 gaussKernel[i] /= sum;
518 programs_[PROG_BLUR]->setUniform(
"Tex", 0);
519 programs_[PROG_BLUR]->setUniform(
"TexelSize",
ACG::Vec2f(_texelSize));
520 programs_[PROG_BLUR]->setUniform(
"Kernel", gaussKernel, 5);
529 glPushAttrib(GL_ALL_ATTRIB_BITS);
533 int viewerId = _properties.
viewerId();
549 GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0_EXT,
550 GL_COLOR_ATTACHMENT1_EXT,
551 GL_COLOR_ATTACHMENT2_EXT,
552 GL_COLOR_ATTACHMENT3_EXT,
553 GL_COLOR_ATTACHMENT4_EXT,
554 GL_COLOR_ATTACHMENT5_EXT,
555 GL_COLOR_ATTACHMENT6_EXT};
558 const float maxDepth = 1000.0f;
560 GLint oldViewport[4];
561 glGetIntegerv(GL_VIEWPORT, oldViewport);
563 for (
int i = 0; i < 6; ++i)
569 float texelSize[4] = {1.0f / float(pViewer->
rtWidth_), 1.0f / float(pViewer->
rtHeight_), 0.0f, 0.0f};
592 glDepthMask(GL_TRUE);
593 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
595 drawScenePass(_glState, _properties, sceneGraphRoot);
597 ACG::GLState::unlockDepthFunc();
608 glDepthMask(GL_TRUE);
613 glClearColor(maxDepth, 0.0f, 0.0f, 0.0f);
614 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
617 glClearColor(0.5f, 0.5f, 0.0f, 0.0f);
618 glClear(GL_COLOR_BUFFER_BIT);
622 programs_[PROG_INIT]->use();
623 drawScenePass(_glState, _properties, sceneGraphRoot);
624 programs_[PROG_INIT]->disable();
631 texelSize[0] = 1.0f / float(pViewer->
rtWidth_);
632 texelSize[1] = 1.0f / float(pViewer->
rtHeight_);
634 programs_[PROG_SSAO]->use();
635 programs_[PROG_SSAO]->setUniform(
"TexelSize",
ACG::Vec2f(texelSize[0], texelSize[1]));
638 GLint location = programs_[PROG_SSAO]->getUniformLocation(
"Kernel");
639 glUniform3fv(location, 32, (GLfloat*)samplingKernel_);
642 programs_[PROG_SSAO]->setUniform(
"RandTex", 3);
643 programs_[PROG_SSAO]->setUniform(
"NormalTex", 2);
644 programs_[PROG_SSAO]->setUniform(
"SceneTex", 1);
645 programs_[PROG_SSAO]->setUniform(
"DepthTex", 0);
674 programs_[PROG_DOWNSAMPLING]->use();
675 programs_[PROG_DOWNSAMPLING]->setUniform(
"TexelSize",
ACG::Vec2f(texelSize));
680 programs_[PROG_DOWNSAMPLING]->setUniform(
"Tex", 0);
687 programs_[PROG_BLUR]->use();
688 programs_[PROG_BLUR]->setUniform(
"DepthTex", 1);
689 programs_[PROG_BLUR]->setUniform(
"EdgeBlur", _properties.
multisampling() ? 0.3f : 0.0f);
697 gaussianBlurPass(pViewer, texelSize, drawBuffers[1], pViewer->
downsampledTex_);
708 glViewport(oldViewport[0], oldViewport[1], oldViewport[2], oldViewport[3]);
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
unsigned int glHeight_
viewer window height
GLuint depthSceneRenderBuf_
depth renderbuffer for sceneFbo
static const unsigned int numSamples_
number of samples
void drawScenePass(ACG::GLState *_glState, Viewer::ViewerProperties &_properties, BaseNode *_sceneGraphRoot)
draw the current scene
void use()
Enables the program object for using.
unsigned int glWidth_
viewer window width
int viewport_width() const
get viewport width
GLSL::PtrFragmentShader loadFragmentShader(const char *name, const GLSL::StringList *macros, bool verbose)
Loads, compiles and installs a new vertex shader.
GLuint downsampledTex_
downsampled depth render target
static void bindTexture(GLenum _target, GLuint _buffer)
replaces glBindTexture, supports locking
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node
void drawMode(ACG::SceneGraph::DrawModes::DrawMode _mode)
set draw mode (No test if this mode is available!)
unsigned int rtDownHeight_
downsampled rt height
static void drawBuffers(GLsizei _n, const GLenum *_bufs)
replaces glDrawBuffers, supports locking
GLuint depthBufTex_
depth buffer render target
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
GLuint downsampledTmpTex_
downsampled temp rt for intermediate results
void traverse_multipass(BaseNode *_node, Action &_action, const unsigned int &_pass)
static GLuint getFramebufferDraw()
get current draw framebuffer of a target
void attach(PtrConstShader _shader)
Attaches a shader object to the program object.
DrawMode DEFAULT
use the default (global) draw mode and not the node's own.
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
GLuint sceneBufTex_
standard scene without a render target
int viewport_height() const
get viewport height
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
bool openGLVersion(const int _major, const int _minor, bool _verbose)
void disable()
Resets to standard rendering pipeline.
unsigned int rtWidth_
render target width
GLuint depthSSAORenderBuf_
depth renderbuffer for ssaoFbo
GLuint occlusionTex_
occlusion render target
GLSL::PtrVertexShader loadVertexShader(const char *name, const GLSL::StringList *macros, bool verbose)
Loads, compiles and installs a new vertex shader.
unsigned int rtSceneHeight_
scene render target height
void drawQuadProj(float _x0=-1.0f, float _y0=1.0f, float _w=2.0f, float _h=2.0f)
draw a quad in projection space (only positions)
void multisampling(bool _state)
set multisampling on/off
void generateSamplingKernel()
computes a hemisphere sampling kernel in [0,1] range
bool checkExtensionSupported(const std::string &_extension)
unsigned int rtHeight_
render target height
unsigned int rtDownWidth_
downsampled rt width
int viewerId()
Get the id of the viewer this viewerproperties belongs to.
void compatibilityProfile(bool _enableCoreProfile)
Store opengl core profile setting.
void destroyResources()
free all gl resources
static void bindFramebuffer(GLenum _target, GLuint _framebuffer)
replaces glBindFramebuffer, supports locking
static void drawBuffer(GLenum _mode)
replaces glDrawBuffer, supports locking
unsigned int rtSceneWidth_
scene render target width
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
void link()
Links the shader objects to the program.
void reloadResources(int _viewerId, unsigned int _sceneTexWidth, unsigned int _sceneTexHeight)
reload gl resources
const Vec4f & clear_color() const
get background color
static void activeTexture(GLenum _texunit)
replaces glActiveTexture, no locking support