23 #ifndef __FRAMEBUFFER__ 24 #define __FRAMEBUFFER__ 28 #include <Eigen/Dense> 104 Framebuffer (
int w,
int h,
int num_buffers = 1, GLenum textype = GL_TEXTURE_2D, GLenum int_frm = GL_RGBA32F, GLenum frm = GL_RGBA, GLenum pix_type = GL_UNSIGNED_BYTE ) :
105 texture_type(textype), internal_format(int_frm), pixel_type(pix_type), format(frm)
109 create(w, h, num_buffers);
115 Framebuffer (
void) : texture_type(GL_TEXTURE_2D), internal_format(GL_RGBA32F), pixel_type(GL_UNSIGNED_BYTE), format(GL_RGBA)
118 size = Eigen::Vector2i(0,0);
120 glGenFramebuffers(1, &fbo_id);
121 fboID_sptr = std::shared_ptr < GLuint > (
124 glDeleteFramebuffers(1, p);
129 glGenRenderbuffers(1, &depthbuffer_id);
130 depthbufferID_sptr = std::shared_ptr < GLuint > (
131 new GLuint (depthbuffer_id),
133 glDeleteFramebuffers(1, p);
146 void create (
int w,
int h,
int num_attachs = 1,
int nsamples = 1)
148 num_samples = nsamples;
151 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_attachs);
152 if (num_attachs > max_attachs)
154 cout <<
"WARNING : number of buffers > Max Color Attachments: " << max_attachs << endl;
157 if (num_samples > 1 && texture_type == GL_TEXTURE_2D)
159 texture_type = GL_TEXTURE_2D_MULTISAMPLE;
168 void create (Eigen::Vector2i size,
int num_attachs = 1,
int nsamples = 1)
170 create(size[0], size[1], num_attachs, nsamples);
179 return size[0] * size[1] * 4;
188 return size[0] * size[1];
198 return fboTextures[tex_id].texID();
208 return &fboTextures[tex_id];
227 fboTextures[attach_id].update(data);
238 fboTextures[attach_id].update(data);
249 glBindFramebuffer(GL_FRAMEBUFFER, *fboID_sptr);
261 glDrawBuffer(GL_COLOR_ATTACHMENT0+attachID);
272 GLenum buffers[2] = {GL_COLOR_ATTACHMENT0+attachID0, GL_COLOR_ATTACHMENT0+attachID1};
273 glDrawBuffers(2, buffers);
285 GLenum buffers[3] = {GL_COLOR_ATTACHMENT0+attachID0, GL_COLOR_ATTACHMENT0+attachID1,
286 GL_COLOR_ATTACHMENT0+attachID2};
287 glDrawBuffers(3, buffers);
297 virtual void bindRenderBuffers (GLuint attachID0, GLuint attachID1, GLuint attachID2, GLuint attachID3)
300 GLenum buffers[4] = {GL_COLOR_ATTACHMENT0+attachID0, GL_COLOR_ATTACHMENT0+attachID1,
301 GL_COLOR_ATTACHMENT0+attachID2, GL_COLOR_ATTACHMENT0+attachID3};
302 glDrawBuffers(4, buffers);
313 virtual void bindRenderBuffers (GLuint attachID0, GLuint attachID1, GLuint attachID2, GLuint attachID3,
317 GLenum buffers[5] = {GL_COLOR_ATTACHMENT0+attachID0, GL_COLOR_ATTACHMENT0+attachID1,
318 GL_COLOR_ATTACHMENT0+attachID2, GL_COLOR_ATTACHMENT0+attachID3,
319 GL_COLOR_ATTACHMENT0+attachID4};
320 glDrawBuffers(5, buffers);
332 virtual void bindRenderBuffers (GLuint attachID0, GLuint attachID1, GLuint attachID2, GLuint attachID3,
333 GLuint attachID4, GLuint attachID5)
336 GLenum buffers[6] = {GL_COLOR_ATTACHMENT0+attachID0, GL_COLOR_ATTACHMENT0+attachID1,
337 GL_COLOR_ATTACHMENT0+attachID2, GL_COLOR_ATTACHMENT0+attachID3,
338 GL_COLOR_ATTACHMENT0+attachID4, GL_COLOR_ATTACHMENT0+attachID5};
339 glDrawBuffers(6, buffers);
352 virtual void bindRenderBuffers (GLuint attachID0, GLuint attachID1, GLuint attachID2, GLuint attachID3,
353 GLuint attachID4, GLuint attachID5, GLuint attachID6)
356 GLenum buffers[7] = {GL_COLOR_ATTACHMENT0+attachID0, GL_COLOR_ATTACHMENT0+attachID1,
357 GL_COLOR_ATTACHMENT0+attachID2, GL_COLOR_ATTACHMENT0+attachID3,
358 GL_COLOR_ATTACHMENT0+attachID4, GL_COLOR_ATTACHMENT0+attachID5,
359 GL_COLOR_ATTACHMENT0+attachID6};
360 glDrawBuffers(7, buffers);
374 virtual void bindRenderBuffers (GLuint attachID0, GLuint attachID1, GLuint attachID2, GLuint attachID3,
375 GLuint attachID4, GLuint attachID5, GLuint attachID6, GLuint attachID7)
378 GLenum buffers[8] = {GL_COLOR_ATTACHMENT0+attachID0, GL_COLOR_ATTACHMENT0+attachID1,
379 GL_COLOR_ATTACHMENT0+attachID2, GL_COLOR_ATTACHMENT0+attachID3,
380 GL_COLOR_ATTACHMENT0+attachID4, GL_COLOR_ATTACHMENT0+attachID5,
381 GL_COLOR_ATTACHMENT0+attachID6, GL_COLOR_ATTACHMENT0+attachID7};
382 glDrawBuffers(8, buffers);
393 glDrawBuffers(n, buffers);
401 glBindFramebuffer(GL_FRAMEBUFFER, 0);
412 glDrawBuffer(GL_BACK);
423 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, copyfbo.
getID());
426 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_id);
427 glReadBuffer (GL_COLOR_ATTACHMENT0 + source_attach);
429 glBlitFramebuffer(0, 0, size[0], size[1], 0, 0, copyfbo.
getWidth(), copyfbo.
getHeight(), GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
453 if (pixel_type == GL_RGBA32UI)
455 glClearColor(0, 0, 0, 0);
459 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
461 for (
unsigned int i = 0; i < fboTextures.size(); ++i)
463 glDrawBuffer(GL_COLOR_ATTACHMENT0 + i);
464 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
477 void clearAttachment (
int attachment, Eigen::Vector4f clear_color = Eigen::Vector4f::Zero())
481 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
482 glDrawBuffer(GL_COLOR_ATTACHMENT0 + attachment);
483 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
497 glClear(GL_DEPTH_BUFFER_BIT);
512 fboTextures[attachment].bind(texture_unit);
522 return fboTextures[attachment].bind();
530 for (
unsigned int i = 0; i < fboTextures.size(); ++i)
532 fboTextures[i].unbind();
544 internal_format = int_frm;
566 pixel_type = in_type;
577 texture_type = tex_type;
588 Eigen::Vector4f
readPixel (
int attach, Eigen::Vector2i pos)
592 glReadBuffer(GL_COLOR_ATTACHMENT0 + attach);
594 glReadPixels(pos[0], pos[1], 1, 1, GL_RGBA, GL_FLOAT, &pixel[0]);
599 Eigen::Vector4f result (pixel[0], pixel[1], pixel[2], pixel[3]);
621 glReadBuffer(GL_COLOR_ATTACHMENT0 + attach_id);
622 glReadPixels(0, 0, size[0], size[1], GL_RGBA, GL_FLOAT, *pixels);
648 glReadBuffer(GL_COLOR_ATTACHMENT0 + attach_id);
649 glReadPixels(0, 0, size[0], size[1], GL_RGBA, GL_UNSIGNED_BYTE, *pixels);
675 glReadBuffer(GL_COLOR_ATTACHMENT0 + attach_id);
676 glReadPixels(0, 0, size[0], size[1], GL_RGBA, GL_UNSIGNED_BYTE, *pixels);
693 void readBuffer (
int attach_id, vector<unsigned char>& pixels)
699 glReadBuffer(GL_COLOR_ATTACHMENT0 + attach_id);
700 glReadPixels(0, 0, size[0], size[1], GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);
723 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
724 glReadBuffer(GL_COLOR_ATTACHMENT0 + attach_id);
725 glReadPixels(0, 0, size[0], size[1], GL_RGBA, GL_FLOAT, &pixels[0]);
738 depth_values.clear();
740 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
741 glBindRenderbuffer(GL_RENDERBUFFER, *depthbufferID_sptr);
742 glReadPixels(0, 0, size[0], size[1], GL_DEPTH_COMPONENT, GL_BYTE, &depth_values[0]);
743 glBindRenderbuffer(GL_RENDERBUFFER, 0);
752 depth_values.clear();
754 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
755 glBindRenderbuffer(GL_RENDERBUFFER, *depthbufferID_sptr);
756 glReadPixels(0, 0, size[0], size[1], GL_DEPTH_COMPONENT, GL_FLOAT, &depth_values[0]);
757 glBindRenderbuffer(GL_RENDERBUFFER, 0);
768 out_stream.open(filename.c_str());
769 out_stream <<
"P3\n";
770 out_stream << size[0] <<
" " << size[1] <<
"\n";
771 out_stream <<
"255\n";
775 GLfloat * pixels =
new GLfloat[(int)(size[0]*size[1]*4)];
777 glReadBuffer(GL_COLOR_ATTACHMENT0+attach);
778 glReadPixels(0, 0, size[0], size[1], GL_RGBA, GL_FLOAT, pixels);
781 for (
int j = size[1]-1; j >= 0; --j)
783 for (
int i = 0 ; i < size[0]; ++i)
785 pos = (i + size[0]*j)*4;
786 out_stream << (int)(255*pixels[pos+0]) <<
" " << (int)(255*pixels[pos+1]) <<
" " << (int)(255*pixels[pos+2]) <<
" ";
807 void printBuffer (
int attach, Eigen::Vector4f exception = Eigen::Vector4f(0.0,0.0,0.0,0.0) )
811 GLfloat * pixels =
new GLfloat[(int)(size[0]*size[1]*4)];
813 glReadBuffer(GL_COLOR_ATTACHMENT0+attach);
814 glReadPixels(0, 0, size[0], size[1], GL_RGBA, GL_FLOAT, pixels);
817 Eigen::Vector4f min = Eigen::Vector4f::Constant(numeric_limits<float>::max());
818 Eigen::Vector4f max = Eigen::Vector4f::Constant (numeric_limits<float>::min());
821 Eigen::Vector4f pixel;
822 for (
int j = 0; j < size[1]; ++j)
824 for (
int i = 0 ; i < size[0]; ++i)
826 pos = (i + size[0]*j)*4;
827 pixel << pixels[pos+0], pixels[pos+1], pixels[pos+2], pixels[pos+3];
828 if (pixel != exception)
830 cout <<
"(" << i <<
"," << j <<
") = [ " << pixel.transpose() <<
" ]" << endl;
833 for (
int k = 0; k < 4; ++k)
835 if (pixel[k] < min[k])
839 if (pixel[k] > max[k])
854 cout << endl <<
"info : " << endl;
855 cout <<
"num valid pixels : " << count << endl;
856 cout <<
"min values : " << min.transpose() << endl;
857 cout <<
"max values : " << max.transpose() << endl;
858 cout <<
"tex id : " << attach << endl;
902 return fboTextures.size();
925 virtual void createFramebuffer (
int viewportWidth,
int viewportHeight,
int numberOfTextures = 1)
929 size << viewportWidth, viewportHeight;
937 fboTextures.resize( numberOfTextures );
938 for (
int i = 0; i < numberOfTextures; ++i)
944 glBindRenderbuffer(GL_RENDERBUFFER, *depthbufferID_sptr);
945 if (num_samples == 1)
947 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size[0], size[1]);
951 glRenderbufferStorageMultisample(GL_RENDERBUFFER, num_samples, GL_DEPTH_COMPONENT, size[0], size[1]);
953 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, *depthbufferID_sptr);
955 GLint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
956 if (status != GL_FRAMEBUFFER_COMPLETE)
958 std::cout <<
"FBO ERROR : " << status << std::endl;
972 fboTextures[attach_id].setNumSamples(num_samples);
974 fboTextures[attach_id].create(texture_type, internal_format, size[0], size[1], format, pixel_type);
976 glBindTexture(texture_type, fboTextures[attach_id].texID());
977 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+attach_id, texture_type, fboTextures[attach_id].texID() , 0);
978 glBindTexture(texture_type, 0);
Eigen::Vector2i getSize() const
Returns the framebuffer's dimensions as a 2-component vector.
Definition: framebuffer.hpp:440
Texture * getTexture(int tex_id)
Returns a pointer to a texture (attachment).
Definition: framebuffer.hpp:206
int bindAttachment(int attachment)
Binds a texture attachment to the first free unit.
Definition: framebuffer.hpp:520
void saveAsPPM(string filename, int attach=0)
Saves the buffer to a PPM image.
Definition: framebuffer.hpp:765
int getHeight(void)
Returns the height of the FBO.
Definition: framebuffer.hpp:893
GLuint depthbuffer_id
The Depthbuffer Object.
Definition: framebuffer.hpp:52
virtual void bindRenderBuffers(GLuint attachID0, GLuint attachID1, GLuint attachID2, GLuint attachID3, GLuint attachID4, GLuint attachID5, GLuint attachID6, GLuint attachID7)
Bind framebuffer object and set render buffer to 8 given attachments.
Definition: framebuffer.hpp:374
void setInputFormat(GLenum in_format)
Sets format to read data to the FBO.
Definition: framebuffer.hpp:553
void readDepthBuffer(vector< float > &depth_values)
Reads the depth buffer and stores it in a CPU vector of float.
Definition: framebuffer.hpp:750
virtual void createTexture(int attach_id)
Generate the ith FBO texture as the ith color attachment.
Definition: framebuffer.hpp:970
virtual void createFramebuffer(int viewportWidth, int viewportHeight, int numberOfTextures=1)
Creates the framebuffer and the depthbuffer.
Definition: framebuffer.hpp:925
GLuint getID(void)
Returns the fbo ID.
Definition: framebuffer.hpp:866
Eigen::Vector2i getDimensions(void)
Returns the dimensions of the FBO.
Definition: framebuffer.hpp:875
Definition: bufferobject.hpp:34
void clearDepth(void)
Clears the FBO depthbuffer.
Definition: framebuffer.hpp:493
void fillTexture(int attach_id, GLubyte *data)
Fills a texture with given data in an array of Bytes.
Definition: framebuffer.hpp:224
void setTextureType(GLenum tex_type)
Sets FBO texture type.
Definition: framebuffer.hpp:575
std::shared_ptr< GLuint > depthbufferID_sptr
Shared pointer to depth buffer id.
Definition: framebuffer.hpp:88
void clearAttachments(Eigen::Vector4f clear_color=Eigen::Vector4f::Zero())
Clears all attachments with a given color.
Definition: framebuffer.hpp:448
virtual void bindRenderBuffers(GLuint attachID0, GLuint attachID1, GLuint attachID2, GLuint attachID3)
Bind framebuffer object and set render buffer to 4 given attachments.
Definition: framebuffer.hpp:297
Eigen::Vector4f readPixel(int attach, Eigen::Vector2i pos)
Reads a pixel from a buffer and returns it as an Eigen vector.
Definition: framebuffer.hpp:588
virtual void bindRenderBuffers(GLuint attachID0, GLuint attachID1, GLuint attachID2, GLuint attachID3, GLuint attachID4)
Bind framebuffer object and set render buffer to 5 given attachments.
Definition: framebuffer.hpp:313
int num_samples
Number of samples (for multisampling)
Definition: framebuffer.hpp:73
void create(Eigen::Vector2i size, int num_attachs=1, int nsamples=1)
Definition: framebuffer.hpp:168
void clearAttachment(int attachment, Eigen::Vector4f clear_color=Eigen::Vector4f::Zero())
Clears a given attachments with a given color.
Definition: framebuffer.hpp:477
std::shared_ptr< GLuint > fboID_sptr
Shared pointer to fbo id.
Definition: framebuffer.hpp:85
GLenum internal_format
Internal format as defined by OpenGL (ex. GL_RGBA, GL_RGBA32F ...).
Definition: framebuffer.hpp:64
virtual void bindRenderBuffer(GLuint attachID)
Bind framebuffer object and set render buffer to given attachment.
Definition: framebuffer.hpp:258
Eigen::Vector2i size
Framebuffer dimensions.
Definition: framebuffer.hpp:61
void readBuffer(int attach_id, vector< unsigned char > &pixels)
Reads a GPU buffer and stores it in a CPU vector of unsigned char.
Definition: framebuffer.hpp:693
int bufferElements() const
Returns the total number of data elements held by the framebuffer, in terms of red, green, blue and alpha components. Use this method if you need to allocate a buffer large enough to copy the framebuffer's contents.
Definition: framebuffer.hpp:178
virtual void bindRenderBuffers(GLuint attachID0, GLuint attachID1, GLuint attachID2, GLuint attachID3, GLuint attachID4, GLuint attachID5)
Bind framebuffer object and set render buffer to 6 given attachments.
Definition: framebuffer.hpp:332
Framebuffer(int w, int h, int num_buffers=1, GLenum textype=GL_TEXTURE_2D, GLenum int_frm=GL_RGBA32F, GLenum frm=GL_RGBA, GLenum pix_type=GL_UNSIGNED_BYTE)
Framebuffer default constructor.
Definition: framebuffer.hpp:104
GLuint fbo_id
The Framebuffer Object.
Definition: framebuffer.hpp:49
Framebuffer(void)
Framebuffer default empty constructor.
Definition: framebuffer.hpp:115
void readBuffer(int attach_id, GLbyte **pixels)
Reads a GPU buffer and stores it in a CPU array of unsigned bytes.
Definition: framebuffer.hpp:640
virtual void bind(void)
Binds framebuffer object.
Definition: framebuffer.hpp:245
void readDepthBuffer(vector< GLbyte > &depth_values)
Reads the depth buffer and stores it in a CPU vector of GLbyte.
Definition: framebuffer.hpp:736
virtual void bindRenderBuffers(GLuint attachID0, GLuint attachID1)
Bind framebuffer object and set render buffer to 2 given attachments.
Definition: framebuffer.hpp:269
GLenum textureType(void)
Definition: framebuffer.hpp:214
std::vector< Texture > fboTextures
Array of textures attachments.
Definition: framebuffer.hpp:55
void setInputType(GLenum in_type)
Sets data type for reading pixels to the FBO.
Definition: framebuffer.hpp:564
void unbind(void)
Unbinds fbo and all texture units in use.
Definition: framebuffer.hpp:408
void readBuffer(int attach_id, vector< float > &pixels)
Reads a GPU buffer and stores it in a CPU vector of float.
Definition: framebuffer.hpp:716
void blitTo(Framebuffer ©fbo, int source_attach=0, int dest_attach=0)
Copy fbo attachment to another fbo with blit operation.
Definition: framebuffer.hpp:421
GLenum pixel_type
Pixel type (GL_FLOAT, GL_UNSIGNED_INT ...)
Definition: framebuffer.hpp:67
A wrapper class for creating and using FBOs.
Definition: framebuffer.hpp:44
void create(int w, int h, int num_attachs=1, int nsamples=1)
Creates the framebuffer with specified parameters.
Definition: framebuffer.hpp:146
bool is_binded
Flag to indicate if buffer is binded or not.
Definition: framebuffer.hpp:82
virtual void bindRenderBuffers(GLuint attachID0, GLuint attachID1, GLuint attachID2)
Bind framebuffer object and set render buffer to 3 given attachments.
Definition: framebuffer.hpp:282
virtual void bindRenderBuffers(GLuint attachID0, GLuint attachID1, GLuint attachID2, GLuint attachID3, GLuint attachID4, GLuint attachID5, GLuint attachID6)
Bind framebuffer object and set render buffer to 7 given attachments.
Definition: framebuffer.hpp:352
void readBuffer(int attach_id, unsigned char **pixels)
Reads a GPU buffer and stores it in a CPU array of unsigned char.
Definition: framebuffer.hpp:667
void unbindAttachments(void)
Unbinds all texture attachments.
Definition: framebuffer.hpp:528
An OpenGL texture. It can be a simple texture or an FBO texture.
Definition: texture.hpp:41
void printBuffer(int attach, Eigen::Vector4f exception=Eigen::Vector4f(0.0, 0.0, 0.0, 0.0))
Prints the content of a GPU. Usually used for debugging.
Definition: framebuffer.hpp:807
int getNumAttachments(void)
Returns the number of attachments.
Definition: framebuffer.hpp:901
int getWidth(void)
Returns the width of the FBO.
Definition: framebuffer.hpp:884
GLenum format
Format as defined by OpenGL (ex. GL_RGBA, GL_RGBA_INTEGER ...)
Definition: framebuffer.hpp:70
int depthBufferElements() const
Returns the total number of depth data elements held by the framebuffer. Use this method if you need ...
Definition: framebuffer.hpp:187
virtual void bindRenderBuffers(GLsizei n, GLuint *buffers)
Bind framebuffer object and set render buffer to given array of buffers.
Definition: framebuffer.hpp:390
GLenum texture_type
Texture type for framebuffer attachments, default is GL_TEXTURE_2D.
Definition: framebuffer.hpp:58
GLuint getTexID(int tex_id)
Returns the id of the texture in given color attachment.
Definition: framebuffer.hpp:196
void readBuffer(int attach_id, GLfloat **pixels)
Reads a GPU buffer and stores it in a CPU array of floats.
Definition: framebuffer.hpp:613
void setInternalFormat(GLenum int_frm)
Sets the internal format of the FBO's texture.
Definition: framebuffer.hpp:542
void bindAttachment(int attachment, int texture_unit)
Binds a texture attachment to a given texture unit.
Definition: framebuffer.hpp:510
virtual void unbindFBO(void)
Unbinds framebuffer object.
Definition: framebuffer.hpp:399
bool isBinded(void)
Returns wether the FBO is currently binded or not.
Definition: framebuffer.hpp:909
void fillTexture(int attach_id, GLfloat *data)
Fill a texture with given data in an array of Floats.
Definition: framebuffer.hpp:235