00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
00073 case GL_DEPTH_COMPONENT:
00074 _format = GL_DEPTH_COMPONENT;
00075 _type = GL_UNSIGNED_INT;
00076 break;
00077
00078
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 }