1 /*
2 OpenUniverse 1.0
3 Copyright (C) 2000 Raul Alonso <amil@las.es>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 /*
21 Initialization routines:
22
23 - Read texture images
24 - Initialize planets' data
25 - Create display lists
26 - Other initialization routines
27 */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <math.h>
33 #include <time.h>
34 extern "C" {
35 #include "jpeglib.h"
36 }
37 #include <setjmp.h>
38 #include "ou.h"
39 #include "texture.h"
40 #include "bmf.h"
41 #include "glext.h"
42
43 GLfloat LightPos[4] = { 0.0, 0.0, 0.0, 1.0 };
44 GLfloat ambient[4] = { 0.2, 0.2, 0.2, 0.0 };
45 GLfloat White[4] = { 1.0, 1.0, 1.0, 1.0 };
46 GLfloat Black[4] = { 0.0, 0.0, 0.0, 1.0 };
47 GLfloat Fog[4] = { 1.0, 0.9, 0.8, 1.0 };
48 float fogdensity = 0.1;
49 int texture = 1, lighting = 1, drawstars = 1, gravity = 1, logo = 1;
50 GLenum smodel = GL_SMOOTH;
51 GLuint StarsDL, MessierDL, MilkyWayDL;
52 int ImgWidth, ImgHeight, components, red, polaris;
53 int width = 640, height = 480; /* default WIDTH and HEIGHT */
54 planetdata planets[MAXBODIES];
55 stardata stars[NUMSTARS];
56 messierdata messierobjs[MAXMESSIER];
57 double days;
58 int timefactor = 1; /* iterarion = 1 second */
59 int slices = 16, stacks = 16, NUMBODIES, num_messier, border = 0, filter =
60 GL_LINEAR;
61 int mipmap = 1, mipmap_filter = GL_LINEAR_MIPMAP_LINEAR;
62 char texturepath[100] = TEXTURE_DIR;
63 char confpath[100] = CONF_DIR;
64 unsigned char tmpimg[258 * 258 * 4], *splash_image;
65 int splashwidth = 0, splashheight = 0, splashbitmap = 1, LOD = HIGH, tex_compr;
66 int color_depth = 24;
67 GLenum cd_rgb, cd_lum, cd_rgba, cd_luma;
68 GLuint splashtex[4], logotex;
69 extern float star_mag;
70
71 static void SetUpTrails(void);
72 static void Spheroid(double, float, float, float, float, int, int,
73 planetdata *, int);
74 void Print(char *), InitLogo(void);
75 GLubyte *read_JPEG_file(char *, int *, int *, int *);
76
77
Init(void)78 void Init(void)
79 {
80 time_t t;
81
82
83 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
84
85 t = time(NULL);
86 srand(t);
87 days = t / 3600.0 / 24.0 - 10092.0;
88 initfontengine();
89 hasPointEXT = glutExtensionSupported("GL_EXT_point_parameters");
90 tex_compr = glutExtensionSupported("GL_EXT_texture_compression_s3tc");
91 tex_compr *= glutExtensionSupported("GL_ARB_texture_compression");
92 #ifdef WIN32
93 InitPointEXT();
94 #endif
95 ReadConfigFile();
96 SetUpTrails();
97 Print("Setting up Stars");
98 InitStars(star_mag, 1);
99 Print("Setting up Messier Objects");
100 InitMessier();
101 Print("Setting up Milky Way");
102 InitMilkyWay();
103 InitLogo();
104 InitFlares();
105 glShadeModel(smodel);
106 glEnable(GL_LIGHTING);
107 glEnable(GL_LIGHT0);
108 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
109 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
110 glHint((GLenum) GL_TEXTURE_COMPRESSION_HINT_ARB, GL_NICEST);
111 glEnable(GL_TEXTURE_2D);
112 glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
113 glEnable(GL_CULL_FACE);
114 glEnable(GL_DEPTH_TEST);
115 }
116
117
InitLogo(void)118 void InitLogo(void)
119 {
120 static int i, width, height, components;
121 static double j;
122 static unsigned char *image, *localimage;
123 char sbuf[80];
124
125 image = read_JPEG_file("cyclo.jpg", &width, &height, &components);
126 if (!image) {
127 sprintf(sbuf, "Couldn't read image %s/cyclo.jpg\n", texturepath);
128 error(sbuf);
129 shutdown(1);
130 }
131
132 localimage = (unsigned char *) malloc(width * height * 4);
133 if (localimage == NULL) {
134 error("Couldn't allocate memory");
135 shutdown(1);
136 }
137
138 for (i = 0; i < (width * height); i++) {
139 localimage[i * 4] = image[i * 3];
140 localimage[i * 4 + 1] = image[i * 3 + 1];
141 localimage[i * 4 + 2] = image[i * 3 + 2];
142 j = (image[i * 3] + image[i * 3 + 1] + image[i * 3 + 2]) / 3.0;
143 if (j < (double) 100.0)
144 j = 0.0;
145 localimage[i * 4 + 3] = j > 255.0 ? 255 : (int) j;
146 }
147
148 glGenTextures(1, &logotex);
149 glBindTexture(GL_TEXTURE_2D, logotex);
150 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
151 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
152 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
153 glTexImage2D(GL_TEXTURE_2D,
154 0,
155 components == 3 ? cd_rgba : cd_luma,
156 width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, localimage);
157 free(image);
158 free(localimage);
159 }
160
161 /*
162 A quick and dirty Print function for the opening screen
163
164 I know it's not the best way to do this but it will only have impact in the
165 loading time ;-)
166 */
Print(char * s)167 void Print(char *s)
168 {
169 glViewport(0, 0, width, height);
170 glMatrixMode(GL_PROJECTION);
171 glLoadIdentity();
172 gluOrtho2D(0, width, 0, height);
173 glMatrixMode(GL_MODELVIEW);
174 glLoadIdentity();
175
176 if (splashbitmap) {
177 if (!splashwidth) {
178 char *files[4]={"splash1.jpg", "splash2.jpg", "splash3.jpg", "splash4.jpg"};
179 int i;
180
181 splash_image =
182 read_JPEG_file(files[rand() % 4], &splashwidth, &splashheight,
183 &components);
184
185 if ((splashwidth != 512) || (splashheight != 512)
186 || (components != 3)) {
187 error("splash.jpg must be 512x512 24bits");
188 shutdown(1);
189 }
190 glGenTextures(4, splashtex);
191
192 for (i = 0; i < 256; i++)
193 memcpy(tmpimg + i * 256 * 3,
194 splash_image + i * splashwidth * components,
195 256 * components);
196
197 glEnable(GL_TEXTURE_2D);
198 glBindTexture(GL_TEXTURE_2D, splashtex[0]);
199 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
200 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
201 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
202 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
203 glTexImage2D(GL_TEXTURE_2D,
204 0,
205 components == 3 ? cd_rgb : cd_lum,
206 256, 256,
207 0,
208 components == 3 ? GL_RGB : GL_LUMINANCE,
209 GL_UNSIGNED_BYTE, tmpimg);
210
211 for (i = 0; i < 256; i++)
212 memcpy(tmpimg + i * 256 * 3,
213 splash_image + i * splashwidth * components +
214 256 * components, 256 * components);
215
216 glBindTexture(GL_TEXTURE_2D, splashtex[1]);
217 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
218 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
219 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
220 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
221 glTexImage2D(GL_TEXTURE_2D,
222 0,
223 components == 3 ? cd_rgb : cd_lum,
224 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, tmpimg);
225
226
227 for (i = 0; i < 256; i++)
228 memcpy(tmpimg + i * 256 * 3,
229 splash_image + (i + 256) * splashwidth * components,
230 256 * components);
231
232 glBindTexture(GL_TEXTURE_2D, splashtex[2]);
233 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
234 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
235 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
236 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
237 glTexImage2D(GL_TEXTURE_2D,
238 0,
239 components == 3 ? cd_rgb : cd_lum,
240 256, 256,
241 0,
242 components == 3 ? GL_RGB : GL_LUMINANCE,
243 GL_UNSIGNED_BYTE, tmpimg);
244
245 for (i = 0; i < 256; i++)
246 memcpy(tmpimg + i * 256 * 3,
247 splash_image + (i +
248 256) * splashwidth * components +
249 256 * components, 256 * components);
250
251 glBindTexture(GL_TEXTURE_2D, splashtex[3]);
252 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
253 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
254 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
255 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
256 glTexImage2D(GL_TEXTURE_2D,
257 0,
258 components == 3 ? cd_rgb : cd_lum,
259 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, tmpimg);
260 free(splash_image);
261 }
262
263 glDisable(GL_LIGHTING);
264 glDisable(GL_DEPTH_TEST);
265 glEnable(GL_TEXTURE_2D);
266 glColor3f(1.0, 1.0, 1.0);
267
268 glBindTexture(GL_TEXTURE_2D, splashtex[0]);
269 glBegin(GL_QUADS);
270 glTexCoord2f(0.0, 0.0);
271 glVertex2i(0, 0);
272 glTexCoord2f(1.0, 0.0);
273 glVertex2i(width / 2, 0);
274 glTexCoord2f(1.0, 1.0);
275 glVertex2i(width / 2, height / 2);
276 glTexCoord2f(0.0, 1.0);
277 glVertex2i(0, height / 2);
278 glEnd();
279
280 glBindTexture(GL_TEXTURE_2D, splashtex[1]);
281 glBegin(GL_QUADS);
282 glTexCoord2f(0.0, 0.0);
283 glVertex2i(width / 2, 0);
284 glTexCoord2f(1.0, 0.0);
285 glVertex2i(width, 0);
286 glTexCoord2f(1.0, 1.0);
287 glVertex2i(width, height / 2);
288 glTexCoord2f(0.0, 1.0);
289 glVertex2i(width / 2, height / 2);
290 glEnd();
291
292 glBindTexture(GL_TEXTURE_2D, splashtex[2]);
293 glBegin(GL_QUADS);
294 glTexCoord2f(0.0, 0.0);
295 glVertex2i(0, height / 2);
296 glTexCoord2f(1.0, 0.0);
297 glVertex2i(width / 2, height / 2);
298 glTexCoord2f(1.0, 1.0);
299 glVertex2i(width / 2, height);
300 glTexCoord2f(0.0, 1.0);
301 glVertex2i(0, height);
302 glEnd();
303
304 glBindTexture(GL_TEXTURE_2D, splashtex[3]);
305 glBegin(GL_QUADS);
306 glTexCoord2f(0.0, 0.0);
307 glVertex2i(width / 2, height / 2);
308 glTexCoord2f(1.0, 0.0);
309 glVertex2i(width, height / 2);
310 glTexCoord2f(1.0, 1.0);
311 glVertex2i(width, height);
312 glTexCoord2f(0.0, 1.0);
313 glVertex2i(width / 2, height);
314 glEnd();
315
316 } else
317 glClear(GL_COLOR_BUFFER_BIT);
318
319
320 switch (fonttype) {
321 case TEXFONT:
322 txfBindFontTexture(txf);
323 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
324 break;
325 case BMAPFONT:
326 glDisable(GL_TEXTURE_2D);
327 glDisable(GL_LIGHTING);
328 glDisable(GL_DEPTH_TEST);
329 glColor3f(1.0, 1.0, 1.0);
330 }
331 printstring(width / 2 - strlen(s) * glyphwidth / 2, height / 2, 0, s);
332 glutSwapBuffers();
333 }
334
335 /*
336 Spheroid drawing routine based on gluSphere Mesa function (src-glu/quadric.c)
337 patched to allow multiple texture objects and flattening.
338 */
Spheroid(double radius,float xflat,float yflat,float zflat,float randomness,int slices,int stacks,planetdata * pdata,int textured)339 static void Spheroid(double radius, float xflat, float yflat, float zflat,
340 float randomness, int slices, int stacks,
341 planetdata * pdata, int textured)
342 {
343 static GLfloat rho, drho, theta, dtheta;
344 GLfloat x, y, z;
345 GLfloat s, t, ds, dt;
346 int i, j, k, imin, imax, tex;
347 double *rarray1, *rarray2, *tmp;
348
349
350 drho = M_PI / (GLfloat) stacks;
351 dtheta = 2.0 * M_PI / (GLfloat) slices;
352
353 /* Allocate memory for surface randomness arrays */
354 rarray1 = (double *) malloc((slices + 1) * 3 * sizeof(double));
355 rarray2 = (double *) malloc((slices + 1) * 3 * sizeof(double));
356
357 if (textured) {
358
359 if (stacks % pdata->texheight) {
360 error("Incorrect STACKS value, edit configuration file\n");
361 shutdown(1);
362 }
363
364 if (slices % pdata->texwidth) {
365 error("Incorrect SLICES value, edit configuration file\n");
366 shutdown(1);
367 }
368
369 ds = 1.0 / slices * pdata->texwidth;
370 dt = 1.0 / stacks * pdata->texheight;
371 t = 1.0;
372 imin = 0;
373 imax = stacks;
374
375
376 /* Initialize surface randomness arrays */
377 for (i = 0; i < (slices + 1) * 3; i++) {
378 rarray1[i] =
379 (1.0 - randomness) +
380 (randomness * 2.0 * rand()) / RAND_MAX;
381 rarray2[i] =
382 (1.0 - randomness) +
383 (randomness * 2.0 * rand()) / RAND_MAX;
384 }
385
386 for (i = imin; i < imax; i++) {
387 rho = i * drho;
388 if (!(i % (imax / pdata->texheight)))
389 t = 1.0;
390 tmp = rarray1;
391 rarray1 = rarray2;
392 rarray2 = tmp;
393 for (k = 0; k < (slices + 1) * 3; k++)
394 rarray2[k] =
395 (1.0 - randomness) +
396 (randomness * 2.0 * rand()) / RAND_MAX;
397
398 for (k = 0; k < pdata->texwidth; k++) {
399 /* Find the texture map we should apply in this iteration */
400 tex = imax / pdata->texheight;
401 tex =
402 (pdata->texwidth * (pdata->texheight - 1) -
403 i / tex * pdata->texwidth) + k;
404 glBindTexture(GL_TEXTURE_2D, pdata->textures[tex]);
405 glBegin(GL_QUAD_STRIP);
406 s = 0.0;
407 /* overwrite last element with first element data */
408 rarray1[(k + 1) * slices / pdata->texwidth * 3] =
409 rarray1[k * slices / pdata->texwidth * 3];
410 rarray1[(k + 1) * slices / pdata->texwidth * 3 + 1] =
411 rarray1[k * slices / pdata->texwidth * 3 + 1];
412 rarray1[(k + 1) * slices / pdata->texwidth * 3 + 2] =
413 rarray1[k * slices / pdata->texwidth * 3 + 2];
414 rarray2[(k + 1) * slices / pdata->texwidth * 3] =
415 rarray2[k * slices / pdata->texwidth * 3];
416 rarray2[(k + 1) * slices / pdata->texwidth * 3 + 1] =
417 rarray2[k * slices / pdata->texwidth * 3 + 1];
418 rarray2[(k + 1) * slices / pdata->texwidth * 3 + 2] =
419 rarray2[k * slices / pdata->texwidth * 3 + 2];
420 for (j = (k * slices / pdata->texwidth);
421 j <= ((k + 1) * slices / pdata->texwidth); j++) {
422 theta = (j == slices) ? 0.0 : j * dtheta;
423 x = -sin(theta) * sin(rho) * rarray1[j * 3];
424 y = cos(theta) * sin(rho) * rarray1[j * 3 + 1];
425 z = cos(rho) * rarray1[j * 3 + 2];
426 glNormal3f(x, y, z);
427 glTexCoord2f(s, t);
428 glVertex3f(x * radius * (1.0 - xflat),
429 y * radius * (1.0 - yflat),
430 z * radius * (1.0 - zflat));
431 x = -sin(theta) * sin(rho + drho) * rarray2[j * 3];
432 y = cos(theta) * sin(rho + drho) * rarray2[j * 3 + 1];
433 z = cos(rho + drho) * rarray2[j * 3 + 2];
434 glNormal3f(x, y, z);
435 glTexCoord2f(s, t - dt);
436 s += ds;
437 glVertex3f(x * radius * (1.0 - xflat),
438 y * radius * (1.0 - yflat),
439 z * radius * (1.0 - zflat));
440 }
441 glEnd();
442 }
443 t -= dt;
444 }
445 } else {
446 ds = 1.0 / slices;
447 dt = 1.0 / stacks;
448 imin = 0;
449 imax = stacks;
450 for (i = imin; i < imax; i++) {
451 rho = i * drho;
452 glBegin(GL_QUAD_STRIP);
453 for (j = 0; j <= slices; j++) {
454 theta = (j == slices) ? 0.0 : j * dtheta;
455 x = -sin(theta) * sin(rho);
456 y = cos(theta) * sin(rho);
457 z = cos(rho);
458 glNormal3f(x, y, z);
459 glVertex3f(x * radius, y * radius, z * radius);
460 x = -sin(theta) * sin(rho + drho);
461 y = cos(theta) * sin(rho + drho);
462 z = cos(rho + drho);
463 glNormal3f(x, y, z);
464 glVertex3f(x * radius, y * radius, z * radius);
465 }
466 glEnd();
467 }
468 }
469 free(rarray1);
470 free(rarray2);
471 }
472
473
474
475 /*
476 Read texture, split large textures into 256x256 pieces and set up
477 display lists
478 */
SetUpBody(int body,char * texfile,int compress_texture)479 void SetUpBody(int body, char *texfile, int compress_texture)
480 {
481 int width = 256, height =
482 256, x1, x2, x3, y, i, j, k, current;
483 GLenum gluerr;
484 BMFObject *obj;
485 char sbuf[80];
486 GLenum intformat, format;
487
488 sprintf(sbuf, "Setting up body: %s", planets[body].Name);
489 Print(sbuf);
490
491 switch (texfile[strlen(texfile) - 1]) {
492 case 'f': /* BMF file */
493 obj = LoadBMF(texfile, RADIUSSCALE(planets[body].Radius));
494 planets[body].HighDetail = glGenLists(1);
495 glNewList(planets[body].HighDetail, GL_COMPILE);
496 glMaterialf(GL_FRONT, GL_SHININESS, 1.0);
497 if (obj->sparse) {
498 for (i = 0; i < obj->NumMaterials; i++) {
499 glInterleavedArrays(GL_T2F_N3F_V3F, 0,
500 obj->sparse[i].vertexlist);
501 glMaterialfv(GL_FRONT, GL_AMBIENT,
502 (GLfloat *) & obj->sparse[i].ambient);
503 glMaterialfv(GL_FRONT, GL_DIFFUSE,
504 (GLfloat *) & obj->sparse[i].diffuse);
505 glMaterialfv(GL_FRONT, GL_SPECULAR,
506 (GLfloat *) & obj->sparse[i].specular);
507
508 if (obj->sparse[i].texture_name_length > 1) {
509 glEnable(GL_TEXTURE_2D);
510 glBindTexture(GL_TEXTURE_2D, obj->sparse[i].texbind);
511 } else
512 glDisable(GL_TEXTURE_2D);
513 glDrawElements(GL_TRIANGLES,
514 obj->sparse[i].number_of_triangles * 3,
515 GL_UNSIGNED_SHORT,
516 obj->sparse[i].indexlist);
517 }
518 } else {
519 for (i = 0; i < obj->NumMaterials; i++) {
520 glInterleavedArrays(GL_T2F_N3F_V3F, 0,
521 obj->strip[i].vertexlist);
522 glMaterialfv(GL_FRONT, GL_AMBIENT,
523 (GLfloat *) & obj->strip[i].ambient);
524 glMaterialfv(GL_FRONT, GL_DIFFUSE,
525 (GLfloat *) & obj->strip[i].diffuse);
526 glMaterialfv(GL_FRONT, GL_SPECULAR,
527 (GLfloat *) & obj->strip[i].specular);
528
529 if (obj->strip[i].texture_name_length > 1) {
530 glEnable(GL_TEXTURE_2D);
531 glBindTexture(GL_TEXTURE_2D, obj->strip[i].texbind);
532 } else
533 glDisable(GL_TEXTURE_2D);
534
535 current = 0;
536 for (j = 0; j < obj->strip[i].number_of_strips; j++) {
537 glDrawElements(GL_TRIANGLE_STRIP,
538 obj->strip[i].length_of_strip[j],
539 GL_UNSIGNED_SHORT,
540 &obj->strip[i].stripindex[current]);
541 current += obj->strip[i].length_of_strip[j];
542 }
543 }
544 }
545 glMaterialfv(GL_FRONT, GL_SPECULAR, Black);
546 glEndList();
547 planets[body].LowDetail = planets[body].MidDetail =
548 planets[body].HighDetail;
549 planets[body].texsize = obj->texsize;
550 break;
551
552 case 'g': /* Spherical body, JPEG texture */
553 planets[body].Image =
554 read_JPEG_file(texfile, &ImgWidth, &ImgHeight, &components);
555
556 if (!planets[body].Image) {
557 sprintf(sbuf, "Couldn't read image %s/%s\n", texturepath,
558 texfile);
559 error(sbuf);
560 shutdown(1);
561 }
562
563 planets[body].Image =
564 texture_LOD(planets[body].Image, &ImgWidth, &ImgHeight,
565 components);
566 if (components == 1)
567 j = 1;
568 else
569 j = color_depth / 8;
570 planets[body].texsize = (ImgWidth * ImgHeight * j);
571
572 if (ImgWidth < width) {
573 planets[body].texwidth = 1;
574 width = ImgWidth;
575 } else
576 planets[body].texwidth = ImgWidth / width;
577 if (ImgHeight < height) {
578 planets[body].texheight = 1;
579 height = ImgHeight;
580 } else
581 planets[body].texheight = ImgHeight / height;
582 planets[body].texnum =
583 planets[body].texwidth * planets[body].texheight;
584 planets[body].textures =
585 (GLuint *) malloc(planets[body].texnum * sizeof(GLuint));
586 if (planets[body].textures == NULL) {
587 error("Couldn't allocate memory");
588 shutdown(1);
589 }
590
591 intformat = components == 3 ? cd_rgb : cd_lum;
592 format = components == 3 ? (GLenum) GL_RGB : (GLenum) GL_LUMINANCE;
593 if ((format == GL_RGB) && tex_compr && compress_texture)
594 intformat = (GLenum) GL_COMPRESSED_RGB_ARB;
595
596
597 glGenTextures(planets[body].texnum, planets[body].textures);
598
599 for (j = 0; j < planets[body].texheight; j++)
600 for (i = 0; i < planets[body].texwidth; i++) {
601 glBindTexture(GL_TEXTURE_2D,
602 planets[body].textures[planets[body].
603 texwidth * j + i]);
604 if (border) {
605 /* Copy pixel data to texture buffer and set up borders */
606 x1 = i * width;
607 x2 = (i * width + ImgWidth - 1) % ImgWidth;
608 x3 = ((i + 1) * width) % ImgWidth;
609 for (k = 0; k < (height + 2); k++) {
610 y = (j * height + k + ImgHeight - 1) % ImgHeight;
611 memcpy(tmpimg + k * (width + 2) * components +
612 components,
613 planets[body].Image +
614 y * ImgWidth * components + x1 * components,
615 width * components);
616 memcpy(tmpimg + k * (width + 2) * components,
617 planets[body].Image +
618 y * ImgWidth * components + x2 * components,
619 components);
620 memcpy(tmpimg + k * (width + 2) * components +
621 (width + 1) * components,
622 planets[body].Image +
623 y * ImgWidth * components + x3 * components,
624 components);
625 }
626 glTexImage2D(GL_TEXTURE_2D,
627 0,
628 intformat,
629 width + 2, height + 2,
630 1,
631 format,
632 GL_UNSIGNED_BYTE, tmpimg);
633 } else {
634 for (k = 0; k < height; k++)
635 memcpy(tmpimg + k * width * components,
636 planets[body].Image +
637 ImgWidth * width * components * j +
638 width * components * i +
639 ImgWidth * components * k,
640 width * components);
641 if (mipmap) {
642 if (
643 (gluerr =
644 (GLenum) gluBuild2DMipmaps(GL_TEXTURE_2D,
645 intformat,
646 width,
647 height,
648 format,
649 GL_UNSIGNED_BYTE,
650 tmpimg))) {
651 error((char *) gluErrorString(gluerr));
652 shutdown(1);
653 }
654 } else {
655 glTexImage2D(GL_TEXTURE_2D,
656 0,
657 intformat,
658 width, height,
659 0,
660 format,
661 GL_UNSIGNED_BYTE, tmpimg);
662 }
663 }
664
665 if (mipmap) {
666 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
667 mipmap_filter);
668 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
669 mipmap_filter);
670 } else {
671 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
672 filter);
673 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
674 filter);
675 }
676 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
677 GL_CLAMP);
678 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
679 GL_CLAMP);
680 }
681 free(planets[body].Image);
682 planets[body].HighDetail = glGenLists(1);
683 glNewList(planets[body].HighDetail, GL_COMPILE);
684 Spheroid(RADIUSSCALE(planets[body].Radius), planets[body].xflat,
685 planets[body].yflat, planets[body].zflat, 0.0,
686 slices, stacks, &planets[body], 1);
687 glEndList();
688 planets[body].MidDetail = glGenLists(1);
689 glNewList(planets[body].MidDetail, GL_COMPILE);
690 Spheroid(RADIUSSCALE(planets[body].Radius), planets[body].xflat,
691 planets[body].yflat, planets[body].zflat, 0.0,
692 slices / 2, stacks / 2, &planets[body], 1);
693 glEndList();
694 planets[body].LowDetail = glGenLists(1);
695 glNewList(planets[body].LowDetail, GL_COMPILE);
696 Spheroid(RADIUSSCALE(planets[body].Radius), planets[body].xflat,
697 planets[body].yflat, planets[body].zflat, 0.0,
698 slices / 4, stacks / 4, &planets[body], 1);
699 glEndList();
700 break;
701 }
702 }
703
704
SetUpAsteroid(int body,char * model)705 void SetUpAsteroid(int body, char *model)
706 {
707 int i, j, current;
708 BMFObject *obj;
709 char sbuf[80];
710
711 sprintf(sbuf, "Setting up Asteroid: %s", planets[body].Name);
712 Print(sbuf);
713 planets[body].Radius /= RADIUSSCALE(1.0);
714 obj = LoadBMF(model, RADIUSSCALE(planets[body].Radius));
715
716 planets[body].HighDetail = glGenLists(1);
717 glNewList(planets[body].HighDetail, GL_COMPILE);
718 glMaterialf(GL_FRONT, GL_SHININESS, 1.0);
719 if (obj->sparse) {
720 for (i = 0; i < obj->NumMaterials; i++) {
721 glInterleavedArrays(GL_T2F_N3F_V3F, 0,
722 obj->sparse[i].vertexlist);
723 glMaterialfv(GL_FRONT, GL_AMBIENT,
724 (GLfloat *) & obj->sparse[i].ambient);
725 glMaterialfv(GL_FRONT, GL_DIFFUSE,
726 (GLfloat *) & obj->sparse[i].diffuse);
727 glMaterialfv(GL_FRONT, GL_SPECULAR,
728 (GLfloat *) & obj->sparse[i].specular);
729
730 if (obj->sparse[i].texture_name_length > 1) {
731 glEnable(GL_TEXTURE_2D);
732 glBindTexture(GL_TEXTURE_2D, obj->sparse[i].texbind);
733 } else
734 glDisable(GL_TEXTURE_2D);
735 glDrawElements(GL_TRIANGLES,
736 obj->sparse[i].number_of_triangles * 3,
737 GL_UNSIGNED_SHORT, obj->sparse[i].indexlist);
738 }
739 } else {
740 for (i = 0; i < obj->NumMaterials; i++) {
741 glInterleavedArrays(GL_T2F_N3F_V3F, 0,
742 obj->strip[i].vertexlist);
743 glMaterialfv(GL_FRONT, GL_AMBIENT,
744 (GLfloat *) & obj->strip[i].ambient);
745 glMaterialfv(GL_FRONT, GL_DIFFUSE,
746 (GLfloat *) & obj->strip[i].diffuse);
747 glMaterialfv(GL_FRONT, GL_SPECULAR,
748 (GLfloat *) & obj->strip[i].specular);
749
750 if (obj->strip[i].texture_name_length > 1) {
751 glEnable(GL_TEXTURE_2D);
752 glBindTexture(GL_TEXTURE_2D, obj->strip[i].texbind);
753 } else
754 glDisable(GL_TEXTURE_2D);
755
756 current = 0;
757 for (j = 0; j < obj->strip[i].number_of_strips; j++) {
758 glDrawElements(GL_TRIANGLE_STRIP,
759 obj->strip[i].length_of_strip[j],
760 GL_UNSIGNED_SHORT,
761 &obj->strip[i].stripindex[current]);
762 current += obj->strip[i].length_of_strip[j];
763 }
764 }
765 }
766 glMaterialfv(GL_FRONT, GL_SPECULAR, Black);
767 glEndList();
768 planets[body].texsize = obj->texsize;
769 }
770
771
772
SetUpComet(int body,char * texfile,float randomness,float lenght,int num_part)773 void SetUpComet(int body, char *texfile, float randomness, float lenght,
774 int num_part)
775 {
776 int i;
777 float a, b, c, xo, yo, zo, xd, yd, zd;
778 char sbuf[80];
779
780 sprintf(sbuf, "Setting up body: %s", planets[body].Name);
781 Print(sbuf);
782
783 planets[body].tail = (particle *) malloc(sizeof(particle) * num_part);
784 planets[body].tail_lenght = lenght;
785 planets[body].num_particles = num_part;
786 for (i = 0; i < num_part; i++) {
787 a = (rand() % 360) * M_PI / 180.0;
788 b = (float) rand() / RAND_MAX;
789 b *= RADIUSSCALE(planets[body].Radius);
790 c = (float) i / (float) num_part *lenght;
791 xo = yo = zo = 0.0;
792 xd = 0.1 * b / RADIUSSCALE(planets[body].Radius) * sin(a);
793 yd = RADIUSSCALE(planets[body].Radius);
794 zd = 0.1 * b / RADIUSSCALE(planets[body].Radius) * cos(a);
795 planets[body].tail[i].dist = c;
796 c = DISTANCE(xd, yd, zd);
797 planets[body].tail[i].origin[0] = xo;
798 planets[body].tail[i].origin[1] = yo;
799 planets[body].tail[i].origin[2] = zo;
800 planets[body].tail[i].dir[0] = xd / c;
801 planets[body].tail[i].dir[1] = zd / c;
802 planets[body].tail[i].dir[2] = yd / c;
803 }
804 }
805
806
SetUpOrbiter(int body,char * model)807 void SetUpOrbiter(int body, char *model)
808 {
809 int i, j, current;
810 BMFObject *obj;
811 char sbuf[80];
812
813 sprintf(sbuf, "Setting up orbiter: %s", planets[body].Name);
814 Print(sbuf);
815 planets[body].Radius /= RADIUSSCALE(1.0);
816 obj = LoadBMF(model, RADIUSSCALE(planets[body].Radius));
817 planets[body].HighDetail = glGenLists(1);
818 glNewList(planets[body].HighDetail, GL_COMPILE);
819 glMaterialf(GL_FRONT, GL_SHININESS, 1.0);
820 if (obj->sparse) {
821 for (i = 0; i < obj->NumMaterials; i++) {
822 glInterleavedArrays(GL_T2F_N3F_V3F, 0,
823 obj->sparse[i].vertexlist);
824 glMaterialfv(GL_FRONT, GL_AMBIENT,
825 (GLfloat *) & obj->sparse[i].ambient);
826 glMaterialfv(GL_FRONT, GL_DIFFUSE,
827 (GLfloat *) & obj->sparse[i].diffuse);
828 glMaterialfv(GL_FRONT, GL_SPECULAR,
829 (GLfloat *) & obj->sparse[i].specular);
830
831 if (obj->sparse[i].texture_name_length > 1) {
832 glEnable(GL_TEXTURE_2D);
833 glBindTexture(GL_TEXTURE_2D, obj->sparse[i].texbind);
834 } else
835 glDisable(GL_TEXTURE_2D);
836 glDrawElements(GL_TRIANGLES,
837 obj->sparse[i].number_of_triangles * 3,
838 GL_UNSIGNED_SHORT, obj->sparse[i].indexlist);
839 }
840 } else {
841 for (i = 0; i < obj->NumMaterials; i++) {
842 glInterleavedArrays(GL_T2F_N3F_V3F, 0,
843 obj->strip[i].vertexlist);
844 glMaterialfv(GL_FRONT, GL_AMBIENT,
845 (GLfloat *) & obj->strip[i].ambient);
846 glMaterialfv(GL_FRONT, GL_DIFFUSE,
847 (GLfloat *) & obj->strip[i].diffuse);
848 glMaterialfv(GL_FRONT, GL_SPECULAR,
849 (GLfloat *) & obj->strip[i].specular);
850
851 if (obj->strip[i].texture_name_length > 1) {
852 glEnable(GL_TEXTURE_2D);
853 glBindTexture(GL_TEXTURE_2D, obj->strip[i].texbind);
854 } else
855 glDisable(GL_TEXTURE_2D);
856
857 current = 0;
858 for (j = 0; j < obj->strip[i].number_of_strips; j++) {
859 glDrawElements(GL_TRIANGLE_STRIP,
860 obj->strip[i].length_of_strip[j],
861 GL_UNSIGNED_SHORT,
862 &obj->strip[i].stripindex[current]);
863 current += obj->strip[i].length_of_strip[j];
864 }
865 }
866 }
867 glMaterialfv(GL_FRONT, GL_SPECULAR, Black);
868 glEndList();
869 planets[body].texsize = obj->texsize;
870 }
871
872
SetUpSpaceShip(int body,char * model)873 void SetUpSpaceShip(int body, char *model)
874 {
875 int i, j, current;
876 BMFObject *obj;
877 char sbuf[80];
878
879 sprintf(sbuf, "Setting up SpaceShip: %s", planets[body].Name);
880 Print(sbuf);
881 planets[body].Radius /= RADIUSSCALE(1.0);
882 obj = LoadBMF(model, RADIUSSCALE(planets[body].Radius));
883 planets[body].HighDetail = glGenLists(1);
884 glNewList(planets[body].HighDetail, GL_COMPILE);
885 glMaterialf(GL_FRONT, GL_SHININESS, 1.0);
886 if (obj->sparse) {
887 for (i = 0; i < obj->NumMaterials; i++) {
888 glInterleavedArrays(GL_T2F_N3F_V3F, 0,
889 obj->sparse[i].vertexlist);
890 glMaterialfv(GL_FRONT, GL_AMBIENT,
891 (GLfloat *) & obj->sparse[i].ambient);
892 glMaterialfv(GL_FRONT, GL_DIFFUSE,
893 (GLfloat *) & obj->sparse[i].diffuse);
894 glMaterialfv(GL_FRONT, GL_SPECULAR,
895 (GLfloat *) & obj->sparse[i].specular);
896
897 if (obj->sparse[i].texture_name_length > 1) {
898 glEnable(GL_TEXTURE_2D);
899 glBindTexture(GL_TEXTURE_2D, obj->sparse[i].texbind);
900 } else
901 glDisable(GL_TEXTURE_2D);
902
903 glDrawElements(GL_TRIANGLES,
904 obj->sparse[i].number_of_triangles * 3,
905 GL_UNSIGNED_SHORT, obj->sparse[i].indexlist);
906
907 if (obj->sparse[i].texture_name_length <= 1)
908 glEnable(GL_TEXTURE_2D);
909
910 }
911 } else {
912 for (i = 0; i < obj->NumMaterials; i++) {
913 glInterleavedArrays(GL_T2F_N3F_V3F, 0,
914 obj->strip[i].vertexlist);
915 glMaterialfv(GL_FRONT, GL_AMBIENT,
916 (GLfloat *) & obj->strip[i].ambient);
917 glMaterialfv(GL_FRONT, GL_DIFFUSE,
918 (GLfloat *) & obj->strip[i].diffuse);
919 glMaterialfv(GL_FRONT, GL_SPECULAR,
920 (GLfloat *) & obj->strip[i].specular);
921
922 if (obj->strip[i].texture_name_length > 1) {
923 glEnable(GL_TEXTURE_2D);
924 glBindTexture(GL_TEXTURE_2D, obj->strip[i].texbind);
925 } else
926 glDisable(GL_TEXTURE_2D);
927
928 current = 0;
929 for (j = 0; j < obj->strip[i].number_of_strips; j++) {
930 glDrawElements(GL_TRIANGLE_STRIP,
931 obj->strip[i].length_of_strip[j],
932 GL_UNSIGNED_SHORT,
933 &obj->strip[i].stripindex[current]);
934 current += obj->strip[i].length_of_strip[j];
935 }
936
937 if (obj->strip[i].texture_name_length <= 1)
938 glEnable(GL_TEXTURE_2D);
939
940 }
941 }
942 glMaterialfv(GL_FRONT, GL_SPECULAR, Black);
943 glEndList();
944 planets[body].texsize = obj->texsize;
945 }
946
947
948
949
SetUpRings(int body,char * texfile,float inner_radius,float outter_radius,float tlevel)950 void SetUpRings(int body, char *texfile, float inner_radius,
951 float outter_radius, float tlevel)
952 {
953 unsigned char *localimage;
954 int i;
955 char sbuf[80];
956
957 sprintf(sbuf, "Setting up rings: %s", planets[planets[body].Sat].Name);
958 Print(sbuf);
959
960 planets[body].Image =
961 read_JPEG_file(texfile, &ImgWidth, &ImgHeight, &components);
962 if (!planets[body].Image) {
963 sprintf(sbuf, "Couldn't read image %s/%s\n", texturepath, texfile);
964 error(sbuf);
965 shutdown(1);
966 }
967
968 localimage =
969 (unsigned char *) malloc(ImgHeight * ImgWidth * (components + 1));
970 if (localimage == NULL) {
971 error("Couldn't allocate memory");
972 shutdown(1);
973 }
974
975
976 switch (components) {
977 case 1:
978 for (i = 0; i < (ImgHeight * ImgWidth); i++) {
979 localimage[i * 2] = planets[body].Image[i];
980 localimage[i * 2 + 1] =
981 (unsigned char) (planets[body].Image[i] / tlevel);
982 }
983 break;
984 case 3:
985 for (i = 0; i < (ImgHeight * ImgWidth); i++) {
986 localimage[i * 4] = planets[body].Image[i * 3];
987 localimage[i * 4 + 1] = planets[body].Image[i * 3 + 1];
988 localimage[i * 4 + 2] = planets[body].Image[i * 3 + 2];
989 localimage[i * 4 + 3] =
990 (unsigned
991 char) ((planets[body].Image[i * 3] +
992 planets[body].Image[i * 3 + 1] +
993 planets[body].Image[i * 3 + 2]) / 3 / tlevel);
994 }
995 break;
996 }
997
998 planets[body].texnum = 1;
999 planets[body].textures =
1000 (GLuint *) malloc(planets[body].texnum * sizeof(GLuint));
1001 if (planets[body].textures == NULL) {
1002 error("Couldn't allocate memory");
1003 shutdown(1);
1004 }
1005 glGenTextures(planets[body].texnum, planets[body].textures);
1006 glBindTexture(GL_TEXTURE_2D, planets[body].textures[0]);
1007 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
1008 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
1009 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1010 glTexImage2D(GL_TEXTURE_2D,
1011 0,
1012 components == 3 ? cd_rgba : cd_luma,
1013 ImgWidth, ImgHeight,
1014 0,
1015 components == 3 ? GL_RGBA : GL_LUMINANCE_ALPHA,
1016 GL_UNSIGNED_BYTE, localimage);
1017
1018 free(planets[body].Image);
1019 free(localimage);
1020
1021
1022 }
1023
1024
SetUpAtmosphere(int body,char * texfile,float level,int cut)1025 void SetUpAtmosphere(int body, char *texfile, float level, int cut)
1026 {
1027 int width = 256, height = 256, x1, x2, x3, y, i, j, k;
1028 unsigned char localimage[258 * 258 * 4];
1029 GLenum gluerr;
1030 char sbuf[80];
1031
1032 sprintf(sbuf, "Setting up atmosphere: %s",
1033 planets[planets[body].Sat].Name);
1034 Print(sbuf);
1035
1036 planets[body].Image =
1037 read_JPEG_file(texfile, &ImgWidth, &ImgHeight, &components);
1038 if (!planets[body].Image) {
1039 sprintf(sbuf, "Couldn't read image %s/%s\n", texturepath, texfile);
1040 error(sbuf);
1041 shutdown(1);
1042 }
1043
1044 planets[body].Image =
1045 texture_LOD(planets[body].Image, &ImgWidth, &ImgHeight,
1046 components);
1047 if (components == 1)
1048 j = 1;
1049 else
1050 j = color_depth / 8;
1051 planets[body].texsize = (ImgWidth * ImgHeight * j);
1052
1053 if (ImgWidth < width) {
1054 planets[body].texwidth = 1;
1055 width = ImgWidth;
1056 } else
1057 planets[body].texwidth = ImgWidth / width;
1058 if (ImgHeight < height) {
1059 planets[body].texheight = 1;
1060 height = ImgHeight;
1061 } else
1062 planets[body].texheight = ImgHeight / height;
1063 planets[body].texnum =
1064 planets[body].texwidth * planets[body].texheight;
1065 planets[body].textures =
1066 (GLuint *) malloc(planets[body].texnum * sizeof(GLuint));
1067 if (planets[body].textures == NULL) {
1068 error("Couldn't allocate memory");
1069 shutdown(1);
1070 }
1071 glGenTextures(planets[body].texnum, planets[body].textures);
1072
1073 for (j = 0; j < planets[body].texheight; j++)
1074 for (i = 0; i < planets[body].texwidth; i++) {
1075
1076 glBindTexture(GL_TEXTURE_2D,
1077 planets[body].textures[planets[body].texwidth *
1078 j + i]);
1079
1080 if (border) {
1081 /* Copy pixel data to texture buffer and set up borders */
1082 x1 = i * width;
1083 x2 = (i * width + ImgWidth - 1) % ImgWidth;
1084 x3 = ((i + 1) * width) % ImgWidth;
1085 for (k = 0; k < (height + 2); k++) {
1086 y = (j * height + k + ImgHeight - 1) % ImgHeight;
1087 memcpy(tmpimg + k * (width + 2) * components +
1088 components,
1089 planets[body].Image +
1090 y * ImgWidth * components + x1 * components,
1091 width * components);
1092 memcpy(tmpimg + k * (width + 2) * components,
1093 planets[body].Image +
1094 y * ImgWidth * components + x2 * components,
1095 components);
1096 memcpy(tmpimg + k * (width + 2) * components +
1097 (width + 1) * components,
1098 planets[body].Image +
1099 y * ImgWidth * components + x3 * components,
1100 components);
1101 }
1102
1103 for (k = 0; k < (258 * 258); k++) {
1104 localimage[k * (components + 1)] =
1105 tmpimg[k * components];
1106 localimage[k * (components + 1) + 1] =
1107 tmpimg[k * components + 1];
1108 localimage[k * (components + 1) + 2] =
1109 tmpimg[k * components + 2];
1110 if (components == 3)
1111 y =
1112 (tmpimg[k * 3] + tmpimg[k * 3 + 1] +
1113 tmpimg[k * 3 + 2]) / 3;
1114 else
1115 y = tmpimg[k];
1116 if (y < cut)
1117 y = 0;
1118 localimage[k * (components + 1) + components] =
1119 (unsigned char) ((float) y / level);
1120 }
1121
1122 glTexImage2D(GL_TEXTURE_2D,
1123 0,
1124 components == 3 ? cd_rgba : cd_luma,
1125 width + 2, height + 2,
1126 1,
1127 components ==
1128 3 ? GL_RGBA : GL_LUMINANCE_ALPHA,
1129 GL_UNSIGNED_BYTE, localimage);
1130 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
1131 filter);
1132 } else {
1133 for (k = 0; k < height; k++)
1134 memcpy(tmpimg + k * width * components,
1135 planets[body].Image +
1136 ImgWidth * width * components * j +
1137 width * components * i +
1138 ImgWidth * components * k, width * components);
1139
1140 for (k = 0; k < (256 * 256); k++) {
1141 localimage[k * (components + 1)] =
1142 tmpimg[k * components];
1143 localimage[k * (components + 1) + 1] =
1144 tmpimg[k * components + 1];
1145 localimage[k * (components + 1) + 2] =
1146 tmpimg[k * components + 2];
1147 if (components == 3)
1148 y =
1149 (tmpimg[k * 3] + tmpimg[k * 3 + 1] +
1150 tmpimg[k * 3 + 2]) / 3;
1151 else
1152 y = tmpimg[k];
1153 if (y < cut)
1154 y = 0;
1155 localimage[k * (components + 1) + components] =
1156 (unsigned char) ((float) y / level);
1157 }
1158
1159 if (mipmap) {
1160 if (
1161 (gluerr =
1162 (GLenum) gluBuild2DMipmaps(GL_TEXTURE_2D,
1163 components ==
1164 3 ? cd_rgba : cd_luma,
1165 width, height,
1166 components ==
1167 3 ? GL_RGBA :
1168 GL_LUMINANCE_ALPHA,
1169 GL_UNSIGNED_BYTE,
1170 localimage))) {
1171 error((char *) gluErrorString(gluerr));
1172 shutdown(1);
1173 }
1174 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
1175 mipmap_filter);
1176 } else {
1177 glTexImage2D(GL_TEXTURE_2D,
1178 0,
1179 components == 3 ? cd_rgba : cd_luma,
1180 width, height,
1181 0,
1182 components ==
1183 3 ? GL_RGBA : GL_LUMINANCE_ALPHA,
1184 GL_UNSIGNED_BYTE, localimage);
1185 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
1186 filter);
1187 }
1188
1189 }
1190 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1191 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1192 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
1193 }
1194 free(planets[body].Image);
1195 planets[body].HighDetail = glGenLists(1);
1196 glNewList(planets[body].HighDetail, GL_COMPILE);
1197 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1198 glEnable(GL_BLEND);
1199 Spheroid(RADIUSSCALE(planets[body].Radius),
1200 planets[planets[body].Sat].xflat,
1201 planets[planets[body].Sat].yflat,
1202 planets[planets[body].Sat].zflat, 0.0, slices, stacks,
1203 &planets[body], 1);
1204 glDisable(GL_BLEND);
1205 glEndList();
1206 planets[body].MidDetail = glGenLists(1);
1207 glNewList(planets[body].MidDetail, GL_COMPILE);
1208 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1209 glEnable(GL_BLEND);
1210 Spheroid(RADIUSSCALE(planets[body].Radius),
1211 planets[planets[body].Sat].xflat,
1212 planets[planets[body].Sat].yflat,
1213 planets[planets[body].Sat].zflat, 0.0, slices / 2, stacks / 2,
1214 &planets[body], 1);
1215 glDisable(GL_BLEND);
1216 glEndList();
1217 planets[body].LowDetail = glGenLists(1);
1218 glNewList(planets[body].LowDetail, GL_COMPILE);
1219 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1220 glEnable(GL_BLEND);
1221 Spheroid(RADIUSSCALE(planets[body].Radius),
1222 planets[planets[body].Sat].xflat,
1223 planets[planets[body].Sat].yflat,
1224 planets[planets[body].Sat].zflat, 0.0, slices / 4, stacks / 4,
1225 &planets[body], 1);
1226 glDisable(GL_BLEND);
1227 glEndList();
1228 }
1229
1230
1231
SetUpTrails(void)1232 static void SetUpTrails(void)
1233 {
1234 int i, j;
1235 double d;
1236
1237 Print("Setting up Trails");
1238 for (i = 1; i < NUMBODIES; i++) {
1239 if ((planets[i].Type != PLANET) &&
1240 (planets[i].Type != ASTEROID) && (planets[i].Type != COMET))
1241 continue;
1242 planets[i].Trail = glGenLists(1);
1243 glNewList(planets[i].Trail, GL_COMPILE);
1244 glColor3f(planets[i].Color[0], planets[i].Color[1],
1245 planets[i].Color[2]);
1246 glBegin(GL_LINE_LOOP);
1247 d = 0.0;
1248 for (j = 0; j < 360; j++) {
1249 UpdatePositions(d, i);
1250 glVertex3dv(planets[i].pos);
1251 d += planets[i].OrbitalPeriod / 360.0;
1252 }
1253 glEnd();
1254 glEndList();
1255 }
1256 }
1257
1258
1259
InitSun(char * filename,double blend,int cutlevel)1260 void InitSun(char *filename, double blend, int cutlevel)
1261 {
1262 static int i;
1263 char sbuf[80];
1264
1265 Print("Setting up The Sun");
1266
1267 planets[0].Radius = 2.0; /*Real Radius is 109.6 */
1268 planets[0].Degrees = 0.0;
1269 planets[0].DeltaRotation = 0.0;
1270 planets[0].Rotation = 360.0 / 28.0;
1271 planets[0].Inclination = 0.0;
1272 planets[0].Sat = 0;
1273 INITVECTOR(planets[0].pos, 0.0, 0.0, 0.0);
1274 INITVECTOR(planets[0].vel, 0.0, 0.0, 0.0);
1275 sprintf(planets[0].Name, "Sun");
1276
1277 planets[0].Image =
1278 read_JPEG_file(filename, &ImgWidth, &ImgHeight, &components);
1279 if (!planets[0].Image) {
1280 sprintf(sbuf, "Couldn't read image %s/sun.jpg\n", texturepath);
1281 error(sbuf);
1282 shutdown(1);
1283 }
1284 if (components == 1)
1285 i = 1;
1286 else
1287 i = color_depth / 8;
1288 planets[0].texsize = (ImgWidth * ImgHeight * i);
1289
1290 planets[0].texnum = 7;
1291 planets[0].textures = (GLuint *) malloc(sizeof(GLuint) * 7);
1292 if (planets[0].textures == NULL) {
1293 error("Couldn't allocate memory");
1294 shutdown(1);
1295 }
1296
1297 glGenTextures(7, planets[0].textures);
1298 glBindTexture(GL_TEXTURE_2D, planets[0].textures[0]);
1299 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
1300 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
1301 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1302 glTexImage2D(GL_TEXTURE_2D,
1303 0,
1304 components == 3 ? cd_rgb : cd_lum,
1305 ImgWidth, ImgHeight,
1306 0, GL_RGB, GL_UNSIGNED_BYTE, planets[0].Image);
1307
1308 free(planets[0].Image);
1309 }
1310