132001f49Smrg/* 232001f49Smrg * This program is under the GNU GPL. 332001f49Smrg * Use at your own risk. 432001f49Smrg * 532001f49Smrg * written by David Bucciarelli (tech.hmw@plus.it) 632001f49Smrg * Humanware s.r.l. 732001f49Smrg * 832001f49Smrg * based on a Mikael SkiZoWalker's (MoDEL) / France (Skizo@Hol.Fr) demo 932001f49Smrg */ 1032001f49Smrg 1132001f49Smrg#include <assert.h> 1232001f49Smrg#include <stdio.h> 1332001f49Smrg#include <math.h> 1432001f49Smrg#include <stdlib.h> 1532001f49Smrg#include <string.h> 1632001f49Smrg#include <time.h> 1732001f49Smrg 1832001f49Smrg#ifdef WIN32 1932001f49Smrg#include <windows.h> 2032001f49Smrg#endif 2132001f49Smrg 2232001f49Smrg#include "glut_wrap.h" 2332001f49Smrg 2432001f49Smrg#ifdef XMESA 2532001f49Smrg#include "GL/xmesa.h" 2632001f49Smrgstatic int fullscreen = 1; 2732001f49Smrg#endif 2832001f49Smrg 2932001f49Smrg#ifndef M_PI 3032001f49Smrg#define M_PI 3.14159265 3132001f49Smrg#endif 3232001f49Smrg 3332001f49Smrg#define heightMnt 450 3432001f49Smrg#define lenghtXmnt 62 3532001f49Smrg#define lenghtYmnt 62 3632001f49Smrg 3732001f49Smrg#define stepXmnt 96.0 3832001f49Smrg#define stepYmnt 96.0 3932001f49Smrg 4032001f49Smrg#define WIDTH 640 4132001f49Smrg#define HEIGHT 480 4232001f49Smrg 4332001f49Smrgstatic GLint T0 = 0; 4432001f49Smrgstatic GLint Frames = 0; 4532001f49Smrg 4632001f49Smrg#define TSCALE 4 4732001f49Smrg 4832001f49Smrg#define FOV 85 4932001f49Smrg 5032001f49Smrgstatic GLfloat terrain[256 * 256]; 5132001f49Smrgstatic GLfloat terraincolor[256 * 256][3]; 5232001f49Smrg 5332001f49Smrgstatic int win = 0; 5432001f49Smrg 5532001f49Smrgstatic int fog = 1; 5632001f49Smrgstatic int bfcull = 1; 5732001f49Smrgstatic int usetex = 1; 5832001f49Smrgstatic int poutline = 0; 5932001f49Smrgstatic int help = 1; 6032001f49Smrgstatic int joyavailable = 0; 6132001f49Smrgstatic int joyactive = 0; 6232001f49Smrgstatic float ModZMnt; 6332001f49Smrgstatic long GlobalMnt = 0; 6432001f49Smrg 6532001f49Smrgstatic int scrwidth = WIDTH; 6632001f49Smrgstatic int scrheight = HEIGHT; 6732001f49Smrg 6832001f49Smrg#define OBSSTARTX 992.0 6932001f49Smrg#define OBSSTARTY 103.0 7032001f49Smrg 7132001f49Smrgstatic float obs[3] = { OBSSTARTX, heightMnt * 1.3, OBSSTARTY }; 7232001f49Smrgstatic float dir[3], v1[2], v2[2]; 7332001f49Smrgstatic float v = 900.0; 7432001f49Smrgstatic float alpha = 75.0; 7532001f49Smrgstatic float beta = 90.0; 7632001f49Smrg 7732001f49Smrgstatic void 7832001f49Smrgcalcposobs(void) 7932001f49Smrg{ 8032001f49Smrg float alpha1, alpha2; 8132001f49Smrg static double t0 = -1.; 8232001f49Smrg double dt, t = glutGet(GLUT_ELAPSED_TIME) / 1000.0; 8332001f49Smrg if (t0 < 0.0) 8432001f49Smrg t0 = t; 8532001f49Smrg dt = t - t0; 8632001f49Smrg t0 = t; 8732001f49Smrg 8832001f49Smrg dir[0] = sin(alpha * M_PI / 180.0); 8932001f49Smrg dir[2] = cos(alpha * M_PI / 180.0) * sin(beta * M_PI / 180.0); 9032001f49Smrg dir[1] = cos(beta * M_PI / 180.0); 9132001f49Smrg 9232001f49Smrg if (dir[0] < 1.0e-5 && dir[0] > -1.0e-5) 9332001f49Smrg dir[0] = 0; 9432001f49Smrg if (dir[1] < 1.0e-5 && dir[1] > -1.0e-5) 9532001f49Smrg dir[1] = 0; 9632001f49Smrg if (dir[2] < 1.0e-5 && dir[2] > -1.0e-5) 9732001f49Smrg dir[2] = 0; 9832001f49Smrg 9932001f49Smrg alpha1 = alpha + FOV / 2.0; 10032001f49Smrg v1[0] = sin(alpha1 * M_PI / 180.0); 10132001f49Smrg v1[1] = cos(alpha1 * M_PI / 180.0); 10232001f49Smrg 10332001f49Smrg alpha2 = alpha - FOV / 2.0; 10432001f49Smrg v2[0] = sin(alpha2 * M_PI / 180.0); 10532001f49Smrg v2[1] = cos(alpha2 * M_PI / 180.0); 10632001f49Smrg 10732001f49Smrg obs[0] += v * dir[0] * dt; 10832001f49Smrg obs[1] += v * dir[1] * dt; 10932001f49Smrg obs[2] += v * dir[2] * dt; 11032001f49Smrg 11132001f49Smrg if (obs[1] < 0.0) 11232001f49Smrg obs[1] = 0.0; 11332001f49Smrg} 11432001f49Smrg 11532001f49Smrgstatic void 11632001f49Smrgreshape(int width, int height) 11732001f49Smrg{ 11832001f49Smrg scrwidth = width; 11932001f49Smrg scrheight = height; 12032001f49Smrg glViewport(0, 0, (GLint) width, (GLint) height); 12132001f49Smrg glMatrixMode(GL_PROJECTION); 12232001f49Smrg glLoadIdentity(); 12332001f49Smrg gluPerspective(50.0, ((GLfloat) width / (GLfloat) height), 12432001f49Smrg lenghtXmnt * stepYmnt * 0.01, lenghtXmnt * stepYmnt * 0.7); 12532001f49Smrg glMatrixMode(GL_MODELVIEW); 12632001f49Smrg glLoadIdentity(); 12732001f49Smrg} 12832001f49Smrg 12932001f49Smrgstatic int 13032001f49Smrgclipstrip(float y, float *start, float *end) 13132001f49Smrg{ 13232001f49Smrg float x1, x2, t1, t2, tmp; 13332001f49Smrg 13432001f49Smrg if (v1[1] == 0.0) { 13532001f49Smrg t1 = 0.0; 13632001f49Smrg x1 = -HUGE_VAL; 13732001f49Smrg } 13832001f49Smrg else { 13932001f49Smrg t1 = y / v1[1]; 14032001f49Smrg x1 = t1 * v1[0]; 14132001f49Smrg } 14232001f49Smrg 14332001f49Smrg if (v2[1] == 0.0) { 14432001f49Smrg t2 = 0.0; 14532001f49Smrg x2 = HUGE_VAL; 14632001f49Smrg } 14732001f49Smrg else { 14832001f49Smrg t2 = y / v2[1]; 14932001f49Smrg x2 = t2 * v2[0]; 15032001f49Smrg } 15132001f49Smrg 15232001f49Smrg if (((x1 < -(lenghtXmnt * stepXmnt) / 2) && (t2 <= 0.0)) || 15332001f49Smrg ((t1 <= 0.0) && (x2 > (lenghtXmnt * stepXmnt) / 2)) || 15432001f49Smrg ((t1 < 0.0) && (t2 < 0.0))) 15532001f49Smrg return 0; 15632001f49Smrg 15732001f49Smrg if ((t1 == 0.0) && (t2 == 0.0)) { 15832001f49Smrg if ((v1[0] < 0.0) && (v1[1] > 0.0) && (v2[0] < 0.0) && (v2[1] < 0.0)) { 15932001f49Smrg *start = -(lenghtXmnt * stepXmnt) / 2; 16032001f49Smrg *end = stepXmnt; 16132001f49Smrg return 1; 16232001f49Smrg } 16332001f49Smrg else { 16432001f49Smrg if ((v1[0] > 0.0) && (v1[1] < 0.0) && (v2[0] > 0.0) && (v2[1] > 0.0)) { 16532001f49Smrg *start = -stepXmnt; 16632001f49Smrg *end = (lenghtXmnt * stepXmnt) / 2; 16732001f49Smrg return 1; 16832001f49Smrg } 16932001f49Smrg else 17032001f49Smrg return 0; 17132001f49Smrg } 17232001f49Smrg } 17332001f49Smrg else { 17432001f49Smrg if (t2 < 0.0) { 17532001f49Smrg if (x1 < 0.0) 17632001f49Smrg x2 = -(lenghtXmnt * stepXmnt) / 2; 17732001f49Smrg else 17832001f49Smrg x2 = (lenghtXmnt * stepXmnt) / 2; 17932001f49Smrg } 18032001f49Smrg 18132001f49Smrg if (t1 < 0.0) { 18232001f49Smrg if (x2 < 0.0) 18332001f49Smrg x1 = -(lenghtXmnt * stepXmnt) / 2; 18432001f49Smrg else 18532001f49Smrg x1 = (lenghtXmnt * stepXmnt) / 2; 18632001f49Smrg } 18732001f49Smrg } 18832001f49Smrg 18932001f49Smrg if (x1 > x2) { 19032001f49Smrg tmp = x1; 19132001f49Smrg x1 = x2; 19232001f49Smrg x2 = tmp; 19332001f49Smrg } 19432001f49Smrg 19532001f49Smrg x1 -= stepXmnt; 19632001f49Smrg if (x1 < -(lenghtXmnt * stepXmnt) / 2) 19732001f49Smrg x1 = -(lenghtXmnt * stepXmnt) / 2; 19832001f49Smrg 19932001f49Smrg x2 += stepXmnt; 20032001f49Smrg if (x2 > (lenghtXmnt * stepXmnt) / 2) 20132001f49Smrg x2 = (lenghtXmnt * stepXmnt) / 2; 20232001f49Smrg 20332001f49Smrg *start = ((int) (x1 / stepXmnt)) * stepXmnt; 20432001f49Smrg *end = ((int) (x2 / stepXmnt)) * stepXmnt; 20532001f49Smrg 20632001f49Smrg return 1; 20732001f49Smrg} 20832001f49Smrg 20932001f49Smrgstatic void 21032001f49Smrgprintstring(void *font, char *string) 21132001f49Smrg{ 21232001f49Smrg int len, i; 21332001f49Smrg 21432001f49Smrg len = (int) strlen(string); 21532001f49Smrg for (i = 0; i < len; i++) 21632001f49Smrg glutBitmapCharacter(font, string[i]); 21732001f49Smrg} 21832001f49Smrg 21932001f49Smrgstatic void 22032001f49Smrgprinthelp(void) 22132001f49Smrg{ 22232001f49Smrg glEnable(GL_BLEND); 22332001f49Smrg glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 22432001f49Smrg glColor4f(0.0, 0.0, 0.0, 0.5); 22532001f49Smrg glRecti(40, 40, 600, 440); 22632001f49Smrg glDisable(GL_BLEND); 22732001f49Smrg 22832001f49Smrg glColor3f(1.0, 0.0, 0.0); 22932001f49Smrg glRasterPos2i(300, 420); 23032001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Help"); 23132001f49Smrg 23232001f49Smrg glRasterPos2i(60, 390); 23332001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "h - Toggle Help"); 23432001f49Smrg glRasterPos2i(60, 360); 23532001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "t - Toggle Textures"); 23632001f49Smrg glRasterPos2i(60, 330); 23732001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "f - Toggle Fog"); 23832001f49Smrg glRasterPos2i(60, 300); 23932001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "p - Wire frame"); 24032001f49Smrg glRasterPos2i(60, 270); 24132001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "b - Toggle Back face culling"); 24232001f49Smrg glRasterPos2i(60, 240); 24332001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Arrow Keys - Rotate"); 24432001f49Smrg glRasterPos2i(60, 210); 24532001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "a - Increase velocity"); 24632001f49Smrg glRasterPos2i(60, 180); 24732001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "z - Decrease velocity"); 24832001f49Smrg 24932001f49Smrg glRasterPos2i(60, 150); 25032001f49Smrg if (joyavailable) 25132001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, 25232001f49Smrg "j - Toggle jostick control (Joystick control available)"); 25332001f49Smrg else 25432001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, 25532001f49Smrg "(No Joystick control available)"); 25632001f49Smrg} 25732001f49Smrg 25832001f49Smrgstatic void 25932001f49Smrgdrawterrain(void) 26032001f49Smrg{ 26132001f49Smrg int h, i, idx, ox, oy; 26232001f49Smrg float j, k, start, end; 26332001f49Smrg 26432001f49Smrg ox = (int) (obs[0] / stepXmnt); 26532001f49Smrg oy = (int) (obs[2] / stepYmnt); 26632001f49Smrg GlobalMnt = ((ox * TSCALE) & 255) + ((oy * TSCALE) & 255) * 256; 26732001f49Smrg 26832001f49Smrg glPushMatrix(); 26932001f49Smrg glTranslatef((float) ox * stepXmnt, 0, (float) oy * stepYmnt); 27032001f49Smrg 27132001f49Smrg for (h = 0, k = -(lenghtYmnt * stepYmnt) / 2; h < lenghtYmnt; 27232001f49Smrg k += stepYmnt, h++) { 27332001f49Smrg if (!clipstrip(k, &start, &end)) 27432001f49Smrg continue; 27532001f49Smrg 27632001f49Smrg glBegin(GL_TRIANGLE_STRIP); /* I hope that the optimizer will be able to improve this code */ 27732001f49Smrg for (i = (int) (lenghtXmnt / 2 + start / stepXmnt), j = start; j <= end; 27832001f49Smrg j += stepXmnt, i++) { 27932001f49Smrg idx = (i * TSCALE + h * 256 * TSCALE + GlobalMnt) & 65535; 28032001f49Smrg glColor3fv(terraincolor[idx]); 28132001f49Smrg glTexCoord2f((ox + i) / 8.0, (oy + h) / 8.0); 28232001f49Smrg glVertex3f(j, terrain[idx], k); 28332001f49Smrg 28432001f49Smrg idx = 28532001f49Smrg (i * TSCALE + h * 256 * TSCALE + 256 * TSCALE + 28632001f49Smrg GlobalMnt) & 65535; 28732001f49Smrg glColor3fv(terraincolor[idx]); 28832001f49Smrg glTexCoord2f((ox + i) / 8.0, (oy + h + 1) / 8.0); 28932001f49Smrg glVertex3f(j, terrain[idx], k + stepYmnt); 29032001f49Smrg } 29132001f49Smrg glEnd(); 29232001f49Smrg } 29332001f49Smrg 29432001f49Smrg glDisable(GL_CULL_FACE); 29532001f49Smrg glDisable(GL_TEXTURE_2D); 29632001f49Smrg glEnable(GL_BLEND); 29732001f49Smrg glBegin(GL_QUADS); 29832001f49Smrg glColor4f(0.1, 0.7, 1.0, 0.4); 29932001f49Smrg glVertex3f(-(lenghtXmnt * stepXmnt) / 2.0, heightMnt * 0.6, 30032001f49Smrg -(lenghtYmnt * stepYmnt) / 2.0); 30132001f49Smrg glVertex3f(-(lenghtXmnt * stepXmnt) / 2.0, heightMnt * 0.6, 30232001f49Smrg (lenghtYmnt * stepYmnt) / 2.0); 30332001f49Smrg glVertex3f((lenghtXmnt * stepXmnt) / 2.0, heightMnt * 0.6, 30432001f49Smrg (lenghtYmnt * stepYmnt) / 2.0); 30532001f49Smrg glVertex3f((lenghtXmnt * stepXmnt) / 2.0, heightMnt * 0.6, 30632001f49Smrg -(lenghtYmnt * stepYmnt) / 2.0); 30732001f49Smrg glEnd(); 30832001f49Smrg glDisable(GL_BLEND); 30932001f49Smrg if (bfcull) 31032001f49Smrg glEnable(GL_CULL_FACE); 31132001f49Smrg glEnable(GL_TEXTURE_2D); 31232001f49Smrg 31332001f49Smrg glPopMatrix(); 31432001f49Smrg 31532001f49Smrg} 31632001f49Smrg 31732001f49Smrgstatic void 31832001f49Smrgdojoy(void) 31932001f49Smrg{ 32032001f49Smrg#ifdef WIN32 32132001f49Smrg static UINT max[2] = { 0, 0 }; 32232001f49Smrg static UINT min[2] = { 0xffffffff, 0xffffffff }, center[2]; 32332001f49Smrg MMRESULT res; 32432001f49Smrg JOYINFO joy; 32532001f49Smrg 32632001f49Smrg res = joyGetPos(JOYSTICKID1, &joy); 32732001f49Smrg 32832001f49Smrg if (res == JOYERR_NOERROR) { 32932001f49Smrg joyavailable = 1; 33032001f49Smrg 33132001f49Smrg if (max[0] < joy.wXpos) 33232001f49Smrg max[0] = joy.wXpos; 33332001f49Smrg if (min[0] > joy.wXpos) 33432001f49Smrg min[0] = joy.wXpos; 33532001f49Smrg center[0] = (max[0] + min[0]) / 2; 33632001f49Smrg 33732001f49Smrg if (max[1] < joy.wYpos) 33832001f49Smrg max[1] = joy.wYpos; 33932001f49Smrg if (min[1] > joy.wYpos) 34032001f49Smrg min[1] = joy.wYpos; 34132001f49Smrg center[1] = (max[1] + min[1]) / 2; 34232001f49Smrg 34332001f49Smrg if (joyactive) { 34432001f49Smrg if (fabs(center[0] - (float) joy.wXpos) > 0.1 * (max[0] - min[0])) 34532001f49Smrg alpha += 34632001f49Smrg 2.5 * (center[0] - (float) joy.wXpos) / (max[0] - min[0]); 34732001f49Smrg if (fabs(center[1] - (float) joy.wYpos) > 0.1 * (max[1] - min[1])) 34832001f49Smrg beta += 2.5 * (center[1] - (float) joy.wYpos) / (max[1] - min[1]); 34932001f49Smrg 35032001f49Smrg if (joy.wButtons & JOY_BUTTON1) 35132001f49Smrg v += 0.5; 35232001f49Smrg if (joy.wButtons & JOY_BUTTON2) 35332001f49Smrg v -= 0.5; 35432001f49Smrg } 35532001f49Smrg } 35632001f49Smrg else 35732001f49Smrg joyavailable = 0; 35832001f49Smrg#endif 35932001f49Smrg} 36032001f49Smrg 36132001f49Smrgstatic void 36232001f49Smrgdrawscene(void) 36332001f49Smrg{ 36432001f49Smrg static char frbuf[80] = ""; 36532001f49Smrg 36632001f49Smrg dojoy(); 36732001f49Smrg 36832001f49Smrg glShadeModel(GL_SMOOTH); 36932001f49Smrg glEnable(GL_DEPTH_TEST); 37032001f49Smrg 37132001f49Smrg if (usetex) 37232001f49Smrg glEnable(GL_TEXTURE_2D); 37332001f49Smrg else 37432001f49Smrg glDisable(GL_TEXTURE_2D); 37532001f49Smrg 37632001f49Smrg if (fog) 37732001f49Smrg glEnable(GL_FOG); 37832001f49Smrg else 37932001f49Smrg glDisable(GL_FOG); 38032001f49Smrg 38132001f49Smrg glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 38232001f49Smrg 38332001f49Smrg glPushMatrix(); 38432001f49Smrg 38532001f49Smrg calcposobs(); 38632001f49Smrg gluLookAt(obs[0], obs[1], obs[2], 38732001f49Smrg obs[0] + dir[0], obs[1] + dir[1], obs[2] + dir[2], 38832001f49Smrg 0.0, 1.0, 0.0); 38932001f49Smrg 39032001f49Smrg drawterrain(); 39132001f49Smrg glPopMatrix(); 39232001f49Smrg 39332001f49Smrg glDisable(GL_TEXTURE_2D); 39432001f49Smrg glDisable(GL_DEPTH_TEST); 39532001f49Smrg glDisable(GL_FOG); 39632001f49Smrg glShadeModel(GL_FLAT); 39732001f49Smrg 39832001f49Smrg glMatrixMode(GL_PROJECTION); 39932001f49Smrg glLoadIdentity(); 40032001f49Smrg glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0); 40132001f49Smrg glMatrixMode(GL_MODELVIEW); 40232001f49Smrg glLoadIdentity(); 40332001f49Smrg 40432001f49Smrg glColor3f(1.0, 0.0, 0.0); 40532001f49Smrg glRasterPos2i(10, 10); 40632001f49Smrg printstring(GLUT_BITMAP_HELVETICA_18, frbuf); 40732001f49Smrg glRasterPos2i(350, 470); 40832001f49Smrg printstring(GLUT_BITMAP_HELVETICA_10, 40932001f49Smrg "Terrain V1.2 Written by David Bucciarelli (tech.hmw@plus.it)"); 41032001f49Smrg glRasterPos2i(434, 457); 41132001f49Smrg printstring(GLUT_BITMAP_HELVETICA_10, 41232001f49Smrg "Based on a Mickael's demo (Skizo@Hol.Fr)"); 41332001f49Smrg 41432001f49Smrg if (help) 41532001f49Smrg printhelp(); 41632001f49Smrg 41732001f49Smrg reshape(scrwidth, scrheight); 41832001f49Smrg 41932001f49Smrg glutSwapBuffers(); 42032001f49Smrg 42132001f49Smrg Frames++; 42232001f49Smrg { 42332001f49Smrg GLint t = glutGet(GLUT_ELAPSED_TIME); 42432001f49Smrg if (t - T0 >= 2000) { 42532001f49Smrg GLfloat seconds = (t - T0) / 1000.0; 42632001f49Smrg GLfloat fps = Frames / seconds; 42732001f49Smrg sprintf(frbuf, "Frame rate: %f", fps); 42832001f49Smrg printf("%s\n", frbuf); 4297ec3b29aSmrg fflush(stdout); 43032001f49Smrg T0 = t; 43132001f49Smrg Frames = 0; 43232001f49Smrg } 43332001f49Smrg } 43432001f49Smrg} 43532001f49Smrg 43632001f49Smrgstatic void 43732001f49Smrgkey(unsigned char k, int x, int y) 43832001f49Smrg{ 43932001f49Smrg switch (k) { 44032001f49Smrg case 27: 44132001f49Smrg exit(0); 44232001f49Smrg break; 44332001f49Smrg case 'a': 44432001f49Smrg v += 50.; 44532001f49Smrg break; 44632001f49Smrg case 'z': 44732001f49Smrg v -= 50.; 44832001f49Smrg break; 44932001f49Smrg case 'p': 45032001f49Smrg if (poutline) { 45132001f49Smrg glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 45232001f49Smrg poutline = 0; 45332001f49Smrg } 45432001f49Smrg else { 45532001f49Smrg glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 45632001f49Smrg poutline = 1; 45732001f49Smrg } 45832001f49Smrg break; 45932001f49Smrg case 'j': 46032001f49Smrg joyactive = (!joyactive); 46132001f49Smrg break; 46232001f49Smrg case 'h': 46332001f49Smrg help = (!help); 46432001f49Smrg break; 46532001f49Smrg case 'f': 46632001f49Smrg fog = (!fog); 46732001f49Smrg break; 46832001f49Smrg case 't': 46932001f49Smrg usetex = (!usetex); 47032001f49Smrg break; 47132001f49Smrg case 'b': 47232001f49Smrg if (bfcull) { 47332001f49Smrg glDisable(GL_CULL_FACE); 47432001f49Smrg bfcull = 0; 47532001f49Smrg } 47632001f49Smrg else { 47732001f49Smrg glEnable(GL_CULL_FACE); 47832001f49Smrg bfcull = 1; 47932001f49Smrg } 48032001f49Smrg break; 48132001f49Smrg#ifdef XMESA 48232001f49Smrg case ' ': 48332001f49Smrg XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW); 48432001f49Smrg fullscreen = (!fullscreen); 48532001f49Smrg break; 48632001f49Smrg#endif 48732001f49Smrg } 48832001f49Smrg} 48932001f49Smrg 49032001f49Smrgstatic void 49132001f49Smrgspecial(int k, int x, int y) 49232001f49Smrg{ 49332001f49Smrg switch (k) { 49432001f49Smrg case GLUT_KEY_LEFT: 49532001f49Smrg alpha += 2.0; 49632001f49Smrg break; 49732001f49Smrg case GLUT_KEY_RIGHT: 49832001f49Smrg alpha -= 2.0; 49932001f49Smrg break; 50032001f49Smrg case GLUT_KEY_DOWN: 50132001f49Smrg beta -= 2.0; 50232001f49Smrg break; 50332001f49Smrg case GLUT_KEY_UP: 50432001f49Smrg beta += 2.0; 50532001f49Smrg break; 50632001f49Smrg } 50732001f49Smrg} 50832001f49Smrg 50932001f49Smrgstatic void 51032001f49Smrgcalccolor(GLfloat height, GLfloat c[3]) 51132001f49Smrg{ 51232001f49Smrg GLfloat color[4][3] = { 51332001f49Smrg {1.0, 1.0, 1.0}, 51432001f49Smrg {0.0, 0.8, 0.0}, 51532001f49Smrg {1.0, 1.0, 0.3}, 51632001f49Smrg {0.0, 0.0, 0.8} 51732001f49Smrg }; 51832001f49Smrg GLfloat fact; 51932001f49Smrg 52032001f49Smrg height = height * (1.0 / 255.0); 52132001f49Smrg 52232001f49Smrg if (height >= 0.9) { 52332001f49Smrg c[0] = color[0][0]; 52432001f49Smrg c[1] = color[0][1]; 52532001f49Smrg c[2] = color[0][2]; 52632001f49Smrg return; 52732001f49Smrg } 52832001f49Smrg 52932001f49Smrg if ((height < 0.9) && (height >= 0.7)) { 53032001f49Smrg fact = (height - 0.7) * 5.0; 53132001f49Smrg c[0] = fact * color[0][0] + (1.0 - fact) * color[1][0]; 53232001f49Smrg c[1] = fact * color[0][1] + (1.0 - fact) * color[1][1]; 53332001f49Smrg c[2] = fact * color[0][2] + (1.0 - fact) * color[1][2]; 53432001f49Smrg return; 53532001f49Smrg } 53632001f49Smrg 53732001f49Smrg if ((height < 0.7) && (height >= 0.6)) { 53832001f49Smrg fact = (height - 0.6) * 10.0; 53932001f49Smrg c[0] = fact * color[1][0] + (1.0 - fact) * color[2][0]; 54032001f49Smrg c[1] = fact * color[1][1] + (1.0 - fact) * color[2][1]; 54132001f49Smrg c[2] = fact * color[1][2] + (1.0 - fact) * color[2][2]; 54232001f49Smrg return; 54332001f49Smrg } 54432001f49Smrg 54532001f49Smrg if ((height < 0.6) && (height >= 0.5)) { 54632001f49Smrg fact = (height - 0.5) * 10.0; 54732001f49Smrg c[0] = fact * color[2][0] + (1.0 - fact) * color[3][0]; 54832001f49Smrg c[1] = fact * color[2][1] + (1.0 - fact) * color[3][1]; 54932001f49Smrg c[2] = fact * color[2][2] + (1.0 - fact) * color[3][2]; 55032001f49Smrg return; 55132001f49Smrg } 55232001f49Smrg 55332001f49Smrg c[0] = color[3][0]; 55432001f49Smrg c[1] = color[3][1]; 55532001f49Smrg c[2] = color[3][2]; 55632001f49Smrg} 55732001f49Smrg 55832001f49Smrgstatic void 55932001f49Smrgloadpic(void) 56032001f49Smrg{ 56132001f49Smrg GLubyte bufferter[256 * 256], terrainpic[256 * 256]; 56232001f49Smrg FILE *FilePic; 56332001f49Smrg int i, tmp; 56432001f49Smrg GLenum gluerr; 56532001f49Smrg size_t result; 56632001f49Smrg 56732001f49Smrg if ((FilePic = fopen(DEMOS_DATA_DIR "terrain.dat", "r")) == NULL) { 56832001f49Smrg fprintf(stderr, "Error loading terrain.dat\n"); 56932001f49Smrg exit(-1); 57032001f49Smrg } 57132001f49Smrg result = fread(bufferter, 256 * 256, 1, FilePic); 57232001f49Smrg assert(result == 1); 57332001f49Smrg fclose(FilePic); 57432001f49Smrg 57532001f49Smrg for (i = 0; i < (256 * 256); i++) { 57632001f49Smrg terrain[i] = (bufferter[i] * (heightMnt / 255.0f)); 57732001f49Smrg calccolor((GLfloat) bufferter[i], terraincolor[i]); 57832001f49Smrg tmp = (((int) bufferter[i]) + 96); 57932001f49Smrg terrainpic[i] = (tmp > 255) ? 255 : tmp; 58032001f49Smrg } 58132001f49Smrg 58232001f49Smrg glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 58332001f49Smrg if ((gluerr = gluBuild2DMipmaps(GL_TEXTURE_2D, 1, 256, 256, GL_LUMINANCE, 58432001f49Smrg GL_UNSIGNED_BYTE, 58532001f49Smrg (GLvoid *) (&terrainpic[0])))) { 58632001f49Smrg fprintf(stderr, "GLULib%s\n", (char *) gluErrorString(gluerr)); 58732001f49Smrg exit(-1); 58832001f49Smrg } 58932001f49Smrg 59032001f49Smrg glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 59132001f49Smrg glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 59232001f49Smrg 59332001f49Smrg glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 59432001f49Smrg GL_LINEAR_MIPMAP_LINEAR); 59532001f49Smrg glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 59632001f49Smrg 59732001f49Smrg glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 59832001f49Smrg glEnable(GL_TEXTURE_2D); 59932001f49Smrg} 60032001f49Smrg 60132001f49Smrgstatic void 60232001f49Smrginit(void) 60332001f49Smrg{ 60432001f49Smrg float fogcolor[4] = { 0.6, 0.7, 0.7, 1.0 }; 60532001f49Smrg 60632001f49Smrg glClearColor(fogcolor[0], fogcolor[1], fogcolor[2], fogcolor[3]); 60732001f49Smrg glClearDepth(1.0); 60832001f49Smrg glDepthFunc(GL_LEQUAL); 60932001f49Smrg glShadeModel(GL_SMOOTH); 61032001f49Smrg glEnable(GL_DEPTH_TEST); 61132001f49Smrg glEnable(GL_CULL_FACE); 61232001f49Smrg 61332001f49Smrg glDisable(GL_BLEND); 61432001f49Smrg glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 61532001f49Smrg 61632001f49Smrg glEnable(GL_FOG); 61732001f49Smrg glFogi(GL_FOG_MODE, GL_EXP2); 61832001f49Smrg glFogfv(GL_FOG_COLOR, fogcolor); 61932001f49Smrg glFogf(GL_FOG_DENSITY, 0.0007); 62032001f49Smrg#ifdef FX 62132001f49Smrg glHint(GL_FOG_HINT, GL_NICEST); 62232001f49Smrg#endif 62332001f49Smrg 62432001f49Smrg reshape(scrwidth, scrheight); 62532001f49Smrg} 62632001f49Smrg 62732001f49Smrg 62832001f49Smrgint 62932001f49Smrgmain(int ac, char **av) 63032001f49Smrg{ 63132001f49Smrg glutInitWindowSize(WIDTH, HEIGHT); 63232001f49Smrg glutInit(&ac, av); 63332001f49Smrg 63432001f49Smrg glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); 63532001f49Smrg 63632001f49Smrg if (!(win = glutCreateWindow("Terrain"))) { 63732001f49Smrg fprintf(stderr, "Error, couldn't open window\n"); 63832001f49Smrg return -1; 63932001f49Smrg } 64032001f49Smrg 64132001f49Smrg ModZMnt = 0.0f; 64232001f49Smrg loadpic(); 64332001f49Smrg 64432001f49Smrg init(); 64532001f49Smrg 64632001f49Smrg#ifndef FX 64732001f49Smrg glDisable(GL_TEXTURE_2D); 64832001f49Smrg usetex = 0; 64932001f49Smrg#endif 65032001f49Smrg 65132001f49Smrg glutReshapeFunc(reshape); 65232001f49Smrg glutDisplayFunc(drawscene); 65332001f49Smrg glutKeyboardFunc(key); 65432001f49Smrg glutSpecialFunc(special); 65532001f49Smrg glutIdleFunc(drawscene); 65632001f49Smrg 65732001f49Smrg glutMainLoop(); 65832001f49Smrg 65932001f49Smrg return 0; 66032001f49Smrg} 661