00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00048 #include "omicron/internal.h"
00049 #include "omicron/render.h"
00050 #include "omicron/texture.h"
00051 #include "omicron/image.h"
00052 #include "omicron/file.h"
00053 #include "omicron/array.h"
00054
00055
00056
00057
00058
00059
00060
00061 texture_manager_c::texture_manager_c()
00062 {
00063 SafeDelete(gv.texman);
00064
00065 gv.texman = this;
00066
00067 textures = new array_c<texture_t>;
00068 }
00069
00070 texture_manager_c::~texture_manager_c()
00071 {
00072 gv.texman = NULL;
00073 freeall();
00074 SafeDelete(textures);
00075 }
00076
00077
00078
00079
00080 sshort texture_manager_c::find
00081 (
00082 const char * name
00083 )
00084 {
00085 for (sshort i=0; i<textures->get_count(); i++)
00086 {
00087 texture_t *tex = textures->get(i);
00088
00089 if (tex->texture != 0 && !strcmpi(name, tex->name))
00090 return i;
00091 }
00092
00093 return TEXTURE_NOTFOUND;
00094 }
00095
00096
00097
00098
00099 sshort texture_manager_c::create
00100 (
00101 ushort width,
00102 ushort height,
00103 const char *szName
00104 )
00105 {
00106 texture_t *tex = new texture_t;
00107
00108 tex->width = width;
00109 tex->height = height;
00110 sprintf(tex->name, "%s", szName);
00111 tex->texture = 0;
00112
00113 return (sshort)textures->add(tex);
00114 }
00115
00116
00117
00118
00119
00120 sshort texture_manager_c::load
00121 (
00122 const char *name,
00123 bool nocomp
00124 )
00125 {
00126 image_c *img;
00127
00128
00129 img = new image_c;
00130 AssertReturnValue1(img, INVALID_INDEX);
00131
00132 if (!img->load(name))
00133 {
00134 SafeDelete(img);
00135 return INVALID_INDEX;
00136 }
00137
00138 sshort num;
00139
00140
00141 if ( ( num = create( img->get_width(), img->get_height(), name ))
00142 == INVALID_INDEX )
00143 {
00144 SafeDelete(img);
00145 return INVALID_INDEX;
00146 }
00147
00148 set_bits(num, img->get_pixels(), true, nocomp);
00149
00150 SafeDelete(img);
00151
00152 return num;
00153 }
00154
00155
00156
00157
00158 void texture_manager_c::freeall
00159 (
00160 )
00161 {
00162 _log_printf(MSG_DEBUG, "freeing textures...");
00163
00164 ulong c = 0;
00165
00166 for (sshort i=0; i<textures->get_count(); i++)
00167 {
00168 texture_t *tex = textures->get(i);
00169
00170 if (!tex)
00171 continue;
00172
00173 if (tex->texture)
00174 glDeleteTextures(1, (GLuint*)&tex->texture);
00175
00176 textures->remove_ptr(tex);
00177
00178 SafeDelete(tex);
00179
00180 c++;
00181 }
00182
00183 _log_printf(MSG_DEBUG, "%u textures freed...", c);
00184 }
00185
00186
00187
00188
00189 void texture_manager_c::freetex
00190 (
00191 sshort num
00192 )
00193 {
00194 texture_t *tex = textures->get(num);
00195
00196 if (!tex)
00197 return;
00198
00199 if (tex->texture)
00200 glDeleteTextures(1, (GLuint*)&tex->texture);
00201
00202 textures->remove_ptr(tex);
00203 SafeDelete(tex);
00204 }
00205
00206
00207
00208
00209 void texture_manager_c::set
00210 (
00211 sshort num,
00212 sshort
00213 )
00214 {
00215 if (num<-1 || num>textures->get_count())
00216 num = -1;
00217
00218 if (num == -1)
00219 {
00220 glDisable(GL_TEXTURE_2D);
00221 return;
00222 }
00223
00224 texture_t *tex = textures->get(num);
00225
00226 glEnable(GL_TEXTURE_2D);
00227 glBindTexture(GL_TEXTURE_2D, tex->texture);
00228 }
00229
00230
00231
00232
00233 void texture_manager_c::set_bits
00234 (
00235 sshort num,
00236 const char * bits,
00237 bool mipmaps,
00238 bool nocompression
00239 )
00240 {
00241 if (num<-1 || num>textures->get_count())
00242 return;
00243
00244 ulong internalformat = GL_RGBA;
00245
00246 AssertReturn1(textures);
00247
00248 texture_t *tex = textures->get(num);
00249
00250 AssertReturn1(tex);
00251
00252 if (!tex->texture)
00253 {
00254 GLuint t;
00255
00256 glGenTextures(1, &t);
00257 tex->texture = t;
00258 }
00259 glBindTexture(GL_TEXTURE_2D, tex->texture);
00260 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00261
00262 #if defined(WIN32)
00263 if (extgl_Extensions.ARB_texture_compression && !nocompression)
00264 {
00265 if (extgl_Extensions.EXT_texture_compression_s3tc)
00266 internalformat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
00267 else
00268 internalformat = GL_COMPRESSED_RGBA_ARB;
00269 }
00270 #endif
00271
00272 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, tex->width, tex->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bits);
00273
00274 if (mipmaps)
00275 gluBuild2DMipmaps(GL_TEXTURE_2D, internalformat, tex->width, tex->height, GL_RGBA, GL_UNSIGNED_BYTE, bits);
00276 }
00277
00278
00279
00280
00281 void texture_manager_c::set_bits24
00282 (
00283 sshort num,
00284 const char * bits,
00285 bool mipmaps,
00286 bool nocompression
00287 )
00288 {
00289 if (num<0 || num>=textures->get_count())
00290 return;
00291
00292 ulong internalformat = GL_RGB;
00293 texture_t *tex = textures->get(num);
00294
00295 glBindTexture(GL_TEXTURE_2D, tex->texture);
00296 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00297
00298 #if defined(WIN32)
00299 if (extgl_Extensions.ARB_texture_compression && !nocompression)
00300 {
00301 if (extgl_Extensions.EXT_texture_compression_s3tc)
00302 internalformat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
00303 else
00304 internalformat = GL_COMPRESSED_RGB_ARB;
00305 }
00306 #endif
00307
00308 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, tex->width, tex->height, 0, GL_RGB, GL_UNSIGNED_BYTE, bits);
00309
00310 if (mipmaps)
00311 gluBuild2DMipmaps(GL_TEXTURE_2D, internalformat, tex->width, tex->height, GL_RGB, GL_UNSIGNED_BYTE, bits);
00312 }
00313
00314
00315
00316
00317 image_c *texture_manager_c::get_image
00318 (
00319 sshort num
00320 )
00321 {
00322 if (num<0 || num>=textures->get_count())
00323 num = 0;
00324
00325 image_c *img = new image_c;
00326 texture_t *tex = textures->get(num);
00327
00328 if (!img) return NULL;
00329
00330 img->buflen = tex->width*tex->height*4;
00331 img->width = tex->width;
00332 img->height = tex->height;
00333 img->hasalpha = false;
00334 img->buf = new char[img->buflen];
00335
00336 glBindTexture(GL_TEXTURE_2D, tex->texture);
00337 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00338 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img->buf);
00339
00340 return img;
00341 }
00342
00343
00344
00345
00346 void texture_manager_c::set_image
00347 (
00348 sshort num,
00349 const image_c * img,
00350 bool mipmaps,
00351 bool nocompression
00352 )
00353 {
00354 AssertReturn1(img);
00355
00356 if (num<0 || num>=textures->get_count())
00357 num = 0;
00358
00359 texture_t *tex = textures->get(num);
00360
00361 if (!tex)
00362 return;
00363
00364 tex->width = img->get_width();
00365 tex->height = img->get_height();
00366
00367 set_bits(num, img->get_pixels(), mipmaps, nocompression);
00368 }
00369
00370
00371 ushort texture_manager_c::get_width(sshort num)
00372 {
00373 if (num<0 || num>=textures->get_count())
00374 return 0;
00375
00376 texture_t *tex = textures->get(num);
00377 return tex->width;
00378 }
00379
00380 ushort texture_manager_c::get_height(sshort num)
00381 {
00382 if (num<0 || num>=textures->get_count())
00383 return 0;
00384
00385 texture_t *tex = textures->get(num);
00386 return tex->height;
00387 }
00388
00389 ulong texture_manager_c::get_gltexture(sshort num)
00390 {
00391 if (num<0 || num>=textures->get_count())
00392 return 0;
00393
00394 texture_t *tex = textures->get(num);
00395 return tex->texture;
00396 }