00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "texture.h"
00021
00022 #include "SDL_image.h"
00023
00024
00025
00026 Texture::Texture():
00027 uiWidth( 0 ),
00028 uiHeight( 0 ),
00029 uiTexture( 0 )
00030 {
00031 OPENCITY_DEBUG("ctor");
00032 }
00033
00034
00035
00036 Texture::Texture( const string & rcFile )
00037 {
00038 OPENCITY_DEBUG("param ctor");
00039 this->uiTexture = Texture::Load( rcFile, this->uiWidth, this->uiHeight );
00040 }
00041
00042
00043
00044 Texture::~Texture()
00045 {
00046 OPENCITY_DEBUG("dtor");
00047
00048
00049 glDeleteTextures( 1, &this->uiTexture );
00050 }
00051
00052
00053
00054
00055
00056 const GLuint
00057 Texture::Load( const string & rcFile )
00058 {
00059 uint w, h;
00060 return Texture::Load( rcFile, w, h );
00061 }
00062
00063
00064
00065 const GLuint
00066 Texture::Load
00067 (
00068 const string & rcFile,
00069 uint & ruiW,
00070 uint & ruiH
00071 )
00072 {
00073 SDL_Surface* pImage = NULL;
00074 SDL_Surface* pMirror = NULL;
00075 GLuint uiTexture = 0;
00076
00077 OPENCITY_DEBUG( rcFile.c_str() );
00078
00079
00080
00081 pImage = IMG_Load( rcFile.c_str() );
00082 assert( pImage != NULL );
00083
00084
00085 ruiW = pImage->w;
00086 ruiH = pImage->h;
00087
00088
00089
00090 assert( pImage->format->BytesPerPixel == 4 );
00091
00092
00093
00094
00095
00096
00097
00098
00099 pMirror = Texture::HorizontalMirror( pImage );
00100
00101
00102
00103 Texture::Surface2Texture( pMirror, uiTexture );
00104 SDL_FreeSurface( pImage );
00105 SDL_FreeSurface( pMirror );
00106
00107 return uiTexture;
00108 }
00109
00110
00111
00112 SDL_Surface*
00113 Texture::HorizontalMirror(
00114 const SDL_Surface* const psurface
00115 )
00116 {
00117 SDL_Surface* psNew = NULL;
00118 int h, iBytesPerRow;
00119 OC_CHAR* pPixelDest;
00120 OC_CHAR* pPixelSrc;
00121
00122
00123 if (SDL_MUSTLOCK( psurface )) {
00124 SDL_LockSurface( const_cast<SDL_Surface*>(psurface) );
00125 }
00126
00127
00128 psNew = SDL_CreateRGBSurface(
00129 SDL_SWSURFACE,
00130 psurface->w,
00131 psurface->h,
00132 psurface->format->BitsPerPixel,
00133 psurface->format->Rmask,
00134 psurface->format->Gmask,
00135 psurface->format->Bmask,
00136 psurface->format->Amask );
00137 assert( psNew != NULL );
00138 SDL_LockSurface( psNew );
00139
00140
00141 iBytesPerRow = psurface->w * psurface->format->BytesPerPixel;
00142 pPixelDest = (OC_CHAR*)psNew->pixels;
00143 pPixelSrc = (OC_CHAR*)psurface->pixels + ((psurface->h-1) * iBytesPerRow);
00144
00145
00146
00147 for ( h = psurface->h-1; h >= 0; h-- ) {
00148 memcpy( pPixelDest, pPixelSrc, iBytesPerRow );
00149 pPixelDest += iBytesPerRow;
00150 pPixelSrc -= iBytesPerRow;
00151
00152 }
00153
00154 SDL_UnlockSurface( psNew );
00155
00156
00157 if (SDL_MUSTLOCK( psurface )) {
00158 SDL_UnlockSurface( const_cast<SDL_Surface*>(psurface) );
00159 }
00160
00161 return psNew;
00162 }
00163
00164
00165
00166 void
00167 Texture::Surface2Texture(
00168 const SDL_Surface* const psurface,
00169 GLuint & ruiTexture )
00170 {
00171 uint glW, glH;
00172 void* pPixels = NULL;
00173
00174
00175 if (glIsTexture( ruiTexture ) == GL_TRUE)
00176 glDeleteTextures( 1, &ruiTexture );
00177
00178
00179 glGenTextures( 1, &ruiTexture );
00180 glBindTexture( GL_TEXTURE_2D, ruiTexture );
00181
00182 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00183 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00184
00185
00186
00187
00188
00189 SDL_LockSurface( const_cast<SDL_Surface*>(psurface) );
00190
00191
00192 Texture::GetCorrectSize( psurface->w, psurface->h, glW, glH );
00193
00194
00195 if ((psurface->w != (int)glW) || (psurface->h != (int)glH)) {
00196 OPENCITY_DEBUG("Texture's size has been fixed");
00197 pPixels = malloc( glW * glH * psurface->format->BytesPerPixel );
00198
00199
00200 (void)gluScaleImage(
00201 GL_RGBA,
00202 psurface->w,
00203 psurface->h,
00204 GL_UNSIGNED_BYTE,
00205 psurface->pixels,
00206 glW,
00207 glH,
00208 GL_UNSIGNED_BYTE,
00209 pPixels
00210 );
00211
00212
00213 glTexImage2D(
00214 GL_TEXTURE_2D,
00215 0,
00216 GL_RGBA,
00217 glW,
00218 glH,
00219 0,
00220 GL_RGBA,
00221 GL_UNSIGNED_BYTE,
00222 pPixels
00223 );
00224
00225 free( pPixels );
00226 pPixels = NULL;
00227 }
00228 else {
00229
00230 glTexImage2D(
00231 GL_TEXTURE_2D,
00232 0,
00233 GL_RGBA,
00234 psurface->w,
00235 psurface->h,
00236 0,
00237 GL_RGBA,
00238 GL_UNSIGNED_BYTE,
00239 psurface->pixels
00240 );
00241 }
00242
00243 SDL_UnlockSurface( const_cast<SDL_Surface*>(psurface) );
00244
00245
00246 GLenum glError = glGetError();
00247 if (glError != GL_NO_ERROR) {
00248 GLint maxTexSize;
00249 glGetIntegerv( GL_MAX_TEXTURE_SIZE, &maxTexSize );
00250
00251 OPENCITY_DEBUG( "CRITIC GL ERROR while loading texture" );
00252 cout << "Max texture size is: " << maxTexSize << endl;
00253 cout << "GL error code: 0x";
00254 cout.flags( cout.hex );
00255 cout << glError << endl;
00256 cout.flags( cout.dec );
00257 }
00258 }
00259
00260
00261
00262 void
00263 Texture::GetCorrectSize(
00264 const uint w, const uint h,
00265 uint & rW, uint & rH )
00266 {
00267 rW = 64;
00268 while (rW < w) rW = rW << 1;
00269
00270 rH = 64;
00271 while (rH < h) rH = rH << 1;
00272 }
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301