2 * This program is under the GNU GPL.
3 * Use at your own risk.
5 * written by David Bucciarelli (tech.hmw@plus.it)
14 #if defined (WIN32)|| defined(_WIN32)
25 static int fullscreen
= 1;
28 static int WIDTH
= 640;
29 static int HEIGHT
= 480;
36 #define TEX_SKY_WIDTH 256
37 #define TEX_SKY_HEIGHT TEX_SKY_WIDTH
40 #define M_PI 3.1415926535
53 static float obs
[3] = { 3.8, 0.0, 0.0 };
56 static float alpha
= -90.0;
57 static float beta
= 90.0;
60 static int bfcull
= 1;
61 static int usetex
= 1;
63 static int poutline
= 0;
64 static int normext
= 1;
65 static int joyavailable
= 0;
66 static int joyactive
= 0;
67 static int LODbias
= 3;
68 static int maxdepth
= MAX_LOD
;
70 static unsigned int totpoly
= 0;
72 static GLuint t1id
, t2id
;
73 static GLuint skydlist
, LODdlist
[MAX_LOD
], LODnumpoly
[MAX_LOD
];
78 GLfloat lspec
[4] = { 1.0, 1.0, 1.0, 1.0 };
79 static GLfloat lightpos
[4] = { 30, 15.0, 30.0, 1.0 };
81 glLightfv(GL_LIGHT0
, GL_POSITION
, lightpos
);
82 glLightfv(GL_LIGHT0
, GL_SPECULAR
, lspec
);
84 glMaterialf(GL_FRONT_AND_BACK
, GL_SHININESS
, 32.0);
85 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, lspec
);
91 static int slicetable
[MAX_LOD
][2] = {
103 int i
, xslices
, yslices
;
105 obj
= gluNewQuadric();
107 skydlist
= glGenLists(1);
108 glNewList(skydlist
, GL_COMPILE
);
109 glBindTexture(GL_TEXTURE_2D
, t2id
);
110 glTexEnvf(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_REPLACE
);
111 glColor3f(1.0f
, 1.0f
, 1.0f
);
113 gluQuadricDrawStyle(obj
, GLU_FILL
);
114 gluQuadricNormals(obj
, GLU_NONE
);
115 gluQuadricTexture(obj
, GL_TRUE
);
116 gluQuadricOrientation(obj
, GLU_INSIDE
);
117 gluSphere(obj
, 40.0f
, 18, 9);
121 for (i
= 0; i
< MAX_LOD
; i
++) {
122 LODdlist
[i
] = glGenLists(1);
123 glNewList(LODdlist
[i
], GL_COMPILE
);
125 gluQuadricDrawStyle(obj
, GLU_FILL
);
126 gluQuadricNormals(obj
, GLU_SMOOTH
);
127 gluQuadricTexture(obj
, GL_TRUE
);
128 gluQuadricOrientation(obj
, GLU_OUTSIDE
);
129 xslices
= slicetable
[i
][0];
130 yslices
= slicetable
[i
][1];
131 gluSphere(obj
, 1.0f
, xslices
, yslices
);
132 LODnumpoly
[i
] = xslices
* (yslices
- 2) + 2 * (xslices
- 1);
141 GLubyte tsky
[TEX_SKY_HEIGHT
][TEX_SKY_WIDTH
][3];
148 glGenTextures(1, &t1id
);
149 glBindTexture(GL_TEXTURE_2D
, t1id
);
151 if (!LoadRGBMipmaps("../images/bw.rgb", 3)) {
152 fprintf(stderr
, "Error reading a texture.\n");
156 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_REPEAT
);
157 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_REPEAT
);
159 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
,
160 GL_LINEAR_MIPMAP_LINEAR
);
161 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
165 glGenTextures(1, &t2id
);
166 glBindTexture(GL_TEXTURE_2D
, t2id
);
168 for (y
= 0; y
< TEX_SKY_HEIGHT
; y
++)
169 for (x
= 0; x
< TEX_SKY_WIDTH
; x
++)
170 if (y
< TEX_SKY_HEIGHT
/ 2) {
171 fact
= y
/ (GLfloat
) (TEX_SKY_HEIGHT
/ 2);
173 (GLubyte
) (255.0f
* (0.1f
* fact
+ 0.3f
* (1.0f
- fact
)));
175 (GLubyte
) (255.0f
* (0.2f
* fact
+ 1.0f
* (1.0f
- fact
)));
179 tsky
[y
][x
][0] = tsky
[TEX_SKY_HEIGHT
- y
- 1][x
][0];
180 tsky
[y
][x
][1] = tsky
[TEX_SKY_HEIGHT
- y
- 1][x
][1];
184 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
187 gluBuild2DMipmaps(GL_TEXTURE_2D
, 3, TEX_SKY_WIDTH
, TEX_SKY_HEIGHT
,
188 GL_RGB
, GL_UNSIGNED_BYTE
, (GLvoid
*) (tsky
)))) {
189 fprintf(stderr
, "GLULib%s\n", (char *) gluErrorString(gluerr
));
193 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_REPEAT
);
194 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_REPEAT
);
196 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
,
197 GL_LINEAR_MIPMAP_LINEAR
);
198 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
204 dir
[0] = sin(alpha
* M_PI
/ 180.0);
205 dir
[1] = cos(alpha
* M_PI
/ 180.0) * sin(beta
* M_PI
/ 180.0);
206 dir
[2] = cos(beta
* M_PI
/ 180.0);
208 if (dir
[0] < 1.0e-5 && dir
[0] > -1.0e-5)
210 if (dir
[1] < 1.0e-5 && dir
[1] > -1.0e-5)
212 if (dir
[2] < 1.0e-5 && dir
[2] > -1.0e-5)
215 obs
[0] += v
* dir
[0];
216 obs
[1] += v
* dir
[1];
217 obs
[2] += v
* dir
[2];
221 special(int k
, int x
, int y
)
240 key(unsigned char k
, int x
, int y
)
256 fullscreen
= (!fullscreen
);
257 XMesaSetFXmode(fullscreen
? XMESA_FX_FULLSCREEN
: XMESA_FX_WINDOW
);
268 joyactive
= (!joyactive
);
280 normext
= (!normext
);
284 glDisable(GL_CULL_FACE
);
288 glEnable(GL_CULL_FACE
);
294 glPolygonMode(GL_FRONT_AND_BACK
, GL_FILL
);
299 glPolygonMode(GL_FRONT_AND_BACK
, GL_LINE
);
308 reshape(int w
, int h
)
312 glMatrixMode(GL_PROJECTION
);
314 gluPerspective(90.0, w
/ (float) h
, 0.8, 100.0);
315 glMatrixMode(GL_MODELVIEW
);
317 glViewport(0, 0, w
, h
);
321 printstring(void *font
, char *string
)
325 len
= (int) strlen(string
);
326 for (i
= 0; i
< len
; i
++)
327 glutBitmapCharacter(font
, string
[i
]);
334 glColor4f(0.5, 0.5, 0.5, 0.5);
335 glRecti(40, 40, 600, 440);
338 glColor3f(1.0, 0.0, 0.0);
339 glRasterPos2i(300, 420);
340 printstring(GLUT_BITMAP_TIMES_ROMAN_24
, "Help");
342 glRasterPos2i(60, 390);
343 printstring(GLUT_BITMAP_TIMES_ROMAN_24
, "h - Toggle Help");
344 glRasterPos2i(60, 360);
345 printstring(GLUT_BITMAP_TIMES_ROMAN_24
, "t - Toggle Textures");
346 glRasterPos2i(60, 330);
347 printstring(GLUT_BITMAP_TIMES_ROMAN_24
, "f - Toggle Fog");
348 glRasterPos2i(60, 300);
349 printstring(GLUT_BITMAP_TIMES_ROMAN_24
, "b - Toggle Back face culling");
350 glRasterPos2i(60, 270);
351 printstring(GLUT_BITMAP_TIMES_ROMAN_24
, "Arrow Keys - Rotate");
352 glRasterPos2i(60, 240);
353 printstring(GLUT_BITMAP_TIMES_ROMAN_24
, "a - Increase velocity");
354 glRasterPos2i(60, 210);
355 printstring(GLUT_BITMAP_TIMES_ROMAN_24
, "z - Decrease velocity");
356 glRasterPos2i(60, 180);
357 printstring(GLUT_BITMAP_TIMES_ROMAN_24
, "p - Toggle Wire frame");
358 glRasterPos2i(60, 150);
359 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,
360 "n - Toggle GL_EXT_rescale_normal extension");
361 glRasterPos2i(60, 120);
362 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,
363 "+/- - Increase/decrease the Object maximum LOD");
365 glRasterPos2i(60, 90);
367 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,
368 "j - Toggle jostick control (Joystick control available)");
370 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,
371 "(No Joystick control available)");
378 static UINT max
[2] = { 0, 0 };
379 static UINT min
[2] = { 0xffffffff, 0xffffffff }, center
[2];
383 res
= joyGetPos(JOYSTICKID1
, &joy
);
385 if (res
== JOYERR_NOERROR
) {
388 if (max
[0] < joy
.wXpos
)
390 if (min
[0] > joy
.wXpos
)
392 center
[0] = (max
[0] + min
[0]) / 2;
394 if (max
[1] < joy
.wYpos
)
396 if (min
[1] > joy
.wYpos
)
398 center
[1] = (max
[1] + min
[1]) / 2;
401 if (fabs(center
[0] - (float) joy
.wXpos
) > 0.1 * (max
[0] - min
[0]))
403 2.0 * (center
[0] - (float) joy
.wXpos
) / (max
[0] - min
[0]);
404 if (fabs(center
[1] - (float) joy
.wYpos
) > 0.1 * (max
[1] - min
[1]))
405 beta
+= 2.0 * (center
[1] - (float) joy
.wYpos
) / (max
[1] - min
[1]);
407 if (joy
.wButtons
& JOY_BUTTON1
)
409 if (joy
.wButtons
& JOY_BUTTON2
)
419 drawipers(int depth
, int from
)
423 if (depth
== maxdepth
)
426 lod
= depth
+ LODbias
;
434 glCallList(LODdlist
[lod
]);
437 drawipers(depth
, FROM_DOWN
);
438 drawipers(depth
, FROM_UP
);
439 drawipers(depth
, FROM_FRONT
);
440 drawipers(depth
, FROM_BACK
);
441 drawipers(depth
, FROM_LEFT
);
442 drawipers(depth
, FROM_RIGHT
);
446 glTranslatef(0.0f
, -1.5f
, 0.0f
);
447 glScalef(0.5f
, 0.5f
, 0.5f
);
449 glCallList(LODdlist
[lod
]);
452 drawipers(depth
, FROM_DOWN
);
453 drawipers(depth
, FROM_UP
);
454 drawipers(depth
, FROM_FRONT
);
455 drawipers(depth
, FROM_LEFT
);
456 drawipers(depth
, FROM_RIGHT
);
461 glTranslatef(0.0f
, 1.5f
, 0.0f
);
462 glScalef(0.5f
, 0.5f
, 0.5f
);
464 glCallList(LODdlist
[lod
]);
467 drawipers(depth
, FROM_DOWN
);
468 drawipers(depth
, FROM_UP
);
469 drawipers(depth
, FROM_BACK
);
470 drawipers(depth
, FROM_LEFT
);
471 drawipers(depth
, FROM_RIGHT
);
476 glTranslatef(-1.5f
, 0.0f
, 0.0f
);
477 glScalef(0.5f
, 0.5f
, 0.5f
);
479 glCallList(LODdlist
[lod
]);
482 drawipers(depth
, FROM_DOWN
);
483 drawipers(depth
, FROM_UP
);
484 drawipers(depth
, FROM_FRONT
);
485 drawipers(depth
, FROM_BACK
);
486 drawipers(depth
, FROM_LEFT
);
491 glTranslatef(1.5f
, 0.0f
, 0.0f
);
492 glScalef(0.5f
, 0.5f
, 0.5f
);
494 glCallList(LODdlist
[lod
]);
497 drawipers(depth
, FROM_DOWN
);
498 drawipers(depth
, FROM_UP
);
499 drawipers(depth
, FROM_FRONT
);
500 drawipers(depth
, FROM_BACK
);
501 drawipers(depth
, FROM_RIGHT
);
506 glTranslatef(0.0f
, 0.0f
, 1.5f
);
507 glScalef(0.5f
, 0.5f
, 0.5f
);
509 glCallList(LODdlist
[lod
]);
512 drawipers(depth
, FROM_DOWN
);
513 drawipers(depth
, FROM_FRONT
);
514 drawipers(depth
, FROM_BACK
);
515 drawipers(depth
, FROM_LEFT
);
516 drawipers(depth
, FROM_RIGHT
);
521 glTranslatef(0.0f
, 0.0f
, -1.5f
);
522 glScalef(0.5f
, 0.5f
, 0.5f
);
524 glCallList(LODdlist
[lod
]);
527 drawipers(depth
, FROM_UP
);
528 drawipers(depth
, FROM_FRONT
);
529 drawipers(depth
, FROM_BACK
);
530 drawipers(depth
, FROM_LEFT
);
531 drawipers(depth
, FROM_RIGHT
);
536 totpoly
+= LODnumpoly
[lod
];
542 static char frbuf
[80] = "";
543 static GLfloat alpha
= 0.0f
;
544 static GLfloat beta
= 0.0f
;
545 static float fr
= 0.0;
546 static double t0
= -1.;
547 double dt
, t
= glutGet(GLUT_ELAPSED_TIME
) / 1000.0;
555 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
558 glEnable(GL_TEXTURE_2D
);
560 glDisable(GL_TEXTURE_2D
);
569 gluLookAt(obs
[0], obs
[1], obs
[2],
570 obs
[0] + dir
[0], obs
[1] + dir
[1], obs
[2] + dir
[2],
574 glEnable(GL_DEPTH_TEST
);
576 glShadeModel(GL_SMOOTH
);
577 glBindTexture(GL_TEXTURE_2D
, t1id
);
578 glTexEnvf(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
579 glColor3f(1.0f
, 1.0f
, 1.0f
);
581 glEnable(GL_LIGHTING
);
584 glEnable(GL_RESCALE_NORMAL_EXT
);
586 glEnable(GL_NORMALIZE
);
589 glRotatef(alpha
, 0.0f
, 0.0f
, 1.0f
);
590 glRotatef(beta
, 1.0f
, 0.0f
, 0.0f
);
592 drawipers(0, FROM_NONE
);
598 glDisable(GL_LIGHTING
);
599 glDisable(GL_LIGHT0
);
600 glShadeModel(GL_FLAT
);
603 glDisable(GL_RESCALE_NORMAL_EXT
);
605 glDisable(GL_NORMALIZE
);
607 glCallList(skydlist
);
614 "Frame rate: %0.2f LOD: %d Tot. poly.: %d Poly/sec: %.1f",
615 fr
, LODbias
, totpoly
, totpoly
* fr
);
617 glDisable(GL_TEXTURE_2D
);
619 glShadeModel(GL_FLAT
);
620 glDisable(GL_DEPTH_TEST
);
622 glMatrixMode(GL_PROJECTION
);
625 glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0);
627 glMatrixMode(GL_MODELVIEW
);
630 glColor3f(1.0, 0.0, 0.0);
631 glRasterPos2i(10, 10);
632 printstring(GLUT_BITMAP_HELVETICA_18
, frbuf
);
633 glRasterPos2i(350, 470);
634 printstring(GLUT_BITMAP_HELVETICA_10
,
635 "IperS V1.0 Written by David Bucciarelli (tech.hmw@plus.it)");
640 glMatrixMode(GL_PROJECTION
);
642 glMatrixMode(GL_MODELVIEW
);
648 GLint t
= glutGet(GLUT_ELAPSED_TIME
);
649 if (t
- T0
>= 2000) {
650 GLfloat seconds
= (t
- T0
) / 1000.0;
651 fr
= Frames
/ seconds
;
659 main(int ac
, char **av
)
661 float fogcolor
[4] = { 0.7, 0.7, 0.7, 1.0 };
664 "IperS V1.0\nWritten by David Bucciarelli (tech.hmw@plus.it)\n");
666 glutInitWindowPosition(0, 0);
667 glutInitWindowSize(WIDTH
, HEIGHT
);
670 glutInitDisplayMode(GLUT_RGB
| GLUT_DEPTH
| GLUT_DOUBLE
);
672 if (!(win
= glutCreateWindow("IperS"))) {
673 fprintf(stderr
, "Error, couldn't open window\n");
677 reshape(WIDTH
, HEIGHT
);
679 glShadeModel(GL_SMOOTH
);
680 glEnable(GL_DEPTH_TEST
);
681 glEnable(GL_CULL_FACE
);
682 glEnable(GL_TEXTURE_2D
);
684 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
687 glFogi(GL_FOG_MODE
, GL_EXP2
);
688 glFogfv(GL_FOG_COLOR
, fogcolor
);
690 glFogf(GL_FOG_DENSITY
, 0.006);
692 glHint(GL_FOG_HINT
, GL_NICEST
);
698 glClearColor(fogcolor
[0], fogcolor
[1], fogcolor
[2], fogcolor
[3]);
699 glClear(GL_COLOR_BUFFER_BIT
);
703 glutReshapeFunc(reshape
);
704 glutDisplayFunc(draw
);
705 glutKeyboardFunc(key
);
706 glutSpecialFunc(special
);