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.
43 #include "TextureLoader.h"
46 // the header of an uncompressed TGA file
47 const GLubyte header_image
[11] = { 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
49 GLubyte
*TextureLoader::loadAlphaTGA ( const char *tga_file_name
, int _height
,
52 GLubyte
*full_texture
= loadTGA(tga_file_name
, _height
, _width
);
54 int texture_size
= _width
* _height
;
56 GLubyte
*alpha_texture
= new GLubyte
[texture_size
];
58 for (int n
= 0; n
< texture_size
; n
++)
59 alpha_texture
[n
] = full_texture
[4 * n
+ 3];
61 if (full_texture
!= null
) {
62 delete [] full_texture
;
69 GLubyte
*TextureLoader::loadNoAlphaTGA ( const char *tga_file_name
, int _height
,
72 GLubyte
*full_texture
= loadTGA(tga_file_name
, _height
, _width
);
74 int texture_size
= _width
* _height
;
76 GLubyte
*no_alpha_texture
= new GLubyte
[texture_size
* 3];
78 for (int n
= 0; n
< texture_size
; n
++) {
79 float alpha
= full_texture
[4 * n
+ 3] * (1.0f
/ 255.0f
);
80 no_alpha_texture
[3 * n
+ 0] = (GLubyte
) (alpha
* full_texture
[4 * n
+ 0]);
81 no_alpha_texture
[3 * n
+ 1] = (GLubyte
) (alpha
* full_texture
[4 * n
+ 1]);
82 no_alpha_texture
[3 * n
+ 2] = (GLubyte
) (alpha
* full_texture
[4 * n
+ 2]);
85 if (full_texture
!= null
) {
86 delete [] full_texture
;
90 return no_alpha_texture
;
93 GLubyte
*TextureLoader::loadTGA ( const char *tga_file_name
, int _height
,
94 int _width
, int _color_depth
)
97 ifstream
file(tga_file_name
);
99 ifstream
file(tga_file_name
, ios::binary
);
102 cerr
<< "Error opening texture file '" << tga_file_name
<< "'." << endl
;
107 file
.read((char *) &id_length
, 1);
109 GLubyte static_header
[11];
110 file
.read((char *) static_header
, sizeof(static_header
));
111 if (memcmp(static_header
, header_image
, sizeof(static_header
)) != 0) {
112 cerr
<< "Texture file '" << tga_file_name
<< "' is not in uncompressed "
113 "TGA format." << endl
;
118 file
.read((char *) header
, sizeof(header
));
120 int width
= header
[1] * 256 + header
[0];
121 int height
= header
[3] * 256 + header
[2];
123 if (width
!= _width
|| height
!= _height
) {
124 cerr
<< "Texture file '" << tga_file_name
<< "' does not have the expected "
125 "height and width. [" << height
<< 'x' << width
<< "] vs expected ["
126 << _height
<< 'x' << _width
<< "]." << endl
;
130 int color_depth
= header
[4];
131 if (color_depth
!= 24 && color_depth
!= 32) {
132 cerr
<< "Texture file '" << tga_file_name
<< "' has an unsupported color "
136 if (_color_depth
!= 0 && _color_depth
!= color_depth
) {
137 cerr
<< "Texture file '" << tga_file_name
<< "' does not have the expected "
138 "color depth." << endl
;
144 file
.read((char *) &b
, 1);
146 int texture_size
= width
* height
* color_depth
/ 8;
148 GLubyte
*texture
= new GLubyte
[texture_size
];
150 file
.read((char *) texture
, texture_size
);
153 for (int n
= 0; n
< texture_size
; n
+= color_depth
/ 8) {
154 GLubyte swap
= texture
[n
];
155 texture
[n
] = texture
[n
+ 2];
156 texture
[n
+ 2] = swap
;
162 void TextureLoader::createTGA ( const char *tga_file_name
, GLubyte
*texture
,
163 int _height
, int _width
, const char *tga_id
)
166 ofstream
file(tga_file_name
);
168 ofstream
file(tga_file_name
, ios::binary
);
171 cerr
<< "Error creating texture file '" << tga_file_name
<< "'." << endl
;
175 GLubyte tga_id_length
= strlen(tga_id
);
176 file
.write((char *) &tga_id_length
, 1);
178 file
.write((char *) header_image
, sizeof(header_image
));
181 header
[1] = _width
/ 256;
182 header
[0] = _width
- 256 * header
[1];
183 header
[3] = _height
/ 256;
184 header
[2] = _height
- 256 * header
[3];
187 file
.write((char *) header
, sizeof(header
));
189 file
.write((char *) tga_id
, tga_id_length
);
192 for (int n
= 0; n
< _width
* _height
* 4; n
+= 4) {
193 GLubyte swap
= texture
[n
];
194 texture
[n
] = texture
[n
+ 2];
195 texture
[n
+ 2] = swap
;
198 file
.write((char *) texture
, _width
* _height
* 4);
200 for (int n
= 0; n
< _width
* _height
* 4; n
+= 4) {
201 GLubyte swap
= texture
[n
];
202 texture
[n
] = texture
[n
+ 2];
203 texture
[n
+ 2] = swap
;
207 bool TextureLoader::fileExists ( const char *file_name
)
209 struct stat file_stats
;
212 #else // stat fails to find directories with trailing delimiters in _WIN32
213 if (file_name
[strlen(file_name
) - 1] == GC_DD
[0]) {
214 char truncated_file_name
[256];
215 strncpy(truncated_file_name
, file_name
, 256);
216 truncated_file_name
[strlen(file_name
) - 1] = '\0';
217 return !stat(truncated_file_name
, &file_stats
);
220 return !stat(file_name
, &file_stats
);
223 unsigned long TextureLoader::determineTGACheckSum ( const char *tga_file_name
,
224 int _height
, int _width
)
226 GLubyte
*texture
= loadTGA(tga_file_name
, _height
, _width
);
228 unsigned long check_sum
= 0;
229 for (int n
= _width
* _height
* 4; n
--; )
230 check_sum
+= texture
[n
];
232 if (texture
!= null
) {
240 void TextureLoader::determineTGASize ( const char *tga_file_name
, int &height
,
244 ifstream
file(tga_file_name
);
246 ifstream
file(tga_file_name
, ios::binary
);
249 cerr
<< "Error opening texture file '" << tga_file_name
<< "'." << endl
;
254 file
.read((char *) &id_length
, 1);
256 GLubyte static_header
[11];
257 file
.read((char *) static_header
, sizeof(static_header
));
258 if (memcmp(static_header
, header_image
, sizeof(static_header
)) != 0) {
259 cerr
<< "Texture file '" << tga_file_name
<< "' is not in uncompressed "
260 "TGA format." << endl
;
265 file
.read((char *) header
, sizeof(header
));
267 width
= header
[1] * 256 + header
[0];
268 height
= header
[3] * 256 + header
[2];