PDA

View Full Version : basic fbo issue



sajis997
04-09-2014, 08:09 AM
Hi forum,

I am trying to implement the basic fbo technique where a cube is rendered to the texture first and unbind the frame buffer object , read the rendered texture and pass it through the shader and eventually render the cube to the default frame buffer - the window.

I should get a output where a image of the first cube we rendered in shown on each face of the second cube. But I am not getting it. I am getting the second cube only render on the default framebuffer. I am attaching the code snippet, Some hint would really be appreciated.


Thanks



// Include standard headers
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <vector>

#include "config.h"
GLFWwindow* window;

// Include GLM
#define GLM_FORCE_RADIANS
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
using namespace glm;


int winWidth = 800;
int winHeight = 600;
float aspect = 0.0f;

GLuint program1;
GLuint program2;
GLuint vao;
GLuint position_buffer;
GLuint index_buffer;
GLuint fbo;
GLuint color_texture;
GLuint depth_texture;
GLint mv_location;
GLint proj_location;
GLuint mv_location2;
GLuint proj_location2;

//set the window background clearing color
static const GLfloat backgroundcolor[] = {0.0f,0.0f,0.0f,1.0f};
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void render(double time);

void startup();

int main( void )
{
// Initialise GLFW
if( !glfwInit() )
{
std::cerr << "Failed to initialize GLFW." << std::endl;
exit(EXIT_FAILURE);
}

glfwWindowHint(GLFW_SAMPLES, 4);
//we want the opengl 4
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
//we do not want the old opengl
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

// Open a window and create its OpenGL context
window = glfwCreateWindow( winWidth, winHeight, "Blending Functions", NULL, NULL);

if( window == NULL )
{
fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 4.3 compatible. Try the 2.1 version of the tutorials.\n" );
glfwTerminate();
exit(EXIT_FAILURE);
}

glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
//make the current window context current
glfwMakeContextCurrent(window);
glfwSwapInterval(1);


glfwGetFramebufferSize(window,&winWidth,&winHeight);
framebuffer_size_callback(window,winWidth,winHeigh t);

// Initialize GLEW
glewExperimental = true; // Needed for core profile
if (glewInit() != GLEW_OK)
{
fprintf(stderr, "Failed to initialize GLEW\n");
exit(EXIT_FAILURE);
}

while(glGetError() != GL_NO_ERROR) {}

//print out information aout the graphics driver
std::cout << std::endl;
std::cout << "OpenGL Version: " << glGetString(GL_VERSION) << std::endl;
std::cout << "GLSL Version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;
std::cout << "GLEW Verion: " << glewGetString(GLEW_VERSION) << std::endl;
std::cout << "OpenGL Vendor: " << glGetString(GL_VENDOR) << std::endl;
std::cout << "Renderer: " << glGetString(GL_RENDERER) << std::endl;

//load the texture and the shaders
startup();

do{
render(glfwGetTime());
// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();

} // Check if the ESC key was pressed or the window was closed
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0 );


glfwDestroyWindow(window);

// Close OpenGL window and terminate GLFW
glfwTerminate();

glDeleteVertexArrays(1, &vao);
glDeleteProgram(program1);
glDeleteProgram(program2);
glDeleteBuffers(1, &position_buffer);
glDeleteFramebuffers(1, &fbo);
glDeleteTextures(1, &color_texture);

exit(EXIT_SUCCESS);
}



void render(double currentTime)
{
static const GLfloat green[] = { 0.0f, 0.1f, 0.0f, 1.0f };
static const GLfloat blue[] = { 0.0f, 0.0f, 0.3f, 1.0f };
static const GLfloat one = 1.0f;

glm::mat4 proj_matrix = glm::perspective(50.0f,
(float)winWidth / (float)winHeight,
0.1f,
1000.0f);

float f = (float)currentTime * 0.3f;

glm::mat4 mv_matrix = glm::translate(glm::mat4(1.0f),glm::vec3(0.0f, 0.0f, -4.0f)) *
glm::translate(glm::mat4(1.0f) , glm::vec3(sinf(2.1f * f) * 0.5f,
cosf(1.7f * f) * 0.5f,
sinf(1.3f * f) * cosf(1.5f * f) * 2.0f)) *
glm::rotate(glm::mat4(1.0),(float)currentTime * 45.0f, glm::vec3(0.0f, 1.0f, 0.0f)) *
glm::rotate(glm::mat4(1.0),(float)currentTime * 81.0f, glm::vec3(1.0f, 0.0f, 0.0f));

//bind to the framebuffer so that all the following rendering
//will be done on the depth and color buffers
glBindFramebuffer(GL_FRAMEBUFFER, fbo);

//set the viewport and dimension of the framebuffer
glViewport(0, 0, 512, 512);

//clear the color buffer
glClearBufferfv(GL_COLOR, 0, green);
glClearBufferfv(GL_DEPTH, 0, &one);

glUseProgram(program1);

glUniformMatrix4fv(proj_location, 1, GL_FALSE, glm::value_ptr(proj_matrix));
glUniformMatrix4fv(mv_location, 1, GL_FALSE, glm::value_ptr(mv_matrix));

//the cube is rendered to the texture we attached before
glDrawArrays(GL_TRIANGLES, 0, 36);

//unbind the framebuffer, returning to the default framebuffer - the window
glBindFramebuffer(GL_FRAMEBUFFER, 0);

glViewport(0, 0, winWidth, winHeight);
glClearBufferfv(GL_COLOR, 0, blue);
glClearBufferfv(GL_DEPTH, 0, &one);

//render the cube again
//bind the texture we just rendered to for reading
glBindTexture(GL_TEXTURE_2D, color_texture);

//activate the program that will read from the texture
glUseProgram(program2);

glUniformMatrix4fv(proj_location2, 1, GL_FALSE, glm::value_ptr(proj_matrix));
glUniformMatrix4fv(mv_location2, 1, GL_FALSE, glm::value_ptr(mv_matrix));

glDrawArrays(GL_TRIANGLES, 0, 36);

glBindTexture(GL_TEXTURE_2D, 0);
}

void startup()
{
static const char * vs_source[] =
{
"#version 410 core \n"
" \n"
"layout (location = 0) in vec4 position; \n"
"layout (location = 1) in vec2 texcoord; \n"
" \n"
"out VS_OUT \n"
"{ \n"
" vec4 color; \n"
" vec2 texcoord; \n"
"} vs_out; \n"
" \n"
"uniform mat4 mv_matrix; \n"
"uniform mat4 proj_matrix; \n"
" \n"
"void main(void) \n"
"{ \n"
" gl_Position = proj_matrix * mv_matrix * position; \n"
" vs_out.color = position * 2.0 + vec4(0.5, 0.5, 0.5, 0.0); \n"
" vs_out.texcoord = texcoord; \n"
"} \n"
};

static const char * fs_source1[] =
{
"#version 410 core \n"
" \n"
"in VS_OUT \n"
"{ \n"
" vec4 color; \n"
" vec2 texcoord; \n"
"} fs_in; \n"
" \n"
"out vec4 color; \n"
" \n"
"void main(void) \n"
"{ \n"
" color = sin(fs_in.color * vec4(40.0, 20.0, 30.0, 1.0)) * 0.5 + vec4(0.5); \n"
"} \n"
};

static const char * fs_source2[] =
{
"#version 420 core \n"
" \n"
"uniform sampler2D tex; \n"
" \n"
"out vec4 color; \n"
" \n"
"in VS_OUT \n"
"{ \n"
" vec4 color; \n"
" vec2 texcoord; \n"
"} fs_in; \n"
" \n"
"void main(void) \n"
"{ \n"
" color = mix(fs_in.color, texture(tex, fs_in.texcoord), 0.7); \n"
"} \n"
};

program1 = glCreateProgram();
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, fs_source1, NULL);
glCompileShader(fs);

GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, vs_source, NULL);
glCompileShader(vs);

glAttachShader(program1, vs);
glAttachShader(program1, fs);

glLinkProgram(program1);

glDeleteShader(vs);
glDeleteShader(fs);

program2 = glCreateProgram();
fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, fs_source2, NULL);
glCompileShader(fs);

vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, vs_source, NULL);
glCompileShader(vs);

glAttachShader(program2, vs);
glAttachShader(program2, fs);

glLinkProgram(program2);

glDeleteShader(vs);
glDeleteShader(fs);

mv_location = glGetUniformLocation(program1, "mv_matrix");
proj_location = glGetUniformLocation(program1, "proj_matrix");
mv_location2 = glGetUniformLocation(program2, "mv_matrix");
proj_location2 = glGetUniformLocation(program2, "proj_matrix");

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

static const GLushort vertex_indices[] =
{
0, 1, 2,
2, 1, 3,
2, 3, 4,
4, 3, 5,
4, 5, 6,
6, 5, 7,
6, 7, 0,
0, 7, 1,
6, 0, 2,
2, 4, 6,
7, 5, 3,
7, 3, 1
};

static const GLfloat vertex_data[] =
{
// Position Tex Coord
-0.25f, -0.25f, 0.25f, 0.0f, 1.0f,
-0.25f, -0.25f, -0.25f, 0.0f, 0.0f,
0.25f, -0.25f, -0.25f, 1.0f, 0.0f,

0.25f, -0.25f, -0.25f, 1.0f, 0.0f,
0.25f, -0.25f, 0.25f, 1.0f, 1.0f,
-0.25f, -0.25f, 0.25f, 0.0f, 1.0f,

0.25f, -0.25f, -0.25f, 0.0f, 0.0f,
0.25f, 0.25f, -0.25f, 1.0f, 0.0f,
0.25f, -0.25f, 0.25f, 0.0f, 1.0f,

0.25f, 0.25f, -0.25f, 1.0f, 0.0f,
0.25f, 0.25f, 0.25f, 1.0f, 1.0f,
0.25f, -0.25f, 0.25f, 0.0f, 1.0f,

0.25f, 0.25f, -0.25f, 1.0f, 0.0f,
-0.25f, 0.25f, -0.25f, 0.0f, 0.0f,
0.25f, 0.25f, 0.25f, 1.0f, 1.0f,

-0.25f, 0.25f, -0.25f, 0.0f, 0.0f,
-0.25f, 0.25f, 0.25f, 0.0f, 1.0f,
0.25f, 0.25f, 0.25f, 1.0f, 1.0f,

-0.25f, 0.25f, -0.25f, 1.0f, 0.0f,
-0.25f, -0.25f, -0.25f, 0.0f, 0.0f,
-0.25f, 0.25f, 0.25f, 1.0f, 1.0f,

-0.25f, -0.25f, -0.25f, 0.0f, 0.0f,
-0.25f, -0.25f, 0.25f, 0.0f, 1.0f,
-0.25f, 0.25f, 0.25f, 1.0f, 1.0f,

-0.25f, 0.25f, -0.25f, 0.0f, 1.0f,
0.25f, 0.25f, -0.25f, 1.0f, 1.0f,
0.25f, -0.25f, -0.25f, 1.0f, 0.0f,

0.25f, -0.25f, -0.25f, 1.0f, 0.0f,
-0.25f, -0.25f, -0.25f, 0.0f, 0.0f,
-0.25f, 0.25f, -0.25f, 0.0f, 1.0f,

-0.25f, -0.25f, 0.25f, 0.0f, 0.0f,
0.25f, -0.25f, 0.25f, 1.0f, 0.0f,
0.25f, 0.25f, 0.25f, 1.0f, 1.0f,

0.25f, 0.25f, 0.25f, 1.0f, 1.0f,
-0.25f, 0.25f, 0.25f, 0.0f, 1.0f,
-0.25f, -0.25f, 0.25f, 0.0f, 0.0f,
};

glGenBuffers(1, &position_buffer);
glBindBuffer(GL_ARRAY_BUFFER, position_buffer);
glBufferData(GL_ARRAY_BUFFER,
sizeof(vertex_data),
vertex_data,
GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), NULL);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid *)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);

glGenBuffers(1, &index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
sizeof(vertex_indices),
vertex_indices,
GL_STATIC_DRAW);

glEnable(GL_CULL_FACE);

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);

glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);

glGenTextures(1, &color_texture);
glBindTexture(GL_TEXTURE_2D, color_texture);
glTexImage2D(GL_TEXTURE_2D, //target
1, //level
GL_RGBA8, //internalformat
winWidth, //width
winHeight, //height
0, //border
GL_RGBA8, //format
GL_UNSIGNED_BYTE, //type
0); //pointer to data

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glGenTextures(1, &depth_texture);
glBindTexture(GL_TEXTURE_2D, depth_texture);
glTexImage2D(GL_TEXTURE_2D,1,GL_DEPTH_COMPONENT32F ,winWidth,winHeight,0,GL_DEPTH_COMPONENT32F,GL_FLO AT,0);

glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, color_texture, 0);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depth_texture, 0);

static const GLenum draw_buffers[] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, draw_buffers);
}


void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
float ratio = 1.0f;

if(height > 0)
ratio = (float)width / (float)height;


winWidth = width;
winHeight = height;

}

Osbios
04-09-2014, 09:46 AM
I saw two things, did not test the code.

This:

glTexImage2D(GL_TEXTURE_2D, //target
1, //level
GL_RGBA8, //internalformat
winWidth, //width
winHeight, //height
0, //border
GL_RGBA8, //format
GL_UNSIGNED_BYTE, //type
0); //pointer to data
...
glTexImage2D(GL_TEXTURE_2D,1,GL_DEPTH_COMPONENT32F ,winWidth,winHeight,0,GL_DEPTH_COMPONENT32F,GL_FLO AT,0);

Should be changed to this:

glTexImage2D(GL_TEXTURE_2D, //target
0, //level
GL_RGBA8, //internalformat
winWidth, //width
winHeight, //height
0, //border
GL_RGBA, //format
GL_UNSIGNED_BYTE, //type
0); //pointer to data
...
glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT32F ,winWidth,winHeight,0,GL_DEPTH_COMPONENT,GL_FLOAT, 0);


By the way, if you dont need a float depth buffer there is no reason to use it. Normaly depth buffers are NOT floating point!