OSDN Git Service

progs/demos: print more info in fbotexture.c
[android-x86/external-mesa.git] / progs / demos / ray.c
1 /*
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 <string.h>
12 #include <math.h>
13
14 #ifdef WIN32
15 #include <windows.h>
16 #endif
17
18 #include <GL/glut.h>
19
20 #ifdef XMESA
21 #include "GL/xmesa.h"
22 static int fullscreen = 1;
23 #endif
24
25 static int WIDTH = 640;
26 static int HEIGHT = 480;
27
28 static GLint T0 = 0;
29 static GLint Frames = 0;
30
31 #define BASESIZE 7.5f
32 #define SPHERE_RADIUS 0.75f
33
34 #define TEX_CHECK_WIDTH 256
35 #define TEX_CHECK_HEIGHT 256
36 #define TEX_CHECK_SLOT_SIZE (TEX_CHECK_HEIGHT/16)
37 #define TEX_CHECK_NUMSLOT (TEX_CHECK_HEIGHT/TEX_CHECK_SLOT_SIZE)
38
39 #define TEX_REFLECT_WIDTH 256
40 #define TEX_REFLECT_HEIGHT 256
41 #define TEX_REFLECT_SLOT_SIZE (TEX_REFLECT_HEIGHT/16)
42 #define TEX_REFLECT_NUMSLOT (TEX_REFLECT_HEIGHT/TEX_REFLECT_SLOT_SIZE)
43
44 #ifndef M_PI
45 #define M_PI 3.1415926535
46 #endif
47
48 #define EPSILON 0.0001
49
50 #define clamp255(a)  ( (a)<(0.0f) ? (0.0f) : ((a)>(255.0f) ? (255.0f) : (a)) )
51
52 #ifndef fabs
53 #define fabs(x) ((x)<0.0f?-(x):(x))
54 #endif
55
56 #define vequ(a,b) { (a)[0]=(b)[0]; (a)[1]=(b)[1]; (a)[2]=(b)[2]; }
57 #define vsub(a,b,c) { (a)[0]=(b)[0]-(c)[0]; (a)[1]=(b)[1]-(c)[1]; (a)[2]=(b)[2]-(c)[2]; }
58 #define dprod(a,b) ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[2])
59 #define vnormalize(a,b) { \
60   register float m_norm; \
61   m_norm=sqrt((double)dprod((a),(a))); \
62   (a)[0] /=m_norm; \
63   (a)[1] /=m_norm; \
64   (a)[2] /=m_norm; }
65
66 static GLubyte checkmap[TEX_CHECK_HEIGHT][TEX_CHECK_WIDTH][3];
67 static GLuint checkid;
68 static int checkmap_currentslot = 0;
69
70 static GLubyte reflectmap[TEX_REFLECT_HEIGHT][TEX_REFLECT_WIDTH][3];
71 static GLuint reflectid;
72 static int reflectmap_currentslot = 0;
73
74 static GLuint lightdlist;
75 static GLuint objdlist;
76
77 static float lightpos[3] = { 2.1, 2.1, 2.8 };
78 static float objpos[3] = { 0.0, 0.0, 1.0 };
79
80 static float sphere_pos[TEX_CHECK_HEIGHT][TEX_REFLECT_WIDTH][3];
81
82 static int win = 0;
83
84 static float fogcolor[4] = { 0.05, 0.05, 0.05, 1.0 };
85
86 static float obs[3] = { 7.0, 0.0, 2.0 };
87 static float dir[3];
88 static float v = 0.0;
89 static float alpha = -90.0;
90 static float beta = 90.0;
91
92 static int fog = 1;
93 static int bfcull = 1;
94 static int poutline = 0;
95 static int help = 1;
96 static int showcheckmap = 1;
97 static int showreflectmap = 1;
98 static int joyavailable = 0;
99 static int joyactive = 0;
100
101 static void
102 calcposobs(void)
103 {
104    dir[0] = sin(alpha * M_PI / 180.0);
105    dir[1] = cos(alpha * M_PI / 180.0) * sin(beta * M_PI / 180.0);
106    dir[2] = cos(beta * M_PI / 180.0);
107
108    if (dir[0] < 1.0e-5 && dir[0] > -1.0e-5)
109       dir[0] = 0;
110    if (dir[1] < 1.0e-5 && dir[1] > -1.0e-5)
111       dir[1] = 0;
112    if (dir[2] < 1.0e-5 && dir[2] > -1.0e-5)
113       dir[2] = 0;
114
115    obs[0] += v * dir[0];
116    obs[1] += v * dir[1];
117    obs[2] += v * dir[2];
118 }
119
120 static void
121 special(int k, int x, int y)
122 {
123    switch (k) {
124    case GLUT_KEY_LEFT:
125       alpha -= 2.0;
126       break;
127    case GLUT_KEY_RIGHT:
128       alpha += 2.0;
129       break;
130    case GLUT_KEY_DOWN:
131       beta -= 2.0;
132       break;
133    case GLUT_KEY_UP:
134       beta += 2.0;
135       break;
136    }
137 }
138
139 static void
140 key(unsigned char k, int x, int y)
141 {
142    switch (k) {
143    case 27:
144       exit(0);
145       break;
146
147    case 's':
148       lightpos[1] -= 0.1;
149       break;
150    case 'd':
151       lightpos[1] += 0.1;
152       break;
153    case 'e':
154       lightpos[0] -= 0.1;
155       break;
156    case 'x':
157       lightpos[0] += 0.1;
158       break;
159    case 'w':
160       lightpos[2] -= 0.1;
161       break;
162    case 'r':
163       lightpos[2] += 0.1;
164       break;
165
166    case 'j':
167       objpos[1] -= 0.1;
168       break;
169    case 'k':
170       objpos[1] += 0.1;
171       break;
172    case 'i':
173       objpos[0] -= 0.1;
174       break;
175    case 'm':
176       objpos[0] += 0.1;
177       break;
178    case 'u':
179       objpos[2] -= 0.1;
180       break;
181    case 'o':
182       objpos[2] += 0.1;
183       break;
184
185    case 'a':
186       v += 0.005;
187       break;
188    case 'z':
189       v -= 0.005;
190       break;
191
192    case 'g':
193       joyactive = (!joyactive);
194       break;
195    case 'h':
196       help = (!help);
197       break;
198    case 'f':
199       fog = (!fog);
200       break;
201
202    case '1':
203       showcheckmap = (!showcheckmap);
204       break;
205    case '2':
206       showreflectmap = (!showreflectmap);
207       break;
208
209    case 'b':
210       if (bfcull) {
211          glDisable(GL_CULL_FACE);
212          bfcull = 0;
213       }
214       else {
215          glEnable(GL_CULL_FACE);
216          bfcull = 1;
217       }
218       break;
219    case 'p':
220       if (poutline) {
221          glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
222          poutline = 0;
223       }
224       else {
225          glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
226          poutline = 1;
227       }
228       break;
229 #ifdef XMESA
230    case ' ':
231       XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW);
232       fullscreen = (!fullscreen);
233       break;
234 #endif
235    }
236 }
237
238 static void
239 reshape(int w, int h)
240 {
241    WIDTH = w;
242    HEIGHT = h;
243    glViewport(0, 0, w, h);
244    glMatrixMode(GL_PROJECTION);
245    glLoadIdentity();
246    gluPerspective(45.0, w / (float) h, 0.8, 40.0);
247    glMatrixMode(GL_MODELVIEW);
248    glLoadIdentity();
249 }
250
251 static void
252 printstring(void *font, char *string)
253 {
254    int len, i;
255
256    len = (int) strlen(string);
257    for (i = 0; i < len; i++)
258       glutBitmapCharacter(font, string[i]);
259 }
260
261 static void
262 printhelp(void)
263 {
264    glEnable(GL_BLEND);
265    glColor4f(0.5, 0.5, 0.5, 0.5);
266    glRecti(40, 40, 600, 440);
267    glDisable(GL_BLEND);
268
269    glColor3f(0.0, 0.0, 1.0);
270    glRasterPos2i(300, 420);
271    printstring(GLUT_BITMAP_HELVETICA_18, "Help");
272
273    glRasterPos2i(60, 390);
274    printstring(GLUT_BITMAP_HELVETICA_12, "h - Toggle Help");
275    glRasterPos2i(60, 370);
276    printstring(GLUT_BITMAP_HELVETICA_12, "f - Toggle Fog");
277    glRasterPos2i(60, 350);
278    printstring(GLUT_BITMAP_HELVETICA_12, "b - Toggle Back face culling");
279    glRasterPos2i(60, 330);
280    printstring(GLUT_BITMAP_HELVETICA_12, "p - Toggle Wire frame");
281    glRasterPos2i(60, 310);
282    printstring(GLUT_BITMAP_HELVETICA_12, "Arrow Keys - Rotate");
283    glRasterPos2i(60, 290);
284    printstring(GLUT_BITMAP_HELVETICA_12, "a - Increase velocity");
285    glRasterPos2i(60, 270);
286    printstring(GLUT_BITMAP_HELVETICA_12, "z - Decrease velocity");
287
288    glRasterPos2i(60, 250);
289    if (joyavailable)
290       printstring(GLUT_BITMAP_HELVETICA_12,
291                   "j - Toggle jostick control (Joystick control available)");
292    else
293       printstring(GLUT_BITMAP_HELVETICA_12,
294                   "(No Joystick control available)");
295
296    glRasterPos2i(60, 230);
297    printstring(GLUT_BITMAP_HELVETICA_12,
298                "To move the light source: s - left,  d - right,  e - far,  x - near,  w - down r - up");
299    glRasterPos2i(60, 210);
300    printstring(GLUT_BITMAP_HELVETICA_12,
301                "To move the mirror sphere: j - left,  k - right,  i - far,  m - near,  u - down o - up");
302
303    glRasterPos2i(60, 190);
304    printstring(GLUT_BITMAP_HELVETICA_12,
305                "1 - Toggle the plane texture map window");
306
307    glRasterPos2i(60, 170);
308    printstring(GLUT_BITMAP_HELVETICA_12,
309                "2 - Toggle the sphere texture map window");
310 }
311
312 static GLboolean
313 seelight(float p[3], float dir[3])
314 {
315    float c[3], b, a, d, t, dist[3];
316
317    vsub(c, p, objpos);
318    b = -dprod(c, dir);
319    a = dprod(c, c) - SPHERE_RADIUS * SPHERE_RADIUS;
320
321    if ((d = b * b - a) < 0.0 || (b < 0.0 && a > 0.0))
322       return GL_FALSE;
323
324    d = sqrt(d);
325
326    t = b - d;
327
328    if (t < EPSILON) {
329       t = b + d;
330       if (t < EPSILON)
331          return GL_FALSE;
332    }
333
334    vsub(dist, lightpos, p);
335    if (dprod(dist, dist) < t * t)
336       return GL_FALSE;
337
338    return GL_TRUE;
339 }
340
341 static int
342 colorcheckmap(float ppos[3], float c[3])
343 {
344    static float norm[3] = { 0.0f, 0.0f, 1.0f };
345    float ldir[3], vdir[3], h[3], dfact, kfact, r, g, b;
346    int x, y;
347
348    x = (int) ((ppos[0] + BASESIZE / 2) * (10.0f / BASESIZE));
349    if ((x < 0) || (x > 10))
350       return GL_FALSE;
351
352    y = (int) ((ppos[1] + BASESIZE / 2) * (10.0f / BASESIZE));
353    if ((y < 0) || (y > 10))
354       return GL_FALSE;
355
356    r = 255.0f;
357    if (y & 1) {
358       if (x & 1)
359          g = 255.0f;
360       else
361          g = 0.0f;
362    }
363    else {
364       if (x & 1)
365          g = 0.0f;
366       else
367          g = 255.0f;
368    }
369    b = 0.0f;
370
371    vsub(ldir, lightpos, ppos);
372    vnormalize(ldir, ldir);
373
374    if (seelight(ppos, ldir)) {
375       c[0] = r * 0.05f;
376       c[1] = g * 0.05f;
377       c[2] = b * 0.05f;
378
379       return GL_TRUE;
380    }
381
382    dfact = dprod(ldir, norm);
383    if (dfact < 0.0f)
384       dfact = 0.0f;
385
386    vsub(vdir, obs, ppos);
387    vnormalize(vdir, vdir);
388    h[0] = 0.5f * (vdir[0] + ldir[0]);
389    h[1] = 0.5f * (vdir[1] + ldir[1]);
390    h[2] = 0.5f * (vdir[2] + ldir[2]);
391    kfact = dprod(h, norm);
392    kfact = pow(kfact, 6.0) * 7.0 * 255.0;
393
394    r = r * dfact + kfact;
395    g = g * dfact + kfact;
396    b = b * dfact + kfact;
397
398    c[0] = clamp255(r);
399    c[1] = clamp255(g);
400    c[2] = clamp255(b);
401
402    return GL_TRUE;
403 }
404
405 static void
406 updatecheckmap(int slot)
407 {
408    float c[3], ppos[3];
409    int x, y;
410
411    glBindTexture(GL_TEXTURE_2D, checkid);
412
413    ppos[2] = 0.0f;
414    for (y = slot * TEX_CHECK_SLOT_SIZE; y < (slot + 1) * TEX_CHECK_SLOT_SIZE;
415         y++) {
416       ppos[1] = (y / (float) TEX_CHECK_HEIGHT) * BASESIZE - BASESIZE / 2;
417
418       for (x = 0; x < TEX_CHECK_WIDTH; x++) {
419          ppos[0] = (x / (float) TEX_CHECK_WIDTH) * BASESIZE - BASESIZE / 2;
420
421          colorcheckmap(ppos, c);
422          checkmap[y][x][0] = (GLubyte) c[0];
423          checkmap[y][x][1] = (GLubyte) c[1];
424          checkmap[y][x][2] = (GLubyte) c[2];
425       }
426    }
427
428    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, slot * TEX_CHECK_SLOT_SIZE,
429                    TEX_CHECK_WIDTH, TEX_CHECK_SLOT_SIZE, GL_RGB,
430                    GL_UNSIGNED_BYTE,
431                    &checkmap[slot * TEX_CHECK_SLOT_SIZE][0][0]);
432
433 }
434
435 static void
436 updatereflectmap(int slot)
437 {
438    float rf, r, g, b, t, dfact, kfact, rdir[3];
439    float rcol[3], ppos[3], norm[3], ldir[3], h[3], vdir[3], planepos[3];
440    int x, y;
441
442    glBindTexture(GL_TEXTURE_2D, reflectid);
443
444    for (y = slot * TEX_REFLECT_SLOT_SIZE;
445         y < (slot + 1) * TEX_REFLECT_SLOT_SIZE; y++)
446       for (x = 0; x < TEX_REFLECT_WIDTH; x++) {
447          ppos[0] = sphere_pos[y][x][0] + objpos[0];
448          ppos[1] = sphere_pos[y][x][1] + objpos[1];
449          ppos[2] = sphere_pos[y][x][2] + objpos[2];
450
451          vsub(norm, ppos, objpos);
452          vnormalize(norm, norm);
453
454          vsub(ldir, lightpos, ppos);
455          vnormalize(ldir, ldir);
456          vsub(vdir, obs, ppos);
457          vnormalize(vdir, vdir);
458
459          rf = 2.0f * dprod(norm, vdir);
460          if (rf > EPSILON) {
461             rdir[0] = rf * norm[0] - vdir[0];
462             rdir[1] = rf * norm[1] - vdir[1];
463             rdir[2] = rf * norm[2] - vdir[2];
464
465             t = -objpos[2] / rdir[2];
466
467             if (t > EPSILON) {
468                planepos[0] = objpos[0] + t * rdir[0];
469                planepos[1] = objpos[1] + t * rdir[1];
470                planepos[2] = 0.0f;
471
472                if (!colorcheckmap(planepos, rcol))
473                   rcol[0] = rcol[1] = rcol[2] = 0.0f;
474             }
475             else
476                rcol[0] = rcol[1] = rcol[2] = 0.0f;
477          }
478          else
479             rcol[0] = rcol[1] = rcol[2] = 0.0f;
480
481          dfact = 0.1f * dprod(ldir, norm);
482
483          if (dfact < 0.0f) {
484             dfact = 0.0f;
485             kfact = 0.0f;
486          }
487          else {
488             h[0] = 0.5f * (vdir[0] + ldir[0]);
489             h[1] = 0.5f * (vdir[1] + ldir[1]);
490             h[2] = 0.5f * (vdir[2] + ldir[2]);
491             kfact = dprod(h, norm);
492             kfact = pow(kfact, 4.0);
493             if (kfact < 1.0e-10)
494                kfact = 0.0;
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
524 static void
525 drawbase(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
547 static void
548 drawobj(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
560 static void
561 dojoy(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
604 static void
605 updatemaps(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
615 static void
616 draw(void)
617 {
618    static char frbuf[80] = "";
619
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
651    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
735    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    }
746 }
747
748 static void
749 inittextures(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
790 static void
791 initspherepos(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
815 static void
816 initdlists(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
839 int
840 main(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 }