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"
47 // the header of an uncompressed TGA file
48 const GLubyte header_image
[11] = { 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
50 GLubyte
*TextureLoader::loadAlphaTGA ( const char *tga_file_name
, int _height
,
53 GLubyte
*full_texture
= loadTGA(tga_file_name
, _height
, _width
);
55 int texture_size
= _width
* _height
;
57 GLubyte
*alpha_texture
= new GLubyte
[texture_size
];
59 for (int n
= 0; n
< texture_size
; n
++)
60 alpha_texture
[n
] = full_texture
[4 * n
+ 3];
62 if (full_texture
!= null
) {
63 delete [] full_texture
;
70 GLubyte
*TextureLoader::loadNoAlphaTGA ( const char *tga_file_name
, int _height
,
73 GLubyte
*full_texture
= loadTGA(tga_file_name
, _height
, _width
);
75 int texture_size
= _width
* _height
;
77 GLubyte
*no_alpha_texture
= new GLubyte
[texture_size
* 3];
79 for (int n
= 0; n
< texture_size
; n
++) {
80 float alpha
= full_texture
[4 * n
+ 3] * (1.0f
/ 255.0f
);
81 no_alpha_texture
[3 * n
+ 0] = (GLubyte
) (alpha
* full_texture
[4 * n
+ 0]);
82 no_alpha_texture
[3 * n
+ 1] = (GLubyte
) (alpha
* full_texture
[4 * n
+ 1]);
83 no_alpha_texture
[3 * n
+ 2] = (GLubyte
) (alpha
* full_texture
[4 * n
+ 2]);
86 if (full_texture
!= null
) {
87 delete [] full_texture
;
91 return no_alpha_texture
;
94 GLubyte
*TextureLoader::loadTGA ( const char *tga_file_name
, int _height
,
95 int _width
, int _color_depth
)
98 ifstream
file(tga_file_name
);
100 ifstream
file(tga_file_name
, ios::binary
);
103 cerr
<< "Error opening texture file '" << tga_file_name
<< "'." << endl
;
108 file
.read((char *) &id_length
, 1);
110 GLubyte static_header
[11];
111 file
.read((char *) static_header
, sizeof(static_header
));
112 if (memcmp(static_header
, header_image
, sizeof(static_header
)) != 0) {
113 cerr
<< "Texture file '" << tga_file_name
<< "' is not in uncompressed "
114 "TGA format." << endl
;
119 file
.read((char *) header
, sizeof(header
));
121 int width
= header
[1] * 256 + header
[0];
122 int height
= header
[3] * 256 + header
[2];
124 if (width
!= _width
|| height
!= _height
) {
125 cerr
<< "Texture file '" << tga_file_name
<< "' does not have the expected "
126 "height and width. [" << height
<< 'x' << width
<< "] vs expected ["
127 << _height
<< 'x' << _width
<< "]." << endl
;
131 int color_depth
= header
[4];
132 if (color_depth
!= 24 && color_depth
!= 32) {
133 cerr
<< "Texture file '" << tga_file_name
<< "' has an unsupported color "
137 if (_color_depth
!= 0 && _color_depth
!= color_depth
) {
138 cerr
<< "Texture file '" << tga_file_name
<< "' does not have the expected "
139 "color depth." << endl
;
145 file
.read((char *) &b
, 1);
147 int texture_size
= width
* height
* color_depth
/ 8;
149 GLubyte
*texture
= new GLubyte
[texture_size
];
151 file
.read((char *) texture
, texture_size
);
154 for (int n
= 0; n
< texture_size
; n
+= color_depth
/ 8) {
155 GLubyte swap
= texture
[n
];
156 texture
[n
] = texture
[n
+ 2];
157 texture
[n
+ 2] = swap
;
163 void TextureLoader::createTGA ( const char *tga_file_name
, GLubyte
*texture
,
164 int _height
, int _width
, const char *tga_id
)
167 ofstream
file(tga_file_name
);
169 ofstream
file(tga_file_name
, ios::binary
);
172 cerr
<< "Error creating texture file '" << tga_file_name
<< "'." << endl
;
176 GLubyte tga_id_length
= strlen(tga_id
);
177 file
.write((char *) &tga_id_length
, 1);
179 file
.write((char *) header_image
, sizeof(header_image
));
182 header
[1] = _width
/ 256;
183 header
[0] = _width
- 256 * header
[1];
184 header
[3] = _height
/ 256;
185 header
[2] = _height
- 256 * header
[3];
188 file
.write((char *) header
, sizeof(header
));
190 file
.write(tga_id
, tga_id_length
);
193 for (int n
= 0; n
< _width
* _height
* 4; n
+= 4) {
194 GLubyte swap
= texture
[n
];
195 texture
[n
] = texture
[n
+ 2];
196 texture
[n
+ 2] = swap
;
199 file
.write((char *) texture
, _width
* _height
* 4);
201 for (int n
= 0; n
< _width
* _height
* 4; n
+= 4) {
202 GLubyte swap
= texture
[n
];
203 texture
[n
] = texture
[n
+ 2];
204 texture
[n
+ 2] = swap
;
208 bool TextureLoader::fileExists ( const char *file_name
)
210 struct stat file_stats
;
213 #else // stat fails to find directories with trailing delimiters in _WIN32
214 if (file_name
[strlen(file_name
) - 1] == GC_DD
[0]) {
215 char truncated_file_name
[256];
216 strncpy(truncated_file_name
, file_name
, 256);
217 truncated_file_name
[strlen(file_name
) - 1] = '\0';
218 return !stat(truncated_file_name
, &file_stats
);
221 return !stat(file_name
, &file_stats
);
224 unsigned long TextureLoader::determineTGACheckSum ( const char *tga_file_name
,
225 int _height
, int _width
)
227 GLubyte
*texture
= loadTGA(tga_file_name
, _height
, _width
);
229 unsigned long check_sum
= 0;
230 for (int n
= _width
* _height
* 4; n
--; )
231 check_sum
+= texture
[n
];
233 if (texture
!= null
) {
241 void TextureLoader::determineTGASize ( const char *tga_file_name
, int &height
,
245 ifstream
file(tga_file_name
);
247 ifstream
file(tga_file_name
, ios::binary
);
250 cerr
<< "Error opening texture file '" << tga_file_name
<< "'." << endl
;
255 file
.read((char *) &id_length
, 1);
257 GLubyte static_header
[11];
258 file
.read((char *) static_header
, sizeof(static_header
));
259 if (memcmp(static_header
, header_image
, sizeof(static_header
)) != 0) {
260 cerr
<< "Texture file '" << tga_file_name
<< "' is not in uncompressed "
261 "TGA format." << endl
;
266 file
.read((char *) header
, sizeof(header
));
268 width
= header
[1] * 256 + header
[0];
269 height
= header
[3] * 256 + header
[2];