SparrowRenderer/src/textureblur.cpp

116 lines
3.6 KiB
C++

#include "textureblur.h"
#include "framebuffer.h"
#include "shader.h"
#include "shadersource.h"
#include "texture.h"
TextureBlur::TextureBlur(FrameBuffer* input, int downsampling, int textureId) :
m_input(input),
m_downsampling(downsampling),
horizontal(NULL),
vertical(NULL)
{
Texture* srcTexture = input->getTexture(textureId);
int nb_fbos = (downsampling+1)*2;
fbos = new FrameBuffer[nb_fbos];
Texture* tex = srcTexture;
for(int i=0; i<nb_fbos/2; ++i)
{
// ping FBOs
fbos[i].addTexture(tex, GL_COLOR_ATTACHMENT0);
fbos[i].initColorAttachments();
tex = new Texture(tex, false);
tex->setWrap(GL_CLAMP_TO_EDGE);
tex->setFiltering(GL_LINEAR);
// pong FBOs
fbos[i+nb_fbos/2].addTexture(tex, GL_COLOR_ATTACHMENT0);
fbos[i+nb_fbos/2].initColorAttachments();
if(i < nb_fbos-1)
{
tex = new Texture(tex, true);
tex->setWrap(GL_CLAMP_TO_EDGE);
tex->setFiltering(GL_LINEAR);
}
}
}
TextureBlur::~TextureBlur()
{
for(int i=1; i<(m_downsampling+1)*2; ++i)
delete(fbos[i].getTexture(0));
delete[](fbos);
}
void TextureBlur::setSource(ShaderSource* source)
{
std::vector<const char*> defines(1);
defines[0] = "HORIZONTAL_BLUR";
horizontal = source->compile(defines);
defines[0] = "VERTICAL_BLUR";
vertical = source->compile(defines);
uniformLocations[H_SAMPLER] = horizontal->getLocation("colorSampler");
uniformLocations[H_WIDTH] = horizontal->getLocation("width");
uniformLocations[H_HEIGHT] = horizontal->getLocation("height");
uniformLocations[V_SAMPLER] = vertical->getLocation("colorSampler");
uniformLocations[V_WIDTH] = vertical->getLocation("width");
uniformLocations[V_HEIGHT] = vertical->getLocation("height");
}
void TextureBlur::blur()
{
// downsampling
for(int i=0; i<m_downsampling; ++i)
{
FrameBuffer* src = fbos + i;
FrameBuffer* dst = fbos + (i + 1);
src->setTarget(GL_READ_FRAMEBUFFER);
src->bindFBO();
dst->setTarget(GL_DRAW_FRAMEBUFFER);
dst->bindFBO();
glBlitFramebuffer(0, 0,
src->getTexture(0)->getWidth(),
src->getTexture(0)->getHeight(),
0, 0,
dst->getTexture(0)->getWidth(),
dst->getTexture(0)->getHeight(),
GL_COLOR_BUFFER_BIT, GL_LINEAR);
}
// blurring
for(int i=0; i<m_downsampling+1; ++i)
{
FrameBuffer* ping = fbos + i;
FrameBuffer* pong = ping + (m_downsampling + 1);
Texture* tex = ping->getTexture(0);
glViewport(0, 0, tex->getWidth(), tex->getHeight());
// ping (horizontal blur)
horizontal->bind();
pong->bindFBO();
tex->bind(0);
horizontal->bindInteger(uniformLocations[H_SAMPLER], 0);
horizontal->bindInteger(uniformLocations[H_WIDTH], tex->getWidth());
horizontal->bindInteger(uniformLocations[H_HEIGHT], tex->getHeight());
glDrawArrays(GL_TRIANGLES, 0, 3);
// pong (vertical blur)
vertical->bind();
ping->bindFBO();
tex = pong->getTexture(0);
tex->bind(0);
vertical->bindInteger(uniformLocations[V_SAMPLER], 0);
vertical->bindInteger(uniformLocations[V_WIDTH], tex->getWidth());
vertical->bindInteger(uniformLocations[V_HEIGHT], tex->getHeight());
glDrawArrays(GL_TRIANGLES, 0, 3);
}
}
Texture* TextureBlur::getTexture(int downsamplingLevel)
{
return fbos[downsamplingLevel].getTexture(0);
}