texture.cpp

00001 
00002 /* Copyright (c) 2009, Stefan Eilemann <eile@equalizergraphics.com>
00003  *
00004  * This library is free software; you can redistribute it and/or modify it under
00005  * the terms of the GNU Lesser General Public License version 2.1 as published
00006  * by the Free Software Foundation.
00007  *  
00008  * This library is distributed in the hope that it will be useful, but WITHOUT
00009  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00010  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00011  * details.
00012  * 
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this library; if not, write to the Free Software Foundation, Inc.,
00015  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00016  */
00017 
00018 #include "texture.h"
00019 
00020 #include "image.h"
00021 #include "window.h"
00022 
00023 namespace eq
00024 {
00025 Texture::Texture( GLEWContext* const glewContext )
00026         : _id( 0 )
00027         , _internalFormat( 0 )
00028         , _format( 0 )
00029         , _type( 0 )
00030         , _width( 0 )
00031         , _height( 0 )
00032         , _defined( false ) 
00033         , _glewContext( glewContext )
00034 {
00035 }
00036 
00037 Texture::~Texture()
00038 {
00039     if( _id != 0 )
00040         EQWARN << "OpenGL texture was not freed" << std::endl;
00041 
00042     _id      = 0;
00043     _defined = false;
00044 }
00045 
00046 bool Texture::isValid() const
00047 { 
00048     return ( _id != 0 && _defined );
00049 }
00050 
00051 void Texture::flush()
00052 {
00053     if( _id == 0 )
00054         return;
00055 
00056     CHECK_THREAD( _thread );
00057     glDeleteTextures( 1, &_id );
00058     _id = 0;
00059     _defined = false;
00060 }
00061 
00062 void Texture::setFormat( const GLuint format )
00063 {
00064     if( _internalFormat == format )
00065         return;
00066 
00067     _defined = false;
00068     _internalFormat = format;
00069 
00070     switch( format )
00071     {
00072         // depth format
00073         case GL_DEPTH_COMPONENT:
00074             _format = GL_DEPTH_COMPONENT;
00075             _type   = GL_UNSIGNED_INT;
00076             break;
00077 
00078         // color formats
00079         case GL_RGBA8:
00080         case GL_RGBA16:
00081         case GL_BGRA:
00082             _format = GL_BGRA;
00083             _type   = GL_UNSIGNED_BYTE;
00084             break;
00085 
00086         case GL_RGBA16F:
00087             _format = GL_RGBA;
00088             _type   = GL_HALF_FLOAT;
00089             break;
00090         case GL_RGBA32F:
00091             _format = GL_RGBA;
00092             _type   = GL_FLOAT;
00093             break;
00094 
00095         case GL_ALPHA32F_ARB:
00096             _format = GL_ALPHA;
00097             _type   = GL_FLOAT;
00098             break;
00099 
00100         case GL_RGBA32UI:
00101             _format = GL_RGBA_INTEGER_EXT;
00102             _type   = GL_UNSIGNED_INT;
00103             break;
00104 
00105         default:
00106             _format = _internalFormat;
00107             _type   = GL_UNSIGNED_BYTE;
00108     }
00109 }
00110 
00111 void Texture::_generate()
00112 {
00113     CHECK_THREAD( _thread );
00114     if( _id != 0 )
00115         return;
00116 
00117     _defined = false;
00118     glGenTextures( 1, &_id );
00119 }
00120 
00121 void Texture::_resize( const int32_t width, const int32_t height )
00122 {
00123     if( _width < width )
00124     {
00125         _width   = width;
00126         _defined = false;
00127     }
00128 
00129     if( _height < height )
00130     {
00131         _height  = height;
00132         _defined = false;
00133     }
00134 }
00135 
00136 void Texture::copyFromFrameBuffer( const PixelViewport& pvp )
00137 {
00138     CHECK_THREAD( _thread );
00139     EQASSERT( _internalFormat != 0 );
00140 
00141     _generate();
00142     _resize( pvp.w, pvp.h );
00143     glBindTexture( GL_TEXTURE_RECTANGLE_ARB, _id );
00144 
00145     if( !_defined )
00146         resize( _width, _height );
00147 
00148     EQ_GL_CALL( glCopyTexSubImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
00149                                      pvp.x, pvp.y, pvp.w, pvp.h ));
00150     glFinish();
00151 }
00152 
00153 void Texture::upload( const Image* image, const Frame::Buffer which )
00154 {
00155     CHECK_THREAD( _thread );
00156 
00157     setFormat( image->getInternalTextureFormat( which ));
00158     EQASSERT( _internalFormat != 0 );
00159 
00160     const eq::PixelViewport& pvp = image->getPixelViewport();
00161 
00162     _generate();
00163     _resize( pvp.w, pvp.h );
00164     glBindTexture( GL_TEXTURE_RECTANGLE_ARB, _id );
00165 
00166     if( !_defined )
00167         resize( _width, _height );
00168 
00169     EQ_GL_CALL( glTexSubImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
00170                                  pvp.w, pvp.h,
00171                                  image->getFormat( which ),
00172                                  image->getType( which ),
00173                                  image->getPixelPointer( which )));
00174 }
00175 
00176 void Texture::download( void* buffer, const uint32_t format,
00177                         const uint32_t type ) const
00178 {
00179     CHECK_THREAD( _thread );
00180     EQASSERT( _defined );
00181     glBindTexture( GL_TEXTURE_RECTANGLE_ARB, _id );
00182     glGetTexImage( GL_TEXTURE_RECTANGLE_ARB, 0, format, type, buffer );
00183 }
00184 
00185 void Texture::download( void* buffer ) const
00186 {
00187     download( buffer, _format, _type );
00188 }
00189 
00190 void Texture::bindToFBO( const GLenum target, const int width, 
00191                          const int height )
00192 {
00193     CHECK_THREAD( _thread );
00194     EQASSERT( _internalFormat );
00195     EQASSERT( _glewContext );
00196 
00197     _generate();
00198 
00199     glBindTexture( GL_TEXTURE_RECTANGLE_ARB, _id );
00200 
00201     glTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, _internalFormat, width, height,
00202                   0, _format, _type, 0 );
00203 
00204     glFramebufferTexture2DEXT( GL_FRAMEBUFFER, target, GL_TEXTURE_RECTANGLE_ARB,
00205                                _id, 0 );
00206 
00207     _width = width;
00208     _height = height;
00209     _defined = true;
00210 }
00211 
00212 void Texture::resize( const int width, const int height )
00213 {
00214     CHECK_THREAD( _thread );
00215     EQASSERT( _id );
00216     EQASSERT( _internalFormat );
00217     EQASSERT( width > 0 && height > 0 );
00218 
00219     if( _width == width && _height == height && _defined )
00220         return;
00221 
00222     glBindTexture( GL_TEXTURE_RECTANGLE_ARB, _id );
00223     glTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, _internalFormat, width, height,
00224                   0, _format, _type, 0 );
00225 
00226     _width  = width;
00227     _height = height;
00228     _defined = true;
00229 }
00230 
00231 }
Generated on Mon Aug 10 18:58:41 2009 for Equalizer 0.9 by  doxygen 1.5.8