3 * Daniel Nelson - 9/14/0
5 * Copyright (C) 2000 Daniel Nelson
6 * Copyright (C) 2004 Andrew Sayman
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 * Daniel Nelson - aluminumangel.org
26 * Loads textures from uncompressed TGA files.
29 #include "TextureLoader.h"
36 #include <SDL/SDL_image.h>
48 // the header of an uncompressed TGA file
49 const GLubyte header_image
[11] = { 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
51 GLubyte
*TextureLoader::loadImageAlpha ( const char *file_name
, int _height
,
54 GLubyte
*full_texture
= loadImage(file_name
, _height
, _width
);
56 int texture_size
= _width
* _height
;
58 GLubyte
*alpha_texture
= new GLubyte
[texture_size
];
60 for (int n
= 0; n
< texture_size
; n
++)
61 alpha_texture
[n
] = full_texture
[4 * n
+ 3];
63 if (full_texture
!= null
) {
64 delete [] full_texture
;
71 GLubyte
*TextureLoader::loadImageNoAlpha ( const char *file_name
,
72 int _height
, int _width
)
74 GLubyte
*full_texture
= loadImage(file_name
, _height
, _width
);
76 int texture_size
= _width
* _height
;
78 GLubyte
*no_alpha_texture
= new GLubyte
[texture_size
* 3];
80 for (int n
= 0; n
< texture_size
; n
++) {
81 float alpha
= full_texture
[4 * n
+ 3] * (1.0f
/ 255.0f
);
82 no_alpha_texture
[3 * n
+ 0] = (GLubyte
) (alpha
* full_texture
[4 * n
+ 0]);
83 no_alpha_texture
[3 * n
+ 1] = (GLubyte
) (alpha
* full_texture
[4 * n
+ 1]);
84 no_alpha_texture
[3 * n
+ 2] = (GLubyte
) (alpha
* full_texture
[4 * n
+ 2]);
87 if (full_texture
!= null
) {
88 delete [] full_texture
;
92 return no_alpha_texture
;
95 GLubyte
*TextureLoader::loadImage ( const char *file_name
, int _height
,
98 SDL_Surface
*img
= IMG_Load(file_name
);
101 cerr
<< "Error opening texture file '" << file_name
<< "'." << endl
;
108 if (width
!= _width
|| height
!= _height
) {
109 cerr
<< "Texture file '" << file_name
<< "' does not have the expected "
110 "height and width. [" << height
<< 'x' << width
<< "] vs expected ["
111 << _height
<< 'x' << _width
<< "]." << endl
;
115 // Convert the loaded image to a standard 32 bit format
117 Uint32 rmask
, gmask
, bmask
, amask
;
118 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
130 SDL_Surface
*formatImg
= SDL_CreateRGBSurface(
131 SDL_SWSURFACE
, 0, 0, 32, rmask
, gmask
, bmask
, amask
);
133 if (formatImg
== NULL
) {
134 cerr
<< "Out of memory while opening texture file '" << file_name
136 SDL_FreeSurface(img
);
140 SDL_Surface
*tmp
= SDL_ConvertSurface(img
, formatImg
->format
, SDL_SWSURFACE
);
142 SDL_FreeSurface(img
);
143 SDL_FreeSurface(formatImg
);
145 // TODO: This memcpy is rather pointless. Maybe find a way to avoid it.
147 int texture_size
= width
* height
* 32 / 8;
148 GLubyte
*texture
= new GLubyte
[texture_size
];
149 memcpy(texture
, tmp
->pixels
, texture_size
);
151 SDL_FreeSurface(tmp
);
153 //cout << "Succesfully loaded '" << file_name << "'." << endl;
158 void TextureLoader::createTGA ( const char *tga_file_name
, GLubyte
*texture
,
159 int _height
, int _width
, const char *tga_id
)
162 ofstream
file(tga_file_name
);
164 ofstream
file(tga_file_name
, ios::binary
);
167 cerr
<< "Error creating texture file '" << tga_file_name
<< "'." << endl
;
171 GLubyte tga_id_length
= strlen(tga_id
);
172 file
.write((char *) &tga_id_length
, 1);
174 file
.write((char *) header_image
, sizeof(header_image
));
177 header
[1] = _width
/ 256;
178 header
[0] = _width
- 256 * header
[1];
179 header
[3] = _height
/ 256;
180 header
[2] = _height
- 256 * header
[3];
183 file
.write((char *) header
, sizeof(header
));
185 file
.write(tga_id
, tga_id_length
);
188 for (int n
= 0; n
< _width
* _height
* 4; n
+= 4) {
189 GLubyte swap
= texture
[n
];
190 texture
[n
] = texture
[n
+ 2];
191 texture
[n
+ 2] = swap
;
194 file
.write((char *) texture
, _width
* _height
* 4);
196 for (int n
= 0; n
< _width
* _height
* 4; n
+= 4) {
197 GLubyte swap
= texture
[n
];
198 texture
[n
] = texture
[n
+ 2];
199 texture
[n
+ 2] = swap
;
203 bool TextureLoader::fileExists ( const char *file_name
)
205 struct stat file_stats
;
207 // stat fails to find directories with trailing delimiters in _WIN32
209 if (file_name
[strlen(file_name
) - 1] == GC_DD
[0]) {
210 char truncated_file_name
[256];
211 strncpy(truncated_file_name
, file_name
, 256);
212 truncated_file_name
[strlen(file_name
) - 1] = '\0';
213 return !stat(truncated_file_name
, &file_stats
);
216 return !stat(file_name
, &file_stats
);
219 unsigned long TextureLoader::determineImageCheckSum ( const char *file_name
,
220 int _height
, int _width
)
222 GLubyte
*texture
= loadImage(file_name
, _height
, _width
);
224 unsigned long check_sum
= 0;
225 for (int n
= _width
* _height
* 4; n
--; )
226 check_sum
+= texture
[n
];
228 if (texture
!= null
) {
236 void TextureLoader::determineImageSize ( const char *file_name
, int &height
,
239 SDL_Surface
*img
= IMG_Load(file_name
);
242 cerr
<< "Error opening texture file '" << file_name
<< "'." << endl
;
249 SDL_FreeSurface(img
);