WIP - port to Mali EGL
[mesa-demos/mali.git] / src / demos / ray.c
blob10d80e6251551e0de68e8f70c36c7796d9102e0f
1 /*
2 * This program is under the GNU GPL.
3 * Use at your own risk.
5 * written by David Bucciarelli (tech.hmw@plus.it)
6 * Humanware s.r.l.
7 */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <math.h>
14 #ifdef WIN32
15 #include <windows.h>
16 #endif
18 #include "glut_wrap.h"
20 #ifdef XMESA
21 #include "GL/xmesa.h"
22 static int fullscreen = 1;
23 #endif
25 static int WIDTH = 640;
26 static int HEIGHT = 480;
28 static GLint T0 = 0;
29 static GLint Frames = 0;
31 #define BASESIZE 7.5f
32 #define SPHERE_RADIUS 0.75f
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)
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)
44 #ifndef M_PI
45 #define M_PI 3.1415926535
46 #endif
48 #define EPSILON 0.0001
50 #define clamp255(a) ( (a)<(0.0f) ? (0.0f) : ((a)>(255.0f) ? (255.0f) : (a)) )
52 #ifndef fabs
53 #define fabs(x) ((x)<0.0f?-(x):(x))
54 #endif
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; }
66 static GLubyte checkmap[TEX_CHECK_HEIGHT][TEX_CHECK_WIDTH][3];
67 static GLuint checkid;
68 static int checkmap_currentslot = 0;
70 static GLubyte reflectmap[TEX_REFLECT_HEIGHT][TEX_REFLECT_WIDTH][3];
71 static GLuint reflectid;
72 static int reflectmap_currentslot = 0;
74 static GLuint lightdlist;
75 static GLuint objdlist;
77 static float lightpos[3] = { 2.1, 2.1, 2.8 };
78 static float objpos[3] = { 0.0, 0.0, 1.0 };
80 static float sphere_pos[TEX_CHECK_HEIGHT][TEX_REFLECT_WIDTH][3];
82 static int win = 0;
84 static float fogcolor[4] = { 0.05, 0.05, 0.05, 1.0 };
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;
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;
101 static void
102 calcposobs(void)
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);
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;
115 obs[0] += v * dir[0];
116 obs[1] += v * dir[1];
117 obs[2] += v * dir[2];
120 static void
121 special(int k, int x, int y)
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;
139 static void
140 key(unsigned char k, int x, int y)
142 switch (k) {
143 case 27:
144 exit(0);
145 break;
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;
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;
185 case 'a':
186 v += 0.005;
187 break;
188 case 'z':
189 v -= 0.005;
190 break;
192 case 'g':
193 joyactive = (!joyactive);
194 break;
195 case 'h':
196 help = (!help);
197 break;
198 case 'f':
199 fog = (!fog);
200 break;
202 case '1':
203 showcheckmap = (!showcheckmap);
204 break;
205 case '2':
206 showreflectmap = (!showreflectmap);
207 break;
209 case 'b':
210 if (bfcull) {
211 glDisable(GL_CULL_FACE);
212 bfcull = 0;
214 else {
215 glEnable(GL_CULL_FACE);
216 bfcull = 1;
218 break;
219 case 'p':
220 if (poutline) {
221 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
222 poutline = 0;
224 else {
225 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
226 poutline = 1;
228 break;
229 #ifdef XMESA
230 case ' ':
231 XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW);
232 fullscreen = (!fullscreen);
233 break;
234 #endif
238 static void
239 reshape(int w, int h)
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();
251 static void
252 printstring(void *font, char *string)
254 int len, i;
256 len = (int) strlen(string);
257 for (i = 0; i < len; i++)
258 glutBitmapCharacter(font, string[i]);
261 static void
262 printhelp(void)
264 glEnable(GL_BLEND);
265 glColor4f(0.5, 0.5, 0.5, 0.5);
266 glRecti(40, 40, 600, 440);
267 glDisable(GL_BLEND);
269 glColor3f(0.0, 0.0, 1.0);
270 glRasterPos2i(300, 420);
271 printstring(GLUT_BITMAP_HELVETICA_18, "Help");
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");
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)");
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");
303 glRasterPos2i(60, 190);
304 printstring(GLUT_BITMAP_HELVETICA_12,
305 "1 - Toggle the plane texture map window");
307 glRasterPos2i(60, 170);
308 printstring(GLUT_BITMAP_HELVETICA_12,
309 "2 - Toggle the sphere texture map window");
312 static GLboolean
313 seelight(float p[3], float dir[3])
315 float c[3], b, a, d, t, dist[3];
317 vsub(c, p, objpos);
318 b = -dprod(c, dir);
319 a = dprod(c, c) - SPHERE_RADIUS * SPHERE_RADIUS;
321 if ((d = b * b - a) < 0.0 || (b < 0.0 && a > 0.0))
322 return GL_FALSE;
324 d = sqrt(d);
326 t = b - d;
328 if (t < EPSILON) {
329 t = b + d;
330 if (t < EPSILON)
331 return GL_FALSE;
334 vsub(dist, lightpos, p);
335 if (dprod(dist, dist) < t * t)
336 return GL_FALSE;
338 return GL_TRUE;
341 static int
342 colorcheckmap(float ppos[3], float c[3])
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;
348 x = (int) ((ppos[0] + BASESIZE / 2) * (10.0f / BASESIZE));
349 if ((x < 0) || (x > 10))
350 return GL_FALSE;
352 y = (int) ((ppos[1] + BASESIZE / 2) * (10.0f / BASESIZE));
353 if ((y < 0) || (y > 10))
354 return GL_FALSE;
356 r = 255.0f;
357 if (y & 1) {
358 if (x & 1)
359 g = 255.0f;
360 else
361 g = 0.0f;
363 else {
364 if (x & 1)
365 g = 0.0f;
366 else
367 g = 255.0f;
369 b = 0.0f;
371 vsub(ldir, lightpos, ppos);
372 vnormalize(ldir, ldir);
374 if (seelight(ppos, ldir)) {
375 c[0] = r * 0.05f;
376 c[1] = g * 0.05f;
377 c[2] = b * 0.05f;
379 return GL_TRUE;
382 dfact = dprod(ldir, norm);
383 if (dfact < 0.0f)
384 dfact = 0.0f;
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;
394 r = r * dfact + kfact;
395 g = g * dfact + kfact;
396 b = b * dfact + kfact;
398 c[0] = clamp255(r);
399 c[1] = clamp255(g);
400 c[2] = clamp255(b);
402 return GL_TRUE;
405 static void
406 updatecheckmap(int slot)
408 float c[3], ppos[3];
409 int x, y;
411 glBindTexture(GL_TEXTURE_2D, checkid);
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;
418 for (x = 0; x < TEX_CHECK_WIDTH; x++) {
419 ppos[0] = (x / (float) TEX_CHECK_WIDTH) * BASESIZE - BASESIZE / 2;
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];
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]);
435 static void
436 updatereflectmap(int slot)
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;
442 glBindTexture(GL_TEXTURE_2D, reflectid);
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];
451 vsub(norm, ppos, objpos);
452 vnormalize(norm, norm);
454 vsub(ldir, lightpos, ppos);
455 vnormalize(ldir, ldir);
456 vsub(vdir, obs, ppos);
457 vnormalize(vdir, vdir);
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];
465 t = -objpos[2] / rdir[2];
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;
472 if (!colorcheckmap(planepos, rcol))
473 rcol[0] = rcol[1] = rcol[2] = 0.0f;
475 else
476 rcol[0] = rcol[1] = rcol[2] = 0.0f;
478 else
479 rcol[0] = rcol[1] = rcol[2] = 0.0f;
481 dfact = 0.1f * dprod(ldir, norm);
483 if (dfact < 0.0f) {
484 dfact = 0.0f;
485 kfact = 0.0f;
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;
497 r = dfact + kfact;
498 g = dfact + kfact;
499 b = dfact + kfact;
501 r *= 255.0f;
502 g *= 255.0f;
503 b *= 255.0f;
505 r += rcol[0];
506 g += rcol[1];
507 b += rcol[2];
509 r = clamp255(r);
510 g = clamp255(g);
511 b = clamp255(b);
513 reflectmap[y][x][0] = (GLubyte) r;
514 reflectmap[y][x][1] = (GLubyte) g;
515 reflectmap[y][x][2] = (GLubyte) b;
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]);
524 static void
525 drawbase(void)
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);
531 glBegin(GL_QUADS);
532 glTexCoord2f(0.0f, 0.0f);
533 glVertex3f(-BASESIZE / 2.0f, -BASESIZE / 2.0f, 0.0f);
535 glTexCoord2f(1.0f, 0.0f);
536 glVertex3f(BASESIZE / 2.0f, -BASESIZE / 2.0f, 0.0f);
538 glTexCoord2f(1.0f, 1.0f);
539 glVertex3f(BASESIZE / 2.0f, BASESIZE / 2.0f, 0.0f);
541 glTexCoord2f(0.0f, 1.0f);
542 glVertex3f(-BASESIZE / 2.0f, BASESIZE / 2.0f, 0.0f);
544 glEnd();
547 static void
548 drawobj(void)
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);
554 glPushMatrix();
555 glTranslatef(objpos[0], objpos[1], objpos[2]);
556 glCallList(objdlist);
557 glPopMatrix();
560 static void
561 dojoy(void)
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;
569 res = joyGetPos(JOYSTICKID1, &joy);
571 if (res == JOYERR_NOERROR) {
572 joyavailable = 1;
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;
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;
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]);
593 if (joy.wButtons & JOY_BUTTON1)
594 v += 0.005;
595 if (joy.wButtons & JOY_BUTTON2)
596 v -= 0.005;
599 else
600 joyavailable = 0;
601 #endif
604 static void
605 updatemaps(void)
607 updatecheckmap(checkmap_currentslot);
608 checkmap_currentslot = (checkmap_currentslot + 1) % TEX_CHECK_NUMSLOT;
610 updatereflectmap(reflectmap_currentslot);
611 reflectmap_currentslot =
612 (reflectmap_currentslot + 1) % TEX_REFLECT_NUMSLOT;
615 static void
616 draw(void)
618 static char frbuf[80] = "";
620 dojoy();
622 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
624 glEnable(GL_TEXTURE_2D);
625 glEnable(GL_DEPTH_TEST);
626 if (fog)
627 glEnable(GL_FOG);
628 else
629 glDisable(GL_FOG);
631 glPushMatrix();
632 calcposobs();
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);
638 drawbase();
639 drawobj();
641 glColor3f(1.0, 1.0, 1.0);
642 glDisable(GL_TEXTURE_2D);
644 glPushMatrix();
645 glTranslatef(lightpos[0], lightpos[1], lightpos[2]);
646 glCallList(lightdlist);
647 glPopMatrix();
649 glPopMatrix();
651 glDisable(GL_DEPTH_TEST);
652 glDisable(GL_FOG);
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);
660 glColor3f(0.0f, 0.3f, 1.0f);
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);
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();
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");
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);
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();
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");
716 glDisable(GL_TEXTURE_2D);
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)");
724 if (help)
725 printhelp();
727 glMatrixMode(GL_PROJECTION);
728 glPopMatrix();
729 glMatrixMode(GL_MODELVIEW);
731 updatemaps();
733 glutSwapBuffers();
735 Frames++;
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 printf("%s\n", frbuf);
743 T0 = t;
744 Frames = 0;
749 static void
750 inittextures(void)
752 int y;
754 glGenTextures(1, &checkid);
755 glBindTexture(GL_TEXTURE_2D, checkid);
757 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
758 glTexImage2D(GL_TEXTURE_2D, 0, 3, TEX_CHECK_WIDTH, TEX_CHECK_HEIGHT,
759 0, GL_RGB, GL_UNSIGNED_BYTE, checkmap);
761 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
762 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
764 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
765 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
767 for (y = 0; y < TEX_CHECK_NUMSLOT; y++)
768 updatecheckmap(y);
772 glGenTextures(1, &reflectid);
773 glBindTexture(GL_TEXTURE_2D, reflectid);
775 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
776 glTexImage2D(GL_TEXTURE_2D, 0, 3, TEX_REFLECT_WIDTH, TEX_REFLECT_HEIGHT,
777 0, GL_RGB, GL_UNSIGNED_BYTE, reflectmap);
779 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
780 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
782 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
783 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
785 for (y = 0; y < TEX_REFLECT_NUMSLOT; y++)
786 updatereflectmap(y);
791 static void
792 initspherepos(void)
794 float alpha, beta, sa, ca, sb, cb;
795 int x, y;
797 for (y = 0; y < TEX_REFLECT_HEIGHT; y++) {
798 beta = M_PI - y * (M_PI / TEX_REFLECT_HEIGHT);
800 for (x = 0; x < TEX_REFLECT_WIDTH; x++) {
801 alpha = -x * (2.0f * M_PI / TEX_REFLECT_WIDTH);
803 sa = sin(alpha);
804 ca = cos(alpha);
806 sb = sin(beta);
807 cb = cos(beta);
809 sphere_pos[y][x][0] = SPHERE_RADIUS * sa * sb;
810 sphere_pos[y][x][1] = SPHERE_RADIUS * ca * sb;
811 sphere_pos[y][x][2] = SPHERE_RADIUS * cb;
816 static void
817 initdlists(void)
819 GLUquadricObj *obj;
821 obj = gluNewQuadric();
823 lightdlist = glGenLists(1);
824 glNewList(lightdlist, GL_COMPILE);
825 gluQuadricDrawStyle(obj, GLU_FILL);
826 gluQuadricNormals(obj, GLU_NONE);
827 gluQuadricTexture(obj, GL_TRUE);
828 gluSphere(obj, 0.25f, 6, 6);
829 glEndList();
831 objdlist = glGenLists(1);
832 glNewList(objdlist, GL_COMPILE);
833 gluQuadricDrawStyle(obj, GLU_FILL);
834 gluQuadricNormals(obj, GLU_NONE);
835 gluQuadricTexture(obj, GL_TRUE);
836 gluSphere(obj, SPHERE_RADIUS, 16, 16);
837 glEndList();
839 gluDeleteQuadric(obj);
843 main(int ac, char **av)
845 fprintf(stderr,
846 "Ray V1.0\nWritten by David Bucciarelli (tech.hmw@plus.it)\n");
849 if(!SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS)) {
850 fprintf(stderr,"Error setting the process class.\n");
851 return 0;
854 if(!SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL)) {
855 fprintf(stderr,"Error setting the process priority.\n");
856 return 0;
860 glutInitWindowSize(WIDTH, HEIGHT);
861 glutInit(&ac, av);
863 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
865 if (!(win = glutCreateWindow("Ray"))) {
866 fprintf(stderr, "Error, couldn't open window\n");
867 return -1;
870 reshape(WIDTH, HEIGHT);
872 glShadeModel(GL_FLAT);
873 glEnable(GL_DEPTH_TEST);
874 glDepthFunc(GL_LEQUAL);
875 glEnable(GL_CULL_FACE);
876 glEnable(GL_TEXTURE_2D);
877 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
879 glEnable(GL_FOG);
880 glFogi(GL_FOG_MODE, GL_EXP2);
881 glFogfv(GL_FOG_COLOR, fogcolor);
883 glFogf(GL_FOG_DENSITY, 0.01);
884 #ifdef FX
885 glHint(GL_FOG_HINT, GL_NICEST);
886 #endif
888 calcposobs();
890 initspherepos();
892 inittextures();
893 initdlists();
895 glClearColor(fogcolor[0], fogcolor[1], fogcolor[2], fogcolor[3]);
897 glutReshapeFunc(reshape);
898 glutDisplayFunc(draw);
899 glutKeyboardFunc(key);
900 glutSpecialFunc(special);
901 glutIdleFunc(draw);
903 glutMainLoop();
905 return 0;