00001
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "Display.h"
00026
00027 #include <cstdlib>
00028 #include <cmath>
00029
00030 #include "Constants.h"
00031 #include "Accum.h"
00032 #include "Jitter.h"
00033
00039 void display_timer(int value) {
00040 Display::instance()->timer(value);
00041 }
00042
00043 Display* Display::_instance = NULL;
00044
00045 Display::Display() : _world(12, 12, 2) {
00046
00047 _center_x = (GLint) (_world.getWidth() / 2) * CELL_SIZE;
00048 _center_y = 0;
00049 _center_z = (GLint) (_world.getHeight() / 2) * CELL_SIZE;
00050
00051
00052 _camera_x = (GLint) _center_x;
00053 _camera_y = (GLint) HEIGHT_MAX / 4;
00054 _camera_z = (GLint) _center_z + 3 * CELL_SIZE;
00055
00056
00057 _near = 0.1;
00058 _far = HORIZON;
00059
00060
00061 _fovy = 45.0;
00062
00063
00064 _timer = true;
00065 glutTimerFunc(REDISPLAY_NB_MILLI_SEC, display_timer, 0);
00066 }
00067
00068 GLfloat Display::focal_distance() {
00069 return sqrt((_camera_x - _center_x) * (_camera_x - _center_x) +
00070 (_camera_y - _center_y) * (_camera_y - _center_y) +
00071 (_camera_y - _center_y) * (_camera_y - _center_y));
00072 }
00073
00074 void Display::translate_camera(GLfloat inc_x, GLfloat inc_z) {
00075 GLfloat tmp_x = _center_x + inc_x;
00076 GLfloat tmp_z = _center_z + inc_z;
00077
00078 if(tmp_x > 0.0 && tmp_x < (_world.getWidth() - 1.0) * CELL_SIZE &&
00079 tmp_z > 0.0 && tmp_z < (_world.getHeight() - 1.0) * CELL_SIZE) {
00080 _camera_x += inc_x;
00081 _center_x = tmp_x;
00082 _camera_z += inc_z;
00083 _center_z = tmp_z;
00084 glutPostRedisplay();
00085 }
00086 }
00087
00088 void Display::move_camera(GLfloat inc_y) {
00089 GLfloat tmp_y = _camera_y + inc_y;
00090
00091 if(tmp_y >= HEIGHT_MIN && tmp_y <= HEIGHT_MAX) {
00092 _camera_y += inc_y;
00093 glutPostRedisplay();
00094 }
00095 }
00096
00097 void Display::zoom_camera(GLfloat inc) {
00098 GLfloat tmp = focal_distance();
00099
00100 if(_camera_y + inc >= HEIGHT_MIN && _camera_y + inc <= HEIGHT_MAX) {
00101 _camera_x = ((_camera_x - _center_x) * (1 + inc / tmp)) + _center_x;
00102 _camera_y = ((_camera_y - _center_y) * (1 + inc / tmp)) + _center_y;
00103 _camera_z = ((_camera_z - _center_z) * (1 + inc / tmp)) + _center_z;
00104 glutPostRedisplay();
00105 }
00106 }
00107
00108 void Display::rotate_camera(GLfloat inc) {
00109 GLfloat tmp = _camera_x;
00110 _camera_x = ((_camera_x - _center_x) * cos(inc) -
00111 (_camera_z - _center_z) * sin(inc)) + _center_x;
00112 _camera_z = ((tmp - _center_x) * sin(inc) +
00113 (_camera_z - _center_z) * cos(inc)) + _center_z;
00114 glutPostRedisplay();
00115 }
00116
00117 Display::~Display() {
00118 destroy();
00119 }
00120
00121 Display* Display::instance() {
00122 if(_instance == NULL) {
00123 _instance = new Display();
00124 }
00125
00126 return _instance;
00127 }
00128
00129 void Display::destroy() {
00130 if(_instance != NULL) {
00131 delete _instance;
00132 _instance = NULL;
00133 }
00134 }
00135
00136 void Display::init() {
00137
00138 GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0};
00139 GLfloat mat_shininess[] = {100.0};
00140 GLfloat white_light[] = {1.0, 1.0, 1.0, 1.0};
00141 GLfloat light_position[] = {
00142 _world.getWidth() / 2.0,
00143 HEIGHT_MAX,
00144 _world.getHeight() / 2.0,
00145 0.0
00146 };
00147
00148
00149 glClearColor(0.0, 0.0, 0.0, 1.0);
00150
00151
00152 glShadeModel(GL_FLAT);
00153
00154
00155 glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
00156 glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
00157
00158
00159 glLightfv(GL_LIGHT0, GL_POSITION, light_position);
00160 glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);
00161 glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);
00162
00163
00164 glEnable(GL_LIGHTING);
00165 glEnable(GL_LIGHT0);
00166
00167
00168 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00169 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
00170
00171
00172 glEnable(GL_COLOR_MATERIAL);
00173
00174
00175 glClearDepth(1.0);
00176 glDepthFunc(GL_LESS);
00177 glEnable(GL_DEPTH_TEST);
00178
00179
00180 glEnable(GL_AUTO_NORMAL);
00181 glEnable(GL_NORMALIZE);
00182 }
00183
00184 void Display::quit() {
00185
00186 }
00187
00188 void Display::timer(int value) {
00189 _world.iteration();
00190 glutPostRedisplay();
00191 if(_timer) {
00192
00193 glutTimerFunc(REDISPLAY_NB_MILLI_SEC, display_timer, 0);
00194 }
00195 }
00196
00197 void Display::draw() {
00198 GLint viewport[4];
00199 GLdouble ratio;
00200 int nb_steps = j[ANTIALIASING_LEVEL].nb;
00201 GLdouble step = 1.0 / nb_steps;
00202 jitter_point* jp = j[ANTIALIASING_LEVEL].jitter_points;
00203 int jitter;
00204
00205
00206 glGetIntegerv(GL_VIEWPORT, viewport);
00207
00208 ratio = (GLdouble) viewport[2] / (GLdouble) viewport[3];
00209
00210
00211 glClear(GL_ACCUM_BUFFER_BIT);
00212 for(jitter = 0; jitter < nb_steps; jitter++) {
00213 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
00214
00215
00216
00217 accPerspective(_fovy, ratio, _near, _far,
00218 jp[jitter].x, jp[jitter].y,
00219 0.0, 0.0, 1.0);
00220
00221
00222 glMatrixMode(GL_MODELVIEW);
00223
00224
00225 glLoadIdentity();
00226
00227 gluLookAt(_camera_x, _camera_y, _camera_z,
00228 _center_x, _center_y, _center_z,
00229 0.0, 1.0, 0.0);
00230
00231
00232 glColor3ub((GLubyte) (0.7 * COLOR_MAX), COLOR_MAX, COLOR_MAX);
00233 glPushMatrix();
00234 glTranslatef(_center_x, _center_y + 0.01 * CELL_SIZE, _center_z);
00235 glRotatef(90.0, 1.0, 0.0, 0.0);
00236 glutSolidTorus (0.03 * CELL_SIZE, 0.75 * CELL_SIZE,
00237 CELL_SIZE, 5 * CELL_SIZE);
00238 glPopMatrix();
00239
00240
00241 _world.draw();
00242
00243
00244 glAccum(GL_ACCUM, step);
00245 }
00246
00247
00248 glAccum(GL_RETURN, 1.0);
00249
00250
00251 glutSwapBuffers();
00252 }
00253
00254 void Display::reshape(int width, int height) {
00255
00256 if (height == 0)
00257 height = 1;
00258
00259
00260 glViewport(0, 0, width, height);
00261
00262
00263 glMatrixMode(GL_PROJECTION);
00264
00265
00266 glLoadIdentity();
00267 gluPerspective(_fovy, (float) width / height, _near, _far);
00268
00269
00270 glMatrixMode(GL_MODELVIEW);
00271 }
00272
00273 void Display::inputKey(unsigned char key, int x, int y) {
00274 GLint specialKey = glutGetModifiers();
00275
00276 switch(key) {
00277 case TRANSLATE_LEFT :
00278 translate_camera(-CELL_SIZE, 0.0);
00279 break;
00280 case TRANSLATE_RIGHT :
00281 translate_camera(CELL_SIZE, 0.0);;
00282 break;
00283 case TRANSLATE_UP :
00284 translate_camera(0.0, -CELL_SIZE);
00285 break;
00286 case TRANSLATE_DOWN :
00287 translate_camera(0.0, CELL_SIZE);
00288 break;
00289 case ZOOM_IN :
00290 if(specialKey == GLUT_ACTIVE_CTRL) {
00291 move_camera(MOVE_UP_SPEED);
00292 } else {
00293 zoom_camera(-ZOOM_SPEED);
00294 }
00295 break;
00296 case ZOOM_OUT :
00297 if(specialKey == GLUT_ACTIVE_CTRL) {
00298 move_camera(-MOVE_UP_SPEED);
00299 } else {
00300 zoom_camera(ZOOM_SPEED);
00301 }
00302 break;
00303 case ROTATE_LEFT :
00304 rotate_camera(-ROTATE_ANGLE);
00305 break;
00306 case ROTATE_RIGHT :
00307 rotate_camera(ROTATE_ANGLE);
00308 break;
00309 case PAUSE :
00310 if(_timer) {
00311 _timer = false;
00312 } else {
00313 _timer = true;
00314
00315 glutTimerFunc(REDISPLAY_NB_MILLI_SEC, display_timer, 0);
00316 }
00317 break;
00318 case VALIDATE :
00319 _world.addGodsGift((unsigned int) _center_z / CELL_SIZE,
00320 (unsigned int) _center_x / CELL_SIZE);
00321 glutPostRedisplay();
00322 break;
00323 }
00324 }
00325
00326 void Display::inputMouse(int button, int state, int x, int y) {
00327 GLint specialKey = glutGetModifiers();
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 if(state == GLUT_DOWN) {
00349 switch(button) {
00350 case GLUT_UP_BUTTON :
00351 if(specialKey == GLUT_ACTIVE_CTRL) {
00352 move_camera(MOVE_UP_SPEED);
00353 } else {
00354 zoom_camera(-ZOOM_SPEED);
00355 }
00356 break;
00357 case GLUT_DOWN_BUTTON :
00358 if(specialKey == GLUT_ACTIVE_CTRL) {
00359 move_camera(-MOVE_UP_SPEED);
00360 } else {
00361 zoom_camera(ZOOM_SPEED);
00362 }
00363 break;
00364 case GLUT_LEFT_BUTTON :
00365 if(specialKey == GLUT_ACTIVE_CTRL) {
00366 rotate_camera(-ROTATE_ANGLE);
00367 } else {
00368 _world.iteration();
00369 glutPostRedisplay();
00370 }
00371 break;
00372 case GLUT_RIGHT_BUTTON :
00373 if(specialKey == GLUT_ACTIVE_CTRL) {
00374 rotate_camera(ROTATE_ANGLE);
00375 }
00376 break;
00377 }
00378 }
00379 }