gKitGL
TPFramebuffer.h
00001 
00002 #ifndef _TP_FRAMEBUFFER_H
00003 #define _TP_FRAMEBUFFER_H
00004 
00005 #include "GLResource.h"
00006 #include "GL/TPTexture.h"
00007 
00008 
00009 namespace  gk {
00010 
00011 //! identification des textures associees au framebuffer.
00012 enum 
00013 {
00014     COLOR0= 0,
00015     COLOR1= 1,
00016     COLOR2= 2,
00017     COLOR3= 3,
00018     COLOR4= 4,
00019     COLOR5= 5,
00020     COLOR6= 6,
00021     COLOR7= 7,
00022     FRAMEBUFFER_LAST_COLOR= 8,
00023     DEPTH= 9,
00024     FRAMEBUFFER_LAST= 10
00025 };
00026 
00027 //! creation des textures par le framebuffer : identification des textures a initialiser.
00028 enum
00029 {
00030     COLOR0_BIT= 1<<COLOR0,
00031     COLOR1_BIT= 1<<COLOR1,
00032     COLOR2_BIT= 1<<COLOR2,
00033     COLOR3_BIT= 1<<COLOR3,
00034     COLOR4_BIT= 1<<COLOR4,
00035     COLOR5_BIT= 1<<COLOR5,
00036     COLOR6_BIT= 1<<COLOR6,
00037     COLOR7_BIT= 1<<COLOR7,
00038     DEPTH_BIT= 1<<DEPTH
00039 };
00040 
00041 //! identification des drawbuffers.
00042 enum
00043 {
00044     DRAW0= 0,
00045     DRAW1= 1,
00046     DRAW2= 2,
00047     DRAW3= 3,
00048     DRAW4= 4,
00049     DRAW5= 5,
00050     DRAW6= 6,
00051     DRAW7= 7,
00052 };
00053 
00054 //! representation du format des pixels d'une texture
00055 struct RenderbufferFormat
00056 {
00057     GLenum internal;
00058     int samples;        // coverage samples
00059     int color_samples;  // color samples
00060     
00061     RenderbufferFormat( )
00062         :
00063         internal(GL_RGBA),
00064         samples(0),
00065         color_samples(0)
00066     {}
00067     
00068     RenderbufferFormat( const GLenum _internal, const int _samples= 0, const int _color_samples= 0 )
00069         :
00070         internal(_internal),
00071         samples(_samples),
00072         color_samples(_color_samples)
00073     {}
00074 };
00075 
00076 //! representation interne. representation d'un renderbuffer / utiliser une texture plutot qu'un renderbuffer.
00077 class GLRenderbuffer : public GLResource
00078 {
00079     // non copyable
00080     GLRenderbuffer( const GLRenderbuffer& );
00081     GLRenderbuffer& operator= ( const GLRenderbuffer& );
00082 
00083 protected:
00084     GLenum m_target;
00085     RenderbufferFormat m_format;
00086     int m_width;
00087     int m_height;
00088     
00089 public:
00090     GLRenderbuffer( const GLenum target )
00091         :
00092         GLResource(),
00093         m_target(target)
00094     {
00095         glGenRenderbuffers(1, &m_name);
00096     }
00097     
00098     virtual ~GLRenderbuffer( ) 
00099     {
00100         glDeleteRenderbuffers(1, &m_name);
00101     }
00102     
00103     //! creation de l'objet opengl.
00104     int createGLResource( )
00105     {
00106         return (m_name != 0) ? 0 : -1;
00107     }
00108     
00109     //! destruction de l'objet opengl.
00110     int releaseGLResource( )
00111     {
00112         return (m_name != 0) ? 0 : -1;
00113     }
00114 
00115     //! renvoie le type de texture : GL_TEXTURE_2D, etc.
00116     GLenum target( ) const
00117     {
00118         return m_target;
00119     }
00120     
00121     //! renvoie le format de la texture GL_RGBA, etc.
00122     const RenderbufferFormat& format( ) const
00123     {
00124         return m_format;
00125     }
00126     
00127     //! renvoie la largeur de la texture.
00128     int width( ) const
00129     {
00130         return m_width;
00131     }
00132     
00133     //! renvoie la hauteur de la texture 2d ou 3d, ou le nombre de textures dans un texture1DArray.
00134     int height( ) const
00135     {
00136         return m_height;
00137     }
00138 };
00139 
00140 class GLRenderbuffer2D : public GLRenderbuffer
00141 {
00142 public:
00143     GLRenderbuffer2D( const int w, const int h, const RenderbufferFormat& format );
00144     ~GLRenderbuffer2D();
00145 };
00146 
00147 
00148 //! utilisation interne. representation d'un framebuffer.
00149 class GLRendertarget : public GLResource
00150 {
00151     // non copyable
00152     GLRendertarget( const GLRendertarget& );
00153     GLRendertarget& operator= ( const GLRendertarget& );
00154 
00155 protected:
00156     std::vector<GLTexture *> m_textures;
00157     std::vector<GLRenderbuffer *> m_renderbuffers;
00158     std::vector<GLenum> m_draw_buffers;
00159     int m_width;
00160     int m_height;
00161     int m_color_mask;
00162     int m_depth_mask;
00163 
00164     template< typename Texture >
00165     int attach_buffer( const unsigned int buffer, Texture *texture )
00166     {
00167         if(m_name == 0)
00168             return -1;
00169         if(buffer >= FRAMEBUFFER_LAST)
00170             return -1;
00171         if(texture == NULL)
00172             return -1;
00173 
00174     #ifdef VERBOSE_DEBUG
00175         if(buffer < FRAMEBUFFER_LAST_COLOR)
00176             printf("GLFramebuffer::attachTexture( ): buffer 0x%x, texture %d.\n", 
00177                 GL_COLOR_ATTACHMENT0 + buffer, texture->name());
00178         else if(buffer == DEPTH)
00179             printf("GLFramebuffer::attachTexture( ): buffer 0x%x, texture %d\n.", 
00180                 GL_DEPTH_ATTACHMENT, texture->name());
00181     #endif
00182         
00183         // verifie les dimensions de la texture
00184         if(m_width > 0 && texture->width() != m_width)
00185             return -1;
00186         m_width= texture->width();
00187         if(m_height > 0 && texture->height() != m_height)
00188             return -1;
00189         m_height= texture->height();
00190         
00191         // attache la texture
00192         if(m_renderbuffers[buffer] != NULL)
00193             // une texture et un renderbuffer sont attaches au meme draw buffer.
00194             return -1;
00195         
00196         m_textures[buffer]= static_cast<GLTexture *>(texture);
00197         if(buffer == DEPTH)
00198         {
00199             m_depth_mask= 1;
00200             return GL_DEPTH_ATTACHMENT;
00201         }
00202 
00203         // recompte le nombre de draw buffers couleur
00204         m_color_mask= 0;
00205         int draw_buffer= -1;
00206         m_draw_buffers.clear();
00207         for(unsigned int i= 0; i < FRAMEBUFFER_LAST_COLOR; i++)
00208         {
00209             if(m_textures[i]  == NULL
00210             && m_renderbuffers[i] == NULL)
00211                 continue;
00212 
00213             if(i == buffer)
00214                 draw_buffer= GL_COLOR_ATTACHMENT0 + (unsigned int) m_draw_buffers.size();
00215             
00216             m_draw_buffers.push_back(GL_COLOR_ATTACHMENT0 + (unsigned int) m_draw_buffers.size());
00217             m_color_mask= 1;
00218         }
00219         
00220         // renvoyer l'indice du draw buffer associe a la texture
00221         return draw_buffer;
00222     }
00223 
00224 public:
00225     //! constructeur par defaut.
00226     GLRendertarget( const GLenum target );
00227 
00228     //! associe une texture existante au framebuffer. buffer = gk::COLOR0, etc. ou gk::DEPTH. 
00229     //! toutes les textures doivent avoir les memes dimensions.\n
00230     int attachTexture( const GLenum target, const unsigned int buffer, GLTexture *texture, const int level= 0 );
00231     int attachTexture( const GLenum target, const unsigned int buffer, GLDepthTexture *texture, const int level= 0 );
00232     int attachTexture( const GLenum target, const unsigned int buffer, GLTexture2DArray *texture, const int layer, const int level= 0 );
00233     int attachTexture( const GLenum target, const unsigned int buffer, GLTextureCube *texture, const  GLenum face, const int level= 0 );
00234 
00235     int attachRenderbuffer(const GLenum target, const unsigned int buffer, GLRenderbuffer *renderbuffer );
00236 
00237     //! constructeur : cree les textures et les associe au framebuffer. buffer_bits= gk::COLOR0_BIT | gk::DEPTH_BIT, par exemple.
00238     /*! exemple d'utilisation :
00239     \code
00240     gk::GLFramebuffer framebuffer(512, 512, gk::COLOR0_BIT | gk::DEPTH_BIT);    // cree un framebuffer + une texture couleur + une texture profondeur
00241     gk::GLTexture *color= framebuffer.texture(gk::COLOR0);  // pour recuperer la texture associee au framebuffer.
00242     gk::GLDepthTexture *depth= framebuffer.zbuffer();  // pour recuperer la texture de profondeur associee au framebuffer.
00243     \endcode
00244     */
00245     GLRendertarget( const GLenum target, const int w, const int h, const unsigned int buffer_bits, 
00246         const TextureFormat& color_format= TextureRGBA, const TextureFormat& depth_format= TextureDepth );
00247     
00248     //! destructeur.
00249     virtual ~GLRendertarget(  );
00250 
00251     //! creation de l'objet opengl.
00252     int createGLResource( )
00253     {
00254         return (m_name != 0) ? 0 : -1;
00255     }
00256     
00257     //! destruction de l'objet opengl.
00258     int releaseGLResource( )
00259     {
00260         return (m_name != 0) ? 0 : -1;
00261     }
00262     
00263     //! verifie la configuration du framebuffer.
00264     int validate( const GLenum target );
00265     
00266     //! renvoie la largeur du framebuffer. renvoie 0, si la largeur du framebuffer n'est pas definie.
00267     int width( ) const
00268     {
00269         return m_width;
00270     }
00271     
00272     //! renvoie la hauteur du framebuffer. renvoie 0, si la hauteur du framebuffer n'est pas definie.
00273     int height( ) const
00274     {
00275         return m_height;
00276     }
00277     
00278     //! renvoie la texture associee a buffer (cf gk::COLOR0, gk::COLOR1, etc.)
00279     GLTexture *texture( const unsigned int buffer );
00280     //! renvoie le renderbuffer associe a buffer (cf gk::COLOR0, gk::COLOR1, gk::DEPTH, etc.)
00281     GLRenderbuffer *renderbuffer( const unsigned int buffer );
00282     
00283     //! renvoie le zbuffer, la texture associee a gk::DEPTH
00284     GLDepthTexture *depthtexture( );
00285 
00286     //! renvoie les draw buffers opengl / textures attachees (cf. glDrawBuffers() et GL_COLOR_ATTACHMENT0, etc.).
00287     /*!
00288     \code
00289     const std::vector<GLenum>& buffers= framebuffer->drawBuffers();
00290     glDrawbuffers((GLsizei) buffers.size(), &buffers.front());
00291     \endcode
00292     */
00293     const std::vector<GLenum>& drawBuffers( )
00294     {
00295         if(m_draw_buffers.empty())
00296             // le frame buffer ne contient probablement qu'un depth attachement.
00297             m_draw_buffers.push_back(GL_NONE);
00298         
00299         return m_draw_buffers;
00300     }
00301     
00302     //! renvoie vrai si des textures couleurs sont attachees.
00303     //! cf. glColorMask( ) pour bloquer l'ecriture dans le framebuffer, si necessaire.
00304     bool colorMask( ) const
00305     {
00306         return m_color_mask;
00307     }
00308     
00309     //! renvoie vrai si un zbuffer est attache.
00310     //! cf. glDepthMask( ) pour bloquer l'ecriture dans le framebuffer, si necessaire.
00311     bool depthMask( ) const
00312     {
00313         return m_depth_mask;
00314     }
00315 };
00316 
00317 //! representation d'un (draw) framebuffer.
00318 class GLFramebuffer : public GLRendertarget
00319 {
00320 public:
00321     //! constructeur.
00322     GLFramebuffer(  )
00323         :
00324         GLRendertarget(GL_DRAW_FRAMEBUFFER)
00325     {}
00326     
00327     //! constructeur, cf GLRendertarget().
00328     GLFramebuffer( const int w, const int h, const unsigned int buffer_bits, 
00329         const TextureFormat& color_format= TextureRGBA, const TextureFormat& depth_format= TextureDepth )
00330         :
00331         GLRendertarget(GL_DRAW_FRAMEBUFFER, w, h, buffer_bits, color_format, depth_format)
00332     {}
00333 
00334     //! destructeur.
00335     ~GLFramebuffer(  ) {}
00336 
00337     //! associe une texture au framebuffer. cf GLRendertarget::attachTexture().
00338     int attachTexture( const unsigned int buffer, GLTexture *texture, const int level= 0 )
00339     {
00340         return GLRendertarget::attachTexture(GL_DRAW_FRAMEBUFFER, buffer, texture, level);
00341     }
00342     //! associe une texture au framebuffer. cf GLRendertarget::attachTexture().
00343     int attachTexture( const GLenum target, const unsigned int buffer, GLDepthTexture *texture, const int level= 0 )
00344     {
00345         return GLRendertarget::attachTexture(GL_DRAW_FRAMEBUFFER, buffer, texture, level);
00346     }
00347     //! associe une texture au framebuffer. cf GLRendertarget::attachTexture().
00348     int attachTexture( const GLenum target, const unsigned int buffer, GLTexture2DArray *texture, const int layer, const int level= 0 )
00349     {
00350         return GLRendertarget::attachTexture(GL_DRAW_FRAMEBUFFER, buffer, texture, layer, level);
00351     }
00352     //! associe une texture au framebuffer. cf GLRendertarget::attachTexture().
00353     int attachTexture( const GLenum target, const unsigned int buffer, GLTextureCube *texture, const  GLenum face, const int level= 0 )
00354     {
00355         return GLRendertarget::attachTexture(GL_DRAW_FRAMEBUFFER, buffer, texture, face, level);
00356     }
00357     
00358     int attachRenderbuffer( const unsigned int buffer, GLRenderbuffer *renderbuffer )
00359     {
00360         return GLRendertarget::attachRenderbuffer(GL_DRAW_FRAMEBUFFER, buffer, renderbuffer);
00361     }
00362 
00363     //! valide la configuration du framebuffer.
00364     int validate( )
00365     {
00366         return GLRendertarget::validate(GL_DRAW_FRAMEBUFFER);
00367     }
00368 };
00369 
00370 //! representation d'un (read) framebuffer.
00371 class GLReadFramebuffer : public GLRendertarget
00372 {
00373 public:
00374     //! constructeur.
00375     GLReadFramebuffer( )
00376         :
00377         GLRendertarget(GL_READ_FRAMEBUFFER)
00378     {}
00379     
00380     //! constructeur. cf GLRendertarget::GLRendertarget( ).
00381     GLReadFramebuffer( const int w, const int h, const unsigned int buffer_bits, 
00382         const TextureFormat& color_format= TextureRGBA, const TextureFormat& depth_format= TextureDepth )
00383         :
00384         GLRendertarget(GL_READ_FRAMEBUFFER, w, h, buffer_bits, color_format, depth_format)
00385     {}
00386 
00387     //! destructeur.
00388     ~GLReadFramebuffer(  ) {}
00389 
00390     //! associe une texture au framebuffer. cf GLRendertarget::attachTexture().
00391     int attachTexture( const unsigned int buffer, GLTexture *texture, const int level= 0 )
00392     {
00393         return GLRendertarget::attachTexture(GL_READ_FRAMEBUFFER, buffer, texture, level);
00394     }
00395     //! associe une texture au framebuffer. cf GLRendertarget::attachTexture().
00396     int attachTexture( const GLenum target, const unsigned int buffer, GLDepthTexture *texture, const int level= 0 )
00397     {
00398         return GLRendertarget::attachTexture(GL_READ_FRAMEBUFFER, buffer, texture, level);
00399     }
00400     //! associe une texture au framebuffer. cf GLRendertarget::attachTexture().
00401     int attachTexture( const GLenum target, const unsigned int buffer, GLTexture2DArray *texture, const int layer, const int level= 0 )
00402     {
00403         return GLRendertarget::attachTexture(GL_READ_FRAMEBUFFER, buffer, texture, layer, level);
00404     }
00405     //! associe une texture au framebuffer. cf GLRendertarget::attachTexture().
00406     int attachTexture( const GLenum target, const unsigned int buffer, GLTextureCube *texture, const  GLenum face, const int level= 0 )
00407     {
00408         return GLRendertarget::attachTexture(GL_READ_FRAMEBUFFER, buffer, texture, face, level);
00409     }
00410     
00411     //! verifie la configuration du framebuffer.
00412     int validate( )
00413     {
00414         return GLRendertarget::validate(GL_READ_FRAMEBUFFER);
00415     }
00416 };
00417 
00418 }
00419 
00420 #endif
 All Classes Namespaces Functions Variables Typedefs Enumerator Friends