@@ -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); | |||
} |
@@ -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; | |||
} |
@@ -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; | |||
} |
@@ -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]; | |||
} |
@@ -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 |
@@ -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); | |||
} |
@@ -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; | |||
} |
@@ -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]); | |||
} |
@@ -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; | |||
} |
@@ -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; | |||
} |
@@ -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; | |||
} |
@@ -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; | |||
} |
@@ -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 | |||
}; | |||