21 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
22 |
*/ |
*/ |
23 |
|
|
|
#include <stdlib.h> |
|
|
#include <stdio.h> |
|
|
#include <string.h> |
|
|
#include <GL/glut.h> |
|
|
#include <Foundation/Foundation.h> |
|
|
#include <errno.h> |
|
|
|
|
|
#include "Common/Coord.h" |
|
24 |
#include "Common/Camera.h" |
#include "Common/Camera.h" |
|
|
|
25 |
#include "Map/Sea/SeaDisplay.h" |
#include "Map/Sea/SeaDisplay.h" |
26 |
|
#include "Common/Testing.h" |
27 |
|
|
28 |
|
static SeaDisplay *_sea; |
29 |
|
static double _speed = 1.0; |
30 |
|
static BOOL _pause = NO; |
31 |
|
|
32 |
static const GLfloat lightAmbient[] = { 0.75f, 0.75f, 0.75f, 1.0f }; |
void |
33 |
static const GLfloat lightDiffuse[] = { 0.7f, 0.7f, 0.7f, 1.0f }; |
testing_display (Camera *camera) |
|
//static const GLfloat lightPosition[] = { 50.0f, 100.0f, 50.0f}; |
|
|
static const GLfloat lightPosition[] = { 0.0f, 10.0f, 0.0f}; |
|
|
static const GLfloat lightSpecular[] = {0.0, 0.0, 0.0}; |
|
|
|
|
|
Camera *cam; |
|
|
Camera *camCopy; |
|
|
SeaDisplay * sea; |
|
|
double speed = 1.0; |
|
|
unsigned char modePlein=1; /* Affichage en mode plein ou fil de fer */ |
|
|
int pause=0; |
|
|
int repere=0; |
|
|
coord_t initEye; |
|
|
coord_t initCenter;// = MakeCoord (60.0, 30.0, 0.0); |
|
|
coord_t initUp;// = MakeCoord (0.0, 1.0, 0.0); |
|
|
|
|
|
/* Prototypes des fonctions */ |
|
|
|
|
|
void init(); |
|
|
void affichage(); |
|
|
void clavier(unsigned char touche,int x,int y); |
|
|
void redim(int l,int h); |
|
|
void creeRepere(); |
|
|
|
|
|
//FPS utilities |
|
|
int frame,t,timebase=0; |
|
|
char s[100]; |
|
|
|
|
|
|
|
|
int main(int argc, char **argv) |
|
|
{ |
|
|
CREATE_AUTORELEASE_POOL(pool); |
|
|
|
|
|
initEye = MakeCoord (100.0, 100.0, 400.0); |
|
|
initCenter = MakeCoord (100.0, 100.0, 0.0); |
|
|
initUp = MakeCoord (0.0, 1.0, 0.0); |
|
|
|
|
|
sea = [[SeaDisplay alloc] |
|
|
initWithGridLength2Exponent: (u_int8_t) 5//7 |
|
|
realLength: 200.0//1500.0 |
|
|
windVector: MakePlaneCoord (22.0, 24.0)//54.0) |
|
|
wavesHeightFactor: 15.0 |
|
|
seaLevel: 0.0]; |
|
|
|
|
|
|
|
|
/* Initialisation de glut */ |
|
|
glutInit(&argc,argv); |
|
|
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); |
|
|
glutInitWindowSize(1400,1400); |
|
|
glutCreateWindow(argv[0]); |
|
|
|
|
|
/*Initialisation d'OpenGL */ |
|
|
init(); |
|
|
|
|
|
creeRepere(); |
|
|
|
|
|
glutMainLoop(); |
|
|
|
|
|
[sea dealloc]; |
|
|
RELEASE(pool); |
|
|
|
|
|
return 0; |
|
|
} |
|
|
|
|
|
|
|
|
/* Initialisation d'openGL */ |
|
|
void init() |
|
|
{ |
|
|
cam = [Camera alloc]; |
|
|
[cam initWithFovy: 50.0 |
|
|
aspect: 1.0 |
|
|
zNear: 1.0 //better |
|
|
zFar: 750.0 |
|
|
eye: initEye |
|
|
center: initCenter |
|
|
up: initUp]; |
|
|
|
|
|
/* gl options activated */ |
|
|
glEnable(GL_LIGHTING); // Enable Lighting |
|
|
glEnable(GL_LIGHT0); // Enable Light Number #0 |
|
|
glLightfv (GL_LIGHT0, GL_AMBIENT, lightAmbient ); |
|
|
glLightfv (GL_LIGHT0, GL_DIFFUSE, lightDiffuse ); |
|
|
glLightfv (GL_LIGHT0, GL_SPECULAR, lightSpecular); |
|
|
|
|
|
//glClearColor(0.,0.,0.,1.0); |
|
|
glClearColor(0.,0.,0.,1.0); |
|
|
glEnable(GL_DEPTH_TEST); |
|
|
if (modePlein) |
|
|
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); |
|
|
else |
|
|
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); |
|
|
|
|
|
glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); |
|
|
|
|
|
|
|
|
/* openGL options */ |
|
|
|
|
|
// glPushAttrib (GL_ALL_ATTRIB_BITS); |
|
|
glEnable (GL_DEPTH_TEST); |
|
|
glShadeModel (GL_SMOOTH); |
|
|
glEnable (GL_NORMALIZE); |
|
|
glEnable (GL_ALPHA_TEST); |
|
|
glEnable (GL_COLOR_MATERIAL); |
|
|
|
|
|
/* Mise en place des fonctions de rappel */ |
|
|
glutDisplayFunc(affichage); |
|
|
glutKeyboardFunc(clavier); |
|
|
glutReshapeFunc(redim); |
|
|
} |
|
|
|
|
|
/* Fonction de rappel pour l'affichage */ |
|
|
void affichage() |
|
34 |
{ |
{ |
35 |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
if (!_pause) |
|
glLoadIdentity(); |
|
|
|
|
|
glLightfv( GL_LIGHT0, GL_POSITION, lightPosition ); |
|
|
|
|
|
//FPS displaying |
|
|
frame++; |
|
|
t = glutGet(GLUT_ELAPSED_TIME); |
|
|
if (t - timebase > 1000) |
|
|
{ |
|
|
sprintf(s, "FPS:%4.2f", frame * 1000.0 / (t - timebase)); |
|
|
glutSetWindowTitle(s); |
|
|
timebase = t; |
|
|
frame = 0; |
|
|
} |
|
|
|
|
|
gluLookAt((GLdouble)[cam eye].x, |
|
|
(GLdouble)[cam eye].y, |
|
|
(GLdouble)[cam eye].z, |
|
|
(GLdouble)[cam center].x, |
|
|
(GLdouble)[cam center].y, |
|
|
(GLdouble)[cam center].z, |
|
|
(GLdouble)[cam up].x, |
|
|
(GLdouble)[cam up].y, |
|
|
(GLdouble)[cam up].z); |
|
|
|
|
|
if (!pause) |
|
36 |
{ |
{ |
37 |
double time = speed * (double)glutGet(GLUT_ELAPSED_TIME) / 1000.0; |
const double time |
38 |
[sea updateAtTime: time]; |
= _speed * [[NSDate date] timeIntervalSinceReferenceDate]; |
39 |
|
[_sea updateAtTime: time]; |
40 |
} |
} |
|
[sea displayWithCamera: cam]; |
|
|
// [sea displayNormals]; |
|
41 |
|
|
42 |
glCallList(repere); |
[_sea displayWithCamera: camera]; |
|
|
|
|
glFlush(); |
|
|
glutSwapBuffers (); |
|
|
glutPostRedisplay (); |
|
43 |
} |
} |
44 |
|
|
45 |
/* Fonction de rappel pour le clavier */ |
void |
46 |
void clavier(unsigned char touche,int x,int y) |
testing_keyboard (unsigned char key,int x,int y) |
47 |
{ |
{ |
48 |
switch (touche) { |
switch (key) |
49 |
case 27: /* touche 'ESC' pour quitter */ |
{ |
50 |
[sea dealloc]; |
case 'p': |
51 |
exit(0); |
_pause = !_pause; |
52 |
|
break; |
53 |
case 'p': /* pause */ |
|
54 |
pause = !pause; |
case '+': |
55 |
break; |
[_sea setSeaLevel: [_sea seaLevel] + 1.0]; |
56 |
|
break; |
57 |
case 'q': |
case '-': |
58 |
[cam strafLeft: 1.0]; |
[_sea setSeaLevel: [_sea seaLevel] - 1.0]; |
59 |
break; |
break; |
60 |
case 'd': |
|
61 |
[cam strafRight: 1.0]; |
case 'b': |
62 |
break; |
_speed *= 0.95; |
63 |
case 'z': |
break; |
64 |
[cam forward: 1.0]; |
|
65 |
break; |
case 'n': |
66 |
case 's': |
_speed *= 1.05; |
67 |
[cam backward: 1.0]; |
break; |
68 |
break; |
|
69 |
case 'a': |
default: |
70 |
[cam moveUp: 1.0]; |
break; |
|
break; |
|
|
case 'e': |
|
|
[cam moveDown: 1.0]; |
|
|
break; |
|
|
|
|
|
case 'h': |
|
|
[cam rotateHeading: 2.0]; |
|
|
break; |
|
|
case 'k': |
|
|
[cam rotateHeading: -2.0]; |
|
|
break; |
|
|
case 'u': |
|
|
[cam rotatePitch: 1.0]; |
|
|
break; |
|
|
case 'j': |
|
|
[cam rotatePitch: -1.0]; |
|
|
break; |
|
|
case 'y': |
|
|
[cam rotateRoll: -1.0]; |
|
|
break; |
|
|
case 'i': |
|
|
[cam rotateRoll: 1.0]; |
|
|
break; |
|
|
|
|
|
case 'o': |
|
|
[cam rotateAroundViewHeading: 1.0]; |
|
|
break; |
|
|
|
|
|
case 't': |
|
|
[cam rotateAroundViewHeading: -1.0]; |
|
|
break; |
|
|
|
|
|
case ' ': /* reinitialize */ |
|
|
[cam setEye: initEye]; |
|
|
[cam setCenter: initCenter]; |
|
|
[cam setUp: initUp]; |
|
|
break; |
|
|
|
|
|
case '+': |
|
|
[sea setSeaLevel: [sea seaLevel] + 1.0]; |
|
|
break; |
|
|
case '-': |
|
|
[sea setSeaLevel: [sea seaLevel] - 1.0]; |
|
|
break; |
|
|
|
|
|
case 'f': |
|
|
modePlein=1-modePlein; |
|
|
if (modePlein) |
|
|
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); |
|
|
else |
|
|
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); |
|
|
break; |
|
|
|
|
|
case 'x': |
|
|
[cam setAspect: [cam aspect]*0.9]; |
|
|
printf("aspect: %f\nfovx: %f\nfovy: %f\n", |
|
|
[cam aspect], |
|
|
[cam fovx], [cam fovy]); |
|
|
break; |
|
|
|
|
|
case 'b': |
|
|
speed *= 0.95; |
|
|
break; |
|
|
|
|
|
case 'n': |
|
|
speed *= 1.05; |
|
|
break; |
|
|
|
|
|
default: |
|
|
break; |
|
71 |
} |
} |
|
|
|
|
glutPostRedisplay(); |
|
72 |
} |
} |
73 |
|
|
74 |
|
void |
75 |
/* Fonction de rappel pour le redimensionnement de fenetre */ |
testing_special (int key, int x, int y) |
|
void redim(int l,int h) |
|
76 |
{ |
{ |
|
/* Mise en place de la perspective */ |
|
|
glMatrixMode(GL_PROJECTION); |
|
|
glLoadIdentity(); |
|
|
gluPerspective((GLdouble) [cam fovy], |
|
|
(GLdouble) [cam aspect], |
|
|
(GLdouble) [cam zNear], |
|
|
(GLdouble) ([cam zFar])); |
|
|
glMatrixMode(GL_MODELVIEW); |
|
|
|
|
|
if (l<h) |
|
|
glViewport(0,(h-l)/2,l,l); |
|
|
else |
|
|
glViewport((l-h)/2,0,h,h); |
|
77 |
} |
} |
78 |
|
|
79 |
/* Creation de la liste d'affichage pour le repere */ |
void |
80 |
void creeRepere() |
testing_init (void) |
81 |
{ |
{ |
82 |
repere=glGenLists(1); |
_sea = [[SeaDisplay alloc] |
83 |
glNewList(repere,GL_COMPILE); |
initWithGridLength2Exponent: (u_int8_t) 5//7 |
84 |
glDisable(GL_LIGHTING); |
realLength: 200.0//1500.0 |
85 |
glLineWidth(2.0); |
windVector: MakePlaneCoord (22.0, 24.0)//54.0) |
86 |
GLfloat lineLength = 30.0; |
wavesHeightFactor: 15.0 |
87 |
glBegin(GL_LINES); |
ground: nil |
88 |
glColor3f(1.0,0.0,0.0); |
seaLevel: 0.0]; |
89 |
glVertex3f(0.0,0.0,0.0); |
} |
|
glVertex3f(lineLength,0.0,0.0); |
|
|
|
|
|
glColor3f(0.0,1.0,0.0); |
|
|
glVertex3f(0.0,0.0,0.0); |
|
|
glVertex3f(0.0,lineLength,0.0); |
|
|
|
|
|
glColor3f(0.0,0.0,1.0); |
|
|
glVertex3f(0.0,0.0,0.0); |
|
|
glVertex3f(0.0,0.0,lineLength); |
|
|
glEnd(); |
|
|
glEnable(GL_LIGHTING); |
|
|
glLineWidth(1.0); |
|
|
glEndList(); |
|
|
} |
|