diff options
author | Brian Paul <brian.paul@tungstengraphics.com> | 2000-06-27 16:52:38 +0000 |
---|---|---|
committer | Brian Paul <brian.paul@tungstengraphics.com> | 2000-06-27 16:52:38 +0000 |
commit | 5b0a7f397104ff1938908410b422e529120acde5 (patch) | |
tree | 9602945668b91eef92d8986c0ed909b4218ac9d9 /progs | |
parent | e4b40b0211db61c219b6349e16835d4cdf4641aa (diff) |
initial check-in
Diffstat (limited to 'progs')
-rw-r--r-- | progs/demos/fire.c | 732 | ||||
-rw-r--r-- | progs/demos/gltestperf.c | 580 | ||||
-rw-r--r-- | progs/demos/ipers.c | 704 | ||||
-rw-r--r-- | progs/demos/particles.cxx | 219 | ||||
-rw-r--r-- | progs/demos/particles.h | 81 | ||||
-rw-r--r-- | progs/demos/rain.cxx | 388 | ||||
-rw-r--r-- | progs/demos/ray.c | 908 | ||||
-rw-r--r-- | progs/demos/shadow.c | 117 | ||||
-rw-r--r-- | progs/demos/teapot.c | 575 | ||||
-rw-r--r-- | progs/demos/terrain.c | 653 | ||||
-rw-r--r-- | progs/demos/tunnel.c | 514 | ||||
-rw-r--r-- | progs/demos/tunnel2.c | 618 | ||||
-rw-r--r-- | progs/demos/tunneldat.c | 83 |
13 files changed, 6172 insertions, 0 deletions
diff --git a/progs/demos/fire.c b/progs/demos/fire.c new file mode 100644 index 0000000000..056598d5c3 --- /dev/null +++ b/progs/demos/fire.c @@ -0,0 +1,732 @@ +/* + * This program is under the GNU GPL. + * Use at your own risk. + * + * written by David Bucciarelli (tech.hmw@plus.it) + * Humanware s.r.l. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <time.h> + +#ifdef WIN32 +#include <windows.h> +#include <mmsystem.h> +#endif + +#include <GL/glut.h> +#include "../util/readtex.c" + +#ifdef XMESA +#include "GL/xmesa.h" +static int fullscreen = 1; +#endif + +#ifndef M_PI +#define M_PI 3.1415926535 +#endif + +#define vinit(a,i,j,k) {\ + (a)[0]=i;\ + (a)[1]=j;\ + (a)[2]=k;\ +} + +#define vinit4(a,i,j,k,w) {\ + (a)[0]=i;\ + (a)[1]=j;\ + (a)[2]=k;\ + (a)[3]=w;\ +} + + +#define vadds(a,dt,b) {\ + (a)[0]+=(dt)*(b)[0];\ + (a)[1]+=(dt)*(b)[1];\ + (a)[2]+=(dt)*(b)[2];\ +} + +#define vequ(a,b) {\ + (a)[0]=(b)[0];\ + (a)[1]=(b)[1];\ + (a)[2]=(b)[2];\ +} + +#define vinter(a,dt,b,c) {\ + (a)[0]=(dt)*(b)[0]+(1.0-dt)*(c)[0];\ + (a)[1]=(dt)*(b)[1]+(1.0-dt)*(c)[1];\ + (a)[2]=(dt)*(b)[2]+(1.0-dt)*(c)[2];\ +} + +#define clamp(a) ((a) < 0.0 ? 0.0 : ((a) < 1.0 ? (a) : 1.0)) + +#define vclamp(v) {\ + (v)[0]=clamp((v)[0]);\ + (v)[1]=clamp((v)[1]);\ + (v)[2]=clamp((v)[2]);\ +} + +static int WIDTH = 640; +static int HEIGHT = 480; + +#define FRAME 50 +#define DIMP 20.0 +#define DIMTP 16.0 + +#define RIDCOL 0.4 + +#define NUMTREE 50 +#define TREEINR 2.5 +#define TREEOUTR 8.0 + +#define AGRAV -9.8 + +typedef struct +{ + int age; + float p[3][3]; + float v[3]; + float c[3][4]; +} +part; + +static float treepos[NUMTREE][3]; + +static float black[3] = { 0.0, 0.0, 0.0 }; +static float blu[3] = { 0.0, 0.2, 1.0 }; +static float blu2[3] = { 0.0, 1.0, 1.0 }; + +static float fogcolor[4] = { 1.0, 1.0, 1.0, 1.0 }; + +static float q[4][3] = { + {-DIMP, 0.0, -DIMP}, + {DIMP, 0.0, -DIMP}, + {DIMP, 0.0, DIMP}, + {-DIMP, 0.0, DIMP} +}; + +static float qt[4][2] = { + {-DIMTP, -DIMTP}, + {DIMTP, -DIMTP}, + {DIMTP, DIMTP}, + {-DIMTP, DIMTP} +}; + +static int win = 0; + +static int np; +static float eject_r, dt, maxage, eject_vy, eject_vl; +static short shadows; +static float ridtri; +static int fog = 1; +static int help = 1; +static int joyavailable = 0; +static int joyactive = 0; + +static part *p; + +static GLuint groundid; +static GLuint treeid; + +static float obs[3] = { 2.0, 1.0, 0.0 }; +static float dir[3]; +static float v = 0.0; +static float alpha = -90.0; +static float beta = 90.0; + +static float +gettime(void) +{ + static clock_t told = 0; + clock_t tnew, ris; + + tnew = clock(); + + ris = tnew - told; + + told = tnew; + + return (ris / (float) CLOCKS_PER_SEC); +} + +float +vrnd(void) +{ + return (((float) rand()) / RAND_MAX); +} + +static void +setnewpart(part * p) +{ + float a, v[3], *c; + + p->age = 0; + + a = vrnd() * 3.14159265359 * 2.0; + + vinit(v, sin(a) * eject_r * vrnd(), 0.15, cos(a) * eject_r * vrnd()); + vinit(p->p[0], v[0] + vrnd() * ridtri, v[1] + vrnd() * ridtri, + v[2] + vrnd() * ridtri); + vinit(p->p[1], v[0] + vrnd() * ridtri, v[1] + vrnd() * ridtri, + v[2] + vrnd() * ridtri); + vinit(p->p[2], v[0] + vrnd() * ridtri, v[1] + vrnd() * ridtri, + v[2] + vrnd() * ridtri); + + vinit(p->v, v[0] * eject_vl / (eject_r / 2), + vrnd() * eject_vy + eject_vy / 2, v[2] * eject_vl / (eject_r / 2)); + + c = blu; + + vinit4(p->c[0], c[0] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), + c[1] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), + c[2] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 1.0); + vinit4(p->c[1], c[0] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), + c[1] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), + c[2] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 1.0); + vinit4(p->c[2], c[0] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), + c[1] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), + c[2] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 1.0); +} + +static void +setpart(part * p) +{ + float fact; + + if (p->p[0][1] < 0.1) { + setnewpart(p); + return; + } + + p->v[1] += AGRAV * dt; + + vadds(p->p[0], dt, p->v); + vadds(p->p[1], dt, p->v); + vadds(p->p[2], dt, p->v); + + p->age++; + + if ((p->age) > maxage) { + vequ(p->c[0], blu2); + vequ(p->c[1], blu2); + vequ(p->c[2], blu2); + } + else { + fact = 1.0 / maxage; + vadds(p->c[0], fact, blu2); + vclamp(p->c[0]); + p->c[0][3] = fact * (maxage - p->age); + + vadds(p->c[1], fact, blu2); + vclamp(p->c[1]); + p->c[1][3] = fact * (maxage - p->age); + + vadds(p->c[2], fact, blu2); + vclamp(p->c[2]); + p->c[2][3] = fact * (maxage - p->age); + } +} + +static void +drawtree(float x, float y, float z) +{ + glBegin(GL_QUADS); + glTexCoord2f(0.0, 0.0); + glVertex3f(x - 1.5, y + 0.0, z); + + glTexCoord2f(1.0, 0.0); + glVertex3f(x + 1.5, y + 0.0, z); + + glTexCoord2f(1.0, 1.0); + glVertex3f(x + 1.5, y + 3.0, z); + + glTexCoord2f(0.0, 1.0); + glVertex3f(x - 1.5, y + 3.0, z); + + + glTexCoord2f(0.0, 0.0); + glVertex3f(x, y + 0.0, z - 1.5); + + glTexCoord2f(1.0, 0.0); + glVertex3f(x, y + 0.0, z + 1.5); + + glTexCoord2f(1.0, 1.0); + glVertex3f(x, y + 3.0, z + 1.5); + + glTexCoord2f(0.0, 1.0); + glVertex3f(x, y + 3.0, z - 1.5); + + glEnd(); + +} + +static void +calcposobs(void) +{ + dir[0] = sin(alpha * M_PI / 180.0); + dir[2] = cos(alpha * M_PI / 180.0) * sin(beta * M_PI / 180.0); + dir[1] = cos(beta * M_PI / 180.0); + + obs[0] += v * dir[0]; + obs[1] += v * dir[1]; + obs[2] += v * dir[2]; +} + +static void +printstring(void *font, char *string) +{ + int len, i; + + len = (int) strlen(string); + for (i = 0; i < len; i++) + glutBitmapCharacter(font, string[i]); +} + +static void +reshape(int width, int height) +{ + WIDTH = width; + HEIGHT = height; + glViewport(0, 0, (GLint) width, (GLint) height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(70.0, width / (float) height, 0.1, 30.0); + + glMatrixMode(GL_MODELVIEW); +} + +static void +printhelp(void) +{ + glColor4f(0.0, 0.0, 0.0, 0.5); + glRecti(40, 40, 600, 440); + + glColor3f(1.0, 0.0, 0.0); + glRasterPos2i(300, 420); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Help"); + + glRasterPos2i(60, 390); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "h - Togle Help"); + + glRasterPos2i(60, 360); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "t - Increase particle size"); + glRasterPos2i(60, 330); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "T - Decrease particle size"); + + glRasterPos2i(60, 300); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "r - Increase emission radius"); + glRasterPos2i(60, 270); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "R - Decrease emission radius"); + + glRasterPos2i(60, 240); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "f - Togle Fog"); + glRasterPos2i(60, 210); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "s - Togle shadows"); + glRasterPos2i(60, 180); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Arrow Keys - Rotate"); + glRasterPos2i(60, 150); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "a - Increase velocity"); + glRasterPos2i(60, 120); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "z - Decrease velocity"); + + glRasterPos2i(60, 90); + if (joyavailable) + printstring(GLUT_BITMAP_TIMES_ROMAN_24, + "j - Togle jostick control (Joystick control available)"); + else + printstring(GLUT_BITMAP_TIMES_ROMAN_24, + "(No Joystick control available)"); +} + +static void +dojoy(void) +{ +#ifdef WIN32 + static UINT max[2] = { 0, 0 }; + static UINT min[2] = { 0xffffffff, 0xffffffff }, center[2]; + MMRESULT res; + JOYINFO joy; + + res = joyGetPos(JOYSTICKID1, &joy); + + if (res == JOYERR_NOERROR) { + joyavailable = 1; + + if (max[0] < joy.wXpos) + max[0] = joy.wXpos; + if (min[0] > joy.wXpos) + min[0] = joy.wXpos; + center[0] = (max[0] + min[0]) / 2; + + if (max[1] < joy.wYpos) + max[1] = joy.wYpos; + if (min[1] > joy.wYpos) + min[1] = joy.wYpos; + center[1] = (max[1] + min[1]) / 2; + + if (joyactive) { + if (fabs(center[0] - (float) joy.wXpos) > 0.1 * (max[0] - min[0])) + alpha += + 2.5 * (center[0] - (float) joy.wXpos) / (max[0] - min[0]); + if (fabs(center[1] - (float) joy.wYpos) > 0.1 * (max[1] - min[1])) + beta += 2.5 * (center[1] - (float) joy.wYpos) / (max[1] - min[1]); + + if (joy.wButtons & JOY_BUTTON1) + v += 0.01; + if (joy.wButtons & JOY_BUTTON2) + v -= 0.01; + } + } + else + joyavailable = 0; +#endif +} + +static void +drawfire(void) +{ + static int count = 0; + static char frbuf[80]; + int j; + float fr; + + dojoy(); + + glEnable(GL_DEPTH_TEST); + + if (fog) + glEnable(GL_FOG); + else + glDisable(GL_FOG); + + glDepthMask(GL_TRUE); + glClearColor(1.0, 1.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + calcposobs(); + gluLookAt(obs[0], obs[1], obs[2], + obs[0] + dir[0], obs[1] + dir[1], obs[2] + dir[2], + 0.0, 1.0, 0.0); + + glColor4f(1.0, 1.0, 1.0, 1.0); + + glEnable(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_2D, groundid); + glBegin(GL_QUADS); + glTexCoord2fv(qt[0]); + glVertex3fv(q[0]); + glTexCoord2fv(qt[1]); + glVertex3fv(q[1]); + glTexCoord2fv(qt[2]); + glVertex3fv(q[2]); + glTexCoord2fv(qt[3]); + glVertex3fv(q[3]); + glEnd(); + + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GEQUAL, 0.9); + + glBindTexture(GL_TEXTURE_2D, treeid); + for (j = 0; j < NUMTREE; j++) + drawtree(treepos[j][0], treepos[j][1], treepos[j][2]); + + glDisable(GL_TEXTURE_2D); + glDepthMask(GL_FALSE); + glDisable(GL_ALPHA_TEST); + + if (shadows) { + glBegin(GL_TRIANGLES); + for (j = 0; j < np; j++) { + glColor4f(black[0], black[1], black[2], p[j].c[0][3]); + glVertex3f(p[j].p[0][0], 0.1, p[j].p[0][2]); + + glColor4f(black[0], black[1], black[2], p[j].c[1][3]); + glVertex3f(p[j].p[1][0], 0.1, p[j].p[1][2]); + + glColor4f(black[0], black[1], black[2], p[j].c[2][3]); + glVertex3f(p[j].p[2][0], 0.1, p[j].p[2][2]); + } + glEnd(); + } + + glBegin(GL_TRIANGLES); + for (j = 0; j < np; j++) { + glColor4fv(p[j].c[0]); + glVertex3fv(p[j].p[0]); + + glColor4fv(p[j].c[1]); + glVertex3fv(p[j].p[1]); + + glColor4fv(p[j].c[2]); + glVertex3fv(p[j].p[2]); + + setpart(&p[j]); + } + glEnd(); + + if ((count % FRAME) == 0) { + fr = gettime(); + sprintf(frbuf, "Frame rate: %f", FRAME / fr); + } + + glDisable(GL_TEXTURE_2D); + glDisable(GL_ALPHA_TEST); + glDisable(GL_DEPTH_TEST); + glDisable(GL_FOG); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glColor3f(1.0, 0.0, 0.0); + glRasterPos2i(10, 10); + printstring(GLUT_BITMAP_HELVETICA_18, frbuf); + glRasterPos2i(370, 470); + printstring(GLUT_BITMAP_HELVETICA_10, + "Fire V1.5 Written by David Bucciarelli (tech.hmw@plus.it)"); + + if (help) + printhelp(); + + reshape(WIDTH, HEIGHT); + glPopMatrix(); + + glutSwapBuffers(); + + count++; +} + + +static void +special(int key, int x, int y) +{ + switch (key) { + case GLUT_KEY_LEFT: + alpha += 2.0; + break; + case GLUT_KEY_RIGHT: + alpha -= 2.0; + break; + case GLUT_KEY_DOWN: + beta -= 2.0; + break; + case GLUT_KEY_UP: + beta += 2.0; + break; + } +} + +static void +key(unsigned char key, int x, int y) +{ + switch (key) { + case 27: + exit(0); + break; + + case 'a': + v += 0.01; + break; + case 'z': + v -= 0.01; + break; + + case 'j': + joyactive = (!joyactive); + break; + case 'h': + help = (!help); + break; + case 'f': + fog = (!fog); + break; + case 's': + shadows = !shadows; + break; + case 'R': + eject_r -= 0.03; + break; + case 'r': + eject_r += 0.03; + break; + case 't': + ridtri += 0.005; + break; + case 'T': + ridtri -= 0.005; + break; +#ifdef XMESA + case ' ': + XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW); + fullscreen = (!fullscreen); + break; +#endif + } +} + +static void +inittextures(void) +{ + GLenum gluerr; + GLubyte tex[128][128][4]; + + glGenTextures(1, &groundid); + glBindTexture(GL_TEXTURE_2D, groundid); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + if (!LoadRGBMipmaps("../images/s128.rgb", GL_RGB)) { + fprintf(stderr, "Error reading a texture.\n"); + exit(-1); + } + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + + glGenTextures(1, &treeid); + glBindTexture(GL_TEXTURE_2D, treeid); + + { + int w, h; + GLenum format; + int x, y; + GLubyte *image = LoadRGBImage("../images/tree2.rgb", &w, &h, &format); + + if (!image) { + fprintf(stderr, "Error reading a texture.\n"); + exit(-1); + } + + for (y = 0; y < 128; y++) + for (x = 0; x < 128; x++) { + tex[x][y][0] = image[(y + x * 128) * 3]; + tex[x][y][1] = image[(y + x * 128) * 3 + 1]; + tex[x][y][2] = image[(y + x * 128) * 3 + 2]; + if ((tex[x][y][0] == tex[x][y][1]) && + (tex[x][y][1] == tex[x][y][2]) && (tex[x][y][2] == 255)) + tex[x][y][3] = 0; + else + tex[x][y][3] = 255; + } + + if ((gluerr = gluBuild2DMipmaps(GL_TEXTURE_2D, 4, 128, 128, GL_RGBA, + GL_UNSIGNED_BYTE, (GLvoid *) (tex)))) { + fprintf(stderr, "GLULib%s\n", gluErrorString(gluerr)); + exit(-1); + } + } + + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +} + +static void +inittree(void) +{ + int i; + float dist; + + for (i = 0; i < NUMTREE; i++) + do { + treepos[i][0] = vrnd() * TREEOUTR * 2.0 - TREEOUTR; + treepos[i][1] = 0.0; + treepos[i][2] = vrnd() * TREEOUTR * 2.0 - TREEOUTR; + dist = + sqrt(treepos[i][0] * treepos[i][0] + + treepos[i][2] * treepos[i][2]); + } while ((dist < TREEINR) || (dist > TREEOUTR)); +} + +int +main(int ac, char **av) +{ + int i; + + fprintf(stderr, + "Fire V1.5\nWritten by David Bucciarelli (tech.hmw@plus.it)\n"); + + /* Default settings */ + + WIDTH = 640; + HEIGHT = 480; + np = 800; + eject_r = 0.1; + dt = 0.015; + eject_vy = 4; + eject_vl = 1; + shadows = 1; + ridtri = 0.1; + + maxage = 1.0 / dt; + + if (ac == 2) + np = atoi(av[1]); + + if (ac == 4) { + WIDTH = atoi(av[2]); + HEIGHT = atoi(av[3]); + } + + glutInitWindowPosition(0, 0); + glutInitWindowSize(WIDTH, HEIGHT); + glutInit(&ac, av); + + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); + + if (!(win = glutCreateWindow("Fire"))) { + fprintf(stderr, "Error opening a window.\n"); + exit(-1); + } + + reshape(WIDTH, HEIGHT); + + inittextures(); + + glShadeModel(GL_FLAT); + glEnable(GL_DEPTH_TEST); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_FOG); + glFogi(GL_FOG_MODE, GL_EXP); + glFogfv(GL_FOG_COLOR, fogcolor); + glFogf(GL_FOG_DENSITY, 0.1); +#ifdef FX + glHint(GL_FOG_HINT, GL_NICEST); +#endif + + p = malloc(sizeof(part) * np); + + for (i = 0; i < np; i++) + setnewpart(&p[i]); + + inittree(); + + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutDisplayFunc(drawfire); + glutIdleFunc(drawfire); + glutReshapeFunc(reshape); + glutMainLoop(); + + return (0); +} diff --git a/progs/demos/gltestperf.c b/progs/demos/gltestperf.c new file mode 100644 index 0000000000..2df168ba54 --- /dev/null +++ b/progs/demos/gltestperf.c @@ -0,0 +1,580 @@ +/* + * This program is under the GNU GPL. + * Use at your own risk. + * + * written by David Bucciarelli (tech.hmw@plus.it) + * Humanware s.r.l. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <math.h> +#include <GL/glut.h> + +typedef struct +{ + char *name; + char *unit; + void (*init) (void); + int (*run) (int, int); + int type; + int numsize; + int size[10]; +} +benchmark; + +static int frontbuffer = 1; + +/***************************************************************************/ + +static void +init_test01(void) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(-0.5, 639.5, -0.5, 479.5); + glMatrixMode(GL_MODELVIEW); + + glShadeModel(GL_FLAT); + glDisable(GL_DEPTH_TEST); + + glClearColor(0.0, 0.1, 1.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + glColor3f(1.0, 0.0, 0.0); +} + +static int +test01(int size, int num) +{ + int x, y; + + glBegin(GL_POINTS); + for (y = 0; y < num; y++) + for (x = 0; x < 480; x++) + glVertex2i(x, x); + glEnd(); + + return 480 * num; +} + +/***************************************************************************/ + +static void +init_test02(void) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(-0.5, 639.5, -0.5, 479.5); + glMatrixMode(GL_MODELVIEW); + + glShadeModel(GL_SMOOTH); + glDisable(GL_DEPTH_TEST); + + glClearColor(0.0, 0.1, 1.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); +} + +static int +test02(int size, int num) +{ + int x, y; + + glBegin(GL_LINES); + for (y = 0; y < num; y++) + for (x = 0; x < size; x++) { + glColor3f(0.0, 1.0, y / (float) num); + glVertex2i(0, size - 1); + glColor3f(1.0, 0.0, x / (float) size); + glVertex2i(x, x); + } + glEnd(); + + return num * size; +} + +/***************************************************************************/ + +static void +init_test03(void) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-0.5, 639.5, -0.5, 479.5, 1.0, -1000.0 * 480.0); + glMatrixMode(GL_MODELVIEW); + + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + + glClearColor(0.0, 0.1, 1.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + +static int +test03(int size, int num) +{ + int x, y, z; + + glBegin(GL_TRIANGLES); + for (y = 0; y < num; y++) + for (x = 0; x < size; x += 5) { + z = num * size - (y * size + x); + glColor3f(0.0, 1.0, 0.0); + glVertex3i(0, x, z); + + glColor3f(1.0, 0.0, x / (float) size); + glVertex3i(size - 1 - x, 0, z); + + glColor3f(1.0, x / (float) size, 0.0); + glVertex3i(x, size - 1 - x, z); + } + glEnd(); + + return size * num / 5; +} + +/***************************************************************************/ + +static void +init_test04(void) +{ + int x, y; + GLubyte tex[128 * 128 * 3]; + GLenum gluerr; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-0.5, 639.5, -0.5, 479.5, 1.0, -1000.0 * 480.0); + + glMatrixMode(GL_MODELVIEW); + + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + for (y = 0; y < 128; y++) + for (x = 0; x < 128; x++) { + tex[(x + y * 128) * 3 + 0] = ((x % (128 / 4)) < (128 / 8)) ? 255 : 0; + tex[(x + y * 128) * 3 + 1] = ((y % (128 / 4)) < (128 / 8)) ? 255 : 0; + tex[(x + y * 128) * 3 + 2] = x; + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + if ((gluerr = gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 128, 128, GL_RGB, + GL_UNSIGNED_BYTE, (GLvoid *) (&tex[0])))) { + fprintf(stderr, "GLULib%s\n", gluErrorString(gluerr)); + exit(-1); + } + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glEnable(GL_TEXTURE_2D); + + glClearColor(0.0, 0.1, 1.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + +static int +test04(int size, int num) +{ + int x, y, z; + + glBegin(GL_TRIANGLES); + for (y = 0; y < num; y++) + for (x = 0; x < size; x += 5) { + z = num * size - (y * size + x); + glTexCoord2f(1.0, 1.0); + glColor3f(1.0, 0.0, 0.0); + glVertex3i(0, x, z); + + glTexCoord2f(0.0, 1.0); + glColor3f(0.0, 1.0, 0.0); + glVertex3i(size - 1 - x, 0, z); + + glTexCoord2f(1.0, 0.0); + glColor3f(0.0, 0.0, 1.0); + glVertex3i(x, size - 1 - x, z); + } + glEnd(); + + return num * size / 5; +} + +/***************************************************************************/ + +static void +init_test05(void) +{ + int x, y; + GLubyte tex[128 * 128 * 3]; + GLenum gluerr; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0); + + glMatrixMode(GL_MODELVIEW); + + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + for (y = 0; y < 128; y++) + for (x = 0; x < 128; x++) { + tex[(x + y * 128) * 3 + 0] = ((x % (128 / 4)) < (128 / 8)) ? 255 : 0; + tex[(x + y * 128) * 3 + 1] = ((y % (128 / 4)) < (128 / 8)) ? 255 : 0; + tex[(x + y * 128) * 3 + 2] = x; + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + if ((gluerr = gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 128, 128, GL_RGB, + GL_UNSIGNED_BYTE, (GLvoid *) (&tex[0])))) { + fprintf(stderr, "GLULib%s\n", gluErrorString(gluerr)); + exit(-1); + } + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glEnable(GL_TEXTURE_2D); + + glDepthFunc(GL_ALWAYS); + + glClearColor(0.0, 0.1, 1.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + +static int +test05(int size, int num) +{ + int y; + float v0[3], v1[3], v2[3], v3[3]; + float cv0[3], cv1[3], cv2[3], cv3[3]; + float tv0[3], tv1[3], tv2[3], tv3[3]; + + v0[0] = 320 - size / 2; + v0[1] = 240 - size / 2; + v0[2] = 0.0; + v1[0] = 320 + size / 2; + v1[1] = 240 - size / 2; + v1[2] = 0.0; + v2[0] = 320 - size / 2; + v2[1] = 240 + size / 2; + v2[2] = 0.0; + v3[0] = 320 + size / 2; + v3[1] = 240 + size / 2; + v3[2] = 0.0; + cv0[0] = 1.0; + cv0[1] = 0.0; + cv0[2] = 0.0; + cv1[0] = 1.0; + cv1[1] = 1.0; + cv1[2] = 0.0; + cv2[0] = 1.0; + cv2[1] = 0.0; + cv2[2] = 1.0; + cv3[0] = 1.0; + cv3[1] = 1.0; + cv3[2] = 1.0; + tv0[0] = 0.0; + tv0[1] = 0.0; + tv0[2] = 0.0; + tv1[0] = 1.0; + tv1[1] = 0.0; + tv1[2] = 0.0; + tv2[0] = 0.0; + tv2[1] = 1.0; + tv2[2] = 0.0; + tv3[0] = 1.0; + tv3[1] = 1.0; + tv3[2] = 0.0; + + glBegin(GL_TRIANGLE_STRIP); + for (y = 0; y < num; y++) { + glColor3fv(cv0); + glTexCoord2fv(tv0); + glVertex3fv(v0); + + glColor3fv(cv1); + glTexCoord2fv(tv1); + glVertex3fv(v1); + + glColor3fv(cv2); + glTexCoord2fv(tv2); + glVertex3fv(v2); + + glColor3fv(cv3); + glTexCoord2fv(tv3); + glVertex3fv(v3); + } + glEnd(); + + return 4 * num - 2; +} + +/***************************************************************************/ + +static void +init_test06(void) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(-0.5, 639.5, -0.5, 479.5); + glMatrixMode(GL_MODELVIEW); + + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + + glClearColor(0.0, 0.1, 1.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + +static int +test06(int size, int num) +{ + int y; + + for (y = 0; y < num; y++) { + glClearColor(y / (float) num, 0.1, 1.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + + return num; +} + +/***************************************************************************/ + +#define BMARKS_TIME 5.0 + +#define NUM_BMARKS 6 + +/* 554 ~= sqrt(640*480) */ + +static benchmark bmarks[NUM_BMARKS] = { + {"Simple Points", "Pnts", init_test01, test01, 0, 0, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, + {"Smooth Lines", "Lins", init_test02, test02, 1, 5, + {480, 250, 100, 50, 25, 0, 0, 0, 0, 0}}, + {"ZSmooth Triangles", "Tris", init_test03, test03, 1, 5, + {480, 250, 100, 50, 25, 0, 0, 0, 0, 0}}, + {"ZSmooth Tex Blend Triangles", "Tris", init_test04, test04, 1, 5, + {480, 250, 100, 50, 25, 0, 0, 0, 0, 0}}, + {"ZSmooth Tex Blend TMesh Triangles", "Tris", init_test05, test05, 2, 8, + {400, 250, 100, 50, 25, 10, 5, 2, 0, 0}}, + {"Color/Depth Buffer Clears", "Clrs", init_test06, test06, 3, 0, + {554, 0, 0, 0, 0, 0, 0, 0, 0, 0}} +}; + +/***************************************************************************/ + +static void +dotest0param(benchmark * bmark) +{ + float stime, etime, dtime, tottime, maxtime, mintime; + int num, numelem, calibnum, j; + + glPushAttrib(GL_ALL_ATTRIB_BITS); + bmark->init(); + + stime = glutGet(GLUT_ELAPSED_TIME); + + dtime = 0.0; + calibnum = 0; + while (dtime < 2.0) { + bmark->run(0, 1); + glFinish(); + etime = glutGet(GLUT_ELAPSED_TIME); + dtime = (etime - stime) / 1000.0; + calibnum++; + } + glPopAttrib(); + + fprintf(stderr, "Elapsed time for the calibration test (%d): %f\n", + calibnum, dtime); + + num = (int) ((BMARKS_TIME / dtime) * calibnum); + + if (num < 1) + num = 1; + + fprintf(stderr, "Selected number of benchmark iterations: %d\n", num); + + mintime = HUGE_VAL; + maxtime = -HUGE_VAL; + + for (tottime = 0.0, j = 0; j < 5; j++) { + glPushAttrib(GL_ALL_ATTRIB_BITS); + bmark->init(); + + stime = glutGet(GLUT_ELAPSED_TIME); + numelem = bmark->run(0, num); + glFinish(); + etime = glutGet(GLUT_ELAPSED_TIME); + + glPopAttrib(); + + dtime = (etime - stime) / 1000.0; + tottime += dtime; + + fprintf(stderr, "Elapsed time for run %d: %f\n", j, dtime); + + if (dtime < mintime) + mintime = dtime; + if (dtime > maxtime) + maxtime = dtime; + } + + tottime -= mintime + maxtime; + + fprintf(stdout, "%s\n%f %s/sec", bmark->name, numelem / (tottime / 3.0), + bmark->unit); + + if (bmark->type == 3) + fprintf(stdout, ", MPixel Fill/sec: %f\n\n", + (numelem * bmark->size[0] * (float) bmark->size[0]) / + (1000000.0 * tottime / 3.0)); + else + fprintf(stdout, "\n\n"); +} + +/***************************************************************************/ + +static void +dotest1param(benchmark * bmark) +{ + float stime, etime, dtime, tottime, maxtime, mintime; + int num, numelem, calibnum, j, k; + + fprintf(stdout, "%s\n", bmark->name); + + for (j = 0; j < bmark->numsize; j++) { + fprintf(stderr, "Current size: %d\n", bmark->size[j]); + + glPushAttrib(GL_ALL_ATTRIB_BITS); + bmark->init(); + + stime = glutGet(GLUT_ELAPSED_TIME); + + dtime = 0.0; + calibnum = 0; + while (dtime < 2.0) { + bmark->run(bmark->size[j], 1); + glFinish(); + etime = glutGet(GLUT_ELAPSED_TIME); + dtime = (etime - stime) / 1000.0; + calibnum++; + } + glPopAttrib(); + + fprintf(stderr, "Elapsed time for the calibration test (%d): %f\n", + calibnum, dtime); + + num = (int) ((BMARKS_TIME / dtime) * calibnum); + + if (num < 1) + num = 1; + + fprintf(stderr, "Selected number of benchmark iterations: %d\n", num); + + mintime = HUGE_VAL; + maxtime = -HUGE_VAL; + + for (numelem = 1, tottime = 0.0, k = 0; k < 5; k++) { + glPushAttrib(GL_ALL_ATTRIB_BITS); + bmark->init(); + + stime = glutGet(GLUT_ELAPSED_TIME); + numelem = bmark->run(bmark->size[j], num); + glFinish(); + etime = glutGet(GLUT_ELAPSED_TIME); + + glPopAttrib(); + + dtime = (etime - stime) / 1000.0; + tottime += dtime; + + fprintf(stderr, "Elapsed time for run %d: %f\n", k, dtime); + + if (dtime < mintime) + mintime = dtime; + if (dtime > maxtime) + maxtime = dtime; + } + + tottime -= mintime + maxtime; + + fprintf(stdout, "SIZE=%03d => %f %s/sec", bmark->size[j], + numelem / (tottime / 3.0), bmark->unit); + if (bmark->type == 2) + fprintf(stdout, ", MPixel Fill/sec: %f\n", + (numelem * bmark->size[j] * bmark->size[j] / 2) / + (1000000.0 * tottime / 3.0)); + else + fprintf(stdout, "\n"); + } + + fprintf(stdout, "\n\n"); +} + +/***************************************************************************/ + +static void +display(void) +{ + int i; + + if (frontbuffer) + glDrawBuffer(GL_FRONT); + else + glDrawBuffer(GL_BACK); + + for (i = 0; i < NUM_BMARKS; i++) { + fprintf(stderr, "Benchmark: %d\n", i); + + switch (bmarks[i].type) { + case 0: + case 3: + dotest0param(&bmarks[i]); + break; + case 1: + case 2: + dotest1param(&bmarks[i]); + break; + } + } + + exit(0); +} + +int +main(int ac, char **av) +{ + fprintf(stderr, "GLTest v1.0\nWritten by David Bucciarelli\n"); + + if (ac == 2) + frontbuffer = 0; + + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); + glutInitWindowPosition(0, 0); + glutInitWindowSize(640, 480); + glutCreateWindow("OpenGL/Mesa Performances"); + glutDisplayFunc(display); + glutMainLoop(); + + return 0; +} diff --git a/progs/demos/ipers.c b/progs/demos/ipers.c new file mode 100644 index 0000000000..76da4c01f1 --- /dev/null +++ b/progs/demos/ipers.c @@ -0,0 +1,704 @@ +/* + * This program is under the GNU GPL. + * Use at your own risk. + * + * written by David Bucciarelli (tech.hmw@plus.it) + * Humanware s.r.l. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <time.h> + +#ifdef WIN32 +#include <windows.h> +#include <mmsystem.h> +#endif + +#include <GL/glut.h> + +#include "../util/readtex.c" + +#ifdef XMESA +#include "GL/xmesa.h" +static int fullscreen = 1; +#endif + +static int WIDTH = 640; +static int HEIGHT = 480; + +#define MAX_LOD 9 + +#define TEX_SKY_WIDTH 256 +#define TEX_SKY_HEIGHT TEX_SKY_WIDTH + +#ifndef M_PI +#define M_PI 3.1415926535 +#endif + +#define FROM_NONE 0 +#define FROM_DOWN 1 +#define FROM_UP 2 +#define FROM_LEFT 3 +#define FROM_RIGHT 4 +#define FROM_FRONT 5 +#define FROM_BACK 6 + +static int win = 0; + +static float obs[3] = { 3.8, 0.0, 0.0 }; +static float dir[3]; +static float v = 0.0; +static float alpha = -90.0; +static float beta = 90.0; + +static int fog = 1; +static int bfcull = 1; +static int usetex = 1; +static int help = 1; +static int poutline = 0; +static int normext = 1; +static int joyavailable = 0; +static int joyactive = 0; +static int LODbias = 3; +static int maxdepth = MAX_LOD; + +static unsigned int totpoly = 0; + +static GLuint t1id, t2id; +static GLuint skydlist, LODdlist[MAX_LOD], LODnumpoly[MAX_LOD]; + +static void +initlight(void) +{ + GLfloat lspec[4] = { 1.0, 1.0, 1.0, 1.0 }; + static GLfloat lightpos[4] = { 30, 15.0, 30.0, 1.0 }; + + glLightfv(GL_LIGHT0, GL_POSITION, lightpos); + glLightfv(GL_LIGHT0, GL_SPECULAR, lspec); + + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 32.0); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, lspec); +} + +static void +initdlists(void) +{ + static slicetable[MAX_LOD][2] = { + {21, 10}, + {18, 9}, + {15, 8}, + {12, 7}, + {9, 6}, + {7, 5}, + {5, 4}, + {4, 3}, + {3, 2} + }; + GLUquadricObj *obj; + int i, xslices, yslices; + + obj = gluNewQuadric(); + + skydlist = glGenLists(1); + glNewList(skydlist, GL_COMPILE); + glBindTexture(GL_TEXTURE_2D, t2id); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glColor3f(1.0f, 1.0f, 1.0f); + + gluQuadricDrawStyle(obj, GLU_FILL); + gluQuadricNormals(obj, GLU_NONE); + gluQuadricTexture(obj, GL_TRUE); + gluQuadricOrientation(obj, GLU_INSIDE); + gluSphere(obj, 40.0f, 18, 9); + + glEndList(); + + for (i = 0; i < MAX_LOD; i++) { + LODdlist[i] = glGenLists(1); + glNewList(LODdlist[i], GL_COMPILE); + + gluQuadricDrawStyle(obj, GLU_FILL); + gluQuadricNormals(obj, GLU_SMOOTH); + gluQuadricTexture(obj, GL_TRUE); + gluQuadricOrientation(obj, GLU_OUTSIDE); + xslices = slicetable[i][0]; + yslices = slicetable[i][1]; + gluSphere(obj, 1.0f, xslices, yslices); + LODnumpoly[i] = xslices * (yslices - 2) + 2 * (xslices - 1); + + glEndList(); + } +} + +static void +inittextures(void) +{ + GLubyte tsky[TEX_SKY_HEIGHT][TEX_SKY_WIDTH][3]; + GLuint x, y; + GLfloat fact; + GLenum gluerr; + + /* Brick */ + + glGenTextures(1, &t1id); + glBindTexture(GL_TEXTURE_2D, t1id); + + if (!LoadRGBMipmaps("../images/bw.rgb", 3)) { + fprintf(stderr, "Error reading a texture.\n"); + exit(-1); + } + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + /* Sky */ + + glGenTextures(1, &t2id); + glBindTexture(GL_TEXTURE_2D, t2id); + + for (y = 0; y < TEX_SKY_HEIGHT; y++) + for (x = 0; x < TEX_SKY_WIDTH; x++) + if (y < TEX_SKY_HEIGHT / 2) { + fact = y / (GLfloat) (TEX_SKY_HEIGHT / 2); + tsky[y][x][0] = + (GLubyte) (255.0f * (0.1f * fact + 0.3f * (1.0f - fact))); + tsky[y][x][1] = + (GLubyte) (255.0f * (0.2f * fact + 1.0f * (1.0f - fact))); + tsky[y][x][2] = 255; + } + else { + tsky[y][x][0] = tsky[TEX_SKY_HEIGHT - y - 1][x][0]; + tsky[y][x][1] = tsky[TEX_SKY_HEIGHT - y - 1][x][1]; + tsky[y][x][2] = 255; + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + if ( + (gluerr = + gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TEX_SKY_WIDTH, TEX_SKY_HEIGHT, + GL_RGB, GL_UNSIGNED_BYTE, (GLvoid *) (tsky)))) { + fprintf(stderr, "GLULib%s\n", gluErrorString(gluerr)); + exit(-1); + } + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +} + +static float +gettime(void) +{ + static clock_t told = 0; + clock_t tnew, ris; + + tnew = clock(); + + ris = tnew - told; + + told = tnew; + + return (ris / (float) CLOCKS_PER_SEC); +} + +static void +calcposobs(void) +{ + dir[0] = sin(alpha * M_PI / 180.0); + dir[1] = cos(alpha * M_PI / 180.0) * sin(beta * M_PI / 180.0); + dir[2] = cos(beta * M_PI / 180.0); + + obs[0] += v * dir[0]; + obs[1] += v * dir[1]; + obs[2] += v * dir[2]; +} + +static void +special(int k, int x, int y) +{ + switch (k) { + case GLUT_KEY_LEFT: + alpha -= 2.0; + break; + case GLUT_KEY_RIGHT: + alpha += 2.0; + break; + case GLUT_KEY_DOWN: + beta -= 2.0; + break; + case GLUT_KEY_UP: + beta += 2.0; + break; + } +} + +static void +key(unsigned char k, int x, int y) +{ + switch (k) { + case 27: + exit(0); + break; + + case 'a': + v += 0.01; + break; + case 'z': + v -= 0.01; + break; + +#ifdef XMESA + case ' ': + fullscreen = (!fullscreen); + XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW); + break; +#endif + + case '+': + LODbias--; + break; + case '-': + LODbias++; + break; + case 'j': + joyactive = (!joyactive); + break; + case 'h': + help = (!help); + break; + case 'f': + fog = (!fog); + break; + case 't': + usetex = (!usetex); + break; + case 'n': + normext = (!normext); + break; + case 'b': + if (bfcull) { + glDisable(GL_CULL_FACE); + bfcull = 0; + } + else { + glEnable(GL_CULL_FACE); + bfcull = 1; + } + break; + case 'p': + if (poutline) { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + poutline = 0; + usetex = 1; + } + else { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + poutline = 1; + usetex = 0; + } + break; + } +} + +static void +reshape(int w, int h) +{ + WIDTH = w; + HEIGHT = h; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(90.0, w / (float) h, 0.8, 100.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glViewport(0, 0, w, h); +} + +static void +printstring(void *font, char *string) +{ + int len, i; + + len = (int) strlen(string); + for (i = 0; i < len; i++) + glutBitmapCharacter(font, string[i]); +} + +static void +printhelp(void) +{ + glEnable(GL_BLEND); + glColor4f(0.5, 0.5, 0.5, 0.5); + glRecti(40, 40, 600, 440); + glDisable(GL_BLEND); + + glColor3f(1.0, 0.0, 0.0); + glRasterPos2i(300, 420); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Help"); + + glRasterPos2i(60, 390); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "h - Toggle Help"); + glRasterPos2i(60, 360); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "t - Toggle Textures"); + glRasterPos2i(60, 330); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "f - Toggle Fog"); + glRasterPos2i(60, 300); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "b - Toggle Back face culling"); + glRasterPos2i(60, 270); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Arrow Keys - Rotate"); + glRasterPos2i(60, 240); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "a - Increase velocity"); + glRasterPos2i(60, 210); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "z - Decrease velocity"); + glRasterPos2i(60, 180); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "p - Toggle Wire frame"); + glRasterPos2i(60, 150); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, + "b - Toggle GL_EXT_rescale_normal extension"); + glRasterPos2i(60, 120); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, + "+/- - Increase/decrease the Object maximum LOD"); + + glRasterPos2i(60, 90); + if (joyavailable) + printstring(GLUT_BITMAP_TIMES_ROMAN_24, + "j - Toggle jostick control (Joystick control available)"); + else + printstring(GLUT_BITMAP_TIMES_ROMAN_24, + "(No Joystick control available)"); +} + +static void +dojoy(void) +{ +#ifdef _WIN32 + static UINT max[2] = { 0, 0 }; + static UINT min[2] = { 0xffffffff, 0xffffffff }, center[2]; + MMRESULT res; + JOYINFO joy; + + res = joyGetPos(JOYSTICKID1, &joy); + + if (res == JOYERR_NOERROR) { + joyavailable = 1; + + if (max[0] < joy.wXpos) + max[0] = joy.wXpos; + if (min[0] > joy.wXpos) + min[0] = joy.wXpos; + center[0] = (max[0] + min[0]) / 2; + + if (max[1] < joy.wYpos) + max[1] = joy.wYpos; + if (min[1] > joy.wYpos) + min[1] = joy.wYpos; + center[1] = (max[1] + min[1]) / 2; + + if (joyactive) { + if (fabs(center[0] - (float) joy.wXpos) > 0.1 * (max[0] - min[0])) + alpha -= + 2.0 * (center[0] - (float) joy.wXpos) / (max[0] - min[0]); + if (fabs(center[1] - (float) joy.wYpos) > 0.1 * (max[1] - min[1])) + beta += 2.0 * (center[1] - (float) joy.wYpos) / (max[1] - min[1]); + + if (joy.wButtons & JOY_BUTTON1) + v += 0.01; + if (joy.wButtons & JOY_BUTTON2) + v -= 0.01; + } + } + else + joyavailable = 0; +#endif +} + +static void +drawipers(int depth, int from) +{ + int lod; + + if (depth == maxdepth) + return; + + lod = depth + LODbias; + if (lod < 0) + lod = 0; + if (lod >= MAX_LOD) + return; + + switch (from) { + case FROM_NONE: + glCallList(LODdlist[lod]); + + depth++; + drawipers(depth, FROM_DOWN); + drawipers(depth, FROM_UP); + drawipers(depth, FROM_FRONT); + drawipers(depth, FROM_BACK); + drawipers(depth, FROM_LEFT); + drawipers(depth, FROM_RIGHT); + break; + case FROM_FRONT: + glPushMatrix(); + glTranslatef(0.0f, -1.5f, 0.0f); + glScalef(0.5f, 0.5f, 0.5f); + + glCallList(LODdlist[lod]); + + depth++; + drawipers(depth, FROM_DOWN); + drawipers(depth, FROM_UP); + drawipers(depth, FROM_FRONT); + drawipers(depth, FROM_LEFT); + drawipers(depth, FROM_RIGHT); + glPopMatrix(); + break; + case FROM_BACK: + glPushMatrix(); + glTranslatef(0.0f, 1.5f, 0.0f); + glScalef(0.5f, 0.5f, 0.5f); + + glCallList(LODdlist[lod]); + + depth++; + drawipers(depth, FROM_DOWN); + drawipers(depth, FROM_UP); + drawipers(depth, FROM_BACK); + drawipers(depth, FROM_LEFT); + drawipers(depth, FROM_RIGHT); + glPopMatrix(); + break; + case FROM_LEFT: + glPushMatrix(); + glTranslatef(-1.5f, 0.0f, 0.0f); + glScalef(0.5f, 0.5f, 0.5f); + + glCallList(LODdlist[lod]); + + depth++; + drawipers(depth, FROM_DOWN); + drawipers(depth, FROM_UP); + drawipers(depth, FROM_FRONT); + drawipers(depth, FROM_BACK); + drawipers(depth, FROM_LEFT); + glPopMatrix(); + break; + case FROM_RIGHT: + glPushMatrix(); + glTranslatef(1.5f, 0.0f, 0.0f); + glScalef(0.5f, 0.5f, 0.5f); + + glCallList(LODdlist[lod]); + + depth++; + drawipers(depth, FROM_DOWN); + drawipers(depth, FROM_UP); + drawipers(depth, FROM_FRONT); + drawipers(depth, FROM_BACK); + drawipers(depth, FROM_RIGHT); + glPopMatrix(); + break; + case FROM_DOWN: + glPushMatrix(); + glTranslatef(0.0f, 0.0f, 1.5f); + glScalef(0.5f, 0.5f, 0.5f); + + glCallList(LODdlist[lod]); + + depth++; + drawipers(depth, FROM_DOWN); + drawipers(depth, FROM_FRONT); + drawipers(depth, FROM_BACK); + drawipers(depth, FROM_LEFT); + drawipers(depth, FROM_RIGHT); + glPopMatrix(); + break; + case FROM_UP: + glPushMatrix(); + glTranslatef(0.0f, 0.0f, -1.5f); + glScalef(0.5f, 0.5f, 0.5f); + + glCallList(LODdlist[lod]); + + depth++; + drawipers(depth, FROM_UP); + drawipers(depth, FROM_FRONT); + drawipers(depth, FROM_BACK); + drawipers(depth, FROM_LEFT); + drawipers(depth, FROM_RIGHT); + glPopMatrix(); + break; + } + + totpoly += LODnumpoly[lod]; +} + +static void +draw(void) +{ + static int count = 0; + static char frbuf[80]; + static GLfloat alpha = 0.0f; + static GLfloat beta = 0.0f; + float fr; + + dojoy(); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (usetex) + glEnable(GL_TEXTURE_2D); + else + glDisable(GL_TEXTURE_2D); + + if (fog) + glEnable(GL_FOG); + else + glDisable(GL_FOG); + + glPushMatrix(); + calcposobs(); + gluLookAt(obs[0], obs[1], obs[2], + obs[0] + dir[0], obs[1] + dir[1], obs[2] + dir[2], + 0.0, 0.0, 1.0); + + /* Scene */ + glEnable(GL_DEPTH_TEST); + + glShadeModel(GL_SMOOTH); + glBindTexture(GL_TEXTURE_2D, t1id); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glColor3f(1.0f, 1.0f, 1.0f); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHTING); + + if (normext) + glEnable(GL_RESCALE_NORMAL_EXT); + else + glEnable(GL_NORMALIZE); + + glPushMatrix(); + glRotatef(alpha, 0.0f, 0.0f, 1.0f); + glRotatef(beta, 1.0f, 0.0f, 0.0f); + totpoly = 0; + drawipers(0, FROM_NONE); + glPopMatrix(); + + alpha += 0.5f; + beta += 0.3f; + + glDisable(GL_LIGHTING); + glDisable(GL_LIGHT0); + glShadeModel(GL_FLAT); + + if (normext) + glDisable(GL_RESCALE_NORMAL_EXT); + else + glDisable(GL_NORMALIZE); + + glCallList(skydlist); + + glPopMatrix(); + + /* Help Screen */ + + fr = gettime(); + sprintf(frbuf, + "Frame rate: %0.2f LOD: %d Tot. poly.: %d Poly/sec: %.1f", + 1.0 / fr, LODbias, totpoly, totpoly / fr); + + glDisable(GL_TEXTURE_2D); + glDisable(GL_FOG); + glShadeModel(GL_FLAT); + glDisable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glColor3f(1.0, 0.0, 0.0); + glRasterPos2i(10, 10); + printstring(GLUT_BITMAP_HELVETICA_18, frbuf); + glRasterPos2i(350, 470); + printstring(GLUT_BITMAP_HELVETICA_10, + "IperS V1.0 Written by David Bucciarelli (tech.hmw@plus.it)"); + + if (help) + printhelp(); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + glutSwapBuffers(); + + count++; +} + +int +main(int ac, char **av) +{ + float fogcolor[4] = { 0.7, 0.7, 0.7, 1.0 }; + + fprintf(stderr, + "IperS V1.0\nWritten by David Bucciarelli (tech.hmw@plus.it)\n"); + + glutInitWindowPosition(0, 0); + glutInitWindowSize(WIDTH, HEIGHT); + glutInit(&ac, av); + + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); + + if (!(win = glutCreateWindow("IperS"))) { + fprintf(stderr, "Error, couldn't open window\n"); + exit(-1); + } + + reshape(WIDTH, HEIGHT); + + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glEnable(GL_TEXTURE_2D); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_FOG); + glFogi(GL_FOG_MODE, GL_EXP2); + glFogfv(GL_FOG_COLOR, fogcolor); + + glFogf(GL_FOG_DENSITY, 0.006); + + glHint(GL_FOG_HINT, GL_NICEST); + + inittextures(); + initdlists(); + initlight(); + + glClearColor(fogcolor[0], fogcolor[1], fogcolor[2], fogcolor[3]); + glClear(GL_COLOR_BUFFER_BIT); + + calcposobs(); + + glutReshapeFunc(reshape); + glutDisplayFunc(draw); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutIdleFunc(draw); + + glutMainLoop(); + + return 0; +} diff --git a/progs/demos/particles.cxx b/progs/demos/particles.cxx new file mode 100644 index 0000000000..b88c318e0b --- /dev/null +++ b/progs/demos/particles.cxx @@ -0,0 +1,219 @@ +/* + * This program is under the GNU GPL. + * Use at your own risk. + * + * written by David Bucciarelli (humanware@plus.it) + * Humanware s.r.l. + */ + +#include <stdlib.h> + +#include "particles.h" + +#define vinit(a,i,j,k) {\ + (a)[0]=i;\ + (a)[1]=j;\ + (a)[2]=k;\ +} + +#define vadds(a,dt,b) {\ + (a)[0]+=(dt)*(b)[0];\ + (a)[1]+=(dt)*(b)[1];\ + (a)[2]+=(dt)*(b)[2];\ +} + +#define vequ(a,b) {\ + (a)[0]=(b)[0];\ + (a)[1]=(b)[1];\ + (a)[2]=(b)[2];\ +} + +#define vinter(a,dt,b,c) {\ + (a)[0]=(dt)*(b)[0]+(1.0-dt)*(c)[0];\ + (a)[1]=(dt)*(b)[1]+(1.0-dt)*(c)[1];\ + (a)[2]=(dt)*(b)[2]+(1.0-dt)*(c)[2];\ +} + +#define clamp(a) ((a) < 0.0 ? 0.0 : ((a) < 1.0 ? (a) : 1.0)) + +#define vclamp(v) {\ + (v)[0]=clamp((v)[0]);\ + (v)[1]=clamp((v)[1]);\ + (v)[2]=clamp((v)[2]);\ +} + + +float rainParticle::min[3]; +float rainParticle::max[3]; +float rainParticle::partLength=0.2f; + + +static float vrnd(void) +{ + return(((float)rand())/RAND_MAX); +} + + +particle::particle() +{ + age=0.0f; + + vinit(acc,0.0f,0.0f,0.0f); + vinit(vel,0.0f,0.0f,0.0f); + vinit(pos,0.0f,0.0f,0.0f); +} + +void particle::elapsedTime(float dt) +{ + age+=dt; + + vadds(vel,dt,acc); + + vadds(pos,dt,vel); +} + +///////////////////////////////////////// +// Particle System +///////////////////////////////////////// + +particleSystem::particleSystem() +{ + t=0.0f; + + part=NULL; + + particleNum=0; +} + +particleSystem::~particleSystem() +{ + if(part) + free(part); +} + +void particleSystem::addParticle(particle *p) +{ + if(!part) { + part=(particle **)calloc(1,sizeof(particle *)); + part[0]=p; + particleNum=1; + } else { + particleNum++; + part=(particle **)realloc(part,sizeof(particle *)*particleNum); + part[particleNum-1]=p; + } +} + +void particleSystem::reset(void) +{ + if(part) + free(part); + + t=0.0f; + + part=NULL; + + particleNum=0; +} + +void particleSystem::draw(void) +{ + if(!part) + return; + + part[0]->beginDraw(); + for(unsigned int i=0;i<particleNum;i++) + part[i]->draw(); + part[0]->endDraw(); +} + +void particleSystem::addTime(float dt) +{ + if(!part) + return; + + for(unsigned int i=0;i<particleNum;i++) { + part[i]->elapsedTime(dt); + part[i]->checkAge(); + } +} + +///////////////////////////////////////// +// Rain +///////////////////////////////////////// + +void rainParticle::init(void) +{ + age=0.0f; + + acc[0]=0.0f; + acc[1]=-0.98f; + acc[2]=0.0f; + + vel[0]=0.0f; + vel[1]=0.0f; + vel[2]=0.0f; + + oldpos[0]=pos[0]=min[0]+(max[0]-min[0])*vrnd(); + oldpos[1]=pos[1]=max[1]+0.2f*max[1]*vrnd(); + oldpos[2]=pos[2]=min[2]+(max[2]-min[2])*vrnd(); + + vadds(oldpos,-partLength,vel); +} + +rainParticle::rainParticle() +{ + init(); +} + +void rainParticle::setRainingArea(float minx, float miny, float minz, + float maxx, float maxy, float maxz) +{ + vinit(min,minx,miny,minz); + vinit(max,maxx,maxy,maxz); +} + +void rainParticle::setLength(float l) +{ + partLength=l; +} + +void rainParticle::draw(void) +{ + glColor4f(0.7f,0.95f,1.0f,0.0f); + glVertex3fv(oldpos); + + glColor4f(0.3f,0.7f,1.0f,1.0f); + glVertex3fv(pos); +} + +void rainParticle::checkAge(void) +{ + if(pos[1]<min[1]) + init(); +} + +void rainParticle::elapsedTime(float dt) +{ + particle::elapsedTime(dt); + + if(pos[0]<min[0]) + pos[0]=max[0]-(min[0]-pos[0]); + if(pos[2]<min[2]) + pos[2]=max[2]-(min[2]-pos[2]); + + if(pos[0]>max[0]) + pos[0]=min[0]+(pos[0]-max[0]); + if(pos[2]>max[2]) + pos[2]=min[2]+(pos[2]-max[2]); + + vequ(oldpos,pos); + vadds(oldpos,-partLength,vel); +} + +void rainParticle::randomHeight(void) +{ + pos[1]=(max[1]-min[1])*vrnd()+min[1]; + + oldpos[1]=pos[1]-partLength*vel[1]; +} diff --git a/progs/demos/particles.h b/progs/demos/particles.h new file mode 100644 index 0000000000..a49dd691e4 --- /dev/null +++ b/progs/demos/particles.h @@ -0,0 +1,81 @@ +/* + * This program is under the GNU GPL. + * Use at your own risk. + * + * written by David Bucciarelli (humanware@plus.it) + * Humanware s.r.l. + */ + +#ifndef PARTICLES_H +#define PARTICLES_H + +#include <GL/gl.h> + +class particle { + protected: + float age; // in seconds + float acc[3]; + float vel[3]; + float pos[3]; + + public: + particle(); + virtual ~particle() {}; + + virtual void beginDraw(void) {}; + virtual void draw(void)=0; + virtual void endDraw(void) {}; + + virtual void elapsedTime(float); + virtual void checkAge(void) {}; +}; + +class particleSystem { + protected: + particle **part; + + float t; + + unsigned long particleNum; + public: + particleSystem(); + ~particleSystem(); + + void addParticle(particle *); + + void reset(void); + + void draw(void); + + void addTime(float); +}; + +class rainParticle : public particle { + protected: + static float min[3]; + static float max[3]; + static float partLength; + + float oldpos[3]; + + void init(void); + public: + rainParticle(); + + static void setRainingArea(float, float, float, + float, float, float); + static void setLength(float); + static float getLength(void) { return partLength; }; + + void beginDraw(void) { glBegin(GL_LINES); }; + void draw(void); + void endDraw(void) { glEnd(); }; + + void elapsedTime(float); + + void checkAge(void); + + void randomHeight(void); +}; + +#endif diff --git a/progs/demos/rain.cxx b/progs/demos/rain.cxx new file mode 100644 index 0000000000..4a7ecde3c8 --- /dev/null +++ b/progs/demos/rain.cxx @@ -0,0 +1,388 @@ +/* + * This program is under the GNU GPL. + * Use at your own risk. + * + * written by David Bucciarelli (humanware@plus.it) + * Humanware s.r.l. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <time.h> +#include <GL/glut.h> + +#include "particles.h" +extern "C" { +#include "image.h" +} + +#ifdef WIN32 +#include <windows.h> +#include <mmsystem.h> +#endif + +#ifdef XMESA +#include "GL/xmesa.h" +static int fullscreen=1; +#endif + +static int WIDTH=640; +static int HEIGHT=480; +static int NUMPART=7500; + +#define FRAME 50 + +static float fogcolor[4]={1.0,1.0,1.0,1.0}; + +#define DIMP 40.0 +#define DIMTP 32.0 + +static float q[4][3]={ + {-DIMP,0.0,-DIMP}, + {DIMP,0.0,-DIMP}, + {DIMP,0.0,DIMP}, + {-DIMP,0.0,DIMP} +}; + +static float qt[4][2]={ + {-DIMTP,-DIMTP}, + {DIMTP,-DIMTP}, + {DIMTP,DIMTP}, + {-DIMTP,DIMTP} +}; + +static int win=0; + +static int fog=1; +static int help=1; + +static GLuint groundid; + +static float obs[3]={2.0,1.0,0.0}; +static float dir[3]; +static float v=0.0; +static float alpha=-90.0; +static float beta=90.0; + +static particleSystem *ps; + +static float gettime() +{ + static clock_t told=0; + clock_t tnew,ris; + + tnew=clock(); + + ris=tnew-told; + + told=tnew; + + return(ris/(float)CLOCKS_PER_SEC); +} + +static float gettimerain() +{ + static clock_t told=0; + clock_t tnew,ris; + + tnew=clock(); + + ris=tnew-told; + + told=tnew; + + return(ris/(float)CLOCKS_PER_SEC); +} + +static void calcposobs(void) +{ + dir[0]=sin(alpha*M_PI/180.0); + dir[2]=cos(alpha*M_PI/180.0)*sin(beta*M_PI/180.0); + dir[1]=cos(beta*M_PI/180.0); + + obs[0]+=v*dir[0]; + obs[1]+=v*dir[1]; + obs[2]+=v*dir[2]; + + rainParticle::setRainingArea(obs[0]-7.0f,-0.2f,obs[2]-7.0f,obs[0]+7.0f,8.0f,obs[2]+7.0f); +} + +static void printstring(void *font, char *string) +{ + int len,i; + + len=(int)strlen(string); + for(i=0;i<len;i++) + glutBitmapCharacter(font,string[i]); +} + +static void reshape(int width, int height) +{ + WIDTH=width; + HEIGHT=height; + glViewport(0,0,(GLint)width,(GLint)height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(70.0,width/(float)height,0.1,30.0); + + glMatrixMode(GL_MODELVIEW); +} + +static void printhelp(void) +{ + glEnable(GL_BLEND); + glColor4f(0.0,0.0,0.0,0.5); + glRecti(40,40,600,440); + glDisable(GL_BLEND); + + glColor3f(1.0,0.0,0.0); + glRasterPos2i(300,420); + printstring(GLUT_BITMAP_TIMES_ROMAN_24,"Help"); + + glRasterPos2i(60,390); + printstring(GLUT_BITMAP_TIMES_ROMAN_24,"h - Togle Help"); + + glRasterPos2i(60,360); + printstring(GLUT_BITMAP_TIMES_ROMAN_24,"f - Togle Fog"); + glRasterPos2i(60,330); + printstring(GLUT_BITMAP_TIMES_ROMAN_24,"Arrow Keys - Rotate"); + glRasterPos2i(60,300); + printstring(GLUT_BITMAP_TIMES_ROMAN_24,"a - Increase velocity"); + glRasterPos2i(60,270); + printstring(GLUT_BITMAP_TIMES_ROMAN_24,"z - Decrease velocity"); + glRasterPos2i(60,240); + printstring(GLUT_BITMAP_TIMES_ROMAN_24,"l - Increase rain length"); + glRasterPos2i(60,210); + printstring(GLUT_BITMAP_TIMES_ROMAN_24,"k - Increase rain length"); +} + +static void drawrain(void) +{ + static int count=0; + static char frbuf[80]; + float fr; + + glEnable(GL_DEPTH_TEST); + + if(fog) + glEnable(GL_FOG); + else + glDisable(GL_FOG); + + glDepthMask(GL_TRUE); + glClearColor(1.0,1.0,1.0,1.0); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + calcposobs(); + gluLookAt(obs[0],obs[1],obs[2], + obs[0]+dir[0],obs[1]+dir[1],obs[2]+dir[2], + 0.0,1.0,0.0); + + glColor4f(1.0,1.0,1.0,1.0); + + glEnable(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_2D,groundid); + glBegin(GL_QUADS); + glTexCoord2fv(qt[0]); + glVertex3fv(q[0]); + glTexCoord2fv(qt[1]); + glVertex3fv(q[1]); + glTexCoord2fv(qt[2]); + glVertex3fv(q[2]); + glTexCoord2fv(qt[3]); + glVertex3fv(q[3]); + glEnd(); + + // Particle System + + glDisable(GL_TEXTURE_2D); + glShadeModel(GL_SMOOTH); + glEnable(GL_BLEND); + + ps->draw(); + ps->addTime(gettimerain()); + + glShadeModel(GL_FLAT); + + + if((count % FRAME)==0) { + fr=gettime(); + sprintf(frbuf,"Frame rate: %f",FRAME/fr); + } + + glDisable(GL_TEXTURE_2D); + glDisable(GL_DEPTH_TEST); + glDisable(GL_FOG); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-0.5,639.5,-0.5,479.5,-1.0,1.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glColor3f(1.0,0.0,0.0); + glRasterPos2i(10,10); + printstring(GLUT_BITMAP_HELVETICA_18,frbuf); + glRasterPos2i(350,470); + printstring(GLUT_BITMAP_HELVETICA_10,"Rain V1.0 Written by David Bucciarelli (humanware@plus.it)"); + + if(help) + printhelp(); + + reshape(WIDTH,HEIGHT); + glPopMatrix(); + + glutSwapBuffers(); + + count++; +} + + +static void special(int key, int x, int y) +{ + switch (key) { + case GLUT_KEY_LEFT: + alpha+=2.0; + break; + case GLUT_KEY_RIGHT: + alpha-=2.0; + break; + case GLUT_KEY_DOWN: + beta-=2.0; + break; + case GLUT_KEY_UP: + beta+=2.0; + break; + } +} + +static void key(unsigned char key, int x, int y) +{ + switch (key) { + case 27: + exit(0); + break; + + case 'a': + v+=0.01; + break; + case 'z': + v-=0.01; + break; + + case 'l': + rainParticle::setLength(rainParticle::getLength()+0.025f); + break; + case 'k': + rainParticle::setLength(rainParticle::getLength()-0.025f); + break; + + case 'h': + help=(!help); + break; + case 'f': + fog=(!fog); + break; +#ifdef XMESA + case ' ': + XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW); + fullscreen=(!fullscreen); + break; +#endif + } +} + +static void inittextures(void) +{ + IMAGE *img; + GLenum gluerr; + + glGenTextures(1,&groundid); + glBindTexture(GL_TEXTURE_2D,groundid); + + if(!(img=ImageLoad("s128.rgb"))) { + fprintf(stderr,"Error reading a texture.\n"); + exit(-1); + } + + glPixelStorei(GL_UNPACK_ALIGNMENT,4); + if((gluerr=(GLenum)gluBuild2DMipmaps(GL_TEXTURE_2D, 3, img->sizeX, img->sizeY, GL_RGB, + GL_UNSIGNED_BYTE, (GLvoid *)(img->data)))) { + fprintf(stderr,"GLULib%s\n",gluErrorString(gluerr)); + exit(-1); + } + + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); + + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL); +} + +static void initparticle(void) +{ + ps=new particleSystem; + + rainParticle::setRainingArea(-7.0f,-0.2f,-7.0f,7.0f,8.0f,7.0f); + + for(int i=0;i<NUMPART;i++) { + rainParticle *p=new rainParticle; + p->randomHeight(); + + ps->addParticle((particle *)p); + } +} + +int main(int ac,char **av) +{ + fprintf(stderr,"Rain V1.0\nWritten by David Bucciarelli (humanware@plus.it)\n"); + + /* Default settings */ + + WIDTH=640; + HEIGHT=480; + + glutInitWindowPosition(0,0); + glutInitWindowSize(WIDTH,HEIGHT); + glutInit(&ac,av); + + glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH|GLUT_DOUBLE); + + if(!(win=glutCreateWindow("Rain"))) { + fprintf(stderr,"Error opening a window.\n"); + exit(-1); + } + + reshape(WIDTH,HEIGHT); + + inittextures(); + + glShadeModel(GL_FLAT); + glEnable(GL_DEPTH_TEST); + + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_FOG); + glFogi(GL_FOG_MODE,GL_EXP); + glFogfv(GL_FOG_COLOR,fogcolor); + glFogf(GL_FOG_DENSITY,0.1); +#ifdef FX + glHint(GL_FOG_HINT,GL_NICEST); +#endif + + initparticle(); + + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutDisplayFunc(drawrain); + glutIdleFunc(drawrain); + glutReshapeFunc(reshape); + glutMainLoop(); + + return(0); +} diff --git a/progs/demos/ray.c b/progs/demos/ray.c new file mode 100644 index 0000000000..24f27a0539 --- /dev/null +++ b/progs/demos/ray.c @@ -0,0 +1,908 @@ +/* + * This program is under the GNU GPL. + * Use at your own risk. + * + * written by David Bucciarelli (tech.hmw@plus.it) + * Humanware s.r.l. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> + +#ifdef WIN32 +#include <windows.h> +#endif + +#include <GL/glut.h> + +#ifdef XMESA +#include "GL/xmesa.h" +static int fullscreen = 1; +#endif + +static int WIDTH = 640; +static int HEIGHT = 480; + +#define FRAME 50 + +#define BASESIZE 7.5f +#define SPHERE_RADIUS 0.75f + +#define TEX_CHECK_WIDTH 256 +#define TEX_CHECK_HEIGHT 256 +#define TEX_CHECK_SLOT_SIZE (TEX_CHECK_HEIGHT/16) +#define TEX_CHECK_NUMSLOT (TEX_CHECK_HEIGHT/TEX_CHECK_SLOT_SIZE) + +#define TEX_REFLECT_WIDTH 256 +#define TEX_REFLECT_HEIGHT 256 +#define TEX_REFLECT_SLOT_SIZE (TEX_REFLECT_HEIGHT/16) +#define TEX_REFLECT_NUMSLOT (TEX_REFLECT_HEIGHT/TEX_REFLECT_SLOT_SIZE) + +#ifndef M_PI +#define M_PI 3.1415926535 +#endif + +#define EPSILON 0.0001 + +#define clamp255(a) ( (a)<(0.0f) ? (0.0f) : ((a)>(255.0f) ? (255.0f) : (a)) ) + +#define fabs(x) ((x)<0.0f?-(x):(x)) + +#define vequ(a,b) { (a)[0]=(b)[0]; (a)[1]=(b)[1]; (a)[2]=(b)[2]; } +#define vsub(a,b,c) { (a)[0]=(b)[0]-(c)[0]; (a)[1]=(b)[1]-(c)[1]; (a)[2]=(b)[2]-(c)[2]; } +#define dprod(a,b) ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[2]) +#define vnormalize(a,b) { \ + register float m_norm; \ + m_norm=sqrt((double)dprod((a),(a))); \ + (a)[0] /=m_norm; \ + (a)[1] /=m_norm; \ + (a)[2] /=m_norm; } + +static GLubyte checkmap[TEX_CHECK_HEIGHT][TEX_CHECK_WIDTH][3]; +static GLuint checkid; +static int checkmap_currentslot = 0; + +static GLubyte reflectmap[TEX_REFLECT_HEIGHT][TEX_REFLECT_WIDTH][3]; +static GLuint reflectid; +static int reflectmap_currentslot = 0; + +static GLuint lightdlist; +static GLuint objdlist; + +static float lightpos[3] = { 2.1, 2.1, 2.8 }; +static float objpos[3] = { 0.0, 0.0, 1.0 }; + +static float sphere_pos[TEX_CHECK_HEIGHT][TEX_REFLECT_WIDTH][3]; + +static int win = 0; + +static float fogcolor[4] = { 0.05, 0.05, 0.05, 1.0 }; + +static float obs[3] = { 7.0, 0.0, 2.0 }; +static float dir[3]; +static float v = 0.0; +static float alpha = -90.0; +static float beta = 90.0; + +static int fog = 1; +static int bfcull = 1; +static int poutline = 0; +static int help = 1; +static int showcheckmap = 1; +static int showreflectmap = 1; +static int joyavailable = 0; +static int joyactive = 0; + +static float +gettime(void) +{ + static float told = 0.0f; + float tnew, ris; + + tnew = glutGet(GLUT_ELAPSED_TIME); + + ris = tnew - told; + + told = tnew; + + return ris / 1000.0; +} + +static void +calcposobs(void) +{ + dir[0] = sin(alpha * M_PI / 180.0); + dir[1] = cos(alpha * M_PI / 180.0) * sin(beta * M_PI / 180.0); + dir[2] = cos(beta * M_PI / 180.0); + + obs[0] += v * dir[0]; + obs[1] += v * dir[1]; + obs[2] += v * dir[2]; +} + +static void +special(int k, int x, int y) +{ + switch (k) { + case GLUT_KEY_LEFT: + alpha -= 2.0; + break; + case GLUT_KEY_RIGHT: + alpha += 2.0; + break; + case GLUT_KEY_DOWN: + beta -= 2.0; + break; + case GLUT_KEY_UP: + beta += 2.0; + break; + } +} + +static void +key(unsigned char k, int x, int y) +{ + switch (k) { + case 27: + exit(0); + break; + + case 's': + lightpos[1] -= 0.1; + break; + case 'd': + lightpos[1] += 0.1; + break; + case 'e': + lightpos[0] -= 0.1; + break; + case 'x': + lightpos[0] += 0.1; + break; + case 'w': + lightpos[2] -= 0.1; + break; + case 'r': + lightpos[2] += 0.1; + break; + + case 'j': + objpos[1] -= 0.1; + break; + case 'k': + objpos[1] += 0.1; + break; + case 'i': + objpos[0] -= 0.1; + break; + case 'm': + objpos[0] += 0.1; + break; + case 'u': + objpos[2] -= 0.1; + break; + case 'o': + objpos[2] += 0.1; + break; + + case 'a': + v += 0.005; + break; + case 'z': + v -= 0.005; + break; + + case 'g': + joyactive = (!joyactive); + break; + case 'h': + help = (!help); + break; + case 'f': + fog = (!fog); + break; + + case '1': + showcheckmap = (!showcheckmap); + break; + case '2': + showreflectmap = (!showreflectmap); + break; + + case 'b': + if (bfcull) { + glDisable(GL_CULL_FACE); + bfcull = 0; + } + else { + glEnable(GL_CULL_FACE); + bfcull = 1; + } + break; + case 'p': + if (poutline) { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + poutline = 0; + } + else { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + poutline = 1; + } + break; +#ifdef XMESA + case ' ': + XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW); + fullscreen = (!fullscreen); + break; +#endif + } +} + +static void +reshape(int w, int h) +{ + WIDTH = w; + HEIGHT = h; + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45.0, w / (float) h, 0.8, 40.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +static void +printstring(void *font, char *string) +{ + int len, i; + + len = (int) strlen(string); + for (i = 0; i < len; i++) + glutBitmapCharacter(font, string[i]); +} + +static void +printhelp(void) +{ + glEnable(GL_BLEND); + glColor4f(0.5, 0.5, 0.5, 0.5); + glRecti(40, 40, 600, 440); + glDisable(GL_BLEND); + + glColor3f(0.0, 0.0, 1.0); + glRasterPos2i(300, 420); + printstring(GLUT_BITMAP_HELVETICA_18, "Help"); + + glRasterPos2i(60, 390); + printstring(GLUT_BITMAP_HELVETICA_12, "h - Togle Help"); + glRasterPos2i(60, 370); + printstring(GLUT_BITMAP_HELVETICA_12, "f - Togle Fog"); + glRasterPos2i(60, 350); + printstring(GLUT_BITMAP_HELVETICA_12, "b - Togle Back face culling"); + glRasterPos2i(60, 330); + printstring(GLUT_BITMAP_HELVETICA_12, "p - Togle Wire frame"); + glRasterPos2i(60, 310); + printstring(GLUT_BITMAP_HELVETICA_12, "Arrow Keys - Rotate"); + glRasterPos2i(60, 290); + printstring(GLUT_BITMAP_HELVETICA_12, "a - Increase velocity"); + glRasterPos2i(60, 270); + printstring(GLUT_BITMAP_HELVETICA_12, "z - Decrease velocity"); + + glRasterPos2i(60, 250); + if (joyavailable) + printstring(GLUT_BITMAP_HELVETICA_12, + "j - Togle jostick control (Joystick control available)"); + else + printstring(GLUT_BITMAP_HELVETICA_12, + "(No Joystick control available)"); + + glRasterPos2i(60, 230); + printstring(GLUT_BITMAP_HELVETICA_12, + "To move the light source: s - left, d - right, e - far, x - near, w - down r - up"); + glRasterPos2i(60, 210); + printstring(GLUT_BITMAP_HELVETICA_12, + "To move the mirror sphere: j - left, k - right, i - far, m - near, u - down o - up"); + + glRasterPos2i(60, 190); + printstring(GLUT_BITMAP_HELVETICA_12, + "1 - Togle the plane texture map window"); + + glRasterPos2i(60, 170); + printstring(GLUT_BITMAP_HELVETICA_12, + "2 - Togle the sphere texture map window"); +} + +static GLboolean +seelight(float p[3], float dir[3]) +{ + float c[3], b, a, d, t, dist[3]; + + vsub(c, p, objpos); + b = -dprod(c, dir); + a = dprod(c, c) - SPHERE_RADIUS * SPHERE_RADIUS; + + if ((d = b * b - a) < 0.0 || (b < 0.0 && a > 0.0)) + return GL_FALSE; + + d = sqrt(d); + + t = b - d; + + if (t < EPSILON) { + t = b + d; + if (t < EPSILON) + return GL_FALSE; + } + + vsub(dist, lightpos, p); + if (dprod(dist, dist) < t * t) + return GL_FALSE; + + return GL_TRUE; +} + +static int +colorcheckmap(float ppos[3], float c[3]) +{ + static float norm[3] = { 0.0f, 0.0f, 1.0f }; + float ldir[3], vdir[3], h[3], dfact, kfact, r, g, b; + int x, y; + + x = (int) ((ppos[0] + BASESIZE / 2) * (10.0f / BASESIZE)); + if ((x < 0) || (x > 10)) + return GL_FALSE; + + y = (int) ((ppos[1] + BASESIZE / 2) * (10.0f / BASESIZE)); + if ((y < 0) || (y > 10)) + return GL_FALSE; + + r = 255.0f; + if (y & 1) { + if (x & 1) + g = 255.0f; + else + g = 0.0f; + } + else { + if (x & 1) + g = 0.0f; + else + g = 255.0f; + } + b = 0.0f; + + vsub(ldir, lightpos, ppos); + vnormalize(ldir, ldir); + + if (seelight(ppos, ldir)) { + c[0] = r * 0.05f; + c[1] = g * 0.05f; + c[2] = b * 0.05f; + + return GL_TRUE; + } + + dfact = dprod(ldir, norm); + if (dfact < 0.0f) + dfact = 0.0f; + + vsub(vdir, obs, ppos); + vnormalize(vdir, vdir); + h[0] = 0.5f * (vdir[0] + ldir[0]); + h[1] = 0.5f * (vdir[1] + ldir[1]); + h[2] = 0.5f * (vdir[2] + ldir[2]); + kfact = dprod(h, norm); + kfact = + kfact * kfact * kfact * kfact * kfact * kfact * kfact * 7.0f * 255.0f; + + r = r * dfact + kfact; + g = g * dfact + kfact; + b = b * dfact + kfact; + + c[0] = clamp255(r); + c[1] = clamp255(g); + c[2] = clamp255(b); + + return GL_TRUE; +} + +static void +updatecheckmap(int slot) +{ + float c[3], ppos[3]; + int x, y; + + glBindTexture(GL_TEXTURE_2D, checkid); + + ppos[2] = 0.0f; + for (y = slot * TEX_CHECK_SLOT_SIZE; y < (slot + 1) * TEX_CHECK_SLOT_SIZE; + y++) { + ppos[1] = (y / (float) TEX_CHECK_HEIGHT) * BASESIZE - BASESIZE / 2; + + for (x = 0; x < TEX_CHECK_WIDTH; x++) { + ppos[0] = (x / (float) TEX_CHECK_WIDTH) * BASESIZE - BASESIZE / 2; + + colorcheckmap(ppos, c); + checkmap[y][x][0] = (GLubyte) c[0]; + checkmap[y][x][1] = (GLubyte) c[1]; + checkmap[y][x][2] = (GLubyte) c[2]; + } + } + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, slot * TEX_CHECK_SLOT_SIZE, + TEX_CHECK_WIDTH, TEX_CHECK_SLOT_SIZE, GL_RGB, + GL_UNSIGNED_BYTE, + &checkmap[slot * TEX_CHECK_SLOT_SIZE][0][0]); + +} + +static void +updatereflectmap(int slot) +{ + float rf, r, g, b, t, dfact, kfact, rdir[3]; + float rcol[3], ppos[3], norm[3], ldir[3], h[3], vdir[3], planepos[3]; + int x, y; + + glBindTexture(GL_TEXTURE_2D, reflectid); + + for (y = slot * TEX_REFLECT_SLOT_SIZE; + y < (slot + 1) * TEX_REFLECT_SLOT_SIZE; y++) + for (x = 0; x < TEX_REFLECT_WIDTH; x++) { + ppos[0] = sphere_pos[y][x][0] + objpos[0]; + ppos[1] = sphere_pos[y][x][1] + objpos[1]; + ppos[2] = sphere_pos[y][x][2] + objpos[2]; + + vsub(norm, ppos, objpos); + vnormalize(norm, norm); + + vsub(ldir, lightpos, ppos); + vnormalize(ldir, ldir); + vsub(vdir, obs, ppos); + vnormalize(vdir, vdir); + + rf = 2.0f * dprod(norm, vdir); + if (rf > EPSILON) { + rdir[0] = rf * norm[0] - vdir[0]; + rdir[1] = rf * norm[1] - vdir[1]; + rdir[2] = rf * norm[2] - vdir[2]; + + t = -objpos[2] / rdir[2]; + + if (t > EPSILON) { + planepos[0] = objpos[0] + t * rdir[0]; + planepos[1] = objpos[1] + t * rdir[1]; + planepos[2] = 0.0f; + + if (!colorcheckmap(planepos, rcol)) + rcol[0] = rcol[1] = rcol[2] = 0.0f; + } + else + rcol[0] = rcol[1] = rcol[2] = 0.0f; + } + else + rcol[0] = rcol[1] = rcol[2] = 0.0f; + + dfact = 0.1f * dprod(ldir, norm); + + if (dfact < 0.0f) { + dfact = 0.0f; + kfact = 0.0f; + } + else { + h[0] = 0.5f * (vdir[0] + ldir[0]); + h[1] = 0.5f * (vdir[1] + ldir[1]); + h[2] = 0.5f * (vdir[2] + ldir[2]); + kfact = dprod(h, norm); + kfact *= kfact; + kfact *= kfact; + kfact *= kfact; + kfact *= kfact; + kfact *= 10.0f; + } + + r = dfact + kfact; + g = dfact + kfact; + b = dfact + kfact; + + r *= 255.0f; + g *= 255.0f; + b *= 255.0f; + + r += rcol[0]; + g += rcol[1]; + b += rcol[2]; + + r = clamp255(r); + g = clamp255(g); + b = clamp255(b); + + reflectmap[y][x][0] = (GLubyte) r; + reflectmap[y][x][1] = (GLubyte) g; + reflectmap[y][x][2] = (GLubyte) b; + } + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, slot * TEX_REFLECT_SLOT_SIZE, + TEX_REFLECT_WIDTH, TEX_REFLECT_SLOT_SIZE, GL_RGB, + GL_UNSIGNED_BYTE, + &reflectmap[slot * TEX_REFLECT_SLOT_SIZE][0][0]); +} + +static void +drawbase(void) +{ + glColor3f(0.0, 0.0, 0.0); + glBindTexture(GL_TEXTURE_2D, checkid); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 0.0f); + glVertex3f(-BASESIZE / 2.0f, -BASESIZE / 2.0f, 0.0f); + + glTexCoord2f(1.0f, 0.0f); + glVertex3f(BASESIZE / 2.0f, -BASESIZE / 2.0f, 0.0f); + + glTexCoord2f(1.0f, 1.0f); + glVertex3f(BASESIZE / 2.0f, BASESIZE / 2.0f, 0.0f); + + glTexCoord2f(0.0f, 1.0f); + glVertex3f(-BASESIZE / 2.0f, BASESIZE / 2.0f, 0.0f); + + glEnd(); +} + +static void +drawobj(void) +{ + glColor3f(0.0, 0.0, 0.0); + glBindTexture(GL_TEXTURE_2D, reflectid); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + glPushMatrix(); + glTranslatef(objpos[0], objpos[1], objpos[2]); + glCallList(objdlist); + glPopMatrix(); +} + +static void +dojoy(void) +{ +#ifdef WIN32 + static UINT max[2] = { 0, 0 }; + static UINT min[2] = { 0xffffffff, 0xffffffff }, center[2]; + MMRESULT res; + JOYINFO joy; + + res = joyGetPos(JOYSTICKID1, &joy); + + if (res == JOYERR_NOERROR) { + joyavailable = 1; + + if (max[0] < joy.wXpos) + max[0] = joy.wXpos; + if (min[0] > joy.wXpos) + min[0] = joy.wXpos; + center[0] = (max[0] + min[0]) / 2; + + if (max[1] < joy.wYpos) + max[1] = joy.wYpos; + if (min[1] > joy.wYpos) + min[1] = joy.wYpos; + center[1] = (max[1] + min[1]) / 2; + + if (joyactive) { + if (fabs(center[0] - (float) joy.wXpos) > 0.1 * (max[0] - min[0])) + alpha -= + 2.5 * (center[0] - (float) joy.wXpos) / (max[0] - min[0]); + if (fabs(center[1] - (float) joy.wYpos) > 0.1 * (max[1] - min[1])) + beta += 2.5 * (center[1] - (float) joy.wYpos) / (max[1] - min[1]); + + if (joy.wButtons & JOY_BUTTON1) + v += 0.005; + if (joy.wButtons & JOY_BUTTON2) + v -= 0.005; + } + } + else + joyavailable = 0; +#endif +} + +static void +updatemaps(void) +{ + updatecheckmap(checkmap_currentslot); + checkmap_currentslot = (checkmap_currentslot + 1) % TEX_CHECK_NUMSLOT; + + updatereflectmap(reflectmap_currentslot); + reflectmap_currentslot = + (reflectmap_currentslot + 1) % TEX_REFLECT_NUMSLOT; +} + +static void +draw(void) +{ + static int count = 0; + static char frbuf[80]; + float fr; + + dojoy(); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable(GL_TEXTURE_2D); + glEnable(GL_DEPTH_TEST); + if (fog) + glEnable(GL_FOG); + else + glDisable(GL_FOG); + + glPushMatrix(); + calcposobs(); + + gluLookAt(obs[0], obs[1], obs[2], + obs[0] + dir[0], obs[1] + dir[1], obs[2] + dir[2], + 0.0, 0.0, 1.0); + + drawbase(); + drawobj(); + + glColor3f(1.0, 1.0, 1.0); + glDisable(GL_TEXTURE_2D); + + glPushMatrix(); + glTranslatef(lightpos[0], lightpos[1], lightpos[2]); + glCallList(lightdlist); + glPopMatrix(); + + glPopMatrix(); + + if ((count % FRAME) == 0) { + fr = gettime(); + sprintf(frbuf, "Frame rate: %f", FRAME / fr); + } + + glDisable(GL_DEPTH_TEST); + glDisable(GL_FOG); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0); + glMatrixMode(GL_MODELVIEW); + + glColor3f(0.0f, 0.3f, 1.0f); + + if (showcheckmap) { + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, checkid); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + glBegin(GL_QUADS); + glTexCoord2f(1.0f, 0.0f); + glVertex2i(10, 30); + glTexCoord2f(1.0f, 1.0f); + glVertex2i(10 + 90, 30); + glTexCoord2f(0.0f, 1.0f); + glVertex2i(10 + 90, 30 + 90); + glTexCoord2f(0.0f, 0.0f); + glVertex2i(10, 30 + 90); + glEnd(); + + glDisable(GL_TEXTURE_2D); + glBegin(GL_LINE_LOOP); + glVertex2i(10, 30); + glVertex2i(10 + 90, 30); + glVertex2i(10 + 90, 30 + 90); + glVertex2i(10, 30 + 90); + glEnd(); + glRasterPos2i(105, 65); + printstring(GLUT_BITMAP_HELVETICA_18, "Plane Texture Map"); + } + + if (showreflectmap) { + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, reflectid); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + glBegin(GL_QUADS); + glTexCoord2f(1.0f, 0.0f); + glVertex2i(540, 30); + glTexCoord2f(1.0f, 1.0f); + glVertex2i(540 + 90, 30); + glTexCoord2f(0.0f, 1.0f); + glVertex2i(540 + 90, 30 + 90); + glTexCoord2f(0.0f, 0.0f); + glVertex2i(540, 30 + 90); + glEnd(); + + glDisable(GL_TEXTURE_2D); + glBegin(GL_LINE_LOOP); + glVertex2i(540, 30); + glVertex2i(540 + 90, 30); + glVertex2i(540 + 90, 30 + 90); + glVertex2i(540, 30 + 90); + glEnd(); + glRasterPos2i(360, 65); + printstring(GLUT_BITMAP_HELVETICA_18, "Sphere Texture Map"); + } + + glDisable(GL_TEXTURE_2D); + + glRasterPos2i(10, 10); + printstring(GLUT_BITMAP_HELVETICA_18, frbuf); + glRasterPos2i(360, 470); + printstring(GLUT_BITMAP_HELVETICA_10, + "Ray V1.0 Written by David Bucciarelli (tech.hmw@plus.it)"); + + if (help) + printhelp(); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + updatemaps(); + + glutSwapBuffers(); + + count++; +} + +static void +inittextures(void) +{ + int y; + + glGenTextures(1, &checkid); + glBindTexture(GL_TEXTURE_2D, checkid); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D(GL_TEXTURE_2D, 0, 3, TEX_CHECK_WIDTH, TEX_CHECK_HEIGHT, + 0, GL_RGB, GL_UNSIGNED_BYTE, checkmap); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + for (y = 0; y < TEX_CHECK_NUMSLOT; y++) + updatecheckmap(y); + + + + glGenTextures(1, &reflectid); + glBindTexture(GL_TEXTURE_2D, reflectid); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D(GL_TEXTURE_2D, 0, 3, TEX_REFLECT_WIDTH, TEX_REFLECT_HEIGHT, + 0, GL_RGB, GL_UNSIGNED_BYTE, reflectmap); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + for (y = 0; y < TEX_REFLECT_NUMSLOT; y++) + updatereflectmap(y); + + +} + +static void +initspherepos(void) +{ + float alpha, beta, sa, ca, sb, cb; + int x, y; + + for (y = 0; y < TEX_REFLECT_HEIGHT; y++) { + beta = M_PI - y * (M_PI / TEX_REFLECT_HEIGHT); + + for (x = 0; x < TEX_REFLECT_WIDTH; x++) { + alpha = -x * (2.0f * M_PI / TEX_REFLECT_WIDTH); + + sa = sin(alpha); + ca = cos(alpha); + + sb = sin(beta); + cb = cos(beta); + + sphere_pos[y][x][0] = SPHERE_RADIUS * sa * sb; + sphere_pos[y][x][1] = SPHERE_RADIUS * ca * sb; + sphere_pos[y][x][2] = SPHERE_RADIUS * cb; + } + } +} + +static void +initdlists(void) +{ + GLUquadricObj *obj; + + obj = gluNewQuadric(); + + lightdlist = glGenLists(1); + glNewList(lightdlist, GL_COMPILE); + gluQuadricDrawStyle(obj, GLU_FILL); + gluQuadricNormals(obj, GLU_NONE); + gluQuadricTexture(obj, GL_TRUE); + gluSphere(obj, 0.25f, 6, 6); + glEndList(); + + objdlist = glGenLists(1); + glNewList(objdlist, GL_COMPILE); + gluQuadricDrawStyle(obj, GLU_FILL); + gluQuadricNormals(obj, GLU_NONE); + gluQuadricTexture(obj, GL_TRUE); + gluSphere(obj, SPHERE_RADIUS, 16, 16); + glEndList(); +} + +int +main(int ac, char **av) +{ + fprintf(stderr, + "Ray V1.0\nWritten by David Bucciarelli (tech.hmw@plus.it)\n"); + + /* + if(!SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS)) { + fprintf(stderr,"Error setting the process class.\n"); + return 0; + } + + if(!SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL)) { + fprintf(stderr,"Error setting the process priority.\n"); + return 0; + } + */ + + glutInitWindowPosition(0, 0); + glutInitWindowSize(WIDTH, HEIGHT); + glutInit(&ac, av); + + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); + + if (!(win = glutCreateWindow("Ray"))) { + fprintf(stderr, "Error, couldn't open window\n"); + return -1; + } + + reshape(WIDTH, HEIGHT); + + glShadeModel(GL_FLAT); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glEnable(GL_CULL_FACE); + glEnable(GL_TEXTURE_2D); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_FOG); + glFogi(GL_FOG_MODE, GL_EXP2); + glFogfv(GL_FOG_COLOR, fogcolor); + + glFogf(GL_FOG_DENSITY, 0.01); +#ifdef FX + glHint(GL_FOG_HINT, GL_NICEST); +#endif + + calcposobs(); + + initspherepos(); + + inittextures(); + initdlists(); + + glClearColor(fogcolor[0], fogcolor[1], fogcolor[2], fogcolor[3]); + + glutReshapeFunc(reshape); + glutDisplayFunc(draw); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutIdleFunc(draw); + + glutMainLoop(); + + return 0; +} diff --git a/progs/demos/shadow.c b/progs/demos/shadow.c new file mode 100644 index 0000000000..a1b3fdeca7 --- /dev/null +++ b/progs/demos/shadow.c @@ -0,0 +1,117 @@ +/** +(c) Copyright 1993, Silicon Graphics, Inc. + +ALL RIGHTS RESERVED + +Permission to use, copy, modify, and distribute this software +for any purpose and without fee is hereby granted, provided +that the above copyright notice appear in all copies and that +both the copyright notice and this permission notice appear in +supporting documentation, and that the name of Silicon +Graphics, Inc. not be used in advertising or publicity +pertaining to distribution of the software without specific, +written prior permission. + +THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU +"AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR +OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF +MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO +EVENT SHALL SILICON GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE +ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR +CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER, +INCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE, +SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR +NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF THE POSSIBILITY +OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE OR +PERFORMANCE OF THIS SOFTWARE. + +US Government Users Restricted Rights + +Use, duplication, or disclosure by the Government is subject to +restrictions set forth in FAR 52.227.19(c)(2) or subparagraph +(c)(1)(ii) of the Rights in Technical Data and Computer +Software clause at DFARS 252.227-7013 and/or in similar or +successor clauses in the FAR or the DOD or NASA FAR +Supplement. Unpublished-- rights reserved under the copyright +laws of the United States. Contractor/manufacturer is Silicon +Graphics, Inc., 2011 N. Shoreline Blvd., Mountain View, CA +94039-7311. + +OpenGL(TM) is a trademark of Silicon Graphics, Inc. +*/ + +/* Taken from the projshadow.c - by Tom McReynolds, SGI */ + +/* Modified by David Bucciarelli */ + +/* Rendering shadows using projective shadows. */ + +#include <GL/glut.h> + +enum { + X, Y, Z, W +}; +enum { + A, B, C, D +}; + +/* create a matrix that will project the desired shadow */ +void +shadowmatrix(GLfloat shadowMat[4][4], + GLfloat groundplane[4], + GLfloat lightpos[4]) +{ + GLfloat dot; + + /* find dot product between light position vector and ground plane normal */ + dot = groundplane[X] * lightpos[X] + + groundplane[Y] * lightpos[Y] + + groundplane[Z] * lightpos[Z] + + groundplane[W] * lightpos[W]; + + shadowMat[0][0] = dot - lightpos[X] * groundplane[X]; + shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y]; + shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z]; + shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W]; + + shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X]; + shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y]; + shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z]; + shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W]; + + shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X]; + shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y]; + shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z]; + shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W]; + + shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X]; + shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y]; + shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z]; + shadowMat[3][3] = dot - lightpos[W] * groundplane[W]; + +} + +/* find the plane equation given 3 points */ +void +findplane(GLfloat plane[4], + GLfloat v0[3], GLfloat v1[3], GLfloat v2[3]) +{ + GLfloat vec0[3], vec1[3]; + + /* need 2 vectors to find cross product */ + vec0[X] = v1[X] - v0[X]; + vec0[Y] = v1[Y] - v0[Y]; + vec0[Z] = v1[Z] - v0[Z]; + + vec1[X] = v2[X] - v0[X]; + vec1[Y] = v2[Y] - v0[Y]; + vec1[Z] = v2[Z] - v0[Z]; + + /* find cross product to get A, B, and C of plane equation */ + plane[A] = vec0[Y] * vec1[Z] - vec0[Z] * vec1[Y]; + plane[B] = -(vec0[X] * vec1[Z] - vec0[Z] * vec1[X]); + plane[C] = vec0[X] * vec1[Y] - vec0[Y] * vec1[X]; + + plane[D] = -(plane[A] * v0[X] + plane[B] * v0[Y] + plane[C] * v0[Z]); +} diff --git a/progs/demos/teapot.c b/progs/demos/teapot.c new file mode 100644 index 0000000000..addee03a3d --- /dev/null +++ b/progs/demos/teapot.c @@ -0,0 +1,575 @@ +/* + * This program is under the GNU GPL. + * Use at your own risk. + * + * written by David Bucciarelli (tech.hmw@plus.it) + * Humanware s.r.l. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <time.h> + +#ifdef WIN32 +#include <windows.h> +#endif + +#include <GL/glut.h> +#include "../util/readtex.c" +#include "shadow.c" + +#ifdef XMESA +#include "GL/xmesa.h" +static int fullscreen=1; +#endif + +static int WIDTH=640; +static int HEIGHT=480; + +#define FRAME 50 + +#define BASESIZE 10.0 + +#define BASERES 12 +#define TEAPOTRES 3 + +#ifndef M_PI +#define M_PI 3.1415926535 +#endif + +extern void shadowmatrix(GLfloat [4][4], GLfloat [4], GLfloat [4]); +extern void findplane(GLfloat [4], GLfloat [3], GLfloat [3], GLfloat [3]); + + +static int win=0; + +static float obs[3]={5.0,0.0,1.0}; +static float dir[3]; +static float v=0.0; +static float alpha=-90.0; +static float beta=90.0; + +static GLfloat baseshadow[4][4]; +static GLfloat lightpos[4]={2.3,0.0,3.0,1.0}; +static GLfloat lightdir[3]={-2.3,0.0,-3.0}; +static GLfloat lightalpha=0.0; + +static int fog=1; +static int bfcull=1; +static int usetex=1; +static int help=1; +static int joyavailable=0; +static int joyactive=0; + +static GLuint t1id,t2id; +static GLuint teapotdlist,basedlist,lightdlist; + +static float gettime(void) +{ + static clock_t told=0; + clock_t tnew,ris; + + tnew=clock(); + + ris=tnew-told; + + told=tnew; + + return(ris/(float)CLOCKS_PER_SEC); +} + +static void calcposobs(void) +{ + dir[0]=sin(alpha*M_PI/180.0); + dir[1]=cos(alpha*M_PI/180.0)*sin(beta*M_PI/180.0); + dir[2]=cos(beta*M_PI/180.0); + + obs[0]+=v*dir[0]; + obs[1]+=v*dir[1]; + obs[2]+=v*dir[2]; +} + +static void special(int k, int x, int y) +{ + switch(k) { + case GLUT_KEY_LEFT: + alpha-=2.0; + break; + case GLUT_KEY_RIGHT: + alpha+=2.0; + break; + case GLUT_KEY_DOWN: + beta-=2.0; + break; + case GLUT_KEY_UP: + beta+=2.0; + break; + } +} + +static void key(unsigned char k, int x, int y) +{ + switch(k) { + case 27: + exit(0); + break; + + case 'a': + v+=0.005; + break; + case 'z': + v-=0.005; + break; + + case 'j': + joyactive=(!joyactive); + break; + case 'h': + help=(!help); + break; + case 'f': + fog=(!fog); + break; + case 't': + usetex=(!usetex); + break; + case 'b': + if(bfcull) { + glDisable(GL_CULL_FACE); + bfcull=0; + } else { + glEnable(GL_CULL_FACE); + bfcull=1; + } + break; +#ifdef XMESA + case ' ': + XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW); + fullscreen=(!fullscreen); + break; +#endif + } +} + +static void reshape(int w, int h) +{ + WIDTH=w; + HEIGHT=h; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45.0,w/(float)h,0.2,40.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glViewport(0,0,w,h); +} + +static void printstring(void *font, char *string) +{ + int len,i; + + len=(int)strlen(string); + for(i=0;i<len;i++) + glutBitmapCharacter(font,string[i]); +} + +static void printhelp(void) +{ + glEnable(GL_BLEND); + glColor4f(0.5,0.5,0.5,0.5); + glRecti(40,40,600,440); + glDisable(GL_BLEND); + + glColor3f(1.0,0.0,0.0); + glRasterPos2i(300,420); + printstring(GLUT_BITMAP_TIMES_ROMAN_24,"Help"); + + glRasterPos2i(60,390); + printstring(GLUT_BITMAP_TIMES_ROMAN_24,"h - Togle Help"); + glRasterPos2i(60,360); + printstring(GLUT_BITMAP_TIMES_ROMAN_24,"t - Togle Textures"); + glRasterPos2i(60,330); + printstring(GLUT_BITMAP_TIMES_ROMAN_24,"f - Togle Fog"); + glRasterPos2i(60,300); + printstring(GLUT_BITMAP_TIMES_ROMAN_24,"b - Togle Back face culling"); + glRasterPos2i(60,270); + printstring(GLUT_BITMAP_TIMES_ROMAN_24,"Arrow Keys - Rotate"); + glRasterPos2i(60,240); + printstring(GLUT_BITMAP_TIMES_ROMAN_24,"a - Increase velocity"); + glRasterPos2i(60,210); + printstring(GLUT_BITMAP_TIMES_ROMAN_24,"z - Decrease velocity"); + + glRasterPos2i(60,180); + if(joyavailable) + printstring(GLUT_BITMAP_TIMES_ROMAN_24,"j - Togle jostick control (Joystick control available)"); + else + printstring(GLUT_BITMAP_TIMES_ROMAN_24,"(No Joystick control available)"); +} + +static void drawbase(void) +{ + int i,j; + float x,y,dx,dy; + + glBindTexture(GL_TEXTURE_2D,t1id); + + dx=BASESIZE/BASERES; + dy=-BASESIZE/BASERES; + for(y=BASESIZE/2.0,j=0;j<BASERES;y+=dy,j++) { + glBegin(GL_QUAD_STRIP); + glColor3f(1.0,1.0,1.0); + glNormal3f(0.0,0.0,1.0); + for(x=-BASESIZE/2.0,i=0;i<BASERES;x+=dx,i++) { + glTexCoord2f(x,y); + glVertex3f(x,y,0.0); + + glTexCoord2f(x,y+dy); + glVertex3f(x,y+dy,0.0); + } + glEnd(); + } +} + +static void drawteapot(void) +{ + static float xrot=0.0; + static float zrot=0.0; + + glPushMatrix(); + glRotatef(lightalpha,0.0,0.0,1.0); + glMultMatrixf((GLfloat *)baseshadow); + glRotatef(-lightalpha,0.0,0.0,1.0); + + glTranslatef(0.0,0.0,1.0); + glRotatef(xrot,1.0,0.0,0.0); + glRotatef(zrot,0.0,0.0,1.0); + + glDisable(GL_TEXTURE_2D); + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + + glColor3f(0.0,0.0,0.0); + glCallList(teapotdlist); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + if(usetex) + glEnable(GL_TEXTURE_2D); + + glPopMatrix(); + + glPushMatrix(); + glTranslatef(0.0,0.0,1.0); + glRotatef(xrot,1.0,0.0,0.0); + glRotatef(zrot,0.0,0.0,1.0); + + glCallList(teapotdlist); + glPopMatrix(); + + xrot+=2.0; + zrot+=1.0; +} + +static void drawlight1(void) +{ + glPushMatrix(); + glRotatef(lightalpha,0.0,0.0,1.0); + glLightfv(GL_LIGHT0,GL_POSITION,lightpos); + glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,lightdir); + + glPopMatrix(); +} + +static void drawlight2(void) +{ + glPushMatrix(); + glRotatef(lightalpha,0.0,0.0,1.0); + glTranslatef(lightpos[0],lightpos[1],lightpos[2]); + + glDisable(GL_TEXTURE_2D); + glCallList(lightdlist); + if(usetex) + glEnable(GL_TEXTURE_2D); + + glPopMatrix(); + + lightalpha+=1.0; +} + +static void dojoy(void) +{ +#ifdef WIN32 + static UINT max[2]={0,0}; + static UINT min[2]={0xffffffff,0xffffffff},center[2]; + MMRESULT res; + JOYINFO joy; + + res=joyGetPos(JOYSTICKID1,&joy); + + if(res==JOYERR_NOERROR) { + joyavailable=1; + + if(max[0]<joy.wXpos) + max[0]=joy.wXpos; + if(min[0]>joy.wXpos) + min[0]=joy.wXpos; + center[0]=(max[0]+min[0])/2; + + if(max[1]<joy.wYpos) + max[1]=joy.wYpos; + if(min[1]>joy.wYpos) + min[1]=joy.wYpos; + center[1]=(max[1]+min[1])/2; + + if(joyactive) { + if(fabs(center[0]-(float)joy.wXpos)>0.1*(max[0]-min[0])) + alpha-=2.5*(center[0]-(float)joy.wXpos)/(max[0]-min[0]); + if(fabs(center[1]-(float)joy.wYpos)>0.1*(max[1]-min[1])) + beta+=2.5*(center[1]-(float)joy.wYpos)/(max[1]-min[1]); + + if(joy.wButtons & JOY_BUTTON1) + v+=0.005; + if(joy.wButtons & JOY_BUTTON2) + v-=0.005; + } + } else + joyavailable=0; +#endif +} + +static void draw(void) +{ + static int count=0; + static char frbuf[80]; + float fr; + + dojoy(); + + glEnable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + if(usetex) + glEnable(GL_TEXTURE_2D); + else + glDisable(GL_TEXTURE_2D); + + if(fog) + glEnable(GL_FOG); + else + glDisable(GL_FOG); + + glEnable(GL_LIGHTING); + + glShadeModel(GL_SMOOTH); + + glPushMatrix(); + calcposobs(); + + gluLookAt(obs[0],obs[1],obs[2], + obs[0]+dir[0],obs[1]+dir[1],obs[2]+dir[2], + 0.0,0.0,1.0); + + drawlight1(); + glCallList(basedlist); + drawteapot(); + drawlight2(); + glPopMatrix(); + + if((count % FRAME)==0) { + fr=gettime(); + sprintf(frbuf,"Frame rate: %f",FRAME/fr); + } + + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + glDisable(GL_DEPTH_TEST); + glDisable(GL_FOG); + glShadeModel(GL_FLAT); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-0.5,639.5,-0.5,479.5,-1.0,1.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glColor3f(1.0,0.0,0.0); + glRasterPos2i(10,10); + printstring(GLUT_BITMAP_HELVETICA_18,frbuf); + glRasterPos2i(350,470); + printstring(GLUT_BITMAP_HELVETICA_10,"Teapot V1.2 Written by David Bucciarelli (tech.hmw@plus.it)"); + + if(help) + printhelp(); + + reshape(WIDTH,HEIGHT); + + glutSwapBuffers(); + + count++; +} + +static void inittextures(void) +{ + GLenum gluerr; + + glGenTextures(1,&t1id); + glBindTexture(GL_TEXTURE_2D,t1id); + + glPixelStorei(GL_UNPACK_ALIGNMENT,4); + if (!LoadRGBMipmaps("../images/tile.rgb", GL_RGB)) { + fprintf(stderr,"Error reading a texture.\n"); + exit(-1); + } + + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); + + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); + + glGenTextures(1,&t2id); + glBindTexture(GL_TEXTURE_2D,t2id); + + if (!LoadRGBMipmaps("../images/bw.rgb", GL_RGB)) { + fprintf(stderr,"Error reading a texture.\n"); + exit(-1); + } + + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); + + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); +} + +static void initlight(void) +{ + float lamb[4]={0.2,0.2,0.2,1.0}; + float lspec[4]={1.0,1.0,1.0,1.0}; + + glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,70.0); + glLightf(GL_LIGHT0,GL_SPOT_EXPONENT,20.0); + glLightfv(GL_LIGHT0,GL_AMBIENT,lamb); + glLightfv(GL_LIGHT0,GL_SPECULAR,lspec); + + glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,20.0); + glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,lspec); + + glEnable(GL_LIGHT0); +} + +static void initdlists(void) +{ + GLUquadricObj *lcone,*lbase; + GLfloat plane[4]; + GLfloat v0[3]={0.0,0.0,0.0}; + GLfloat v1[3]={1.0,0.0,0.0}; + GLfloat v2[3]={0.0,1.0,0.0}; + + findplane(plane,v0,v1,v2); + shadowmatrix(baseshadow,plane,lightpos); + + teapotdlist=glGenLists(1); + glNewList(teapotdlist,GL_COMPILE); + glRotatef(90.0,1.0,0.0,0.0); + glCullFace(GL_FRONT); + glBindTexture(GL_TEXTURE_2D,t2id); + glutSolidTeapot(0.75); + glCullFace(GL_BACK); + glEndList(); + + basedlist=glGenLists(1); + glNewList(basedlist,GL_COMPILE); + drawbase(); + glEndList(); + + lightdlist=glGenLists(1); + glNewList(lightdlist,GL_COMPILE); + glDisable(GL_LIGHTING); + + lcone=gluNewQuadric(); + lbase=gluNewQuadric(); + glRotatef(45.0,0.0,1.0,0.0); + + glColor3f(1.0,1.0,1.0); + glCullFace(GL_FRONT); + gluDisk(lbase,0.0,0.2,12.0,1.0); + glCullFace(GL_BACK); + + glColor3f(0.5,0.0,0.0); + gluCylinder(lcone,0.2,0.0,0.5,12,1); + + gluDeleteQuadric(lcone); + gluDeleteQuadric(lbase); + + glEnable(GL_LIGHTING); + glEndList(); +} + +int main(int ac, char **av) +{ + float fogcolor[4]={0.025,0.025,0.025,1.0}; + + fprintf(stderr,"Teapot V1.2\nWritten by David Bucciarelli (tech.hmw@plus.it)\n"); + + /* + if(!SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS)) { + fprintf(stderr,"Error setting the process class.\n"); + return 0; + } + + if(!SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL)) { + fprintf(stderr,"Error setting the process priority.\n"); + return 0; + } + */ + + glutInitWindowPosition(0,0); + glutInitWindowSize(WIDTH,HEIGHT); + glutInit(&ac,av); + + glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH|GLUT_DOUBLE); + + if(!(win=glutCreateWindow("Teapot"))) { + fprintf(stderr,"Error, couldn't open window\n"); + return -1; + } + + reshape(WIDTH,HEIGHT); + + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glEnable(GL_TEXTURE_2D); + + glEnable(GL_FOG); + glFogi(GL_FOG_MODE,GL_EXP2); + glFogfv(GL_FOG_COLOR,fogcolor); + + glFogf(GL_FOG_DENSITY,0.04); + glHint(GL_FOG_HINT,GL_NICEST); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + calcposobs(); + + inittextures(); + initlight(); + + initdlists(); + + glClearColor(fogcolor[0],fogcolor[1],fogcolor[2],fogcolor[3]); + + glutReshapeFunc(reshape); + glutDisplayFunc(draw); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutIdleFunc(draw); + + glutMainLoop(); + + return 0; +} diff --git a/progs/demos/terrain.c b/progs/demos/terrain.c new file mode 100644 index 0000000000..b708ff826d --- /dev/null +++ b/progs/demos/terrain.c @@ -0,0 +1,653 @@ +/* + * This program is under the GNU GPL. + * Use at your own risk. + * + * written by David Bucciarelli (tech.hmw@plus.it) + * Humanware s.r.l. + * + * based on a Mikael SkiZoWalker's (MoDEL) / France (Skizo@Hol.Fr) demo + */ + +#include <stdio.h> +#include <math.h> +#include <stdlib.h> +#include <time.h> + +#ifdef WIN32 +#include <windows.h> +#endif + +#include <GL/glut.h> + +#ifdef XMESA +#include "GL/xmesa.h" +static int fullscreen = 1; +#endif + +#ifndef M_PI +#define M_PI 3.14159265 +#endif + +#define heightMnt 450 +#define lenghtXmnt 62 +#define lenghtYmnt 62 + +#define stepXmnt 96.0 +#define stepYmnt 96.0 + +#define WIDTH 640 +#define HEIGHT 480 + +#define TSCALE 4 + +#define FRAME 50 + +#define FOV 85 + +static GLfloat terrain[256 * 256]; +static GLfloat terraincolor[256 * 256][3]; + +static int win = 0; + +static int fog = 1; +static int bfcull = 1; +static int usetex = 1; +static int poutline = 0; +static int help = 1; +static int joyavailable = 0; +static int joyactive = 0; +static float ModZMnt; +static long GlobalMnt = 0; + +static int scrwidth = WIDTH; +static int scrheight = HEIGHT; + +#define OBSSTARTX 992.0 +#define OBSSTARTY 103.0 + +static float obs[3] = { OBSSTARTX, heightMnt * 1.3, OBSSTARTY }; +static float dir[3], v1[2], v2[2]; +static float v = 15.0; +static float alpha = 75.0; +static float beta = 90.0; + +static float +gettime(void) +{ + static clock_t told = 0; + clock_t tnew, ris; + + tnew = clock(); + + ris = tnew - told; + + told = tnew; + + return (ris / (float) CLOCKS_PER_SEC); +} + +static void +calcposobs(void) +{ + float alpha1, alpha2; + + dir[0] = sin(alpha * M_PI / 180.0); + dir[2] = cos(alpha * M_PI / 180.0) * sin(beta * M_PI / 180.0); + dir[1] = cos(beta * M_PI / 180.0); + + alpha1 = alpha + FOV / 2.0; + v1[0] = sin(alpha1 * M_PI / 180.0); + v1[1] = cos(alpha1 * M_PI / 180.0); + + alpha2 = alpha - FOV / 2.0; + v2[0] = sin(alpha2 * M_PI / 180.0); + v2[1] = cos(alpha2 * M_PI / 180.0); + + obs[0] += v * dir[0]; + obs[1] += v * dir[1]; + obs[2] += v * dir[2]; + + if (obs[1] < 0.0) + obs[1] = 0.0; +} + +static void +reshape(int width, int height) +{ + scrwidth = width; + scrheight = height; + glViewport(0, 0, (GLint) width, (GLint) height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(50.0, ((GLfloat) width / (GLfloat) height), + lenghtXmnt * stepYmnt * 0.01, lenghtXmnt * stepYmnt * 0.7); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +int +clipstrip(float y, float *start, float *end) +{ + float x1, x2, t1, t2, tmp; + + if (v1[1] == 0.0) { + t1 = 0.0; + x1 = -HUGE_VAL; + } + else { + t1 = y / v1[1]; + x1 = t1 * v1[0]; + } + + if (v2[1] == 0.0) { + t2 = 0.0; + x2 = HUGE_VAL; + } + else { + t2 = y / v2[1]; + x2 = t2 * v2[0]; + } + + if (((x1 < -(lenghtXmnt * stepXmnt) / 2) && (t2 <= 0.0)) || + ((t1 <= 0.0) && (x2 > (lenghtXmnt * stepXmnt) / 2)) || + ((t1 < 0.0) && (t2 < 0.0))) + return 0; + + if ((t1 == 0.0) && (t2 == 0.0)) { + if ((v1[0] < 0.0) && (v1[1] > 0.0) && (v2[0] < 0.0) && (v2[1] < 0.0)) { + *start = -(lenghtXmnt * stepXmnt) / 2; + *end = stepXmnt; + return 1; + } + else { + if ((v1[0] > 0.0) && (v1[1] < 0.0) && (v2[0] > 0.0) && (v2[1] > 0.0)) { + *start = -stepXmnt; + *end = (lenghtXmnt * stepXmnt) / 2; + return 1; + } + else + return 0; + } + } + else { + if (t2 < 0.0) { + if (x1 < 0.0) + x2 = -(lenghtXmnt * stepXmnt) / 2; + else + x2 = (lenghtXmnt * stepXmnt) / 2; + } + + if (t1 < 0.0) { + if (x2 < 0.0) + x1 = -(lenghtXmnt * stepXmnt) / 2; + else + x1 = (lenghtXmnt * stepXmnt) / 2; + } + } + + if (x1 > x2) { + tmp = x1; + x1 = x2; + x2 = tmp; + } + + x1 -= stepXmnt; + if (x1 < -(lenghtXmnt * stepXmnt) / 2) + x1 = -(lenghtXmnt * stepXmnt) / 2; + + x2 += stepXmnt; + if (x2 > (lenghtXmnt * stepXmnt) / 2) + x2 = (lenghtXmnt * stepXmnt) / 2; + + *start = ((int) (x1 / stepXmnt)) * stepXmnt; + *end = ((int) (x2 / stepXmnt)) * stepXmnt; + + return 1; +} + +static void +printstring(void *font, char *string) +{ + int len, i; + + len = (int) strlen(string); + for (i = 0; i < len; i++) + glutBitmapCharacter(font, string[i]); +} + +static void +printhelp(void) +{ + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(0.0, 0.0, 0.0, 0.5); + glRecti(40, 40, 600, 440); + glDisable(GL_BLEND); + + glColor3f(1.0, 0.0, 0.0); + glRasterPos2i(300, 420); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Help"); + + glRasterPos2i(60, 390); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "h - Togle Help"); + glRasterPos2i(60, 360); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "t - Togle Textures"); + glRasterPos2i(60, 330); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "f - Togle Fog"); + glRasterPos2i(60, 300); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "p - Wire frame"); + glRasterPos2i(60, 270); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "b - Togle Back face culling"); + glRasterPos2i(60, 240); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Arrow Keys - Rotate"); + glRasterPos2i(60, 210); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "a - Increase velocity"); + glRasterPos2i(60, 180); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "z - Decrease velocity"); + + glRasterPos2i(60, 150); + if (joyavailable) + printstring(GLUT_BITMAP_TIMES_ROMAN_24, + "j - Togle jostick control (Joystick control available)"); + else + printstring(GLUT_BITMAP_TIMES_ROMAN_24, + "(No Joystick control available)"); +} + +void +drawterrain(void) +{ + int h, i, idx, ox, oy; + float j, k, start, end; + + ox = (int) (obs[0] / stepXmnt); + oy = (int) (obs[2] / stepYmnt); + GlobalMnt = ((ox * TSCALE) & 255) + ((oy * TSCALE) & 255) * 256; + + glPushMatrix(); + glTranslatef((float) ox * stepXmnt, 0, (float) oy * stepYmnt); + + for (h = 0, k = -(lenghtYmnt * stepYmnt) / 2; h < lenghtYmnt; + k += stepYmnt, h++) { + if (!clipstrip(k, &start, &end)) + continue; + + glBegin(GL_TRIANGLE_STRIP); /* I hope that the optimizer will be able to improve this code */ + for (i = (int) (lenghtXmnt / 2 + start / stepXmnt), j = start; j <= end; + j += stepXmnt, i++) { + idx = (i * TSCALE + h * 256 * TSCALE + GlobalMnt) & 65535; + glColor3fv(terraincolor[idx]); + glTexCoord2f((ox + i) / 8.0, (oy + h) / 8.0); + glVertex3f(j, terrain[idx], k); + + idx = + (i * TSCALE + h * 256 * TSCALE + 256 * TSCALE + + GlobalMnt) & 65535; + glColor3fv(terraincolor[idx]); + glTexCoord2f((ox + i) / 8.0, (oy + h + 1) / 8.0); + glVertex3f(j, terrain[idx], k + stepYmnt); + } + glEnd(); + } + + glDisable(GL_CULL_FACE); + glDisable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBegin(GL_QUADS); + glColor4f(0.1, 0.7, 1.0, 0.4); + glVertex3f(-(lenghtXmnt * stepXmnt) / 2.0, heightMnt * 0.6, + -(lenghtYmnt * stepYmnt) / 2.0); + glVertex3f(-(lenghtXmnt * stepXmnt) / 2.0, heightMnt * 0.6, + (lenghtYmnt * stepYmnt) / 2.0); + glVertex3f((lenghtXmnt * stepXmnt) / 2.0, heightMnt * 0.6, + (lenghtYmnt * stepYmnt) / 2.0); + glVertex3f((lenghtXmnt * stepXmnt) / 2.0, heightMnt * 0.6, + -(lenghtYmnt * stepYmnt) / 2.0); + glEnd(); + glDisable(GL_BLEND); + if (bfcull) + glEnable(GL_CULL_FACE); + glEnable(GL_TEXTURE_2D); + + glPopMatrix(); + +} + +static void +dojoy(void) +{ +#ifdef WIN32 + static UINT max[2] = { 0, 0 }; + static UINT min[2] = { 0xffffffff, 0xffffffff }, center[2]; + MMRESULT res; + JOYINFO joy; + + res = joyGetPos(JOYSTICKID1, &joy); + + if (res == JOYERR_NOERROR) { + joyavailable = 1; + + if (max[0] < joy.wXpos) + max[0] = joy.wXpos; + if (min[0] > joy.wXpos) + min[0] = joy.wXpos; + center[0] = (max[0] + min[0]) / 2; + + if (max[1] < joy.wYpos) + max[1] = joy.wYpos; + if (min[1] > joy.wYpos) + min[1] = joy.wYpos; + center[1] = (max[1] + min[1]) / 2; + + if (joyactive) { + if (fabs(center[0] - (float) joy.wXpos) > 0.1 * (max[0] - min[0])) + alpha += + 2.5 * (center[0] - (float) joy.wXpos) / (max[0] - min[0]); + if (fabs(center[1] - (float) joy.wYpos) > 0.1 * (max[1] - min[1])) + beta += 2.5 * (center[1] - (float) joy.wYpos) / (max[1] - min[1]); + + if (joy.wButtons & JOY_BUTTON1) + v += 0.5; + if (joy.wButtons & JOY_BUTTON2) + v -= 0.5; + } + } + else + joyavailable = 0; +#endif +} + +void +drawscene(void) +{ + static int count = 0; + static char frbuf[80]; + float fr; + + dojoy(); + + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + + if (usetex) + glEnable(GL_TEXTURE_2D); + else + glDisable(GL_TEXTURE_2D); + + if (fog) + glEnable(GL_FOG); + else + glDisable(GL_FOG); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + + calcposobs(); + gluLookAt(obs[0], obs[1], obs[2], + obs[0] + dir[0], obs[1] + dir[1], obs[2] + dir[2], + 0.0, 1.0, 0.0); + + drawterrain(); + glPopMatrix(); + + if ((count % FRAME) == 0) { + fr = gettime(); + sprintf(frbuf, "Frame rate: %.3f", FRAME / fr); + } + + glDisable(GL_TEXTURE_2D); + glDisable(GL_DEPTH_TEST); + glDisable(GL_FOG); + glShadeModel(GL_FLAT); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glColor3f(1.0, 0.0, 0.0); + glRasterPos2i(10, 10); + printstring(GLUT_BITMAP_HELVETICA_18, frbuf); + glRasterPos2i(350, 470); + printstring(GLUT_BITMAP_HELVETICA_10, + "Terrain V1.2 Written by David Bucciarelli (tech.hmw@plus.it)"); + glRasterPos2i(434, 457); + printstring(GLUT_BITMAP_HELVETICA_10, + "Based on a Mickael's demo (Skizo@Hol.Fr)"); + + if (help) + printhelp(); + + reshape(scrwidth, scrheight); + + glutSwapBuffers(); + + count++; +} + +static void +key(unsigned char k, int x, int y) +{ + switch (k) { + case 27: + exit(0); + break; + case 'a': + v += 0.5; + break; + case 'z': + v -= 0.5; + break; + case 'p': + if (poutline) { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + poutline = 0; + } + else { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + poutline = 1; + } + break; + case 'j': + joyactive = (!joyactive); + break; + case 'h': + help = (!help); + break; + case 'f': + fog = (!fog); + break; + case 't': + usetex = (!usetex); + break; + case 'b': + if (bfcull) { + glDisable(GL_CULL_FACE); + bfcull = 0; + } + else { + glEnable(GL_CULL_FACE); + bfcull = 1; + } + break; +#ifdef XMESA + case ' ': + XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW); + fullscreen = (!fullscreen); + break; +#endif + } +} + +static void +special(int k, int x, int y) +{ + switch (k) { + case GLUT_KEY_LEFT: + alpha += 2.0; + break; + case GLUT_KEY_RIGHT: + alpha -= 2.0; + break; + case GLUT_KEY_DOWN: + beta -= 2.0; + break; + case GLUT_KEY_UP: + beta += 2.0; + break; + } +} + +static void +calccolor(GLfloat height, GLfloat c[3]) +{ + GLfloat color[4][3] = { + {1.0, 1.0, 1.0}, + {0.0, 0.8, 0.0}, + {1.0, 1.0, 0.3}, + {0.0, 0.0, 0.8} + }; + GLfloat fact; + + height = height * (1.0 / 255.0); + + if (height >= 0.9) { + c[0] = color[0][0]; + c[1] = color[0][1]; + c[2] = color[0][2]; + return; + } + + if ((height < 0.9) && (height >= 0.7)) { + fact = (height - 0.7) * 5.0; + c[0] = fact * color[0][0] + (1.0 - fact) * color[1][0]; + c[1] = fact * color[0][1] + (1.0 - fact) * color[1][1]; + c[2] = fact * color[0][2] + (1.0 - fact) * color[1][2]; + return; + } + + if ((height < 0.7) && (height >= 0.6)) { + fact = (height - 0.6) * 10.0; + c[0] = fact * color[1][0] + (1.0 - fact) * color[2][0]; + c[1] = fact * color[1][1] + (1.0 - fact) * color[2][1]; + c[2] = fact * color[1][2] + (1.0 - fact) * color[2][2]; + return; + } + + if ((height < 0.6) && (height >= 0.5)) { + fact = (height - 0.5) * 10.0; + c[0] = fact * color[2][0] + (1.0 - fact) * color[3][0]; + c[1] = fact * color[2][1] + (1.0 - fact) * color[3][1]; + c[2] = fact * color[2][2] + (1.0 - fact) * color[3][2]; + return; + } + + c[0] = color[3][0]; + c[1] = color[3][1]; + c[2] = color[3][2]; +} + +static void +loadpic(void) +{ + GLubyte bufferter[256 * 256], terrainpic[256 * 256]; + FILE *FilePic; + int i, tmp; + GLenum gluerr; + + if ((FilePic = fopen("terrain.dat", "r")) == NULL) { + fprintf(stderr, "Error loading Mnt.bin\n"); + exit(-1); + } + fread(bufferter, 256 * 256, 1, FilePic); + fclose(FilePic); + + for (i = 0; i < (256 * 256); i++) { + terrain[i] = (bufferter[i] * (heightMnt / 255.0f)); + calccolor((GLfloat) bufferter[i], terraincolor[i]); + tmp = (((int) bufferter[i]) + 96); + terrainpic[i] = (tmp > 255) ? 255 : tmp; + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + if ((gluerr = gluBuild2DMipmaps(GL_TEXTURE_2D, 1, 256, 256, GL_LUMINANCE, + GL_UNSIGNED_BYTE, + (GLvoid *) (&terrainpic[0])))) { + fprintf(stderr, "GLULib%s\n", gluErrorString(gluerr)); + exit(-1); + } + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glEnable(GL_TEXTURE_2D); +} + +static void +init(void) +{ + float fogcolor[4] = { 0.6, 0.7, 0.7, 1.0 }; + + glClearColor(fogcolor[0], fogcolor[1], fogcolor[2], fogcolor[3]); + glClearDepth(1.0); + glDepthFunc(GL_LEQUAL); + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + + glDisable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_FOG); + glFogi(GL_FOG_MODE, GL_EXP2); + glFogfv(GL_FOG_COLOR, fogcolor); + glFogf(GL_FOG_DENSITY, 0.0007); +#ifdef FX + glHint(GL_FOG_HINT, GL_NICEST); +#endif + + reshape(scrwidth, scrheight); +} + + +int +main(int ac, char **av) +{ + glutInitWindowPosition(0, 0); + glutInitWindowSize(WIDTH, HEIGHT); + glutInit(&ac, av); + + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); + + if (!(win = glutCreateWindow("Terrain"))) { + fprintf(stderr, "Error, couldn't open window\n"); + return -1; + } + + ModZMnt = 0.0f; + loadpic(); + + init(); + +#ifndef FX + glDisable(GL_TEXTURE_2D); + usetex = 0; +#endif + + glutReshapeFunc(reshape); + glutDisplayFunc(drawscene); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutIdleFunc(drawscene); + + glutMainLoop(); + + return 0; +} diff --git a/progs/demos/tunnel.c b/progs/demos/tunnel.c new file mode 100644 index 0000000000..3cced8b2a9 --- /dev/null +++ b/progs/demos/tunnel.c @@ -0,0 +1,514 @@ +/* + * This program is under the GNU GPL. + * Use at your own risk. + * + * written by David Bucciarelli (tech.hmw@plus.it) + * Humanware s.r.l. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <time.h> + +#ifdef WIN32 +#include <windows.h> +#endif + +#include <GL/glut.h> +#include "../util/readtex.c" +#include "tunneldat.c" + +#ifdef XMESA +#include "GL/xmesa.h" +static int fullscreen = 1; +#endif + +static int WIDTH = 640; +static int HEIGHT = 480; + +#define FRAME 50 + +#define NUMBLOC 5 + +#ifndef M_PI +#define M_PI 3.1415926535 +#endif + +extern int striplength_skin_13[]; +extern float stripdata_skin_13[]; + +extern int striplength_skin_12[]; +extern float stripdata_skin_12[]; + +extern int striplength_skin_11[]; +extern float stripdata_skin_11[]; + +extern int striplength_skin_9[]; +extern float stripdata_skin_9[]; + + +static int win = 0; + +static float obs[3] = { 1000.0, 0.0, 2.0 }; +static float dir[3]; +static float v = 0.5; +static float alpha = 90.0; +static float beta = 90.0; + +static int fog = 0; +static int bfcull = 1; +static int usetex = 1; +static int cstrip = 0; +static int help = 1; +static int joyavailable = 0; +static int joyactive = 0; + +static GLuint t1id, t2id; + +static void +inittextures(void) +{ + GLenum gluerr; + + glGenTextures(1, &t1id); + glBindTexture(GL_TEXTURE_2D, t1id); + + if (!LoadRGBMipmaps("../images/tile.rgb", GL_RGB)) { + fprintf(stderr, "Error reading a texture.\n"); + exit(-1); + } + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glGenTextures(1, &t2id); + glBindTexture(GL_TEXTURE_2D, t2id); + + if (!LoadRGBMipmaps("../images/bw.rgb", GL_RGB)) { + fprintf(stderr, "Error reading a texture.\n"); + exit(-1); + } + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +} + +static void +drawobjs(int *l, float *f) +{ + int mend, j; + + if (cstrip) { + float r = 0.33, g = 0.33, b = 0.33; + + for (; (*l) != 0;) { + mend = *l++; + + r += 0.33; + if (r > 1.0) { + r = 0.33; + g += 0.33; + if (g > 1.0) { + g = 0.33; + b += 0.33; + if (b > 1.0) + b = 0.33; + } + } + + glColor3f(r, g, b); + glBegin(GL_TRIANGLE_STRIP); + for (j = 0; j < mend; j++) { + f += 4; + glTexCoord2fv(f); + f += 2; + glVertex3fv(f); + f += 3; + } + glEnd(); + } + } + else + for (; (*l) != 0;) { + mend = *l++; + + glBegin(GL_TRIANGLE_STRIP); + for (j = 0; j < mend; j++) { + glColor4fv(f); + f += 4; + glTexCoord2fv(f); + f += 2; + glVertex3fv(f); + f += 3; + } + glEnd(); + } +} + +static float +gettime(void) +{ + static clock_t told = 0; + clock_t tnew, ris; + + tnew = clock(); + + ris = tnew - told; + + told = tnew; + + return (ris / (float) CLOCKS_PER_SEC); +} + +static void +calcposobs(void) +{ + dir[0] = sin(alpha * M_PI / 180.0); + dir[1] = cos(alpha * M_PI / 180.0) * sin(beta * M_PI / 180.0); + dir[2] = cos(beta * M_PI / 180.0); + + obs[0] += v * dir[0]; + obs[1] += v * dir[1]; + obs[2] += v * dir[2]; +} + +static void +special(int k, int x, int y) +{ + switch (k) { + case GLUT_KEY_LEFT: + alpha -= 2.0; + break; + case GLUT_KEY_RIGHT: + alpha += 2.0; + break; + case GLUT_KEY_DOWN: + beta -= 2.0; + break; + case GLUT_KEY_UP: + beta += 2.0; + break; + } +} + +static void +key(unsigned char k, int x, int y) +{ + switch (k) { + case 27: + exit(0); + break; + + case 'a': + v += 0.01; + break; + case 'z': + v -= 0.01; + break; + +#ifdef XMESA + case ' ': + fullscreen = (!fullscreen); + XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW); + break; +#endif + + case 'j': + joyactive = (!joyactive); + break; + case 'h': + help = (!help); + break; + case 'f': + fog = (!fog); + break; + case 't': + usetex = (!usetex); + break; + case 'b': + if (bfcull) { + glDisable(GL_CULL_FACE); + bfcull = 0; + } + else { + glEnable(GL_CULL_FACE); + bfcull = 1; + } + break; + case 'm': + cstrip = (!cstrip); + break; + + case 'd': + fprintf(stderr, "Deleting textures...\n"); + glDeleteTextures(1, &t1id); + glDeleteTextures(1, &t2id); + fprintf(stderr, "Loading textures...\n"); + inittextures(); + fprintf(stderr, "Done.\n"); + break; + } +} + +static void +reshape(int w, int h) +{ + WIDTH = w; + HEIGHT = h; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(80.0, w / (float) h, 1.0, 50.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glViewport(0, 0, w, h); +} + +static void +printstring(void *font, char *string) +{ + int len, i; + + len = (int) strlen(string); + for (i = 0; i < len; i++) + glutBitmapCharacter(font, string[i]); +} + +static void +printhelp(void) +{ + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(0.0, 0.0, 0.0, 0.5); + glRecti(40, 40, 600, 440); + + glColor3f(1.0, 0.0, 0.0); + glRasterPos2i(300, 420); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Help"); + + glRasterPos2i(60, 390); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "h - Togle Help"); + glRasterPos2i(60, 360); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "t - Togle Textures"); + glRasterPos2i(60, 330); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "f - Togle Fog"); + glRasterPos2i(60, 300); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "m - Togle strips"); + glRasterPos2i(60, 270); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "b - Togle Back face culling"); + glRasterPos2i(60, 240); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Arrow Keys - Rotate"); + glRasterPos2i(60, 210); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "a - Increase velocity"); + glRasterPos2i(60, 180); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "z - Decrease velocity"); + + glRasterPos2i(60, 150); + if (joyavailable) + printstring(GLUT_BITMAP_TIMES_ROMAN_24, + "j - Togle jostick control (Joystick control available)"); + else + printstring(GLUT_BITMAP_TIMES_ROMAN_24, + "(No Joystick control available)"); +} + +static void +dojoy(void) +{ +#ifdef WIN32 + static UINT max[2] = { 0, 0 }; + static UINT min[2] = { 0xffffffff, 0xffffffff }, center[2]; + MMRESULT res; + JOYINFO joy; + + res = joyGetPos(JOYSTICKID1, &joy); + + if (res == JOYERR_NOERROR) { + joyavailable = 1; + + if (max[0] < joy.wXpos) + max[0] = joy.wXpos; + if (min[0] > joy.wXpos) + min[0] = joy.wXpos; + center[0] = (max[0] + min[0]) / 2; + + if (max[1] < joy.wYpos) + max[1] = joy.wYpos; + if (min[1] > joy.wYpos) + min[1] = joy.wYpos; + center[1] = (max[1] + min[1]) / 2; + + if (joyactive) { + if (fabs(center[0] - (float) joy.wXpos) > 0.1 * (max[0] - min[0])) + alpha -= + 2.0 * (center[0] - (float) joy.wXpos) / (max[0] - min[0]); + if (fabs(center[1] - (float) joy.wYpos) > 0.1 * (max[1] - min[1])) + beta += 2.0 * (center[1] - (float) joy.wYpos) / (max[1] - min[1]); + + if (joy.wButtons & JOY_BUTTON1) + v += 0.01; + if (joy.wButtons & JOY_BUTTON2) + v -= 0.01; + } + } + else + joyavailable = 0; +#endif +} + +static void +draw(void) +{ + static int count = 0; + static char frbuf[80]; + int i; + float fr, base, offset; + + dojoy(); + + glClear(GL_COLOR_BUFFER_BIT); + + if (usetex) + glEnable(GL_TEXTURE_2D); + else + glDisable(GL_TEXTURE_2D); + + if (fog) + glEnable(GL_FOG); + else + glDisable(GL_FOG); + + glShadeModel(GL_SMOOTH); + + glPushMatrix(); + calcposobs(); + gluLookAt(obs[0], obs[1], obs[2], + obs[0] + dir[0], obs[1] + dir[1], obs[2] + dir[2], + 0.0, 0.0, 1.0); + + if (dir[0] > 0) { + offset = 8.0; + base = obs[0] - fmod(obs[0], 8.0); + } + else { + offset = -8.0; + base = obs[0] + (8.0 - fmod(obs[0], 8.0)); + } + + glPushMatrix(); + glTranslatef(base - offset / 2.0, 0.0, 0.0); + for (i = 0; i < NUMBLOC; i++) { + glTranslatef(offset, 0.0, 0.0); + glBindTexture(GL_TEXTURE_2D, t1id); + drawobjs(striplength_skin_11, stripdata_skin_11); + glBindTexture(GL_TEXTURE_2D, t2id); + drawobjs(striplength_skin_12, stripdata_skin_12); + drawobjs(striplength_skin_9, stripdata_skin_9); + drawobjs(striplength_skin_13, stripdata_skin_13); + } + glPopMatrix(); + glPopMatrix(); + + if ((count % FRAME) == 0) { + fr = gettime(); + sprintf(frbuf, "Frame rate: %f", FRAME / fr); + } + + glDisable(GL_TEXTURE_2D); + glDisable(GL_FOG); + glShadeModel(GL_FLAT); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glColor3f(1.0, 0.0, 0.0); + glRasterPos2i(10, 10); + printstring(GLUT_BITMAP_HELVETICA_18, frbuf); + glRasterPos2i(350, 470); + printstring(GLUT_BITMAP_HELVETICA_10, + "Tunnel V1.5 Written by David Bucciarelli (tech.hmw@plus.it)"); + + if (help) + printhelp(); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + glutSwapBuffers(); + + count++; +} + +int +main(int ac, char **av) +{ + float fogcolor[4] = { 0.7, 0.7, 0.7, 1.0 }; + + fprintf(stderr, + "Tunnel V1.5\nWritten by David Bucciarelli (tech.hmw@plus.it)\n"); + + glutInitWindowPosition(0, 0); + glutInitWindowSize(WIDTH, HEIGHT); + glutInit(&ac, av); + + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + + if (!(win = glutCreateWindow("Tunnel"))) { + fprintf(stderr, "Error, couldn't open window\n"); + return -1; + } + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(80.0, WIDTH / (float) HEIGHT, 1.0, 50.0); + + glMatrixMode(GL_MODELVIEW); + + glShadeModel(GL_SMOOTH); + glDisable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glEnable(GL_TEXTURE_2D); + + glEnable(GL_FOG); + glFogi(GL_FOG_MODE, GL_EXP2); + glFogfv(GL_FOG_COLOR, fogcolor); + + glFogf(GL_FOG_DENSITY, 0.06); + glHint(GL_FOG_HINT, GL_NICEST); + + inittextures(); + + glClearColor(fogcolor[0], fogcolor[1], fogcolor[2], fogcolor[3]); + glClear(GL_COLOR_BUFFER_BIT); + + calcposobs(); + + glutReshapeFunc(reshape); + glutDisplayFunc(draw); + glutKeyboardFunc(key); + glutSpecialFunc(special); + glutIdleFunc(draw); + + glEnable(GL_BLEND); + /*glBlendFunc(GL_SRC_ALPHA_SATURATE,GL_ONE); */ + /*glEnable(GL_POLYGON_SMOOTH); */ + + glutMainLoop(); + + return 0; +} diff --git a/progs/demos/tunnel2.c b/progs/demos/tunnel2.c new file mode 100644 index 0000000000..b8cea412b0 --- /dev/null +++ b/progs/demos/tunnel2.c @@ -0,0 +1,618 @@ +/* + * This program is under the GNU GPL. + * Use at your own risk. + * + * You need TWO Voodoo Graphics boards in order to run + * this demo ! + * + * written by David Bucciarelli (tech.hmw@plus.it) + * Humanware s.r.l. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <time.h> + +#ifdef WIN32 +#include <windows.h> +#endif + +#include <GL/glut.h> +#include "../util/readtex.c" +#include "tunneldat.c" + +#ifdef FX +#endif + +#ifdef XMESA +#include "GL/xmesa.h" +static int fullscreen = 1; +#endif + +#ifdef FX +GLboolean fxMesaSelectCurrentBoard(int); +#endif + +static int WIDTHC0 = 640; +static int HEIGHTC0 = 480; + +static int WIDTHC1 = 640; +static int HEIGHTC1 = 480; + +#define FRAME 50 + +#define NUMBLOC 5 + +#ifndef M_PI +#define M_PI 3.1415926535 +#endif + +extern int striplength_skin_13[]; +extern float stripdata_skin_13[]; + +extern int striplength_skin_12[]; +extern float stripdata_skin_12[]; + +extern int striplength_skin_11[]; +extern float stripdata_skin_11[]; + +extern int striplength_skin_9[]; +extern float stripdata_skin_9[]; + + +static float obs[3] = { 1000.0, 0.0, 2.0 }; +static float dir[3]; +static float v = 0.5; +static float alpha = 90.0; +static float beta = 90.0; + +static int fog = 0; +static int bfcull = 1; +static int usetex = 1; +static int cstrip = 0; +static int help = 1; +static int joyavailable = 0; +static int joyactive = 0; + +static int channel[2]; + +static GLuint t1id, t2id; + +static void +inittextures(void) +{ + GLenum gluerr; + + glGenTextures(1, &t1id); + glBindTexture(GL_TEXTURE_2D, t1id); + + if (!LoadRGBMipmaps("../images/tile.rgb", GL_RGB)) { + fprintf(stderr, "Error reading a texture.\n"); + exit(-1); + } + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glGenTextures(1, &t2id); + glBindTexture(GL_TEXTURE_2D, t2id); + + if (!LoadRGBMipmaps("../images/bw.rgb", GL_RGB)) { + fprintf(stderr, "Error reading a texture.\n"); + exit(-1); + } + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR_MIPMAP_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +} + +static void +drawobjs(int *l, float *f) +{ + int mend, j; + + if (cstrip) { + float r = 0.33, g = 0.33, b = 0.33; + + for (; (*l) != 0;) { + mend = *l++; + + r += 0.33; + if (r > 1.0) { + r = 0.33; + g += 0.33; + if (g > 1.0) { + g = 0.33; + b += 0.33; + if (b > 1.0) + b = 0.33; + } + } + + glColor3f(r, g, b); + glBegin(GL_TRIANGLE_STRIP); + for (j = 0; j < mend; j++) { + f += 4; + glTexCoord2fv(f); + f += 2; + glVertex3fv(f); + f += 3; + } + glEnd(); + } + } + else + for (; (*l) != 0;) { + mend = *l++; + + glBegin(GL_TRIANGLE_STRIP); + for (j = 0; j < mend; j++) { + glColor4fv(f); + f += 4; + glTexCoord2fv(f); + f += 2; + glVertex3fv(f); + f += 3; + } + glEnd(); + } +} + +static float +gettime(void) +{ + static clock_t told = 0; + clock_t tnew, ris; + + tnew = clock(); + + ris = tnew - told; + + told = tnew; + + return (ris / (float) CLOCKS_PER_SEC); +} + +static void +calcposobs(void) +{ + dir[0] = sin(alpha * M_PI / 180.0); + dir[1] = cos(alpha * M_PI / 180.0) * sin(beta * M_PI / 180.0); + dir[2] = cos(beta * M_PI / 180.0); + + obs[0] += v * dir[0]; + obs[1] += v * dir[1]; + obs[2] += v * dir[2]; +} + +static void +special(int k, int x, int y) +{ + switch (k) { + case GLUT_KEY_LEFT: + alpha -= 2.0; + break; + case GLUT_KEY_RIGHT: + alpha += 2.0; + break; + case GLUT_KEY_DOWN: + beta -= 2.0; + break; + case GLUT_KEY_UP: + beta += 2.0; + break; + } +} + +static void +key(unsigned char k, int x, int y) +{ + switch (k) { + case 27: + exit(0); + break; + + case 'a': + v += 0.01; + break; + case 'z': + v -= 0.01; + break; + +#ifdef XMESA + case ' ': + fullscreen = (!fullscreen); + + glutSetWindow(channel[0]); + XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW); + + glutSetWindow(channel[1]); + XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW); + break; +#endif + + case 'j': + joyactive = (!joyactive); + break; + case 'h': + help = (!help); + break; + case 'f': + fog = (!fog); + break; + case 't': + usetex = (!usetex); + break; + case 'b': + if (bfcull) { + glDisable(GL_CULL_FACE); + bfcull = 0; + } + else { + glEnable(GL_CULL_FACE); + bfcull = 1; + } + break; + case 'm': + cstrip = (!cstrip); + break; + + case 'd': + fprintf(stderr, "Deleting textures...\n"); + glDeleteTextures(1, &t1id); + glDeleteTextures(1, &t2id); + fprintf(stderr, "Loading textures...\n"); + inittextures(); + fprintf(stderr, "Done.\n"); + break; + } +} + +static void +reshapechannel0(int w, int h) +{ + float ratio; + + WIDTHC0 = w; + HEIGHTC0 = h; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + ratio = 0.5f * w / (float) h; + + glFrustum(-2.0, 0.0, -1.0 * ratio, 1.0 * ratio, 1.0, 60.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glViewport(0, 0, w, h); +} + +static void +reshapechannel1(int w, int h) +{ + float ratio; + + WIDTHC1 = w; + HEIGHTC1 = h; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + ratio = 0.5f * w / (float) h; + + glFrustum(0.0, 2.0, -1.0 * ratio, 1.0 * ratio, 1.0, 60.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glViewport(0, 0, w, h); +} + +static void +printstring(void *font, char *string) +{ + int len, i; + + len = (int) strlen(string); + for (i = 0; i < len; i++) + glutBitmapCharacter(font, string[i]); +} + +static void +printhelp(void) +{ + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(0.0, 0.0, 0.0, 0.5); + glRecti(40, 40, 600, 440); + + glColor3f(1.0, 0.0, 0.0); + glRasterPos2i(300, 420); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Help"); + + glRasterPos2i(60, 390); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "h - Togle Help"); + glRasterPos2i(60, 360); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "t - Togle Textures"); + glRasterPos2i(60, 330); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "f - Togle Fog"); + glRasterPos2i(60, 300); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "m - Togle strips"); + glRasterPos2i(60, 270); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "b - Togle Back face culling"); + glRasterPos2i(60, 240); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Arrow Keys - Rotate"); + glRasterPos2i(60, 210); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "a - Increase velocity"); + glRasterPos2i(60, 180); + printstring(GLUT_BITMAP_TIMES_ROMAN_24, "z - Decrease velocity"); + + glRasterPos2i(60, 150); + if (joyavailable) + printstring(GLUT_BITMAP_TIMES_ROMAN_24, + "j - Togle jostick control (Joystick control available)"); + else + printstring(GLUT_BITMAP_TIMES_ROMAN_24, + "(No Joystick control available)"); +} + +static void +dojoy(void) +{ +#ifdef WIN32 + static UINT max[2] = { 0, 0 }; + static UINT min[2] = { 0xffffffff, 0xffffffff }, center[2]; + MMRESULT res; + JOYINFO joy; + + res = joyGetPos(JOYSTICKID1, &joy); + + if (res == JOYERR_NOERROR) { + joyavailable = 1; + + if (max[0] < joy.wXpos) + max[0] = joy.wXpos; + if (min[0] > joy.wXpos) + min[0] = joy.wXpos; + center[0] = (max[0] + min[0]) / 2; + + if (max[1] < joy.wYpos) + max[1] = joy.wYpos; + if (min[1] > joy.wYpos) + min[1] = joy.wYpos; + center[1] = (max[1] + min[1]) / 2; + + if (joyactive) { + if (fabs(center[0] - (float) joy.wXpos) > 0.1 * (max[0] - min[0])) + alpha -= + 2.0 * (center[0] - (float) joy.wXpos) / (max[0] - min[0]); + if (fabs(center[1] - (float) joy.wYpos) > 0.1 * (max[1] - min[1])) + beta += 2.0 * (center[1] - (float) joy.wYpos) / (max[1] - min[1]); + + if (joy.wButtons & JOY_BUTTON1) + v += 0.01; + if (joy.wButtons & JOY_BUTTON2) + v -= 0.01; + } + } + else + joyavailable = 0; +#endif +} + +static void +draw(void) +{ + static int count = 0; + static char frbuf[80]; + int i; + float fr, base, offset; + + dojoy(); + + glClear(GL_COLOR_BUFFER_BIT); + + glClear(GL_COLOR_BUFFER_BIT); + + if (usetex) + glEnable(GL_TEXTURE_2D); + else + glDisable(GL_TEXTURE_2D); + + if (fog) + glEnable(GL_FOG); + else + glDisable(GL_FOG); + + glShadeModel(GL_SMOOTH); + + glPushMatrix(); + calcposobs(); + gluLookAt(obs[0], obs[1], obs[2], + obs[0] + dir[0], obs[1] + dir[1], obs[2] + dir[2], + 0.0, 0.0, 1.0); + + if (dir[0] > 0) { + offset = 8.0; + base = obs[0] - fmod(obs[0], 8.0); + } + else { + offset = -8.0; + base = obs[0] + (8.0 - fmod(obs[0], 8.0)); + } + + glPushMatrix(); + glTranslatef(base - offset / 2.0, 0.0, 0.0); + for (i = 0; i < NUMBLOC; i++) { + glTranslatef(offset, 0.0, 0.0); + glBindTexture(GL_TEXTURE_2D, t1id); + drawobjs(striplength_skin_11, stripdata_skin_11); + glBindTexture(GL_TEXTURE_2D, t2id); + drawobjs(striplength_skin_12, stripdata_skin_12); + drawobjs(striplength_skin_9, stripdata_skin_9); + drawobjs(striplength_skin_13, stripdata_skin_13); + } + glPopMatrix(); + glPopMatrix(); + + if ((count % FRAME) == 0) { + fr = gettime(); + sprintf(frbuf, "Frame rate: %f", FRAME / fr); + } + + glDisable(GL_TEXTURE_2D); + glDisable(GL_FOG); + glShadeModel(GL_FLAT); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glColor3f(1.0, 0.0, 0.0); + glRasterPos2i(10, 10); + printstring(GLUT_BITMAP_HELVETICA_18, frbuf); + glRasterPos2i(350, 470); + printstring(GLUT_BITMAP_HELVETICA_10, + "Tunnel2 V1.0 Written by David Bucciarelli (tech.hmw@plus.it)"); + + if (help) + printhelp(); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + count++; +} + +static void +drawchannel0(void) +{ + glutSetWindow(channel[0]); + draw(); + glutSwapBuffers(); +} + +static void +drawchannel1(void) +{ + glutSetWindow(channel[1]); + draw(); + glutSwapBuffers(); +} + +static void +drawall(void) +{ + glutSetWindow(channel[0]); + draw(); + glutSetWindow(channel[1]); + draw(); + + glutSetWindow(channel[0]); + glutSwapBuffers(); + glutSetWindow(channel[1]); + glutSwapBuffers(); +} + +static void +init(void) +{ + float fogcolor[4] = { 0.7, 0.7, 0.7, 1.0 }; + + glShadeModel(GL_SMOOTH); + glDisable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glEnable(GL_TEXTURE_2D); + + glEnable(GL_FOG); + glFogi(GL_FOG_MODE, GL_EXP2); + glFogfv(GL_FOG_COLOR, fogcolor); + + glFogf(GL_FOG_DENSITY, 0.06); + glHint(GL_FOG_HINT, GL_NICEST); + + glEnable(GL_BLEND); + /* + glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE); + glEnable(GL_POLYGON_SMOOTH); + */ + + glClearColor(fogcolor[0], fogcolor[1], fogcolor[2], fogcolor[3]); + glClear(GL_COLOR_BUFFER_BIT); +} + +int +main(int ac, char **av) +{ + fprintf(stderr, + "Tunnel2 V1.0\nWritten by David Bucciarelli (tech.hmw@plus.it)\n"); + fprintf(stderr, + "You need TWO Voodoo Graphics boards in order to run this demo !\n"); + + glutInitWindowPosition(0, 0); + glutInitWindowSize(WIDTHC0, HEIGHTC0); + glutInit(&ac, av); + + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_ALPHA); + +#ifdef FX + if (!fxMesaSelectCurrentBoard(0)) { + fprintf(stderr, "The first Voodoo Graphics board is missing !?!?\n"); + return -1; + } +#endif + if (!(channel[0] = glutCreateWindow("Channel 0"))) { + fprintf(stderr, "Error, couldn't open window\n"); + return -1; + } + + reshapechannel0(WIDTHC0, HEIGHTC0); + init(); + inittextures(); + glutDisplayFunc(drawchannel0); + glutReshapeFunc(reshapechannel0); + glutKeyboardFunc(key); + glutSpecialFunc(special); + +#ifdef FX + if (!fxMesaSelectCurrentBoard(1)) { + fprintf(stderr, "The second Voodoo Graphics board is missing !\n"); + exit(-1); + } +#endif + glutInitWindowPosition(WIDTHC0, 0); + glutInitWindowSize(WIDTHC1, HEIGHTC1); + if (!(channel[1] = glutCreateWindow("Channel 1"))) { + fprintf(stderr, "Error, couldn't open window\n"); + exit(-1); + } + + reshapechannel1(WIDTHC1, HEIGHTC1); + init(); + inittextures(); + glutDisplayFunc(drawchannel1); + glutReshapeFunc(reshapechannel1); + glutKeyboardFunc(key); + glutSpecialFunc(special); + + glutIdleFunc(drawall); + + calcposobs(); + + glutMainLoop(); + + return 0; +} diff --git a/progs/demos/tunneldat.c b/progs/demos/tunneldat.c new file mode 100644 index 0000000000..a4506694be --- /dev/null +++ b/progs/demos/tunneldat.c @@ -0,0 +1,83 @@ +/* Object: skin_13 */ + +#if defined(_MSC_VER) && defined(_WIN32) +#pragma warning( disable : 4305 ) /* 'initializing' : truncation from 'const double' to 'float' */ +#endif + +int striplength_skin_13[]={ +10,7,3,5,5,4,4,4,4,5,3,4,5,4,4,4,4,4,4,6, +6,3,6,3,3,3,3,0}; + +float stripdata_skin_13[]={ +0.415686,0.415686,0.415686,1.000000,0.000000,1.500000,2.000000,4.000000,0.000000,0.341176,0.341176,0.341176,1.000000,-0.500000,1.500000,4.000000,4.000000,0.000000,0.545098,0.545098,0.545098,1.000000,0.000000,1.000000,2.000000,4.000000,2.000000,0.435294,0.435294,0.435294,1.000000,-0.500000,1.000000,4.000000,4.000000,2.000000,0.517647,0.517647,0.517647,1.000000,0.000000,0.500000,2.000000,4.000000,4.000000,0.450980,0.450980,0.450980,1.000000,-0.500000,0.500000,4.000000,4.000000,4.000000,0.427451,0.427451,0.427451,1.000000,0.000000,0.000000,2.000000,4.000000,6.000000,0.388235,0.388235,0.388235,1.000000,-0.500000,0.000000,4.000000,4.000000,6.000000,0.356863,0.356863,0.356863,1.000000,0.000000,-0.500000,2.000000,4.000000,8.000000,0.333333,0.333333,0.333333,1.000000,-0.500000,-0.500000,4.000000,4.000000,8.000000, +0.435294,0.435294,0.435294,1.000000,1.500000,1.000000,-4.000000,4.000000,2.000000,0.415686,0.415686,0.415686,1.000000,1.000000,1.500000,-2.000000,4.000000,0.000000,0.545098,0.545098,0.545098,1.000000,1.000000,1.000000,-2.000000,4.000000,2.000000,0.450980,0.450980,0.450980,1.000000,0.500000,1.500000,0.000000,4.000000,0.000000,0.600000,0.600000,0.600000,1.000000,0.500000,1.000000,0.000000,4.000000,2.000000,0.415686,0.415686,0.415686,1.000000,0.000000,1.500000,2.000000,4.000000,0.000000,0.545098,0.545098,0.545098,1.000000,0.000000,1.000000,2.000000,4.000000,2.000000, +0.435294,0.435294,0.435294,1.000000,1.500000,1.000000,-4.000000,4.000000,2.000000,0.341176,0.341176,0.341176,1.000000,1.500000,1.500000,-4.000000,4.000000,0.000000,0.415686,0.415686,0.415686,1.000000,1.000000,1.500000,-2.000000,4.000000,0.000000, +0.356863,0.356863,0.356863,1.000000,0.000000,-0.500000,2.000000,4.000000,8.000000,0.364706,0.364706,0.364706,1.000000,0.500000,-0.500000,0.000000,4.000000,8.000000,0.427451,0.427451,0.427451,1.000000,0.000000,0.000000,2.000000,4.000000,6.000000,0.415686,0.415686,0.415686,1.000000,0.395020,-0.133318,0.420032,4.000000,6.533272,0.423529,0.423529,0.423529,1.000000,0.388550,-0.103582,0.445932,4.000000,6.414327, +0.423529,0.423529,0.423529,1.000000,0.388550,-0.103582,0.445932,4.000000,6.414327,0.427451,0.427451,0.427451,1.000000,0.383423,-0.069344,0.466541,4.000000,6.277375,0.427451,0.427451,0.427451,1.000000,0.000000,0.000000,2.000000,4.000000,6.000000,0.435294,0.435294,0.435294,1.000000,0.380371,-0.034595,0.478689,4.000000,6.138380,0.439216,0.439216,0.439216,1.000000,0.379272,0.000000,0.482673,4.000000,6.000000, +0.407843,0.407843,0.407843,1.000000,0.414673,-0.191394,0.341301,4.000000,6.765576,0.411765,0.411765,0.411765,1.000000,0.403687,-0.162957,0.385368,4.000000,6.651829,0.364706,0.364706,0.364706,1.000000,0.500000,-0.500000,0.000000,4.000000,8.000000,0.415686,0.415686,0.415686,1.000000,0.395020,-0.133318,0.420032,4.000000,6.533272, +0.400000,0.400000,0.400000,1.000000,0.438232,-0.232438,0.247284,4.000000,6.929754,0.403922,0.403922,0.403922,1.000000,0.425171,-0.212276,0.299425,4.000000,6.849104,0.364706,0.364706,0.364706,1.000000,0.500000,-0.500000,0.000000,4.000000,8.000000,0.407843,0.407843,0.407843,1.000000,0.414673,-0.191394,0.341301,4.000000,6.765576, +0.396078,0.396078,0.396078,1.000000,0.467285,-0.260554,0.130636,4.000000,7.042214,0.400000,0.400000,0.400000,1.000000,0.453857,-0.250068,0.184711,4.000000,7.000273,0.364706,0.364706,0.364706,1.000000,0.500000,-0.500000,0.000000,4.000000,8.000000,0.400000,0.400000,0.400000,1.000000,0.438232,-0.232438,0.247284,4.000000,6.929754, +0.396078,0.396078,0.396078,1.000000,0.500000,-0.270672,0.000000,4.000000,7.082688,0.396078,0.396078,0.396078,1.000000,0.482788,-0.267902,0.068730,4.000000,7.071609,0.364706,0.364706,0.364706,1.000000,0.500000,-0.500000,0.000000,4.000000,8.000000,0.396078,0.396078,0.396078,1.000000,0.467285,-0.260554,0.130636,4.000000,7.042214, +0.439216,0.439216,0.439216,1.000000,0.379272,0.000000,0.482673,4.000000,6.000000,0.474510,0.474510,0.474510,1.000000,0.379272,0.180448,0.482673,4.000000,5.278208,0.517647,0.517647,0.517647,1.000000,0.000000,0.500000,2.000000,4.000000,4.000000,0.513726,0.513726,0.513726,1.000000,0.379272,0.360896,0.482673,4.000000,4.556417,0.545098,0.545098,0.545098,1.000000,0.379272,0.500000,0.482673,4.000000,4.000000, +0.545098,0.545098,0.545098,1.000000,0.379272,0.500000,0.482673,4.000000,4.000000,0.545098,0.545098,0.545098,1.000000,0.000000,1.000000,2.000000,4.000000,2.000000,0.517647,0.517647,0.517647,1.000000,0.000000,0.500000,2.000000,4.000000,4.000000, +0.600000,0.600000,0.600000,1.000000,0.500000,1.000000,0.000000,4.000000,2.000000,0.545098,0.545098,0.545098,1.000000,0.000000,1.000000,2.000000,4.000000,2.000000,0.552941,0.552941,0.552941,1.000000,0.379272,0.541344,0.482673,4.000000,3.834625,0.545098,0.545098,0.545098,1.000000,0.379272,0.500000,0.482673,4.000000,4.000000, +0.552941,0.552941,0.552941,1.000000,0.379272,0.541344,0.482673,4.000000,3.834625,0.556863,0.556863,0.556863,1.000000,0.459717,0.541344,0.160891,4.000000,3.834625,0.600000,0.600000,0.600000,1.000000,0.500000,1.000000,0.000000,4.000000,2.000000,0.556863,0.556863,0.556863,1.000000,0.500000,0.541344,0.000000,4.000000,3.834625,0.556863,0.556863,0.556863,1.000000,0.540283,0.541344,-0.160891,4.000000,3.834625, +0.396078,0.396078,0.396078,1.000000,0.517212,-0.267902,-0.068730,4.000000,7.071609,0.396078,0.396078,0.396078,1.000000,0.500000,-0.270672,0.000000,4.000000,7.082688,0.356863,0.356863,0.356863,1.000000,1.000000,-0.500000,-2.000000,4.000000,8.000000,0.364706,0.364706,0.364706,1.000000,0.500000,-0.500000,0.000000,4.000000,8.000000, +0.400000,0.400000,0.400000,1.000000,0.546143,-0.250068,-0.184711,4.000000,7.000273,0.396078,0.396078,0.396078,1.000000,0.532715,-0.260554,-0.130636,4.000000,7.042214,0.356863,0.356863,0.356863,1.000000,1.000000,-0.500000,-2.000000,4.000000,8.000000,0.396078,0.396078,0.396078,1.000000,0.517212,-0.267902,-0.068730,4.000000,7.071609, +0.403922,0.403922,0.403922,1.000000,0.574829,-0.212276,-0.299425,4.000000,6.849104,0.400000,0.400000,0.400000,1.000000,0.561768,-0.232438,-0.247284,4.000000,6.929754,0.356863,0.356863,0.356863,1.000000,1.000000,-0.500000,-2.000000,4.000000,8.000000,0.400000,0.400000,0.400000,1.000000,0.546143,-0.250068,-0.184711,4.000000,7.000273, +0.411765,0.411765,0.411765,1.000000,0.596313,-0.162957,-0.385368,4.000000,6.651829,0.407843,0.407843,0.407843,1.000000,0.585327,-0.191394,-0.341301,4.000000,6.765576,0.356863,0.356863,0.356863,1.000000,1.000000,-0.500000,-2.000000,4.000000,8.000000,0.403922,0.403922,0.403922,1.000000,0.574829,-0.212276,-0.299425,4.000000,6.849104, +0.423529,0.423529,0.423529,1.000000,0.611450,-0.103582,-0.445931,4.000000,6.414327,0.415686,0.415686,0.415686,1.000000,0.604980,-0.133318,-0.420033,4.000000,6.533272,0.356863,0.356863,0.356863,1.000000,1.000000,-0.500000,-2.000000,4.000000,8.000000,0.411765,0.411765,0.411765,1.000000,0.596313,-0.162957,-0.385368,4.000000,6.651829, +0.435294,0.435294,0.435294,1.000000,0.619629,-0.034595,-0.478689,4.000000,6.138380,0.427451,0.427451,0.427451,1.000000,0.616577,-0.069344,-0.466541,4.000000,6.277375,0.356863,0.356863,0.356863,1.000000,1.000000,-0.500000,-2.000000,4.000000,8.000000,0.423529,0.423529,0.423529,1.000000,0.611450,-0.103582,-0.445931,4.000000,6.414327, +0.513726,0.513726,0.513726,1.000000,0.620728,0.360896,-0.482673,4.000000,4.556417,0.474510,0.474510,0.474510,1.000000,0.620728,0.180448,-0.482673,4.000000,5.278208,0.427451,0.427451,0.427451,1.000000,1.000000,0.000000,-2.000000,4.000000,6.000000,0.439216,0.439216,0.439216,1.000000,0.620728,0.000000,-0.482673,4.000000,6.000000,0.356863,0.356863,0.356863,1.000000,1.000000,-0.500000,-2.000000,4.000000,8.000000,0.435294,0.435294,0.435294,1.000000,0.619629,-0.034595,-0.478689,4.000000,6.138380, +0.333333,0.333333,0.333333,1.000000,1.500000,-0.500000,-4.000000,4.000000,8.000000,0.388235,0.388235,0.388235,1.000000,1.500000,0.000000,-4.000000,4.000000,6.000000,0.427451,0.427451,0.427451,1.000000,1.000000,0.000000,-2.000000,4.000000,6.000000,0.517647,0.517647,0.517647,1.000000,1.000000,0.500000,-2.000000,4.000000,4.000000,0.513726,0.513726,0.513726,1.000000,0.620728,0.360896,-0.482673,4.000000,4.556417,0.545098,0.545098,0.545098,1.000000,0.620728,0.500000,-0.482673,4.000000,4.000000, +0.333333,0.333333,0.333333,1.000000,1.500000,-0.500000,-4.000000,4.000000,8.000000,0.427451,0.427451,0.427451,1.000000,1.000000,0.000000,-2.000000,4.000000,6.000000,0.356863,0.356863,0.356863,1.000000,1.000000,-0.500000,-2.000000,4.000000,8.000000, +0.556863,0.556863,0.556863,1.000000,0.540283,0.541344,-0.160891,4.000000,3.834625,0.552941,0.552941,0.552941,1.000000,0.620728,0.541344,-0.482673,4.000000,3.834625,0.545098,0.545098,0.545098,1.000000,1.000000,1.000000,-2.000000,4.000000,2.000000,0.517647,0.517647,0.517647,1.000000,1.000000,0.500000,-2.000000,4.000000,4.000000,0.450980,0.450980,0.450980,1.000000,1.500000,0.500000,-4.000000,4.000000,4.000000,0.388235,0.388235,0.388235,1.000000,1.500000,0.000000,-4.000000,4.000000,6.000000, +0.517647,0.517647,0.517647,1.000000,1.000000,0.500000,-2.000000,4.000000,4.000000,0.552941,0.552941,0.552941,1.000000,0.620728,0.541344,-0.482673,4.000000,3.834625,0.545098,0.545098,0.545098,1.000000,0.620728,0.500000,-0.482673,4.000000,4.000000, +0.450980,0.450980,0.450980,1.000000,1.500000,0.500000,-4.000000,4.000000,4.000000,0.435294,0.435294,0.435294,1.000000,1.500000,1.000000,-4.000000,4.000000,2.000000,0.545098,0.545098,0.545098,1.000000,1.000000,1.000000,-2.000000,4.000000,2.000000, +0.439216,0.439216,0.439216,1.000000,0.379272,0.000000,0.482673,4.000000,6.000000,0.517647,0.517647,0.517647,1.000000,0.000000,0.500000,2.000000,4.000000,4.000000,0.427451,0.427451,0.427451,1.000000,0.000000,0.000000,2.000000,4.000000,6.000000, +0.556863,0.556863,0.556863,1.000000,0.540283,0.541344,-0.160891,4.000000,3.834625,0.545098,0.545098,0.545098,1.000000,1.000000,1.000000,-2.000000,4.000000,2.000000,0.600000,0.600000,0.600000,1.000000,0.500000,1.000000,0.000000,4.000000,2.000000 + +}; + + +/* Object: skin_12 */ + +int striplength_skin_12[]={ +12,12,12,12,12,0}; + +float stripdata_skin_12[]={ +0.498039,0.498039,0.498039,1.000000,-0.099976,1.500000,-2.400000,-4.000000,-0.000002,0.337255,0.337255,0.337255,1.000000,-0.500000,1.500000,-4.000000,-4.000000,-0.000002,0.568627,0.568627,0.568627,1.000000,-0.099976,1.100000,-2.400000,-4.000000,1.599999,0.341176,0.341176,0.341176,1.000000,-0.500000,1.100000,-4.000000,-4.000000,1.599999,0.498039,0.498039,0.498039,1.000000,-0.099976,0.700000,-2.400000,-4.000000,3.200000,0.325490,0.325490,0.325490,1.000000,-0.500000,0.700000,-4.000000,-4.000000,3.199999,0.352941,0.352941,0.352941,1.000000,-0.099976,0.300000,-2.400000,-4.000000,4.800000,0.282353,0.282353,0.282353,1.000000,-0.500000,0.300000,-4.000000,-4.000000,4.800000,0.282353,0.282353,0.282353,1.000000,-0.099976,-0.100000,-2.400000,-4.000000,6.400001,0.254902,0.254902,0.254902,1.000000,-0.500000,-0.100000,-4.000000,-4.000000,6.400000,0.239216,0.239216,0.239216,1.000000,-0.099976,-0.500000,-2.400000,-4.000000,8.000000,0.227451,0.227451,0.227451,1.000000,-0.500000,-0.500000,-4.000000,-4.000000,8.000000, +0.239216,0.239216,0.239216,1.000000,1.099976,-0.500000,2.400001,-4.000000,8.000000,0.227451,0.227451,0.227451,1.000000,1.500000,-0.500000,4.000002,-4.000000,8.000000,0.282353,0.282353,0.282353,1.000000,1.099976,-0.100000,2.400001,-4.000000,6.400001,0.254902,0.254902,0.254902,1.000000,1.500000,-0.100000,4.000002,-4.000000,6.400001,0.352941,0.352941,0.352941,1.000000,1.099976,0.300000,2.400002,-4.000000,4.800001,0.282353,0.282353,0.282353,1.000000,1.500000,0.300000,4.000002,-4.000000,4.800001,0.498039,0.498039,0.498039,1.000000,1.099976,0.700000,2.400002,-4.000000,3.200000,0.321569,0.321569,0.321569,1.000000,1.500000,0.700000,4.000003,-4.000000,3.200000,0.568627,0.568627,0.568627,1.000000,1.099976,1.100000,2.400002,-4.000000,1.599999,0.341176,0.341176,0.341176,1.000000,1.500000,1.100000,4.000003,-4.000000,1.599999,0.494118,0.494118,0.494118,1.000000,1.099976,1.500000,2.400003,-4.000000,-0.000002,0.337255,0.337255,0.337255,1.000000,1.500000,1.500000,4.000004,-4.000000,-0.000002, +0.639216,0.639216,0.639216,1.000000,0.300049,1.500000,-0.799999,-4.000000,-0.000002,0.498039,0.498039,0.498039,1.000000,-0.099976,1.500000,-2.400000,-4.000000,-0.000002,0.858824,0.858824,0.858824,1.000000,0.300049,1.100000,-0.799999,-4.000000,1.599999,0.568627,0.568627,0.568627,1.000000,-0.099976,1.100000,-2.400000,-4.000000,1.599999,0.686275,0.686275,0.686275,1.000000,0.300049,0.700000,-0.799999,-4.000000,3.200000,0.498039,0.498039,0.498039,1.000000,-0.099976,0.700000,-2.400000,-4.000000,3.200000,0.419608,0.419608,0.419608,1.000000,0.300049,0.300000,-0.800000,-4.000000,4.800000,0.352941,0.352941,0.352941,1.000000,-0.099976,0.300000,-2.400000,-4.000000,4.800000,0.298039,0.298039,0.298039,1.000000,0.300049,-0.100000,-0.800000,-4.000000,6.400001,0.282353,0.282353,0.282353,1.000000,-0.099976,-0.100000,-2.400000,-4.000000,6.400001,0.247059,0.247059,0.247059,1.000000,0.300049,-0.500000,-0.800000,-4.000000,8.000000,0.239216,0.239216,0.239216,1.000000,-0.099976,-0.500000,-2.400000,-4.000000,8.000000, +0.639216,0.639216,0.639216,1.000000,0.699951,1.500000,0.800002,-4.000000,-0.000002,0.639216,0.639216,0.639216,1.000000,0.300049,1.500000,-0.799999,-4.000000,-0.000002,0.858824,0.858824,0.858824,1.000000,0.699951,1.100000,0.800001,-4.000000,1.599999,0.858824,0.858824,0.858824,1.000000,0.300049,1.100000,-0.799999,-4.000000,1.599999,0.686275,0.686275,0.686275,1.000000,0.699951,0.700000,0.800001,-4.000000,3.200000,0.686275,0.686275,0.686275,1.000000,0.300049,0.700000,-0.799999,-4.000000,3.200000,0.419608,0.419608,0.419608,1.000000,0.699951,0.300000,0.800001,-4.000000,4.800001,0.419608,0.419608,0.419608,1.000000,0.300049,0.300000,-0.800000,-4.000000,4.800000,0.298039,0.298039,0.298039,1.000000,0.699951,-0.100000,0.800001,-4.000000,6.400001,0.298039,0.298039,0.298039,1.000000,0.300049,-0.100000,-0.800000,-4.000000,6.400001,0.247059,0.247059,0.247059,1.000000,0.699951,-0.500000,0.800000,-4.000000,8.000000,0.247059,0.247059,0.247059,1.000000,0.300049,-0.500000,-0.800000,-4.000000,8.000000, +0.494118,0.494118,0.494118,1.000000,1.099976,1.500000,2.400003,-4.000000,-0.000002,0.639216,0.639216,0.639216,1.000000,0.699951,1.500000,0.800002,-4.000000,-0.000002,0.568627,0.568627,0.568627,1.000000,1.099976,1.100000,2.400002,-4.000000,1.599999,0.858824,0.858824,0.858824,1.000000,0.699951,1.100000,0.800001,-4.000000,1.599999,0.498039,0.498039,0.498039,1.000000,1.099976,0.700000,2.400002,-4.000000,3.200000,0.686275,0.686275,0.686275,1.000000,0.699951,0.700000,0.800001,-4.000000,3.200000,0.352941,0.352941,0.352941,1.000000,1.099976,0.300000,2.400002,-4.000000,4.800001,0.419608,0.419608,0.419608,1.000000,0.699951,0.300000,0.800001,-4.000000,4.800001,0.282353,0.282353,0.282353,1.000000,1.099976,-0.100000,2.400001,-4.000000,6.400001,0.298039,0.298039,0.298039,1.000000,0.699951,-0.100000,0.800001,-4.000000,6.400001,0.239216,0.239216,0.239216,1.000000,1.099976,-0.500000,2.400001,-4.000000,8.000000,0.247059,0.247059,0.247059,1.000000,0.699951,-0.500000,0.800000,-4.000000,8.000000 + +}; + + +/* Object: skin_11 */ + +int striplength_skin_11[]={ +12,12,12,12,12,0}; + +float stripdata_skin_11[]={ +0.145098,0.145098,0.145098,1.000000,-0.099976,1.500000,-2.400000,4.000002,0.000000,0.141176,0.141176,0.141176,1.000000,-0.500000,1.500000,-4.000000,4.000002,0.000000,0.176471,0.176471,0.176471,1.000000,-0.099976,1.100000,-2.400000,2.400001,0.000000,0.145098,0.145098,0.145098,1.000000,-0.500000,1.100000,-4.000000,2.400001,0.000000,0.341176,0.341176,0.341176,1.000000,-0.099976,0.700000,-2.400000,0.800000,0.000000,0.188235,0.188235,0.188235,1.000000,-0.500000,0.700000,-4.000000,0.800000,0.000000,0.450980,0.450980,0.450980,1.000000,-0.099976,0.300000,-2.400000,-0.800000,0.000000,0.247059,0.247059,0.247059,1.000000,-0.500000,0.300000,-4.000000,-0.800000,0.000000,0.439216,0.439216,0.439216,1.000000,-0.099976,-0.100000,-2.400000,-2.400000,0.000000,0.270588,0.270588,0.270588,1.000000,-0.500000,-0.100000,-4.000000,-2.400000,0.000000,0.364706,0.364706,0.364706,1.000000,-0.099976,-0.500000,-2.400000,-4.000000,0.000000,0.258824,0.258824,0.258824,1.000000,-0.500000,-0.500000,-4.000000,-4.000000,0.000000, +0.364706,0.364706,0.364706,1.000000,1.099976,-0.500000,2.400001,-4.000000,0.000000,0.258824,0.258824,0.258824,1.000000,1.500000,-0.500000,4.000002,-4.000000,0.000000,0.439216,0.439216,0.439216,1.000000,1.099976,-0.100000,2.400001,-2.400001,0.000000,0.270588,0.270588,0.270588,1.000000,1.500000,-0.100000,4.000002,-2.400001,0.000000,0.454902,0.454902,0.454902,1.000000,1.099976,0.300000,2.400002,-0.800000,0.000000,0.247059,0.247059,0.247059,1.000000,1.500000,0.300000,4.000002,-0.800000,0.000000,0.341176,0.341176,0.341176,1.000000,1.099976,0.700000,2.400002,0.800000,0.000000,0.184314,0.184314,0.184314,1.000000,1.500000,0.700000,4.000003,0.800000,0.000000,0.176471,0.176471,0.176471,1.000000,1.099976,1.100000,2.400002,2.400001,0.000000,0.145098,0.145098,0.145098,1.000000,1.500000,1.100000,4.000003,2.400001,0.000000,0.145098,0.145098,0.145098,1.000000,1.099976,1.500000,2.400003,4.000003,0.000000,0.141176,0.141176,0.141176,1.000000,1.500000,1.500000,4.000004,4.000002,0.000000, +0.145098,0.145098,0.145098,1.000000,0.300049,1.500000,-0.799999,4.000002,0.000000,0.145098,0.145098,0.145098,1.000000,-0.099976,1.500000,-2.400000,4.000002,0.000000,0.262745,0.262745,0.262745,1.000000,0.300049,1.100000,-0.799999,2.400001,0.000000,0.176471,0.176471,0.176471,1.000000,-0.099976,1.100000,-2.400000,2.400001,0.000000,0.580392,0.580392,0.580392,1.000000,0.300049,0.700000,-0.799999,0.800000,0.000000,0.341176,0.341176,0.341176,1.000000,-0.099976,0.700000,-2.400000,0.800000,0.000000,0.709804,0.709804,0.709804,1.000000,0.300049,0.300000,-0.800000,-0.800000,0.000000,0.450980,0.450980,0.450980,1.000000,-0.099976,0.300000,-2.400000,-0.800000,0.000000,0.627451,0.627451,0.627451,1.000000,0.300049,-0.100000,-0.800000,-2.400001,0.000000,0.439216,0.439216,0.439216,1.000000,-0.099976,-0.100000,-2.400000,-2.400000,0.000000,0.458824,0.458824,0.458824,1.000000,0.300049,-0.500000,-0.800000,-4.000000,0.000000,0.364706,0.364706,0.364706,1.000000,-0.099976,-0.500000,-2.400000,-4.000000,0.000000, +0.145098,0.145098,0.145098,1.000000,0.699951,1.500000,0.800002,4.000002,0.000000,0.145098,0.145098,0.145098,1.000000,0.300049,1.500000,-0.799999,4.000002,0.000000,0.262745,0.262745,0.262745,1.000000,0.699951,1.100000,0.800001,2.400001,0.000000,0.262745,0.262745,0.262745,1.000000,0.300049,1.100000,-0.799999,2.400001,0.000000,0.580392,0.580392,0.580392,1.000000,0.699951,0.700000,0.800001,0.800000,0.000000,0.580392,0.580392,0.580392,1.000000,0.300049,0.700000,-0.799999,0.800000,0.000000,0.713726,0.713726,0.713726,1.000000,0.699951,0.300000,0.800001,-0.800000,0.000000,0.709804,0.709804,0.709804,1.000000,0.300049,0.300000,-0.800000,-0.800000,0.000000,0.631373,0.631373,0.631373,1.000000,0.699951,-0.100000,0.800001,-2.400001,0.000000,0.627451,0.627451,0.627451,1.000000,0.300049,-0.100000,-0.800000,-2.400001,0.000000,0.458824,0.458824,0.458824,1.000000,0.699951,-0.500000,0.800000,-4.000000,0.000000,0.458824,0.458824,0.458824,1.000000,0.300049,-0.500000,-0.800000,-4.000000,0.000000, +0.145098,0.145098,0.145098,1.000000,1.099976,1.500000,2.400003,4.000003,0.000000,0.145098,0.145098,0.145098,1.000000,0.699951,1.500000,0.800002,4.000002,0.000000,0.176471,0.176471,0.176471,1.000000,1.099976,1.100000,2.400002,2.400001,0.000000,0.262745,0.262745,0.262745,1.000000,0.699951,1.100000,0.800001,2.400001,0.000000,0.341176,0.341176,0.341176,1.000000,1.099976,0.700000,2.400002,0.800000,0.000000,0.580392,0.580392,0.580392,1.000000,0.699951,0.700000,0.800001,0.800000,0.000000,0.454902,0.454902,0.454902,1.000000,1.099976,0.300000,2.400002,-0.800000,0.000000,0.713726,0.713726,0.713726,1.000000,0.699951,0.300000,0.800001,-0.800000,0.000000,0.439216,0.439216,0.439216,1.000000,1.099976,-0.100000,2.400001,-2.400001,0.000000,0.631373,0.631373,0.631373,1.000000,0.699951,-0.100000,0.800001,-2.400001,0.000000,0.364706,0.364706,0.364706,1.000000,1.099976,-0.500000,2.400001,-4.000000,0.000000,0.458824,0.458824,0.458824,1.000000,0.699951,-0.500000,0.800000,-4.000000,0.000000 + +}; + + +/* Object: skin_9 */ + +int striplength_skin_9[]={ +18,0}; + +float stripdata_skin_9[]={ +0.384314,0.384314,0.384314,1.000000,-0.500000,1.500000,-4.000000,4.000000,8.000000,0.384314,0.384314,0.384314,1.000000,1.500000,1.500000,4.000000,4.000000,8.000000,0.376471,0.376471,0.376471,1.000000,-0.500000,1.250000,-4.000000,3.695518,9.530733,0.403922,0.403922,0.403922,1.000000,1.500000,1.250000,4.000000,3.695518,9.530733,0.415686,0.415686,0.415686,1.000000,-0.500000,1.000000,-4.000000,2.828427,10.828427,0.431373,0.431373,0.431373,1.000000,1.500000,1.000000,4.000000,2.828427,10.828427,0.435294,0.435294,0.435294,1.000000,-0.500000,0.750000,-4.000000,1.530734,11.695518,0.443137,0.443137,0.443137,1.000000,1.500000,0.750000,4.000000,1.530734,11.695518,0.439216,0.439216,0.439216,1.000000,-0.500000,0.500000,-4.000000,0.000000,12.000000,0.435294,0.435294,0.435294,1.000000,1.500000,0.500000,4.000000,0.000000,12.000000,0.427451,0.427451,0.427451,1.000000,-0.500000,0.250000,-4.000000,-1.530734,11.695518,0.411765,0.411765,0.411765,1.000000,1.500000,0.250000,4.000000,-1.530734,11.695518,0.396078,0.396078,0.396078,1.000000,-0.500000,0.000000,-4.000000,-2.828427,10.828427,0.368627,0.368627,0.368627,1.000000,1.500000,0.000000,4.000000,-2.828427,10.828427,0.341176,0.341176,0.341176,1.000000,-0.500000,-0.250000,-4.000000,-3.695518,9.530733,0.301961,0.301961,0.301961,1.000000,1.500000,-0.250000,4.000000,-3.695518,9.530733,0.294118,0.294118,0.294118,1.000000,-0.500000,-0.500000,-4.000000,-4.000000,8.000000,0.294118,0.294118,0.294118,1.000000,1.500000,-0.500000,4.000000,-4.000000,8.000000 + +}; + + |