1 /*
2  * garbage.cxx
3  * Daniel Nelson - 10/1/0
4  *
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.
12  *
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.
17  *
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.
21  *
22  * Daniel Nelson - aluminumangel.org
23  * 174 W. 18th Ave.
24  * Columbus, OH  43210
25  *
26  * Generates the lightmap and flavor textures for the garbage.
27  */
28 
29 #define GL_GLEXT_LEGACY
30 #define GL_GLEXT_PROTOTYPES
31 
32 #include <GL/glut.h>
33 #include <GL/glext.h>
34 
35 #include "glext.h"
36 
37 using namespace std;
38 
39 #include "TextureLoader.h"
40 #include "Game.h"
41 #include "Displayer.h"
42 #include "GarbageFlavorImage.h"
43 #include "MetaState.h"
44 #include "Random.h"
45 
46 const char *garbage_lightmap_files[DC_NUMBER_GARBAGE_LIGHTMAPS]
47  = { GC_DATA_DIRECTORY("garbage_lightmap_0.tga"),
48      GC_DATA_DIRECTORY("garbage_lightmap_1.tga"),
49      GC_DATA_DIRECTORY("garbage_lightmap_2.tga"),
50      GC_DATA_DIRECTORY("garbage_lightmap_3.tga"),
51      GC_DATA_DIRECTORY("garbage_lightmap_4.tga"),
52      GC_DATA_DIRECTORY("garbage_lightmap_5.tga") };
53 
54 GLuint Displayer::garbage_lightmap;
55 GLuint Displayer::garbage_texture;
56 
57 GLuint Displayer::garbage_flavor_list;
58 
59 GLubyte *Displayer::garbage_texture_data[DC_NUMBER_USE_GARBAGE_TEX];
60 
generateGarbageExtras()61 void Displayer::generateGarbageExtras (   )
62 {
63   char file_name[256];
64 
65   glGenTextures(1, &garbage_lightmap);
66 
67   glBindTexture(GL_TEXTURE_2D, garbage_lightmap);
68 
69   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
70   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
71   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
72   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
73 
74   // choose a random lightmap for this game
75   GLubyte *texture = TextureLoader::loadAlphaTGA(
76    garbage_lightmap_files[Random::number(DC_NUMBER_GARBAGE_LIGHTMAPS)],
77    DC_GARBAGE_LIGHTMAP_LENGTH, DC_GARBAGE_LIGHTMAP_LENGTH);
78 
79   for (int s = DC_GARBAGE_LIGHTMAP_LENGTH; s--; )
80     for (int t = DC_GARBAGE_LIGHTMAP_LENGTH; t--; )
81       texture[s * DC_GARBAGE_LIGHTMAP_LENGTH + t]
82        = (GLubyte) (255.0f * (DC_GARBAGE_LIGHTMAP_MIN_LUMINANCE
83        + ((1.0f - DC_GARBAGE_LIGHTMAP_MIN_LUMINANCE) / 255.0f)
84        * (float) texture[s * DC_GARBAGE_LIGHTMAP_LENGTH + t]));
85 
86   glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, DC_GARBAGE_LIGHTMAP_LENGTH,
87    DC_GARBAGE_LIGHTMAP_LENGTH, GL_FALSE, GL_LUMINANCE, GL_UNSIGNED_BYTE,
88    texture);
89 
90   if (texture != null) {
91     delete [] texture;
92     texture = null;
93   }
94 
95   glGenTextures(1, &garbage_texture);
96 
97   glBindTexture(GL_TEXTURE_2D, garbage_texture);
98 
99   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
100   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
101   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
102   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
103 
104   // identify which texture files exist
105   int texture_file_count = 0;
106   bool texture_file_flag[GC_GARBAGE_TEX_MAX_NUMBER];
107   for (int n = GC_GARBAGE_TEX_MAX_NUMBER; n--; ) {
108     GarbageFlavorImage::buildGarbageTextureFileName(file_name, n);
109 
110     if (TextureLoader::fileExists(file_name)) {
111       texture_file_count++;
112       texture_file_flag[n] = true;
113     } else
114       texture_file_flag[n] = false;
115   }
116 
117   // if for some reason we don't have enough textures
118   if (texture_file_count < DC_NUMBER_USE_GARBAGE_TEX) {
119     GarbageFlavorImage::buildGarbageTextureFileName(file_name, 0);
120 
121     for (int n = 0; n < DC_NUMBER_USE_GARBAGE_TEX; n++) {
122       garbage_texture_data[n] = TextureLoader::loadTGA(file_name,
123        DC_GARBAGE_TEX_LENGTH, DC_GARBAGE_TEX_LENGTH);
124     }
125 
126   // otherwise, we have plenty
127   } else {
128     int use_textures[DC_NUMBER_USE_GARBAGE_TEX];
129     for (int n = 0; n < DC_NUMBER_USE_GARBAGE_TEX; n++) {
130 
131       // always put the net tex in zero, if there is one
132       if (n == 0 && (MetaState::mode & CM_SOLO)
133        && GarbageFlavorImage::personalGarbageFlavorImageExists())
134         GarbageFlavorImage::handleNetworkGarbageFlavorImage(
135          garbage_texture_data[0]
136          = GarbageFlavorImage::loadPersonalGarbageFlavorImage());
137 
138       else if (n == 0 && !(MetaState::mode & CM_SOLO)
139        && GarbageFlavorImage::network_texture) {
140         char net_tex_file_name[256];
141         TextureLoader::buildLocalDataFileName(GC_GARBAGE_NET_TEX_FILE_NAME,
142          net_tex_file_name);
143 
144         garbage_texture_data[0] = TextureLoader::loadTGA(net_tex_file_name,
145          DC_GARBAGE_TEX_LENGTH, DC_GARBAGE_TEX_LENGTH);
146 
147       } else {
148         bool flag;
149         do {
150           flag = false;
151 
152           int i;
153           int choice = Random::number(texture_file_count);
154           for (i = 0; choice--; i++)
155             while (!texture_file_flag[i])
156               i++;
157           use_textures[n] = i;
158 
159           for (int m = 0; m < n; m++)
160             if (use_textures[n] == use_textures[m]) {
161               flag = true;
162               break;
163             }
164         } while (flag);
165 
166         GarbageFlavorImage::buildGarbageTextureFileName(file_name,
167          use_textures[n]);
168 
169         garbage_texture_data[n] = TextureLoader::loadTGA(file_name,
170          DC_GARBAGE_TEX_LENGTH, DC_GARBAGE_TEX_LENGTH);
171       }
172     }
173   }
174 
175   // the logo may replace the second texture
176   if (Random::chanceIn(DC_CHANCE_IN_NOT_USE_LOGO_FLAVOR_TEX)) {
177     if (garbage_texture_data[1] != null) {
178       delete [] garbage_texture_data[1];
179       garbage_texture_data[1] = null;
180     }
181 
182     if (MetaState::mode & CM_X)
183       garbage_texture_data[1]
184        = TextureLoader::loadTGA(GC_GARBAGE_X_LOGO_TEX_FILE_NAME,
185        DC_GARBAGE_TEX_LENGTH, DC_GARBAGE_TEX_LENGTH);
186     else
187       garbage_texture_data[1]
188        = TextureLoader::loadTGA(GC_GARBAGE_LOGO_TEX_FILE_NAME,
189        DC_GARBAGE_TEX_LENGTH, DC_GARBAGE_TEX_LENGTH);
190   }
191 
192   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, DC_GARBAGE_TEX_LENGTH,
193    DC_GARBAGE_TEX_LENGTH, GL_FALSE, GL_RGBA, GL_UNSIGNED_BYTE,
194    garbage_texture_data[GarbageFlavorImage::current_texture]);
195 
196   GLfloat vertices_0[3 * 6] = {
197     -1.0f, -1.0f, 1.0f,
198     1.0f, -1.0f, 1.0f,
199     -1.0f, 1.0f, 1.0f,
200     1.0f, 1.0f, 1.0f,
201     -1.0f, 3.0f, 1.0f,
202     1.0f, 3.0f, 1.0f
203   };
204 
205   GLfloat normals_0[3 * 6] = {
206     0.0f, 0.0f, 1.0f,
207     0.0f, 0.0f, 1.0f,
208     0.0f, 0.0f, 1.0f,
209     0.0f, 0.0f, 1.0f,
210     0.0f, 0.0f, 1.0f,
211     0.0f, 0.0f, 1.0f
212   };
213 
214   GLfloat tex_coords_flavor[2 * 6] = {
215     0.0f, 1.0f,
216     0.5f, 1.0f,
217     0.0f, 0.5f,
218     0.5f, 0.5f,
219     0.0f, 0.0f,
220     0.5f, 0.0f
221   };
222 
223 #ifndef NO_MULTITEXTURING
224   GLfloat tex_coords_lightmap[2 * 6] = {
225     -DC_GARBAGE_LIGHTMAP_COORD_CONVERTER, -DC_GARBAGE_LIGHTMAP_COORD_CONVERTER,
226     DC_GARBAGE_LIGHTMAP_COORD_CONVERTER, -DC_GARBAGE_LIGHTMAP_COORD_CONVERTER,
227     -DC_GARBAGE_LIGHTMAP_COORD_CONVERTER, DC_GARBAGE_LIGHTMAP_COORD_CONVERTER,
228     DC_GARBAGE_LIGHTMAP_COORD_CONVERTER, DC_GARBAGE_LIGHTMAP_COORD_CONVERTER,
229     -DC_GARBAGE_LIGHTMAP_COORD_CONVERTER,
230      3.0f * DC_GARBAGE_LIGHTMAP_COORD_CONVERTER,
231     DC_GARBAGE_LIGHTMAP_COORD_CONVERTER,
232      3.0f * DC_GARBAGE_LIGHTMAP_COORD_CONVERTER,
233   };
234 #endif
235 
236   garbage_flavor_list = glGenLists(1);
237 
238   glEnableClientState(GL_VERTEX_ARRAY);
239   glEnableClientState(GL_NORMAL_ARRAY);
240   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
241 
242 #ifndef NO_MULTITEXTURING
243   // if multitexturing
244   if (Displayer::state & DS_MULTITEXTURING) {
245 
246     glActiveTextureARB(GL_TEXTURE1_ARB);
247 
248     glBindTexture(GL_TEXTURE_2D, garbage_lightmap);
249     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
250 
251     glActiveTextureARB(GL_TEXTURE0_ARB);
252 
253     glNewList(garbage_flavor_list, GL_COMPILE);
254 
255       glVertexPointer(3, GL_FLOAT, 0, vertices_0);
256       glNormalPointer(GL_FLOAT, 0, normals_0);
257       glTexCoordPointer(2, GL_FLOAT, 0, tex_coords_flavor);
258 
259       glClientActiveTextureARB(GL_TEXTURE1_ARB);
260       glEnableClientState(GL_TEXTURE_COORD_ARRAY);
261       glTexCoordPointer(2, GL_FLOAT, 0, tex_coords_lightmap);
262 
263       glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);
264 
265       for (int n = 6; n--; ) {
266         vertices_0[3 * n + 0] += 2.0f;
267         tex_coords_flavor[2 * n + 0] += 0.5f;
268         tex_coords_lightmap[2 * n + 0]
269          += 2.0f * DC_GARBAGE_LIGHTMAP_COORD_CONVERTER;
270       }
271 
272       glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);
273 
274       glDisableClientState(GL_TEXTURE_COORD_ARRAY);
275       glClientActiveTextureARB(GL_TEXTURE0_ARB);
276 
277     glEndList();
278 
279   // if no multitexturing
280   } else {
281 #endif
282 
283     glNewList(garbage_flavor_list, GL_COMPILE);
284 
285       glVertexPointer(3, GL_FLOAT, 0, vertices_0);
286       glNormalPointer(GL_FLOAT, 0, normals_0);
287       glTexCoordPointer(2, GL_FLOAT, 0, tex_coords_flavor);
288       glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);
289 
290       for (int n = 6; n--; ) {
291         vertices_0[3 * n + 0] += 2.0f;
292         tex_coords_flavor[2 * n + 0] += 0.5f;
293       }
294 
295       glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);
296 
297     glEndList();
298 #ifndef NO_MULTITEXTURING
299   }
300 #endif
301 
302   glDisableClientState(GL_VERTEX_ARRAY);
303   glDisableClientState(GL_NORMAL_ARRAY);
304   glDisableClientState(GL_TEXTURE_COORD_ARRAY);
305 }
306