diff options
Diffstat (limited to 'progs/demos/ray.c')
-rw-r--r-- | progs/demos/ray.c | 902 |
1 files changed, 902 insertions, 0 deletions
diff --git a/progs/demos/ray.c b/progs/demos/ray.c new file mode 100644 index 000000000..eb1d19f86 --- /dev/null +++ b/progs/demos/ray.c @@ -0,0 +1,902 @@ +/* + * 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 <string.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; + +static GLint T0 = 0; +static GLint Frames = 0; + +#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 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); + + if (dir[0] < 1.0e-5 && dir[0] > -1.0e-5) + dir[0] = 0; + if (dir[1] < 1.0e-5 && dir[1] > -1.0e-5) + dir[1] = 0; + if (dir[2] < 1.0e-5 && dir[2] > -1.0e-5) + dir[2] = 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 - Toggle Help"); + glRasterPos2i(60, 370); + printstring(GLUT_BITMAP_HELVETICA_12, "f - Toggle Fog"); + glRasterPos2i(60, 350); + printstring(GLUT_BITMAP_HELVETICA_12, "b - Toggle Back face culling"); + glRasterPos2i(60, 330); + printstring(GLUT_BITMAP_HELVETICA_12, "p - Toggle 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 - Toggle 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 - Toggle the plane texture map window"); + + glRasterPos2i(60, 170); + printstring(GLUT_BITMAP_HELVETICA_12, + "2 - Toggle 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 = pow(kfact, 6.0) * 7.0 * 255.0; + + 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 = pow(kfact, 4.0); + if (kfact < 1.0e-10) + kfact = 0.0; + } + + 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 char frbuf[80] = ""; + + 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(); + + 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(); + + Frames++; + { + GLint t = glutGet(GLUT_ELAPSED_TIME); + if (t - T0 >= 2000) { + GLfloat seconds = (t - T0) / 1000.0; + GLfloat fps = Frames / seconds; + sprintf(frbuf, "Frame rate: %f", fps); + T0 = t; + Frames = 0; + } + } +} + +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; +} |