basic fbo issue

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.
" );
      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,winHeight);
   
   // Initialize GLEW
   glewExperimental = true; // Needed for core profile   
   if (glewInit() != GLEW_OK)
   {
      fprintf(stderr, "Failed to initialize GLEW
");
      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                                                  
"
	 "                                                                   
"
	 "layout (location = 0) in vec4 position;                            
"
	 "layout (location = 1) in vec2 texcoord;                            
"
	 "                                                                   
"
	 "out VS_OUT                                                         
"
	 "{                                                                  
"
	 "    vec4 color;                                                    
"
	 "    vec2 texcoord;                                                 
"
	 "} vs_out;                                                          
"
	 "                                                                   
"
	 "uniform mat4 mv_matrix;                                            
"
	 "uniform mat4 proj_matrix;                                          
"
	 "                                                                   
"
	 "void main(void)                                                    
"
	 "{                                                                  
"
	 "    gl_Position = proj_matrix * mv_matrix * position;              
"
	 "    vs_out.color = position * 2.0 + vec4(0.5, 0.5, 0.5, 0.0);      
"
	 "    vs_out.texcoord = texcoord;                                    
"
	 "}                                                                  
"
      };
   
   static const char * fs_source1[] =
      {
	 "#version 410 core                                                              
"
	 "                                                                               
"
	 "in VS_OUT                                                                      
"
	 "{                                                                              
"
	 "    vec4 color;                                                                
"
	 "    vec2 texcoord;                                                             
"
	 "} fs_in;                                                                       
"
	 "                                                                               
"
	 "out vec4 color;                                                                
"
	 "                                                                               
"
	 "void main(void)                                                                
"
	 "{                                                                              
"
	 "    color = sin(fs_in.color * vec4(40.0, 20.0, 30.0, 1.0)) * 0.5 + vec4(0.5);  
"
	 "}                                                                              
"
      };
   
   static const char * fs_source2[] =
      {
	 "#version 420 core                                                              
"
	 "                                                                               
"
	 "uniform sampler2D tex;                                                         
"
	 "                                                                               
"
	 "out vec4 color;                                                                
"
	 "                                                                               
"
	 "in VS_OUT                                                                      
"
	 "{                                                                              
"
	 "    vec4 color;                                                                
"
	 "    vec2 texcoord;                                                             
"
	 "} fs_in;                                                                       
"
	 "                                                                               
"
	 "void main(void)                                                                
"
	 "{                                                                              
"
	 "    color = mix(fs_in.color, texture(tex, fs_in.texcoord), 0.7);               
"
	 "}                                                                              
"
      };
   
   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_FLOAT,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;

}


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_FLOAT,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!