blob: 44289b7f96551a137936a91d0d03c3e2e8ab87f4 [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);
389 kfact =
390 kfact * kfact * kfact * kfact * kfact * kfact * kfact * 7.0f * 255.0f;
391
392 r = r * dfact + kfact;
393 g = g * dfact + kfact;
394 b = b * dfact + kfact;
395
396 c[0] = clamp255(r);
397 c[1] = clamp255(g);
398 c[2] = clamp255(b);
399
400 return GL_TRUE;
401}
402
403static void
404updatecheckmap(int slot)
405{
406 float c[3], ppos[3];
407 int x, y;
408
409 glBindTexture(GL_TEXTURE_2D, checkid);
410
411 ppos[2] = 0.0f;
412 for (y = slot * TEX_CHECK_SLOT_SIZE; y < (slot + 1) * TEX_CHECK_SLOT_SIZE;
413 y++) {
414 ppos[1] = (y / (float) TEX_CHECK_HEIGHT) * BASESIZE - BASESIZE / 2;
415
416 for (x = 0; x < TEX_CHECK_WIDTH; x++) {
417 ppos[0] = (x / (float) TEX_CHECK_WIDTH) * BASESIZE - BASESIZE / 2;
418
419 colorcheckmap(ppos, c);
420 checkmap[y][x][0] = (GLubyte) c[0];
421 checkmap[y][x][1] = (GLubyte) c[1];
422 checkmap[y][x][2] = (GLubyte) c[2];
423 }
424 }
425
426 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, slot * TEX_CHECK_SLOT_SIZE,
427 TEX_CHECK_WIDTH, TEX_CHECK_SLOT_SIZE, GL_RGB,
428 GL_UNSIGNED_BYTE,
429 &checkmap[slot * TEX_CHECK_SLOT_SIZE][0][0]);
430
431}
432
433static void
434updatereflectmap(int slot)
435{
436 float rf, r, g, b, t, dfact, kfact, rdir[3];
437 float rcol[3], ppos[3], norm[3], ldir[3], h[3], vdir[3], planepos[3];
438 int x, y;
439
440 glBindTexture(GL_TEXTURE_2D, reflectid);
441
442 for (y = slot * TEX_REFLECT_SLOT_SIZE;
443 y < (slot + 1) * TEX_REFLECT_SLOT_SIZE; y++)
444 for (x = 0; x < TEX_REFLECT_WIDTH; x++) {
445 ppos[0] = sphere_pos[y][x][0] + objpos[0];
446 ppos[1] = sphere_pos[y][x][1] + objpos[1];
447 ppos[2] = sphere_pos[y][x][2] + objpos[2];
448
449 vsub(norm, ppos, objpos);
450 vnormalize(norm, norm);
451
452 vsub(ldir, lightpos, ppos);
453 vnormalize(ldir, ldir);
454 vsub(vdir, obs, ppos);
455 vnormalize(vdir, vdir);
456
457 rf = 2.0f * dprod(norm, vdir);
458 if (rf > EPSILON) {
459 rdir[0] = rf * norm[0] - vdir[0];
460 rdir[1] = rf * norm[1] - vdir[1];
461 rdir[2] = rf * norm[2] - vdir[2];
462
463 t = -objpos[2] / rdir[2];
464
465 if (t > EPSILON) {
466 planepos[0] = objpos[0] + t * rdir[0];
467 planepos[1] = objpos[1] + t * rdir[1];
468 planepos[2] = 0.0f;
469
470 if (!colorcheckmap(planepos, rcol))
471 rcol[0] = rcol[1] = rcol[2] = 0.0f;
472 }
473 else
474 rcol[0] = rcol[1] = rcol[2] = 0.0f;
475 }
476 else
477 rcol[0] = rcol[1] = rcol[2] = 0.0f;
478
479 dfact = 0.1f * dprod(ldir, norm);
480
481 if (dfact < 0.0f) {
482 dfact = 0.0f;
483 kfact = 0.0f;
484 }
485 else {
486 h[0] = 0.5f * (vdir[0] + ldir[0]);
487 h[1] = 0.5f * (vdir[1] + ldir[1]);
488 h[2] = 0.5f * (vdir[2] + ldir[2]);
489 kfact = dprod(h, norm);
490 kfact *= kfact;
491 kfact *= kfact;
492 kfact *= kfact;
493 kfact *= kfact;
494 kfact *= 10.0f;
495 }
496
497 r = dfact + kfact;
498 g = dfact + kfact;
499 b = dfact + kfact;
500
501 r *= 255.0f;
502 g *= 255.0f;
503 b *= 255.0f;
504
505 r += rcol[0];
506 g += rcol[1];
507 b += rcol[2];
508
509 r = clamp255(r);
510 g = clamp255(g);
511 b = clamp255(b);
512
513 reflectmap[y][x][0] = (GLubyte) r;
514 reflectmap[y][x][1] = (GLubyte) g;
515 reflectmap[y][x][2] = (GLubyte) b;
516 }
517
518 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, slot * TEX_REFLECT_SLOT_SIZE,
519 TEX_REFLECT_WIDTH, TEX_REFLECT_SLOT_SIZE, GL_RGB,
520 GL_UNSIGNED_BYTE,
521 &reflectmap[slot * TEX_REFLECT_SLOT_SIZE][0][0]);
522}
523
524static void
525drawbase(void)
526{
527 glColor3f(0.0, 0.0, 0.0);
528 glBindTexture(GL_TEXTURE_2D, checkid);
529 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
530
531 glBegin(GL_QUADS);
532 glTexCoord2f(0.0f, 0.0f);
533 glVertex3f(-BASESIZE / 2.0f, -BASESIZE / 2.0f, 0.0f);
534
535 glTexCoord2f(1.0f, 0.0f);
536 glVertex3f(BASESIZE / 2.0f, -BASESIZE / 2.0f, 0.0f);
537
538 glTexCoord2f(1.0f, 1.0f);
539 glVertex3f(BASESIZE / 2.0f, BASESIZE / 2.0f, 0.0f);
540
541 glTexCoord2f(0.0f, 1.0f);
542 glVertex3f(-BASESIZE / 2.0f, BASESIZE / 2.0f, 0.0f);
543
544 glEnd();
545}
546
547static void
548drawobj(void)
549{
550 glColor3f(0.0, 0.0, 0.0);
551 glBindTexture(GL_TEXTURE_2D, reflectid);
552 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
553
554 glPushMatrix();
555 glTranslatef(objpos[0], objpos[1], objpos[2]);
556 glCallList(objdlist);
557 glPopMatrix();
558}
559
560static void
561dojoy(void)
562{
563#ifdef WIN32
564 static UINT max[2] = { 0, 0 };
565 static UINT min[2] = { 0xffffffff, 0xffffffff }, center[2];
566 MMRESULT res;
567 JOYINFO joy;
568
569 res = joyGetPos(JOYSTICKID1, &joy);
570
571 if (res == JOYERR_NOERROR) {
572 joyavailable = 1;
573
574 if (max[0] < joy.wXpos)
575 max[0] = joy.wXpos;
576 if (min[0] > joy.wXpos)
577 min[0] = joy.wXpos;
578 center[0] = (max[0] + min[0]) / 2;
579
580 if (max[1] < joy.wYpos)
581 max[1] = joy.wYpos;
582 if (min[1] > joy.wYpos)
583 min[1] = joy.wYpos;
584 center[1] = (max[1] + min[1]) / 2;
585
586 if (joyactive) {
587 if (fabs(center[0] - (float) joy.wXpos) > 0.1 * (max[0] - min[0]))
588 alpha -=
589 2.5 * (center[0] - (float) joy.wXpos) / (max[0] - min[0]);
590 if (fabs(center[1] - (float) joy.wYpos) > 0.1 * (max[1] - min[1]))
591 beta += 2.5 * (center[1] - (float) joy.wYpos) / (max[1] - min[1]);
592
593 if (joy.wButtons & JOY_BUTTON1)
594 v += 0.005;
595 if (joy.wButtons & JOY_BUTTON2)
596 v -= 0.005;
597 }
598 }
599 else
600 joyavailable = 0;
601#endif
602}
603
604static void
605updatemaps(void)
606{
607 updatecheckmap(checkmap_currentslot);
608 checkmap_currentslot = (checkmap_currentslot + 1) % TEX_CHECK_NUMSLOT;
609
610 updatereflectmap(reflectmap_currentslot);
611 reflectmap_currentslot =
612 (reflectmap_currentslot + 1) % TEX_REFLECT_NUMSLOT;
613}
614
615static void
616draw(void)
617{
Brian Pauld49b34a2000-09-12 18:44:45 +0000618 static char frbuf[80] = "";
Brian Paul5b0a7f32000-06-27 16:52:38 +0000619
620 dojoy();
621
622 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
623
624 glEnable(GL_TEXTURE_2D);
625 glEnable(GL_DEPTH_TEST);
626 if (fog)
627 glEnable(GL_FOG);
628 else
629 glDisable(GL_FOG);
630
631 glPushMatrix();
632 calcposobs();
633
634 gluLookAt(obs[0], obs[1], obs[2],
635 obs[0] + dir[0], obs[1] + dir[1], obs[2] + dir[2],
636 0.0, 0.0, 1.0);
637
638 drawbase();
639 drawobj();
640
641 glColor3f(1.0, 1.0, 1.0);
642 glDisable(GL_TEXTURE_2D);
643
644 glPushMatrix();
645 glTranslatef(lightpos[0], lightpos[1], lightpos[2]);
646 glCallList(lightdlist);
647 glPopMatrix();
648
649 glPopMatrix();
650
Brian Paul5b0a7f32000-06-27 16:52:38 +0000651 glDisable(GL_DEPTH_TEST);
652 glDisable(GL_FOG);
653
654 glMatrixMode(GL_PROJECTION);
655 glPushMatrix();
656 glLoadIdentity();
657 glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0);
658 glMatrixMode(GL_MODELVIEW);
659
660 glColor3f(0.0f, 0.3f, 1.0f);
661
662 if (showcheckmap) {
663 glEnable(GL_TEXTURE_2D);
664 glBindTexture(GL_TEXTURE_2D, checkid);
665 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
666
667 glBegin(GL_QUADS);
668 glTexCoord2f(1.0f, 0.0f);
669 glVertex2i(10, 30);
670 glTexCoord2f(1.0f, 1.0f);
671 glVertex2i(10 + 90, 30);
672 glTexCoord2f(0.0f, 1.0f);
673 glVertex2i(10 + 90, 30 + 90);
674 glTexCoord2f(0.0f, 0.0f);
675 glVertex2i(10, 30 + 90);
676 glEnd();
677
678 glDisable(GL_TEXTURE_2D);
679 glBegin(GL_LINE_LOOP);
680 glVertex2i(10, 30);
681 glVertex2i(10 + 90, 30);
682 glVertex2i(10 + 90, 30 + 90);
683 glVertex2i(10, 30 + 90);
684 glEnd();
685 glRasterPos2i(105, 65);
686 printstring(GLUT_BITMAP_HELVETICA_18, "Plane Texture Map");
687 }
688
689 if (showreflectmap) {
690 glEnable(GL_TEXTURE_2D);
691 glBindTexture(GL_TEXTURE_2D, reflectid);
692 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
693
694 glBegin(GL_QUADS);
695 glTexCoord2f(1.0f, 0.0f);
696 glVertex2i(540, 30);
697 glTexCoord2f(1.0f, 1.0f);
698 glVertex2i(540 + 90, 30);
699 glTexCoord2f(0.0f, 1.0f);
700 glVertex2i(540 + 90, 30 + 90);
701 glTexCoord2f(0.0f, 0.0f);
702 glVertex2i(540, 30 + 90);
703 glEnd();
704
705 glDisable(GL_TEXTURE_2D);
706 glBegin(GL_LINE_LOOP);
707 glVertex2i(540, 30);
708 glVertex2i(540 + 90, 30);
709 glVertex2i(540 + 90, 30 + 90);
710 glVertex2i(540, 30 + 90);
711 glEnd();
712 glRasterPos2i(360, 65);
713 printstring(GLUT_BITMAP_HELVETICA_18, "Sphere Texture Map");
714 }
715
716 glDisable(GL_TEXTURE_2D);
717
718 glRasterPos2i(10, 10);
719 printstring(GLUT_BITMAP_HELVETICA_18, frbuf);
720 glRasterPos2i(360, 470);
721 printstring(GLUT_BITMAP_HELVETICA_10,
722 "Ray V1.0 Written by David Bucciarelli (tech.hmw@plus.it)");
723
724 if (help)
725 printhelp();
726
727 glMatrixMode(GL_PROJECTION);
728 glPopMatrix();
729 glMatrixMode(GL_MODELVIEW);
730
731 updatemaps();
732
733 glutSwapBuffers();
734
Brian Pauld49b34a2000-09-12 18:44:45 +0000735 Frames++;
736 {
737 GLint t = glutGet(GLUT_ELAPSED_TIME);
738 if (t - T0 >= 2000) {
739 GLfloat seconds = (t - T0) / 1000.0;
740 GLfloat fps = Frames / seconds;
741 sprintf(frbuf, "Frame rate: %f", fps);
742 T0 = t;
743 Frames = 0;
744 }
745 }
Brian Paul5b0a7f32000-06-27 16:52:38 +0000746}
747
748static void
749inittextures(void)
750{
751 int y;
752
753 glGenTextures(1, &checkid);
754 glBindTexture(GL_TEXTURE_2D, checkid);
755
756 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
757 glTexImage2D(GL_TEXTURE_2D, 0, 3, TEX_CHECK_WIDTH, TEX_CHECK_HEIGHT,
758 0, GL_RGB, GL_UNSIGNED_BYTE, checkmap);
759
760 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
761 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
762
763 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
764 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
765
766 for (y = 0; y < TEX_CHECK_NUMSLOT; y++)
767 updatecheckmap(y);
768
769
770
771 glGenTextures(1, &reflectid);
772 glBindTexture(GL_TEXTURE_2D, reflectid);
773
774 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
775 glTexImage2D(GL_TEXTURE_2D, 0, 3, TEX_REFLECT_WIDTH, TEX_REFLECT_HEIGHT,
776 0, GL_RGB, GL_UNSIGNED_BYTE, reflectmap);
777
778 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
779 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
780
781 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
782 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
783
784 for (y = 0; y < TEX_REFLECT_NUMSLOT; y++)
785 updatereflectmap(y);
786
787
788}
789
790static void
791initspherepos(void)
792{
793 float alpha, beta, sa, ca, sb, cb;
794 int x, y;
795
796 for (y = 0; y < TEX_REFLECT_HEIGHT; y++) {
797 beta = M_PI - y * (M_PI / TEX_REFLECT_HEIGHT);
798
799 for (x = 0; x < TEX_REFLECT_WIDTH; x++) {
800 alpha = -x * (2.0f * M_PI / TEX_REFLECT_WIDTH);
801
802 sa = sin(alpha);
803 ca = cos(alpha);
804
805 sb = sin(beta);
806 cb = cos(beta);
807
808 sphere_pos[y][x][0] = SPHERE_RADIUS * sa * sb;
809 sphere_pos[y][x][1] = SPHERE_RADIUS * ca * sb;
810 sphere_pos[y][x][2] = SPHERE_RADIUS * cb;
811 }
812 }
813}
814
815static void
816initdlists(void)
817{
818 GLUquadricObj *obj;
819
820 obj = gluNewQuadric();
821
822 lightdlist = glGenLists(1);
823 glNewList(lightdlist, GL_COMPILE);
824 gluQuadricDrawStyle(obj, GLU_FILL);
825 gluQuadricNormals(obj, GLU_NONE);
826 gluQuadricTexture(obj, GL_TRUE);
827 gluSphere(obj, 0.25f, 6, 6);
828 glEndList();
829
830 objdlist = glGenLists(1);
831 glNewList(objdlist, GL_COMPILE);
832 gluQuadricDrawStyle(obj, GLU_FILL);
833 gluQuadricNormals(obj, GLU_NONE);
834 gluQuadricTexture(obj, GL_TRUE);
835 gluSphere(obj, SPHERE_RADIUS, 16, 16);
836 glEndList();
837}
838
839int
840main(int ac, char **av)
841{
842 fprintf(stderr,
843 "Ray V1.0\nWritten by David Bucciarelli (tech.hmw@plus.it)\n");
844
845 /*
846 if(!SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS)) {
847 fprintf(stderr,"Error setting the process class.\n");
848 return 0;
849 }
850
851 if(!SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL)) {
852 fprintf(stderr,"Error setting the process priority.\n");
853 return 0;
854 }
855 */
856
857 glutInitWindowPosition(0, 0);
858 glutInitWindowSize(WIDTH, HEIGHT);
859 glutInit(&ac, av);
860
861 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
862
863 if (!(win = glutCreateWindow("Ray"))) {
864 fprintf(stderr, "Error, couldn't open window\n");
865 return -1;
866 }
867
868 reshape(WIDTH, HEIGHT);
869
870 glShadeModel(GL_FLAT);
871 glEnable(GL_DEPTH_TEST);
872 glDepthFunc(GL_LEQUAL);
873 glEnable(GL_CULL_FACE);
874 glEnable(GL_TEXTURE_2D);
875 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
876
877 glEnable(GL_FOG);
878 glFogi(GL_FOG_MODE, GL_EXP2);
879 glFogfv(GL_FOG_COLOR, fogcolor);
880
881 glFogf(GL_FOG_DENSITY, 0.01);
882#ifdef FX
883 glHint(GL_FOG_HINT, GL_NICEST);
884#endif
885
886 calcposobs();
887
888 initspherepos();
889
890 inittextures();
891 initdlists();
892
893 glClearColor(fogcolor[0], fogcolor[1], fogcolor[2], fogcolor[3]);
894
895 glutReshapeFunc(reshape);
896 glutDisplayFunc(draw);
897 glutKeyboardFunc(key);
898 glutSpecialFunc(special);
899 glutIdleFunc(draw);
900
901 glutMainLoop();
902
903 return 0;
904}