Each module now includes its own header first. Removed sstream.h and the definition...
[crack-attack.git] / src / TextureLoader.cxx
blobe62c11b06fb65012b0cf129673e91583769e59b9
1 /*
2 * TextureLoader.cxx
3 * Daniel Nelson - 9/14/0
5 * Copyright (C) 2000 Daniel Nelson
6 * Copyright (C) 2004 Andrew Sayman
7 *
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
23 * 174 W. 18th Ave.
24 * Columbus, OH 43210
26 * Loads textures from uncompressed TGA files.
29 #include "TextureLoader.h"
31 #include <GL/glut.h>
32 #include <fstream>
33 #include <iostream>
34 #include <cstring>
35 #include <sys/stat.h>
37 #ifndef _WIN32
38 # include <unistd.h>
39 #endif
41 #include "glext.h"
43 #include "Game.h"
45 using namespace std;
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,
51 int _width )
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;
64 full_texture = null;
67 return alpha_texture;
70 GLubyte *TextureLoader::loadNoAlphaTGA ( const char *tga_file_name, int _height,
71 int _width )
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;
88 full_texture = null;
91 return no_alpha_texture;
94 GLubyte *TextureLoader::loadTGA ( const char *tga_file_name, int _height,
95 int _width, int _color_depth )
97 #ifndef _WIN32
98 ifstream file(tga_file_name);
99 #else
100 ifstream file(tga_file_name, ios::binary);
101 #endif
102 if (file.fail()) {
103 cerr << "Error opening texture file '" << tga_file_name << "'." << endl;
104 exit(1);
107 GLubyte id_length;
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;
115 exit(1);
118 GLubyte header[6];
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;
128 exit(1);
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 "
134 "depth." << endl;
135 exit(1);
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;
140 exit(1);
143 GLubyte b;
144 while (id_length--)
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);
153 // tga is BGR
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;
160 return texture;
163 void TextureLoader::createTGA ( const char *tga_file_name, GLubyte *texture,
164 int _height, int _width, const char *tga_id )
166 #ifndef _WIN32
167 ofstream file(tga_file_name);
168 #else
169 ofstream file(tga_file_name, ios::binary);
170 #endif
171 if (file.fail()) {
172 cerr << "Error creating texture file '" << tga_file_name << "'." << endl;
173 exit(1);
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));
181 GLubyte header[6];
182 header[1] = _width / 256;
183 header[0] = _width - 256 * header[1];
184 header[3] = _height / 256;
185 header[2] = _height - 256 * header[3];
186 header[4] = 32;
187 header[5] = 40;
188 file.write((char *) header, sizeof(header));
190 file.write(tga_id, tga_id_length);
192 // tga is BGR
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;
212 #ifndef _WIN32
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);
220 #endif
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) {
234 delete [] texture;
235 texture = null;
238 return check_sum;
241 void TextureLoader::determineTGASize ( const char *tga_file_name, int &height,
242 int &width )
244 #ifndef _WIN32
245 ifstream file(tga_file_name);
246 #else
247 ifstream file(tga_file_name, ios::binary);
248 #endif
249 if (file.fail()) {
250 cerr << "Error opening texture file '" << tga_file_name << "'." << endl;
251 exit(1);
254 GLubyte id_length;
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;
262 exit(1);
265 GLubyte header[6];
266 file.read((char *) header, sizeof(header));
268 width = header[1] * 256 + header[0];
269 height = header[3] * 256 + header[2];