Original Post
Hello every body.
I am trying to use FBO for multi-pass image filtering (simple blur effect). My 1st shader call working fine (bluring object perfectly) but cannot figure out why 2nd call of shader not working ? (that should make object more blur) I've tried all tutorial after googling but still no luck. Defiantly the problem is in FBO. I am implementing a simple .RAW file texture on a teapot and calling the shader on it.
Here is my code
any help would be appreciable
Thnx
I am trying to use FBO for multi-pass image filtering (simple blur effect). My 1st shader call working fine (bluring object perfectly) but cannot figure out why 2nd call of shader not working ? (that should make object more blur) I've tried all tutorial after googling but still no luck. Defiantly the problem is in FBO. I am implementing a simple .RAW file texture on a teapot and calling the shader on it.
Here is my code
****** filter.vert
varying vec2 vTexCoord;
void main(void)
{
gl_Position = ftransform();;
vec2 Pos;
Pos = sign(gl_Vertex.xy);
gl_Position = vec4(Pos, 0.0, 1.0);
vTexCoord = Pos * 0.5 + 0.5;
}****** filter.frag
uniform sampler2D texture1; // the texture with the scene you want to blur
varying vec2 vTexCoord;
const float blurSize = 1.0/512.0; // I've chosen this size because this will result in that every step will be one pixel wide if the RTScene texture is of size 512x512
void main(void)
{
vec4 sum = vec4(0.0);
// blur in y (vertical)
// take nine samples, with the distance blurSize between them
sum += texture2D(texture1, vec2(vTexCoord.x - 4.0*blurSize, vTexCoord.y)) * 0.05;
sum += texture2D(texture1, vec2(vTexCoord.x - 3.0*blurSize, vTexCoord.y)) * 0.09;
sum += texture2D(texture1, vec2(vTexCoord.x - 2.0*blurSize, vTexCoord.y)) * 0.12;
sum += texture2D(texture1, vec2(vTexCoord.x - blurSize, vTexCoord.y)) * 0.15;
sum += texture2D(texture1, vec2(vTexCoord.x, vTexCoord.y)) * 0.16;
sum += texture2D(texture1, vec2(vTexCoord.x + blurSize, vTexCoord.y)) * 0.15;
sum += texture2D(texture1, vec2(vTexCoord.x + 2.0*blurSize, vTexCoord.y)) * 0.12;
sum += texture2D(texture1, vec2(vTexCoord.x + 3.0*blurSize, vTexCoord.y)) * 0.09;
sum += texture2D(texture1, vec2(vTexCoord.x + 4.0*blurSize, vTexCoord.y)) * 0.05;
gl_FragColor = sum;
//gl_FragColor = texture2D( texture, vTexCoord );
}
****** main file
//
#include "stdafx.h"
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <GL/glext.h>
#include <math.h>
#include "shader.h"
#include <string.h>
#include <windows.h>
Shader shader;
GLdouble angle;
GLfloat xRot = 0;
GLfloat yRot = 0;
GLfloat xRotOld = 0;
GLfloat yRotOld = 0;
int mouseState = 0;
int xCenter = 0;
int yCenter = 0;
int n;
int m;
//diffuse light color variables
GLfloat dlr = 1.0;
GLfloat dlg = 1.0;
GLfloat dlb = 1.0;
//ambient light color variables
GLfloat alr = 0.0;
GLfloat alg = 0.0;
GLfloat alb = 0.0;
//specular light color variables
GLfloat slr = 0.0;
GLfloat slg = 1.0;
GLfloat slb = 0.0;
//light position variables
GLfloat lx = 1.0;
GLfloat ly = 0.2;
GLfloat lz = 0.5;
GLfloat lw = 0.0;
int lastw, lasth;
static int slices = 25;
static int stacks = 25;
#define M_ROTATE_XY 1
static GLuint texture;
GLuint raw_texture_load(const char *filename, int width, int height);
unsigned int fbo; // The frame buffer object
unsigned int fbo_depth; // The depth buffer for the frame buffer object
unsigned int fbo_texture; // The texture object to write our frame buffer object to
int window_width = 500; // The width of our window
int window_height = 500; // The height of our window
float rotation_degree = 0.0f;
void initFrameBufferDepthBuffer(void) {
glGenRenderbuffersEXT(1, &fbo_depth); // Generate one render buffer and store the ID in fbo_depth
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo_depth); // Bind the fbo_depth render buffer
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, window_width, window_height); // Set the render buffer storage to be a depth component, with a width and height of the window
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo_depth); // Set the render buffer of this buffer to the depth buffer
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); // Unbind the render buffer
}
void initFrameBufferTexture(void) {
glGenTextures(1, &fbo_texture); // Generate one texture
glBindTexture(GL_TEXTURE_2D, fbo_texture); // Bind the texture fbo_texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, window_width, window_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // Create a standard texture with the width and height of our window
// Setup the basic texture parameters
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// Unbind the texture
glBindTexture(GL_TEXTURE_2D, 0);
}
void initFrameBuffer(void) {
initFrameBufferDepthBuffer(); // Initialize our frame buffer depth buffer
initFrameBufferTexture(); // Initialize our frame buffer texture
glGenFramebuffersEXT(1, &fbo); // Generate one frame buffer and store the ID in fbo
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); // Bind our frame buffer
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fbo_texture, 0); // Attach the texture fbo_texture to the color buffer in our frame buffer
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo_depth); // Attach the depth buffer fbo_depth to our frame buffer
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); // Check that status of our generated frame buffer
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) // If the frame buffer does not report back as complete
{
std::cout << "Couldn't create frame buffer" << std::endl; // Output an error to the console
exit(0); // Exit the application
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // Unbind our frame buffer
}
void init() {
shader.init("filter.vert", "filter.frag");
glClearColor(0, 0, 0, 0);
angle = 0;
texture = raw_texture_load("01.raw", 256, 256);
glEnable(GL_TEXTURE_2D); // Enable texturing so we can bind our frame buffer texture
glEnable(GL_DEPTH_TEST); // Enable depth testing
initFrameBuffer(); // Create our frame buffer object
}
void renderTeapotScene(void) {
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); // Bind our frame buffer for rendering
glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT); // Push our glEnable and glViewport states
glViewport(0, 0, window_width, window_height); // Set the size of the frame buffer view port
glClearColor (0.0f, 0.0f, 1.0f, 1.0f); // Set the clear colour
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the depth and colour buffers
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -5.0f);
glRotatef(0.0f, 1.0f, 1.0f, 0.0f); // Rotate according to our rotation_degree value
glutSolidTeapot(1.5); // Render a teapot
glPopAttrib(); // Restore our glEnable and glViewport states
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // Unbind our texture
rotation_degree += 0.5f;
if (rotation_degree > 360.0f)
rotation_degree = 0.0f;
}
void anim() {
angle += 0.1;
glutPostRedisplay();
}
GLuint raw_texture_load(const char *filename, int width, int height)
{
GLuint texture;
unsigned char *data;
FILE *file;
// open texture data
file = fopen(filename, "rb");
if (file == NULL) return 0;
else std::cout<<"Done";
// allocate buffer
data = (unsigned char*) malloc(width * height * 3);
// read texture data
fread(data, width * height * 3, 1, file);
fclose(file);
// allocate a texture name
glGenTextures(1, &texture);
// select our current texture
glBindTexture(GL_TEXTURE_2D, texture);
// build our texture mipmaps
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);
// free buffer
free(data);
return texture;
}
void FreeTexture( GLuint texture )
{
glDeleteTextures( 1, &texture );
}
void object1 (void) {
glRotatef(angle, 1.0, 0.0, 0.0); //rotate on the x axis
glRotatef(angle, 0.0, 1.0, 0.0); //rotate on the y axis
glRotatef(angle, 0.0, 0.0, 1.0); //rotate on the z axis
glColor4f(1.0, 1.0, 0.2, 1.0);
//glScalef(0.2, 0.2, 0.2);
glutSolidTeapot(1.5);
//glutSolidTorus(0.5,1.0,50,50);
}
void setLighting(void) {
GLfloat DiffuseLight[] = {dlr, dlg, dlb};
GLfloat AmbientLight[] = {alr, alg, alb};
GLfloat SpecularLight[] = {slr, slg, slb};
glLightfv (GL_LIGHT0, GL_DIFFUSE, DiffuseLight);
glLightfv (GL_LIGHT0, GL_AMBIENT, AmbientLight);
glLightfv (GL_LIGHT0, GL_SPECULAR, SpecularLight);
GLfloat LightPosition[] = {lx, ly, lz, lw};
glLightfv (GL_LIGHT0, GL_POSITION, LightPosition);
//glEnable(GL_LIGHTING);
//glEnable(GL_LIGHT0);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, AmbientLight);
glMaterialfv(GL_FRONT, GL_SPECULAR, SpecularLight);
glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);
}
void display (void) {
setLighting();
glRotatef(xRot, 1, 0, 0);
glRotatef(yRot, 0, 1, 0);
renderTeapotScene(); // Render our teapot scene into our frame buffer
glClearColor(1.0f, 0.0f, 0.0f, 1.0f); // Clear the background of our window to red
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clear the colour buffer (more buffers later on)
glLoadIdentity(); // Load the Identity Matrix to reset our drawing locations
glTranslatef(0.0f, 0.0f, -2.0f);
// texture is the input, fbo_texture is the output
//glBindTexture(GL_TEXTURE_2D, texture); // Bind our frame buffer texture
//glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); //fbo_texture
//glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D,fbo_texture,0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texture, 0);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo_texture);
shader.bind();
glBindTexture(GL_TEXTURE_2D,texture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fbo_texture); // Bind our frame buffer texture
GLuint texloc = glGetUniformLocation(shader.id(), "texture1");
glUniform1i(texloc,0);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f); // The bottom left corner
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 0.0f); // The top left corner
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 0.0f); // The top right corner
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f); // The bottom right corner
glEnd();
//shader.unbind();
//fbo_texture have the result, texture should be the output in the next iteration
shader.bind();
glBindTexture(GL_TEXTURE_2D,texture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,fbo_texture);
texloc = glGetUniformLocation(shader.id(),"texture1");
glUniform1i(texloc,0);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f); // The bottom left corner
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 0.0f); // The top left corner
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 0.0f); // The top right corner
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f); // The bottom right corner
glEnd();
shader.unbind();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glUseProgram(0);
glBindTexture(GL_TEXTURE_2D, 1);
glutSwapBuffers();
}
void reshape (int w, int h) {
lastw = w;
lasth = h;
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluOrtho2D(0.0, (GLfloat) n, 0.0, (GLfloat) m);
gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glMatrixMode (GL_MODELVIEW);
}
void mouse(int button, int state, int x, int y) {
xCenter = x;
yCenter = y;
if (state == GLUT_DOWN) {
if (button == GLUT_LEFT_BUTTON) {
mouseState = M_ROTATE_XY;
xRotOld = xRot;
yRotOld = yRot;
}
} else {
mouseState = 0;
}
}
void motion(int x, int y) {
if (mouseState == M_ROTATE_XY) {
xRot = xRotOld + (float)(y - yCenter) / 4.0;
yRot = yRotOld + (float)(x - xCenter) / 4.0;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(600, 500);
//glutInitWindowSize(512, 512);
glutInitWindowPosition(200, 100);
glutCreateWindow("Lab2");
glewInit();
init();
glutDisplayFunc(display);
glutIdleFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutIdleFunc(anim);
glutReshapeFunc(reshape);
reshape(n, m);
glutMainLoop();
system("pause");
return 0;
}
any help would be appreciable
Thnx