gl_surface.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 * VCGLib                                                            o o     *
00003 * Visual and Computer Graphics Library                            o     o   *
00004 *                                                                _   O  _   *
00005 * Copyright(C) 2004                                                \/)\/    *
00006 * Visual Computing Lab                                            /\/|      *
00007 * ISTI - Italian National Research Council                           |      *
00008 *                                                                    \      *
00009 * All rights reserved.                                                      *
00010 *                                                                           *
00011 * This program is free software; you can redistribute it and/or modify      *   
00012 * it under the terms of the GNU General Public License as published by      *
00013 * the Free Software Foundation; either version 2 of the License, or         *
00014 * (at your option) any later version.                                       *
00015 *                                                                           *
00016 * This program is distributed in the hope that it will be useful,           *
00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
00019 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
00020 * for more details.                                                         *
00021 *                                                                           *
00022 ****************************************************************************/
00023 
00024 /****************************************************************************
00025   History
00026 
00027 $Log: not supported by cvs2svn $
00028 Revision 1.1  2007/07/26 16:22:47  m_di_benedetto
00029 First Commit.
00030 
00031 
00032 
00033 ****************************************************************************/
00034 
00035 #ifndef VCGLIB_GL_SURFACE_H
00036 #define VCGLIB_GL_SURFACE_H
00037 
00038 #include <vector>
00039 #include <GL/glew.h>
00040 
00041 namespace vcg
00042 {
00043 
00044 /****************************************************************************
00045 The gl_surface class simplify the render-to-texture OpenGL functionality.
00046 
00047 It provides a framebuffer composed of single or multiple color buffers and
00048 a depth buffer; color-only and depth-only framebuffers can also be created.
00049 
00050 Sample usage:
00051 
00052 ****************************************************************
00053 // *** declaration
00054 
00055 gl_surface my_srf;
00056 
00057 
00058 ***********************
00059 // *** initialization: single color render target, with depth buffer
00060 {
00061         std::vector<GLenum> color_formats;
00062         color_formats.push_back(GL_RGBA8);
00063 
00064         my_srf.set(width, height, color_formats, GL_DEPTH_COMPONENT);
00065 }
00066 ***********************
00067 
00068 
00069 ***********************
00070 //  *** initialization: two color render targets, without depth buffer
00071 // NOTE: the maximum number of color targets is implementation dependent.
00072 // NOTE: DX10 class hardware allows different formats for each color target.
00073 {
00074         std::vector<GLenum> color_formats;
00075         color_formats.push_back(GL_RGBA8);
00076         color_formats.push_back(GL_RGBA8);
00077 
00078         my_srf.set(width, height, color_formats, GL_NONE);
00079 }
00080 ***********************
00081 
00082 
00083 ***********************
00084 // *** usage: render-to-targets
00085 {
00086         my_srf.begin_write();
00087                 application_draw_code();
00088         my_srf.end_write();
00089 }
00090 ***********************
00091 
00092 
00093 ***********************
00094 // *** usage: using rendered textures
00095 {
00096         // 2 buffers
00097 
00098         // bind the second
00099         glActiveTexture(GL_TEXTURE1);
00100         my_srf.begin_read_color(1); // actually does a glBindTexture();
00101 
00102         // bind the first
00103         glActiveTexture(GL_TEXTURE0);
00104         my_srf.begin_read_color(0);
00105 
00106                 application_draw_code();
00107 
00108         // unbind the second
00109         glActiveTexture(GL_TEXTURE1);
00110         my_srf.end_read_color(1);
00111 
00112         // unbind first
00113         glActiveTexture(GL_TEXTURE0);
00114         my_srf.end_read_color(0);
00115 }
00116 
00117 ***********************
00118 // *** usage: use depth map
00119 {
00120         my_srf.begin_read_depth();
00121 
00122                 // use depth map here
00123                 application_draw_code();
00124 
00125         my_srf.end_read_depth();
00126 }
00127 
00128 ***********************
00129 // *** usage: cleanup
00130 {
00131         my_srf.clear();
00132         // clear() is also safely called in the destructor.
00133 }
00134 ***********************
00135 
00136 Other commodity methods for getting/setting pixels are also provided.
00137 
00138 ****************************************************************************/
00139 
00140 class gl_surface
00141 {
00142         public:
00143 
00144                 typedef gl_surface this_type;
00145 
00146                 gl_surface(void) : width(0), height(0), depth_tex(0), fb(0)
00147                 {
00148                         ;
00149                 }
00150 
00151                 ~gl_surface(void)
00152                 {
00153                         this->clear();
00154                 }
00155 
00156                 bool set(int width, int height, const std::vector<GLenum> & color_formats, GLenum depth_format)
00157                 {
00158                         this->clear();
00159 
00160                         this->width  = width;
00161                         this->height = height;
00162 
00163                         this->color_formats = color_formats;
00164 
00165                         this->color_texs.resize(color_formats.size());
00166 
00167                         for (size_t i=0; i<this->color_texs.size(); ++i)
00168                         {
00169                                 glGenTextures   (1, &(this->color_texs[i]));
00170                                 glBindTexture   (GL_TEXTURE_2D, this->color_texs[i]);
00171                                 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,     GL_CLAMP_TO_EDGE);
00172                                 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,     GL_CLAMP_TO_EDGE);
00173                                 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00174                                 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00175                                 glTexImage2D    (GL_TEXTURE_2D, 0, this->color_formats[i], this->width, this->height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);
00176                         }
00177 
00178                         this->depth_format = depth_format;
00179                         if (this->depth_format != GL_NONE)
00180                         {
00181                                 glGenTextures   (1, &(this->depth_tex));
00182                                 glBindTexture   (GL_TEXTURE_2D, this->depth_tex);
00183                                 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,           GL_CLAMP_TO_EDGE);
00184                                 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,           GL_CLAMP_TO_EDGE);
00185                                 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,       GL_NEAREST);
00186                                 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,       GL_NEAREST);
00187                                 glTexParameteri (GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB,   GL_LUMINANCE);
00188                                 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
00189                                 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
00190                                 glTexImage2D    (GL_TEXTURE_2D, 0, this->depth_format, this->width, this->height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
00191                         }
00192 
00193                         glGenFramebuffersEXT(1, &(this->fb));
00194                         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, this->fb);
00195 
00196                         std::vector<GLenum> sites(this->color_texs.size());
00197                         for (size_t i=0; i<this->color_texs.size(); ++i)
00198                         {
00199                                 sites[i] = GL_COLOR_ATTACHMENT0_EXT + ((GLenum)i);
00200                                 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, sites[i], GL_TEXTURE_2D, this->color_texs[i], 0);
00201                         }
00202 
00203                         if (this->depth_format != GL_NONE)
00204                         {
00205                                 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, this->depth_tex, 0);
00206                         }
00207 
00208                         if (!sites.empty())
00209                         {
00210                                 glDrawBuffers((GLsizei)(sites.size()), &(sites[0]));
00211                         }
00212 
00213                         const GLenum s = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
00214                         const bool res = (s == GL_FRAMEBUFFER_COMPLETE_EXT);
00215 
00216                         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
00217 
00218                         if (!res)
00219                         {
00220                                 glDeleteFramebuffersEXT(1, &(this->fb));
00221                                 this->fb = 0;
00222 
00223                                 for (size_t i=0; i<this->color_texs.size(); ++i)
00224                                 {
00225                                         glDeleteTextures(1, &(this->color_texs[i]));
00226                                 }
00227                                 this->color_texs.clear();
00228 
00229                                 this->color_formats.clear();
00230 
00231                                 if (this->depth_tex != 0)
00232                                 {
00233                                         glDeleteTextures(1, &(this->depth_tex));
00234                                         this->depth_tex = 0;
00235                                 }
00236 
00237                                 this->width  = 0;
00238                                 this->height = 0;
00239 
00240                                 return false;
00241                         }
00242 
00243                         return true;
00244                 }
00245 
00246                 bool set_simple(int width, int height)
00247                 {
00248                         std::vector<GLenum> c_formats;
00249                         c_formats.push_back(GL_RGBA8);
00250 
00251                         return this->set(width, height, c_formats, GL_DEPTH_COMPONENT);
00252                 }
00253 
00254                 bool set_color_only(int width, int height, GLenum color_format)
00255                 {
00256                         std::vector<GLenum> c_formats;
00257                         c_formats.push_back(color_format);
00258 
00259                         return this->set(width, height, c_formats, GL_NONE);
00260                 }
00261 
00262                 bool set_color_only(int width, int height, const std::vector<GLenum> & color_formats)
00263                 {
00264                         return this->set(width, height, color_formats, GL_NONE);
00265                 }
00266 
00267                 bool set_depth_only(int width, int height, GLenum depth_format)
00268                 {
00269                         std::vector<GLenum> c_formats;
00270 
00271                         return this->set(width, height, c_formats, depth_format);
00272                 }
00273 
00274                 bool clear(void)
00275                 {
00276                         if (!this->is_valid()) return false;
00277 
00278                         glDeleteFramebuffersEXT(1, &(this->fb));
00279                         this->fb = 0;
00280 
00281                         for (size_t i=0; i<this->color_texs.size(); ++i)
00282                         {
00283                                 glDeleteTextures(1, &(this->color_texs[i]));
00284                         }
00285                         this->color_texs.clear();
00286 
00287                         this->color_formats.clear();
00288 
00289                         if (this->depth_tex != 0)
00290                         {
00291                                 glDeleteTextures(1, &(this->depth_tex));
00292                                 this->depth_tex = 0;
00293                         }
00294 
00295                         this->width  = 0;
00296                         this->height = 0;
00297 
00298                         return true;
00299                 }
00300 
00301                 bool is_valid(void) const
00302                 {
00303                         return (this->fb != 0);
00304                 }
00305 
00306                 int get_width(void) const
00307                 {
00308                         return this->width;
00309                 }
00310 
00311                 int get_height(void) const
00312                 {
00313                         return this->height;
00314                 }
00315 
00316                 int color_attachments_count(void) const
00317                 {
00318                         return ((int)(this->color_texs.size()));
00319                 }
00320 
00321                 GLenum get_color_attachment_format(int attachment) const
00322                 {
00323                         if (!this->is_valid()) return GL_NONE;
00324                         if ((attachment < 0) || (attachment >= this->color_attachments_count())) return GL_NONE;
00325 
00326                         return this->color_formats[attachment];
00327                 }
00328 
00329                 bool has_depth_attachment(void) const
00330                 {
00331                         return (this->depth_tex != 0);
00332                 }
00333 
00334                 GLenum get_depth_attachment_format(void) const
00335                 {
00336                         if (!this->is_valid()) return GL_NONE;
00337                         if (!this->has_depth_attachment()) return GL_NONE;
00338 
00339                         return this->depth_format;
00340                 }
00341 
00342                 bool set_color_pixels(int attachment, GLenum format, GLenum type, const void * pixels)
00343                 {
00344                         if (!this->begin_read_color(attachment)) return false;
00345 
00346                         glTexImage2D(GL_TEXTURE_2D, 0, this->color_formats[attachment], this->width, this->height, 0, format, type, pixels);
00347 
00348                         this->end_read_color(attachment);
00349 
00350                         return true;
00351                 }
00352 
00353                 bool get_color_pixels(int attachment, GLenum format, GLenum type, void * pixels)
00354                 {
00355                         if (!this->begin_read_color(attachment)) return false;
00356 
00357                         glGetTexImage(GL_TEXTURE_2D, 0, format, type, pixels);
00358 
00359                         this->end_read_color(attachment);
00360 
00361                         return true;
00362                 }
00363 
00364                 bool set_depth_pixels(GLenum format, GLenum type, const void * pixels)
00365                 {
00366                         if (!this->is_valid()) return false;
00367                         if (!this->has_depth_attachment()) return false;
00368 
00369                         glTexImage2D(GL_TEXTURE_2D, 0, this->depth_format, this->width, this->height, 0, format, type, pixels);
00370 
00371                         return true;
00372                 }
00373 
00374                 bool get_depth_pixels(GLenum format, GLenum type, void * pixels)
00375                 {
00376                         if (!this->begin_read_depth()) return false;
00377 
00378                         glGetTexImage(GL_TEXTURE_2D, 0, format, type, pixels);
00379 
00380                         this->end_read_depth();
00381 
00382                         return true;
00383                 }
00384 
00385                 bool begin_read_color(int attachment)
00386                 {
00387                         if (!this->is_valid()) return false;
00388                         if ((attachment < 0) || (attachment >= this->color_attachments_count())) return false;
00389 
00390                         glBindTexture(GL_TEXTURE_2D, this->color_texs[attachment]);
00391 
00392                         return true;
00393                 }
00394 
00395                 bool end_read_color(int attachment)
00396                 {
00397                         if (!this->is_valid()) return false;
00398                         if ((attachment < 0) || (attachment >= this->color_attachments_count())) return false;
00399 
00400                         glBindTexture(GL_TEXTURE_2D, 0);
00401 
00402                         return true;
00403                 }
00404 
00405                 bool begin_read_depth(void)
00406                 {
00407                         if (!this->is_valid()) return false;
00408                         if (!this->has_depth_attachment()) return false;
00409 
00410                         glBindTexture(GL_TEXTURE_2D, this->depth_tex);
00411 
00412                         return true;
00413                 }
00414 
00415                 bool end_read_depth(void)
00416                 {
00417                         if (!this->is_valid()) return false;
00418                         if (!this->has_depth_attachment()) return false;
00419 
00420                         glBindTexture(GL_TEXTURE_2D, 0);
00421 
00422                         return true;
00423                 }
00424 
00425                 bool begin_write(void)
00426                 {
00427                         if (!this->is_valid()) return false;
00428 
00429                         glPushAttrib(GL_VIEWPORT_BIT);
00430 
00431                         glViewport(0, 0, this->width, this->height);
00432 
00433                         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, this->fb);
00434 
00435                         return true;
00436                 }
00437 
00438                 bool end_write(void)
00439                 {
00440                         if (!this->is_valid()) return false;
00441 
00442                         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
00443 
00444                         glPopAttrib();
00445 
00446                         return true;
00447                 }
00448 
00449                 bool draw_color_attachment(int x, int y, int width, int height, int attachment)
00450                 {
00451                         if (!this->is_valid()) return false;
00452                         if ((attachment < 0) || (attachment >= this->color_attachments_count())) return false;
00453 
00454                         glPushAttrib(GL_ALL_ATTRIB_BITS);
00455 
00456                         glViewport(x, y, width, height);
00457 
00458                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00459 
00460                         glMatrixMode(GL_PROJECTION);
00461                         glPushMatrix();
00462                         glLoadIdentity();
00463 
00464                         glMatrixMode(GL_MODELVIEW);
00465                         glPushMatrix();
00466                         glLoadIdentity();
00467 
00468                         this->begin_read_color(attachment);
00469                                 glBegin(GL_QUADS);
00470                                         glTexCoord2f(0.0f, 0.0f);    glVertex2f(-1.0f, -1.0f);
00471                                         glTexCoord2f(1.0f, 0.0f);    glVertex2f( 1.0f, -1.0f);
00472                                         glTexCoord2f(1.0f, 1.0f);    glVertex2f( 1.0f,  1.0f);
00473                                         glTexCoord2f(0.0f, 1.0f);    glVertex2f(-1.0f,  1.0f);
00474                                 glEnd();
00475                         this->end_read_color(attachment);
00476 
00477                         glMatrixMode(GL_PROJECTION);
00478                         glPopMatrix();
00479 
00480                         glMatrixMode(GL_MODELVIEW);
00481                         glPopMatrix();
00482 
00483                         glPopAttrib();
00484       return true;
00485                 }
00486 
00487                 bool draw_depth_attachment(int x, int y, int width, int height)
00488                 {
00489                         if (!this->is_valid()) return false;
00490                         if (!this->has_depth_attachment()) return false;
00491 
00492                         glPushAttrib(GL_ALL_ATTRIB_BITS);
00493 
00494                         glViewport(x, y, width, height);
00495 
00496                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00497 
00498                         glMatrixMode(GL_PROJECTION);
00499                         glPushMatrix();
00500                         glLoadIdentity();
00501 
00502                         glMatrixMode(GL_MODELVIEW);
00503                         glPushMatrix();
00504                         glLoadIdentity();
00505 
00506                         this->begin_read_depth();
00507                                 glBegin(GL_QUADS);
00508                                         glTexCoord2f(0.0f, 0.0f);    glVertex2f(-1.0f, -1.0f);
00509                                         glTexCoord2f(1.0f, 0.0f);    glVertex2f( 1.0f, -1.0f);
00510                                         glTexCoord2f(1.0f, 1.0f);    glVertex2f( 1.0f,  1.0f);
00511                                         glTexCoord2f(0.0f, 1.0f);    glVertex2f(-1.0f,  1.0f);
00512                                 glEnd();
00513                         this->end_read_depth();
00514 
00515                         glMatrixMode(GL_PROJECTION);
00516                         glPopMatrix();
00517 
00518                         glMatrixMode(GL_MODELVIEW);
00519                         glPopMatrix();
00520 
00521                         glPopAttrib();
00522       return true;
00523                 }
00524 
00525         protected:
00526 
00527                 int width;
00528                 int height;
00529                 std::vector<GLenum> color_formats;
00530                 std::vector<GLuint> color_texs;
00531                 GLenum depth_format;
00532                 GLuint depth_tex;
00533                 GLuint fb;
00534 };
00535 
00536 } // end namespace vcg
00537 
00538 #endif // VCGLIB_GL_SURFACE_H


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:31:25