I'm currently working on a game project for my school using C++, SFML (for OpenGL context creation, core 3.3), and OpenGL for the rendering part.
Recently, I decided to implement a motion blur. To do this, I need a motion vector for each pixel rendered in my framebuffer object. So in my FBO, i have two texture target :
- one for the color output
- one for the motion vector
The color ouput is correctly filled, but the motion vector is always black. I use BuGLe to check the content of my FBO textures.
I know that my issue may come from my texture creation cause I don't understand well all about internal texture format and so on.
Here is my framebuffer creation :
void Framebuffer::create(int sizeX, int sizeY, bool depthBuffer, int repeatMode)
{
_texture = new GLuint[2];
std::memset(_texture, 0, sizeof(GLuint) * 2);
// Create OpenGL framebuffer
glGenFramebuffersEXT(1, &_fbo);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, _fbo);
// Create texture
glGenTextures(textNbr, _texture);
for (unsigned int i = 0; i < 2; ++i)
{
glBindTexture(GL_TEXTURE_2D, _texture[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, repeatMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, repeatMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Color - 4 float components
if (i == 0)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, sizeX, sizeY, 0, GL_RGBA, GL_FLOAT, NULL);
// Motion vector - 2 float components
else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, sizeX, sizeY, 0, GL_RG, GL_FLOAT, NULL);
// Even if I use "glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, sizeX, sizeY, 0, GL_RGBA, GL_FLOAT, NULL);" for both texture, my motion texture is black
glBindTexture(GL_TEXTURE_2D, 0);
// getColorAttachment only return GL_COLOR_ATTACHMENTi_EXT
glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, getColorAttachment(i), GL_TEXTURE_2D, _texture[i], 0);
}
// Generate depth buffer
if (depthBuffer == true)
{
glGenRenderbuffersEXT(1, &_depth);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, _depth);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, sizeX, sizeY);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
glFramebufferRenderbufferEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, _depth);
}
// Check completion
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
ogl::error("Can't complete framebuffer creation");
// Clean
unbind();
}
Framebuffer binding :
void Framebuffer::bind(void)
{
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, _fbo);
GLuint *attachment = new GLuint[2];
for (unsigned int i = 0; i < 2; ++i)
attachment[i] = getColorAttachment(i);
glDrawBuffers(2, attachment);
delete[] attachment;
}
Then my Fragment shader which should write into both texture target at the same time :
#version 330
in vec4 Color0;
layout(location = 0) out vec4 FragmentColor;
layout(location = 1) out vec2 MotionVector;
void main(void)
{
FragmentColor = Color0;
MotionVector = vec2(1);
}
Result :