2 * This program is under the GNU GPL.
3 * Use at your own risk.
5 * written by David Bucciarelli (tech.hmw@plus.it)
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", 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 obs
[0] += v
* dir
[0];
209 obs
[1] += v
* dir
[1];
210 obs
[2] += v
* dir
[2];
214 special(int k
, int x
, int y
)
233 key(unsigned char k
, int x
, int y
)
249 fullscreen
= (!fullscreen
);
250 XMesaSetFXmode(fullscreen
? XMESA_FX_FULLSCREEN
: XMESA_FX_WINDOW
);
261 joyactive
= (!joyactive
);
273 normext
= (!normext
);
277 glDisable(GL_CULL_FACE
);
281 glEnable(GL_CULL_FACE
);
287 glPolygonMode(GL_FRONT_AND_BACK
, GL_FILL
);
292 glPolygonMode(GL_FRONT_AND_BACK
, GL_LINE
);
301 reshape(int w
, int h
)
305 glMatrixMode(GL_PROJECTION
);
307 gluPerspective(90.0, w
/ (float) h
, 0.8, 100.0);
308 glMatrixMode(GL_MODELVIEW
);
310 glViewport(0, 0, w
, h
);
314 printstring(void *font
, char *string
)
318 len
= (int) strlen(string
);
319 for (i
= 0; i
< len
; i
++)
320 glutBitmapCharacter(font
, string
[i
]);
327 glColor4f(0.5, 0.5, 0.5, 0.5);
328 glRecti(40, 40, 600, 440);
331 glColor3f(1.0, 0.0, 0.0);
332 glRasterPos2i(300, 420);
333 printstring(GLUT_BITMAP_TIMES_ROMAN_24
, "Help");
335 glRasterPos2i(60, 390);
336 printstring(GLUT_BITMAP_TIMES_ROMAN_24
, "h - Toggle Help");
337 glRasterPos2i(60, 360);
338 printstring(GLUT_BITMAP_TIMES_ROMAN_24
, "t - Toggle Textures");
339 glRasterPos2i(60, 330);
340 printstring(GLUT_BITMAP_TIMES_ROMAN_24
, "f - Toggle Fog");
341 glRasterPos2i(60, 300);
342 printstring(GLUT_BITMAP_TIMES_ROMAN_24
, "b - Toggle Back face culling");
343 glRasterPos2i(60, 270);
344 printstring(GLUT_BITMAP_TIMES_ROMAN_24
, "Arrow Keys - Rotate");
345 glRasterPos2i(60, 240);
346 printstring(GLUT_BITMAP_TIMES_ROMAN_24
, "a - Increase velocity");
347 glRasterPos2i(60, 210);
348 printstring(GLUT_BITMAP_TIMES_ROMAN_24
, "z - Decrease velocity");
349 glRasterPos2i(60, 180);
350 printstring(GLUT_BITMAP_TIMES_ROMAN_24
, "p - Toggle Wire frame");
351 glRasterPos2i(60, 150);
352 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,
353 "b - Toggle GL_EXT_rescale_normal extension");
354 glRasterPos2i(60, 120);
355 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,
356 "+/- - Increase/decrease the Object maximum LOD");
358 glRasterPos2i(60, 90);
360 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,
361 "j - Toggle jostick control (Joystick control available)");
363 printstring(GLUT_BITMAP_TIMES_ROMAN_24
,
364 "(No Joystick control available)");
371 static UINT max
[2] = { 0, 0 };
372 static UINT min
[2] = { 0xffffffff, 0xffffffff }, center
[2];
376 res
= joyGetPos(JOYSTICKID1
, &joy
);
378 if (res
== JOYERR_NOERROR
) {
381 if (max
[0] < joy
.wXpos
)
383 if (min
[0] > joy
.wXpos
)
385 center
[0] = (max
[0] + min
[0]) / 2;
387 if (max
[1] < joy
.wYpos
)
389 if (min
[1] > joy
.wYpos
)
391 center
[1] = (max
[1] + min
[1]) / 2;
394 if (fabs(center
[0] - (float) joy
.wXpos
) > 0.1 * (max
[0] - min
[0]))
396 2.0 * (center
[0] - (float) joy
.wXpos
) / (max
[0] - min
[0]);
397 if (fabs(center
[1] - (float) joy
.wYpos
) > 0.1 * (max
[1] - min
[1]))
398 beta
+= 2.0 * (center
[1] - (float) joy
.wYpos
) / (max
[1] - min
[1]);
400 if (joy
.wButtons
& JOY_BUTTON1
)
402 if (joy
.wButtons
& JOY_BUTTON2
)
412 drawipers(int depth
, int from
)
416 if (depth
== maxdepth
)
419 lod
= depth
+ LODbias
;
427 glCallList(LODdlist
[lod
]);
430 drawipers(depth
, FROM_DOWN
);
431 drawipers(depth
, FROM_UP
);
432 drawipers(depth
, FROM_FRONT
);
433 drawipers(depth
, FROM_BACK
);
434 drawipers(depth
, FROM_LEFT
);
435 drawipers(depth
, FROM_RIGHT
);
439 glTranslatef(0.0f
, -1.5f
, 0.0f
);
440 glScalef(0.5f
, 0.5f
, 0.5f
);
442 glCallList(LODdlist
[lod
]);
445 drawipers(depth
, FROM_DOWN
);
446 drawipers(depth
, FROM_UP
);
447 drawipers(depth
, FROM_FRONT
);
448 drawipers(depth
, FROM_LEFT
);
449 drawipers(depth
, FROM_RIGHT
);
454 glTranslatef(0.0f
, 1.5f
, 0.0f
);
455 glScalef(0.5f
, 0.5f
, 0.5f
);
457 glCallList(LODdlist
[lod
]);
460 drawipers(depth
, FROM_DOWN
);
461 drawipers(depth
, FROM_UP
);
462 drawipers(depth
, FROM_BACK
);
463 drawipers(depth
, FROM_LEFT
);
464 drawipers(depth
, FROM_RIGHT
);
469 glTranslatef(-1.5f
, 0.0f
, 0.0f
);
470 glScalef(0.5f
, 0.5f
, 0.5f
);
472 glCallList(LODdlist
[lod
]);
475 drawipers(depth
, FROM_DOWN
);
476 drawipers(depth
, FROM_UP
);
477 drawipers(depth
, FROM_FRONT
);
478 drawipers(depth
, FROM_BACK
);
479 drawipers(depth
, FROM_LEFT
);
484 glTranslatef(1.5f
, 0.0f
, 0.0f
);
485 glScalef(0.5f
, 0.5f
, 0.5f
);
487 glCallList(LODdlist
[lod
]);
490 drawipers(depth
, FROM_DOWN
);
491 drawipers(depth
, FROM_UP
);
492 drawipers(depth
, FROM_FRONT
);
493 drawipers(depth
, FROM_BACK
);
494 drawipers(depth
, FROM_RIGHT
);
499 glTranslatef(0.0f
, 0.0f
, 1.5f
);
500 glScalef(0.5f
, 0.5f
, 0.5f
);
502 glCallList(LODdlist
[lod
]);
505 drawipers(depth
, FROM_DOWN
);
506 drawipers(depth
, FROM_FRONT
);
507 drawipers(depth
, FROM_BACK
);
508 drawipers(depth
, FROM_LEFT
);
509 drawipers(depth
, FROM_RIGHT
);
514 glTranslatef(0.0f
, 0.0f
, -1.5f
);
515 glScalef(0.5f
, 0.5f
, 0.5f
);
517 glCallList(LODdlist
[lod
]);
520 drawipers(depth
, FROM_UP
);
521 drawipers(depth
, FROM_FRONT
);
522 drawipers(depth
, FROM_BACK
);
523 drawipers(depth
, FROM_LEFT
);
524 drawipers(depth
, FROM_RIGHT
);
529 totpoly
+= LODnumpoly
[lod
];
535 static char frbuf
[80] = "";
536 static GLfloat alpha
= 0.0f
;
537 static GLfloat beta
= 0.0f
;
538 static float fr
= 0.0;
542 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
545 glEnable(GL_TEXTURE_2D
);
547 glDisable(GL_TEXTURE_2D
);
556 gluLookAt(obs
[0], obs
[1], obs
[2],
557 obs
[0] + dir
[0], obs
[1] + dir
[1], obs
[2] + dir
[2],
561 glEnable(GL_DEPTH_TEST
);
563 glShadeModel(GL_SMOOTH
);
564 glBindTexture(GL_TEXTURE_2D
, t1id
);
565 glTexEnvf(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
566 glColor3f(1.0f
, 1.0f
, 1.0f
);
568 glEnable(GL_LIGHTING
);
571 glEnable(GL_RESCALE_NORMAL_EXT
);
573 glEnable(GL_NORMALIZE
);
576 glRotatef(alpha
, 0.0f
, 0.0f
, 1.0f
);
577 glRotatef(beta
, 1.0f
, 0.0f
, 0.0f
);
579 drawipers(0, FROM_NONE
);
585 glDisable(GL_LIGHTING
);
586 glDisable(GL_LIGHT0
);
587 glShadeModel(GL_FLAT
);
590 glDisable(GL_RESCALE_NORMAL_EXT
);
592 glDisable(GL_NORMALIZE
);
594 glCallList(skydlist
);
601 "Frame rate: %0.2f LOD: %d Tot. poly.: %d Poly/sec: %.1f",
602 fr
, LODbias
, totpoly
, totpoly
* fr
);
604 glDisable(GL_TEXTURE_2D
);
606 glShadeModel(GL_FLAT
);
607 glDisable(GL_DEPTH_TEST
);
609 glMatrixMode(GL_PROJECTION
);
612 glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0);
614 glMatrixMode(GL_MODELVIEW
);
617 glColor3f(1.0, 0.0, 0.0);
618 glRasterPos2i(10, 10);
619 printstring(GLUT_BITMAP_HELVETICA_18
, frbuf
);
620 glRasterPos2i(350, 470);
621 printstring(GLUT_BITMAP_HELVETICA_10
,
622 "IperS V1.0 Written by David Bucciarelli (tech.hmw@plus.it)");
627 glMatrixMode(GL_PROJECTION
);
629 glMatrixMode(GL_MODELVIEW
);
635 GLint t
= glutGet(GLUT_ELAPSED_TIME
);
636 if (t
- T0
>= 2000) {
637 GLfloat seconds
= (t
- T0
) / 1000.0;
638 fr
= Frames
/ seconds
;
646 main(int ac
, char **av
)
648 float fogcolor
[4] = { 0.7, 0.7, 0.7, 1.0 };
651 "IperS V1.0\nWritten by David Bucciarelli (tech.hmw@plus.it)\n");
653 glutInitWindowPosition(0, 0);
654 glutInitWindowSize(WIDTH
, HEIGHT
);
657 glutInitDisplayMode(GLUT_RGB
| GLUT_DEPTH
| GLUT_DOUBLE
);
659 if (!(win
= glutCreateWindow("IperS"))) {
660 fprintf(stderr
, "Error, couldn't open window\n");
664 reshape(WIDTH
, HEIGHT
);
666 glShadeModel(GL_SMOOTH
);
667 glEnable(GL_DEPTH_TEST
);
668 glEnable(GL_CULL_FACE
);
669 glEnable(GL_TEXTURE_2D
);
671 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
674 glFogi(GL_FOG_MODE
, GL_EXP2
);
675 glFogfv(GL_FOG_COLOR
, fogcolor
);
677 glFogf(GL_FOG_DENSITY
, 0.006);
679 glHint(GL_FOG_HINT
, GL_NICEST
);
685 glClearColor(fogcolor
[0], fogcolor
[1], fogcolor
[2], fogcolor
[3]);
686 glClear(GL_COLOR_BUFFER_BIT
);
690 glutReshapeFunc(reshape
);
691 glutDisplayFunc(draw
);
692 glutKeyboardFunc(key
);
693 glutSpecialFunc(special
);