blob: 2173b54fd4d74d8db812621150fb87802ff919e5 [file] [log] [blame]
Brian Paul5b0a7f32000-06-27 16:52:38 +00001/*
2 * This program is under the GNU GPL.
3 * Use at your own risk.
4 *
5 * written by David Bucciarelli (tech.hmw@plus.it)
6 * Humanware s.r.l.
7 */
8
9#include <stdio.h>
10#include <stdlib.h>
11#include <math.h>
12
13#ifdef WIN32
14#include <windows.h>
15#endif
16
17#include <GL/glut.h>
18
19#ifdef XMESA
20#include "GL/xmesa.h"
21static int fullscreen = 1;
22#endif
23
24static int WIDTH = 640;
25static int HEIGHT = 480;
26
Brian Pauld49b34a2000-09-12 18:44:45 +000027static GLint T0 = 0;
28static GLint Frames = 0;
Brian Paul5b0a7f32000-06-27 16:52:38 +000029
30#define BASESIZE 7.5f
31#define SPHERE_RADIUS 0.75f
32
33#define TEX_CHECK_WIDTH 256
34#define TEX_CHECK_HEIGHT 256
35#define TEX_CHECK_SLOT_SIZE (TEX_CHECK_HEIGHT/16)
36#define TEX_CHECK_NUMSLOT (TEX_CHECK_HEIGHT/TEX_CHECK_SLOT_SIZE)
37
38#define TEX_REFLECT_WIDTH 256
39#define TEX_REFLECT_HEIGHT 256
40#define TEX_REFLECT_SLOT_SIZE (TEX_REFLECT_HEIGHT/16)
41#define TEX_REFLECT_NUMSLOT (TEX_REFLECT_HEIGHT/TEX_REFLECT_SLOT_SIZE)
42
43#ifndef M_PI
44#define M_PI 3.1415926535
45#endif
46
47#define EPSILON 0.0001
48
49#define clamp255(a) ( (a)<(0.0f) ? (0.0f) : ((a)>(255.0f) ? (255.0f) : (a)) )
50
51#define fabs(x) ((x)<0.0f?-(x):(x))
52
53#define vequ(a,b) { (a)[0]=(b)[0]; (a)[1]=(b)[1]; (a)[2]=(b)[2]; }
54#define vsub(a,b,c) { (a)[0]=(b)[0]-(c)[0]; (a)[1]=(b)[1]-(c)[1]; (a)[2]=(b)[2]-(c)[2]; }
55#define dprod(a,b) ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[2])
56#define vnormalize(a,b) { \
57 register float m_norm; \
58 m_norm=sqrt((double)dprod((a),(a))); \
59 (a)[0] /=m_norm; \
60 (a)[1] /=m_norm; \
61 (a)[2] /=m_norm; }
62
63static GLubyte checkmap[TEX_CHECK_HEIGHT][TEX_CHECK_WIDTH][3];
64static GLuint checkid;
65static int checkmap_currentslot = 0;
66
67static GLubyte reflectmap[TEX_REFLECT_HEIGHT][TEX_REFLECT_WIDTH][3];
68static GLuint reflectid;
69static int reflectmap_currentslot = 0;
70
71static GLuint lightdlist;
72static GLuint objdlist;
73
74static float lightpos[3] = { 2.1, 2.1, 2.8 };
75static float objpos[3] = { 0.0, 0.0, 1.0 };
76
77static float sphere_pos[TEX_CHECK_HEIGHT][TEX_REFLECT_WIDTH][3];
78
79static int win = 0;
80
81static float fogcolor[4] = { 0.05, 0.05, 0.05, 1.0 };
82
83static float obs[3] = { 7.0, 0.0, 2.0 };
84static float dir[3];
85static float v = 0.0;
86static float alpha = -90.0;
87static float beta = 90.0;
88
89static int fog = 1;
90static int bfcull = 1;
91static int poutline = 0;
92static int help = 1;
93static int showcheckmap = 1;
94static int showreflectmap = 1;
95static int joyavailable = 0;
96static int joyactive = 0;
97
Brian Paul5b0a7f32000-06-27 16:52:38 +000098static void
99calcposobs(void)
100{
101 dir[0] = sin(alpha * M_PI / 180.0);
102 dir[1] = cos(alpha * M_PI / 180.0) * sin(beta * M_PI / 180.0);
103 dir[2] = cos(beta * M_PI / 180.0);
104
Brian Paula41edc32001-05-09 20:02:28 +0000105 if (dir[0] < 1.0e-5 && dir[0] > -1.0e-5)
106 dir[0] = 0;
107 if (dir[1] < 1.0e-5 && dir[1] > -1.0e-5)
108 dir[1] = 0;
109 if (dir[2] < 1.0e-5 && dir[2] > -1.0e-5)
110 dir[2] = 0;
111
Brian Paul5b0a7f32000-06-27 16:52:38 +0000112 obs[0] += v * dir[0];
113 obs[1] += v * dir[1];
114 obs[2] += v * dir[2];
115}
116
117static void
118special(int k, int x, int y)
119{
120 switch (k) {
121 case GLUT_KEY_LEFT:
122 alpha -= 2.0;
123 break;
124 case GLUT_KEY_RIGHT:
125 alpha += 2.0;
126 break;
127 case GLUT_KEY_DOWN:
128 beta -= 2.0;
129 break;
130 case GLUT_KEY_UP:
131 beta += 2.0;
132 break;
133 }
134}
135
136static void
137key(unsigned char k, int x, int y)
138{
139 switch (k) {
140 case 27:
141 exit(0);
142 break;
143
144 case 's':
145 lightpos[1] -= 0.1;
146 break;
147 case 'd':
148 lightpos[1] += 0.1;
149 break;
150 case 'e':
151 lightpos[0] -= 0.1;
152 break;
153 case 'x':
154 lightpos[0] += 0.1;
155 break;
156 case 'w':
157 lightpos[2] -= 0.1;
158 break;
159 case 'r':
160 lightpos[2] += 0.1;
161 break;
162
163 case 'j':
164 objpos[1] -= 0.1;
165 break;
166 case 'k':
167 objpos[1] += 0.1;
168 break;
169 case 'i':
170 objpos[0] -= 0.1;
171 break;
172 case 'm':
173 objpos[0] += 0.1;
174 break;
175 case 'u':
176 objpos[2] -= 0.1;
177 break;
178 case 'o':
179 objpos[2] += 0.1;
180 break;
181
182 case 'a':
183 v += 0.005;
184 break;
185 case 'z':
186 v -= 0.005;
187 break;
188
189 case 'g':
190 joyactive = (!joyactive);
191 break;
192 case 'h':
193 help = (!help);
194 break;
195 case 'f':
196 fog = (!fog);
197 break;
198
199 case '1':
200 showcheckmap = (!showcheckmap);
201 break;
202 case '2':
203 showreflectmap = (!showreflectmap);
204 break;
205
206 case 'b':
207 if (bfcull) {
208 glDisable(GL_CULL_FACE);
209 bfcull = 0;
210 }
211 else {
212 glEnable(GL_CULL_FACE);
213 bfcull = 1;
214 }
215 break;
216 case 'p':
217 if (poutline) {
218 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
219 poutline = 0;
220 }
221 else {
222 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
223 poutline = 1;
224 }
225 break;
226#ifdef XMESA
227 case ' ':
228 XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW);
229 fullscreen = (!fullscreen);
230 break;
231#endif
232 }
233}
234
235static void
236reshape(int w, int h)
237{
238 WIDTH = w;
239 HEIGHT = h;
240 glViewport(0, 0, w, h);
241 glMatrixMode(GL_PROJECTION);
242 glLoadIdentity();
243 gluPerspective(45.0, w / (float) h, 0.8, 40.0);
244 glMatrixMode(GL_MODELVIEW);
245 glLoadIdentity();
246}
247
248static void
249printstring(void *font, char *string)
250{
251 int len, i;
252
253 len = (int) strlen(string);
254 for (i = 0; i < len; i++)
255 glutBitmapCharacter(font, string[i]);
256}
257
258static void
259printhelp(void)
260{
261 glEnable(GL_BLEND);
262 glColor4f(0.5, 0.5, 0.5, 0.5);
263 glRecti(40, 40, 600, 440);
264 glDisable(GL_BLEND);
265
266 glColor3f(0.0, 0.0, 1.0);
267 glRasterPos2i(300, 420);
268 printstring(GLUT_BITMAP_HELVETICA_18, "Help");
269
270 glRasterPos2i(60, 390);
271 printstring(GLUT_BITMAP_HELVETICA_12, "h - Togle Help");
272 glRasterPos2i(60, 370);
273 printstring(GLUT_BITMAP_HELVETICA_12, "f - Togle Fog");
274 glRasterPos2i(60, 350);
275 printstring(GLUT_BITMAP_HELVETICA_12, "b - Togle Back face culling");
276 glRasterPos2i(60, 330);
277 printstring(GLUT_BITMAP_HELVETICA_12, "p - Togle Wire frame");
278 glRasterPos2i(60, 310);
279 printstring(GLUT_BITMAP_HELVETICA_12, "Arrow Keys - Rotate");
280 glRasterPos2i(60, 290);
281 printstring(GLUT_BITMAP_HELVETICA_12, "a - Increase velocity");
282 glRasterPos2i(60, 270);
283 printstring(GLUT_BITMAP_HELVETICA_12, "z - Decrease velocity");
284
285 glRasterPos2i(60, 250);
286 if (joyavailable)
287 printstring(GLUT_BITMAP_HELVETICA_12,
288 "j - Togle jostick control (Joystick control available)");
289 else
290 printstring(GLUT_BITMAP_HELVETICA_12,
291 "(No Joystick control available)");
292
293 glRasterPos2i(60, 230);
294 printstring(GLUT_BITMAP_HELVETICA_12,
295 "To move the light source: s - left, d - right, e - far, x - near, w - down r - up");
296 glRasterPos2i(60, 210);
297 printstring(GLUT_BITMAP_HELVETICA_12,
298 "To move the mirror sphere: j - left, k - right, i - far, m - near, u - down o - up");
299
300 glRasterPos2i(60, 190);
301 printstring(GLUT_BITMAP_HELVETICA_12,
302 "1 - Togle the plane texture map window");
303
304 glRasterPos2i(60, 170);
305 printstring(GLUT_BITMAP_HELVETICA_12,
306 "2 - Togle the sphere texture map window");
307}
308
309static GLboolean
310seelight(float p[3], float dir[3])
311{
312 float c[3], b, a, d, t, dist[3];
313
314 vsub(c, p, objpos);
315 b = -dprod(c, dir);
316 a = dprod(c, c) - SPHERE_RADIUS * SPHERE_RADIUS;
317
318 if ((d = b * b - a) < 0.0 || (b < 0.0 && a > 0.0))
319 return GL_FALSE;
320
321 d = sqrt(d);
322
323 t = b - d;
324
325 if (t < EPSILON) {
326 t = b + d;
327 if (t < EPSILON)
328 return GL_FALSE;
329 }
330
331 vsub(dist, lightpos, p);
332 if (dprod(dist, dist) < t * t)
333 return GL_FALSE;
334
335 return GL_TRUE;
336}
337
338static int
339colorcheckmap(float ppos[3], float c[3])
340{
341 static float norm[3] = { 0.0f, 0.0f, 1.0f };
342 float ldir[3], vdir[3], h[3], dfact, kfact, r, g, b;
343 int x, y;
344
345 x = (int) ((ppos[0] + BASESIZE / 2) * (10.0f / BASESIZE));
346 if ((x < 0) || (x > 10))
347 return GL_FALSE;
348
349 y = (int) ((ppos[1] + BASESIZE / 2) * (10.0f / BASESIZE));
350 if ((y < 0) || (y > 10))
351 return GL_FALSE;
352
353 r = 255.0f;
354 if (y & 1) {
355 if (x & 1)
356 g = 255.0f;
357 else
358 g = 0.0f;
359 }
360 else {
361 if (x & 1)
362 g = 0.0f;
363 else
364 g = 255.0f;
365 }
366 b = 0.0f;
367
368 vsub(ldir, lightpos, ppos);
369 vnormalize(ldir, ldir);
370
371 if (seelight(ppos, ldir)) {
372 c[0] = r * 0.05f;
373 c[1] = g * 0.05f;
374 c[2] = b * 0.05f;
375
376 return GL_TRUE;
377 }
378
379 dfact = dprod(ldir, norm);
380 if (dfact < 0.0f)
381 dfact = 0.0f;
382
383 vsub(vdir, obs, ppos);
384 vnormalize(vdir, vdir);
385 h[0] = 0.5f * (vdir[0] + ldir[0]);
386 h[1] = 0.5f * (vdir[1] + ldir[1]);
387 h[2] = 0.5f * (vdir[2] + ldir[2]);
388 kfact = dprod(h, norm);
Brian Paulb9f24942001-05-09 21:36:52 +0000389 kfact = pow(kfact, 6.0) * 7.0 * 255.0;
Brian Paul5b0a7f32000-06-27 16:52:38 +0000390
391 r = r * dfact + kfact;
392 g = g * dfact + kfact;
393 b = b * dfact + kfact;
394
395 c[0] = clamp255(r);
396 c[1] = clamp255(g);
397 c[2] = clamp255(b);
398
399 return GL_TRUE;
400}
401
402static void
403updatecheckmap(int slot)
404{
405 float c[3], ppos[3];
406 int x, y;
407
408 glBindTexture(GL_TEXTURE_2D, checkid);
409
410 ppos[2] = 0.0f;
411 for (y = slot * TEX_CHECK_SLOT_SIZE; y < (slot + 1) * TEX_CHECK_SLOT_SIZE;
412 y++) {
413 ppos[1] = (y / (float) TEX_CHECK_HEIGHT) * BASESIZE - BASESIZE / 2;
414
415 for (x = 0; x < TEX_CHECK_WIDTH; x++) {
416 ppos[0] = (x / (float) TEX_CHECK_WIDTH) * BASESIZE - BASESIZE / 2;
417
418 colorcheckmap(ppos, c);
419 checkmap[y][x][0] = (GLubyte) c[0];
420 checkmap[y][x][1] = (GLubyte) c[1];
421 checkmap[y][x][2] = (GLubyte) c[2];
422 }
423 }
424
425 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, slot * TEX_CHECK_SLOT_SIZE,
426 TEX_CHECK_WIDTH, TEX_CHECK_SLOT_SIZE, GL_RGB,
427 GL_UNSIGNED_BYTE,
428 &checkmap[slot * TEX_CHECK_SLOT_SIZE][0][0]);
429
430}
431
432static void
433updatereflectmap(int slot)
434{
435 float rf, r, g, b, t, dfact, kfact, rdir[3];
436 float rcol[3], ppos[3], norm[3], ldir[3], h[3], vdir[3], planepos[3];
437 int x, y;
438
439 glBindTexture(GL_TEXTURE_2D, reflectid);
440
441 for (y = slot * TEX_REFLECT_SLOT_SIZE;
442 y < (slot + 1) * TEX_REFLECT_SLOT_SIZE; y++)
443 for (x = 0; x < TEX_REFLECT_WIDTH; x++) {
444 ppos[0] = sphere_pos[y][x][0] + objpos[0];
445 ppos[1] = sphere_pos[y][x][1] + objpos[1];
446 ppos[2] = sphere_pos[y][x][2] + objpos[2];
447
448 vsub(norm, ppos, objpos);
449 vnormalize(norm, norm);
450
451 vsub(ldir, lightpos, ppos);
452 vnormalize(ldir, ldir);
453 vsub(vdir, obs, ppos);
454 vnormalize(vdir, vdir);
455
456 rf = 2.0f * dprod(norm, vdir);
457 if (rf > EPSILON) {
458 rdir[0] = rf * norm[0] - vdir[0];
459 rdir[1] = rf * norm[1] - vdir[1];
460 rdir[2] = rf * norm[2] - vdir[2];
461
462 t = -objpos[2] / rdir[2];
463
464 if (t > EPSILON) {
465 planepos[0] = objpos[0] + t * rdir[0];
466 planepos[1] = objpos[1] + t * rdir[1];
467 planepos[2] = 0.0f;
468
469 if (!colorcheckmap(planepos, rcol))
470 rcol[0] = rcol[1] = rcol[2] = 0.0f;
471 }
472 else
473 rcol[0] = rcol[1] = rcol[2] = 0.0f;
474 }
475 else
476 rcol[0] = rcol[1] = rcol[2] = 0.0f;
477
478 dfact = 0.1f * dprod(ldir, norm);
479
480 if (dfact < 0.0f) {
481 dfact = 0.0f;
482 kfact = 0.0f;
483 }
484 else {
485 h[0] = 0.5f * (vdir[0] + ldir[0]);
486 h[1] = 0.5f * (vdir[1] + ldir[1]);
487 h[2] = 0.5f * (vdir[2] + ldir[2]);
488 kfact = dprod(h, norm);
Brian Paulb9f24942001-05-09 21:36:52 +0000489 kfact = pow(kfact, 4.0);
490 if (kfact < 1.0e-10)
491 kfact = 0.0;
492 }
Brian Paul5b0a7f32000-06-27 16:52:38 +0000493
494 r = dfact + kfact;
495 g = dfact + kfact;
496 b = dfact + kfact;
497
498 r *= 255.0f;
499 g *= 255.0f;
500 b *= 255.0f;
501
502 r += rcol[0];
503 g += rcol[1];
504 b += rcol[2];
505
506 r = clamp255(r);
507 g = clamp255(g);
508 b = clamp255(b);
509
510 reflectmap[y][x][0] = (GLubyte) r;
511 reflectmap[y][x][1] = (GLubyte) g;
512 reflectmap[y][x][2] = (GLubyte) b;
513 }
514
515 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, slot * TEX_REFLECT_SLOT_SIZE,
516 TEX_REFLECT_WIDTH, TEX_REFLECT_SLOT_SIZE, GL_RGB,
517 GL_UNSIGNED_BYTE,
518 &reflectmap[slot * TEX_REFLECT_SLOT_SIZE][0][0]);
519}
520
521static void
522drawbase(void)
523{
524 glColor3f(0.0, 0.0, 0.0);
525 glBindTexture(GL_TEXTURE_2D, checkid);
526 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
527
528 glBegin(GL_QUADS);
529 glTexCoord2f(0.0f, 0.0f);
530 glVertex3f(-BASESIZE / 2.0f, -BASESIZE / 2.0f, 0.0f);
531
532 glTexCoord2f(1.0f, 0.0f);
533 glVertex3f(BASESIZE / 2.0f, -BASESIZE / 2.0f, 0.0f);
534
535 glTexCoord2f(1.0f, 1.0f);
536 glVertex3f(BASESIZE / 2.0f, BASESIZE / 2.0f, 0.0f);
537
538 glTexCoord2f(0.0f, 1.0f);
539 glVertex3f(-BASESIZE / 2.0f, BASESIZE / 2.0f, 0.0f);
540
541 glEnd();
542}
543
544static void
545drawobj(void)
546{
547 glColor3f(0.0, 0.0, 0.0);
548 glBindTexture(GL_TEXTURE_2D, reflectid);
549 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
550
551 glPushMatrix();
552 glTranslatef(objpos[0], objpos[1], objpos[2]);
553 glCallList(objdlist);
554 glPopMatrix();
555}
556
557static void
558dojoy(void)
559{
560#ifdef WIN32
561 static UINT max[2] = { 0, 0 };
562 static UINT min[2] = { 0xffffffff, 0xffffffff }, center[2];
563 MMRESULT res;
564 JOYINFO joy;
565
566 res = joyGetPos(JOYSTICKID1, &joy);
567
568 if (res == JOYERR_NOERROR) {
569 joyavailable = 1;
570
571 if (max[0] < joy.wXpos)
572 max[0] = joy.wXpos;
573 if (min[0] > joy.wXpos)
574 min[0] = joy.wXpos;
575 center[0] = (max[0] + min[0]) / 2;
576
577 if (max[1] < joy.wYpos)
578 max[1] = joy.wYpos;
579 if (min[1] > joy.wYpos)
580 min[1] = joy.wYpos;
581 center[1] = (max[1] + min[1]) / 2;
582
583 if (joyactive) {
584 if (fabs(center[0] - (float) joy.wXpos) > 0.1 * (max[0] - min[0]))
585 alpha -=
586 2.5 * (center[0] - (float) joy.wXpos) / (max[0] - min[0]);
587 if (fabs(center[1] - (float) joy.wYpos) > 0.1 * (max[1] - min[1]))
588 beta += 2.5 * (center[1] - (float) joy.wYpos) / (max[1] - min[1]);
589
590 if (joy.wButtons & JOY_BUTTON1)
591 v += 0.005;
592 if (joy.wButtons & JOY_BUTTON2)
593 v -= 0.005;
594 }
595 }
596 else
597 joyavailable = 0;
598#endif
599}
600
601static void
602updatemaps(void)
603{
604 updatecheckmap(checkmap_currentslot);
605 checkmap_currentslot = (checkmap_currentslot + 1) % TEX_CHECK_NUMSLOT;
606
607 updatereflectmap(reflectmap_currentslot);
608 reflectmap_currentslot =
609 (reflectmap_currentslot + 1) % TEX_REFLECT_NUMSLOT;
610}
611
612static void
613draw(void)
614{
Brian Pauld49b34a2000-09-12 18:44:45 +0000615 static char frbuf[80] = "";
Brian Paul5b0a7f32000-06-27 16:52:38 +0000616
617 dojoy();
618
619 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
620
621 glEnable(GL_TEXTURE_2D);
622 glEnable(GL_DEPTH_TEST);
623 if (fog)
624 glEnable(GL_FOG);
625 else
626 glDisable(GL_FOG);
627
628 glPushMatrix();
629 calcposobs();
630
631 gluLookAt(obs[0], obs[1], obs[2],
632 obs[0] + dir[0], obs[1] + dir[1], obs[2] + dir[2],
633 0.0, 0.0, 1.0);
634
635 drawbase();
636 drawobj();
637
638 glColor3f(1.0, 1.0, 1.0);
639 glDisable(GL_TEXTURE_2D);
640
641 glPushMatrix();
642 glTranslatef(lightpos[0], lightpos[1], lightpos[2]);
643 glCallList(lightdlist);
644 glPopMatrix();
645
646 glPopMatrix();
647
Brian Paul5b0a7f32000-06-27 16:52:38 +0000648 glDisable(GL_DEPTH_TEST);
649 glDisable(GL_FOG);
650
651 glMatrixMode(GL_PROJECTION);
652 glPushMatrix();
653 glLoadIdentity();
654 glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0);
655 glMatrixMode(GL_MODELVIEW);
656
657 glColor3f(0.0f, 0.3f, 1.0f);
658
659 if (showcheckmap) {
660 glEnable(GL_TEXTURE_2D);
661 glBindTexture(GL_TEXTURE_2D, checkid);
662 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
663
664 glBegin(GL_QUADS);
665 glTexCoord2f(1.0f, 0.0f);
666 glVertex2i(10, 30);
667 glTexCoord2f(1.0f, 1.0f);
668 glVertex2i(10 + 90, 30);
669 glTexCoord2f(0.0f, 1.0f);
670 glVertex2i(10 + 90, 30 + 90);
671 glTexCoord2f(0.0f, 0.0f);
672 glVertex2i(10, 30 + 90);
673 glEnd();
674
675 glDisable(GL_TEXTURE_2D);
676 glBegin(GL_LINE_LOOP);
677 glVertex2i(10, 30);
678 glVertex2i(10 + 90, 30);
679 glVertex2i(10 + 90, 30 + 90);
680 glVertex2i(10, 30 + 90);
681 glEnd();
682 glRasterPos2i(105, 65);
683 printstring(GLUT_BITMAP_HELVETICA_18, "Plane Texture Map");
684 }
685
686 if (showreflectmap) {
687 glEnable(GL_TEXTURE_2D);
688 glBindTexture(GL_TEXTURE_2D, reflectid);
689 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
690
691 glBegin(GL_QUADS);
692 glTexCoord2f(1.0f, 0.0f);
693 glVertex2i(540, 30);
694 glTexCoord2f(1.0f, 1.0f);
695 glVertex2i(540 + 90, 30);
696 glTexCoord2f(0.0f, 1.0f);
697 glVertex2i(540 + 90, 30 + 90);
698 glTexCoord2f(0.0f, 0.0f);
699 glVertex2i(540, 30 + 90);
700 glEnd();
701
702 glDisable(GL_TEXTURE_2D);
703 glBegin(GL_LINE_LOOP);
704 glVertex2i(540, 30);
705 glVertex2i(540 + 90, 30);
706 glVertex2i(540 + 90, 30 + 90);
707 glVertex2i(540, 30 + 90);
708 glEnd();
709 glRasterPos2i(360, 65);
710 printstring(GLUT_BITMAP_HELVETICA_18, "Sphere Texture Map");
711 }
712
713 glDisable(GL_TEXTURE_2D);
714
715 glRasterPos2i(10, 10);
716 printstring(GLUT_BITMAP_HELVETICA_18, frbuf);
717 glRasterPos2i(360, 470);
718 printstring(GLUT_BITMAP_HELVETICA_10,
719 "Ray V1.0 Written by David Bucciarelli (tech.hmw@plus.it)");
720
721 if (help)
722 printhelp();
723
724 glMatrixMode(GL_PROJECTION);
725 glPopMatrix();
726 glMatrixMode(GL_MODELVIEW);
727
728 updatemaps();
729
730 glutSwapBuffers();
731
Brian Pauld49b34a2000-09-12 18:44:45 +0000732 Frames++;
733 {
734 GLint t = glutGet(GLUT_ELAPSED_TIME);
735 if (t - T0 >= 2000) {
736 GLfloat seconds = (t - T0) / 1000.0;
737 GLfloat fps = Frames / seconds;
738 sprintf(frbuf, "Frame rate: %f", fps);
739 T0 = t;
740 Frames = 0;
741 }
742 }
Brian Paul5b0a7f32000-06-27 16:52:38 +0000743}
744
745static void
746inittextures(void)
747{
748 int y;
749
750 glGenTextures(1, &checkid);
751 glBindTexture(GL_TEXTURE_2D, checkid);
752
753 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
754 glTexImage2D(GL_TEXTURE_2D, 0, 3, TEX_CHECK_WIDTH, TEX_CHECK_HEIGHT,
755 0, GL_RGB, GL_UNSIGNED_BYTE, checkmap);
756
757 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
758 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
759
760 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
761 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
762
763 for (y = 0; y < TEX_CHECK_NUMSLOT; y++)
764 updatecheckmap(y);
765
766
767
768 glGenTextures(1, &reflectid);
769 glBindTexture(GL_TEXTURE_2D, reflectid);
770
771 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
772 glTexImage2D(GL_TEXTURE_2D, 0, 3, TEX_REFLECT_WIDTH, TEX_REFLECT_HEIGHT,
773 0, GL_RGB, GL_UNSIGNED_BYTE, reflectmap);
774
775 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
776 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
777
778 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
779 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
780
781 for (y = 0; y < TEX_REFLECT_NUMSLOT; y++)
782 updatereflectmap(y);
783
784
785}
786
787static void
788initspherepos(void)
789{
790 float alpha, beta, sa, ca, sb, cb;
791 int x, y;
792
793 for (y = 0; y < TEX_REFLECT_HEIGHT; y++) {
794 beta = M_PI - y * (M_PI / TEX_REFLECT_HEIGHT);
795
796 for (x = 0; x < TEX_REFLECT_WIDTH; x++) {
797 alpha = -x * (2.0f * M_PI / TEX_REFLECT_WIDTH);
798
799 sa = sin(alpha);
800 ca = cos(alpha);
801
802 sb = sin(beta);
803 cb = cos(beta);
804
805 sphere_pos[y][x][0] = SPHERE_RADIUS * sa * sb;
806 sphere_pos[y][x][1] = SPHERE_RADIUS * ca * sb;
807 sphere_pos[y][x][2] = SPHERE_RADIUS * cb;
808 }
809 }
810}
811
812static void
813initdlists(void)
814{
815 GLUquadricObj *obj;
816
817 obj = gluNewQuadric();
818
819 lightdlist = glGenLists(1);
820 glNewList(lightdlist, GL_COMPILE);
821 gluQuadricDrawStyle(obj, GLU_FILL);
822 gluQuadricNormals(obj, GLU_NONE);
823 gluQuadricTexture(obj, GL_TRUE);
824 gluSphere(obj, 0.25f, 6, 6);
825 glEndList();
826
827 objdlist = glGenLists(1);
828 glNewList(objdlist, GL_COMPILE);
829 gluQuadricDrawStyle(obj, GLU_FILL);
830 gluQuadricNormals(obj, GLU_NONE);
831 gluQuadricTexture(obj, GL_TRUE);
832 gluSphere(obj, SPHERE_RADIUS, 16, 16);
833 glEndList();
834}
835
836int
837main(int ac, char **av)
838{
839 fprintf(stderr,
840 "Ray V1.0\nWritten by David Bucciarelli (tech.hmw@plus.it)\n");
841
842 /*
843 if(!SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS)) {
844 fprintf(stderr,"Error setting the process class.\n");
845 return 0;
846 }
847
848 if(!SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL)) {
849 fprintf(stderr,"Error setting the process priority.\n");
850 return 0;
851 }
852 */
853
854 glutInitWindowPosition(0, 0);
855 glutInitWindowSize(WIDTH, HEIGHT);
856 glutInit(&ac, av);
857
858 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
859
860 if (!(win = glutCreateWindow("Ray"))) {
861 fprintf(stderr, "Error, couldn't open window\n");
862 return -1;
863 }
864
865 reshape(WIDTH, HEIGHT);
866
867 glShadeModel(GL_FLAT);
868 glEnable(GL_DEPTH_TEST);
869 glDepthFunc(GL_LEQUAL);
870 glEnable(GL_CULL_FACE);
871 glEnable(GL_TEXTURE_2D);
872 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
873
874 glEnable(GL_FOG);
875 glFogi(GL_FOG_MODE, GL_EXP2);
876 glFogfv(GL_FOG_COLOR, fogcolor);
877
878 glFogf(GL_FOG_DENSITY, 0.01);
879#ifdef FX
880 glHint(GL_FOG_HINT, GL_NICEST);
881#endif
882
883 calcposobs();
884
885 initspherepos();
886
887 inittextures();
888 initdlists();
889
890 glClearColor(fogcolor[0], fogcolor[1], fogcolor[2], fogcolor[3]);
891
892 glutReshapeFunc(reshape);
893 glutDisplayFunc(draw);
894 glutKeyboardFunc(key);
895 glutSpecialFunc(special);
896 glutIdleFunc(draw);
897
898 glutMainLoop();
899
900 return 0;
901}