gKitGL
|
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