view.cpp (12204B)
1 #include "all_includes.hh" 2 3 View::View(Chose* _root) 4 : root(_root), 5 camera(Camera(Vertex(0,0,5000), 45, 100, 10000, 0.6f)), 6 lod(camera.cameraCenter, _root) { 7 8 fogColor[0] = Couleurs::r(Couleurs::fog) / 255.f; 9 fogColor[1] = Couleurs::g(Couleurs::fog) / 255.f; 10 fogColor[2] = Couleurs::b(Couleurs::fog) / 255.f; 11 fogColor[3] = 1.0; 12 initWindow(); 13 mainLoop(); 14 } 15 16 void View::setColor(unsigned char r, unsigned char g, unsigned char b) { 17 float red = (float)r / 255.f; 18 float green = (float)g / 255.f; 19 float blue = (float)b / 255.f; 20 float MatDif[4] = {red, green, blue, 1.0f}; 21 float MatAmb[4] = {red, green, blue, 1.0f}; 22 glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,MatDif); 23 glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,MatAmb); 24 } 25 26 void View::initWindow() { 27 SDL_Init(SDL_INIT_VIDEO); 28 SDL_WM_SetCaption("Sortie terrain OpenGL",NULL); 29 SDL_SetVideoMode(Dimensions::windowWidth, Dimensions::windowHeight, 32, SDL_OPENGL); 30 glMatrixMode( GL_PROJECTION ); 31 glLoadIdentity(); 32 gluPerspective(70,Dimensions::windowWidth/Dimensions::windowHeight,Dimensions::frontFrustum,Dimensions::backFrustum); 33 glEnable(GL_DEPTH_TEST); 34 glewInit(); 35 36 float MatSpec[4] = {0.0f, 0.0f, 0.0f, 1.0f}; 37 float MatDif[4] = {0.5f, 0.5f, 0.5f, 1.0f}; 38 float MatAmb[4] = {0.3f, 0.3f, 0.6f, 1.0f}; 39 float shininess = 128.0f; 40 41 glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,MatSpec); 42 glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,MatDif); 43 glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,MatAmb); 44 glMaterialfv(GL_FRONT,GL_SHININESS,&shininess); 45 46 glEnable(GL_LIGHTING); // Active l'éclairage 47 glEnable(GL_LIGHT0); // Active la lumière 0; 48 49 glEnable (GL_FOG); 50 glFogi (GL_FOG_MODE, GL_LINEAR); 51 glFogfv (GL_FOG_COLOR, fogColor); 52 glFogf (GL_FOG_START, Dimensions::backFrustum / std::sqrt(3.f) / 2.f); 53 glFogf (GL_FOG_END, Dimensions::backFrustum / std::sqrt(3.f) * 0.9f); 54 //glHint (GL_FOG_HINT, GL_NICEST); 55 } 56 57 void View::setLight() { 58 float Light1Pos[4] = {-0.5f, -1.0f, 1.0f, 0.0f}; 59 float Light1Dif[4] = {1.0f, 1.0f, 1.0f, 1.0f}; 60 float Light1Spec[4] = {0.0f, 0.0f, 0.0f, 1.0f}; 61 float Light1Amb[4] = {0.4f, 0.4f, 0.4f, 1.0f}; 62 63 glLightfv(GL_LIGHT0, GL_DIFFUSE, Light1Dif); 64 glLightfv(GL_LIGHT0, GL_SPECULAR, Light1Spec); 65 glLightfv(GL_LIGHT0, GL_AMBIENT, Light1Amb); 66 glLightfv(GL_LIGHT0, GL_POSITION, Light1Pos); 67 } 68 69 void View::displayAxes() { 70 glDisable(GL_LIGHTING); 71 glDisable(GL_TEXTURE_2D); 72 glEnable(GL_LINE_SMOOTH); 73 glLineWidth(2); 74 glBegin(GL_LINES); 75 glColor3ub(255,0,0); 76 glVertex3f(0.0f, 0.0f, 0.0f); // origin of the line 77 glVertex3f(2500.0f, 0.0f, 0.0f); // ending point of the line 78 glEnd( ); 79 80 glBegin(GL_LINES); 81 glColor3ub(0,255,0); 82 glVertex3f(0.0f, 0.0f, 0.0f); // origin of the line 83 glVertex3f(0.0f, 2500.0f, 0.0f); // ending point of the line 84 glEnd( ); 85 86 glBegin(GL_LINES); 87 glColor3ub(0,0,255); 88 glVertex3f(0.0f, 0.0f, 0.0f); // origin of the line 89 glVertex3f(0.0f, 0.0f, 2500.0f); // ending point of the line 90 glEnd( ); 91 92 glEnable(GL_LIGHTING); 93 } 94 95 void View::setSkybox() { 96 //int z = 40000; 97 float d = Dimensions::backFrustum / std::sqrt(3.f) * 0.9f; 98 glDisable(GL_FOG); 99 glDisable(GL_LIGHTING); 100 glPushMatrix(); 101 glTranslated(camera.cameraCenter.x,camera.cameraCenter.y,0); 102 for(int ii=0; ii<4;ii++) { 103 glBegin(GL_QUADS); 104 { 105 glColor3ub(Couleurs::r(Couleurs::cielBas),Couleurs::g(Couleurs::cielBas),Couleurs::b(Couleurs::cielBas)); 106 glVertex3f(-d,d,-d); 107 glVertex3f(d,d,-d); 108 glColor3ub(Couleurs::r(Couleurs::cielHaut),Couleurs::g(Couleurs::cielHaut),Couleurs::b(Couleurs::cielHaut)); 109 glVertex3f(d,d,d); 110 glVertex3f(-d,d,d); 111 } 112 glEnd(); 113 glRotated(90,0,0,1); 114 } 115 116 glBegin(GL_QUADS); 117 { 118 glColor3ub(Couleurs::r(Couleurs::cielHaut),Couleurs::g(Couleurs::cielHaut),Couleurs::b(Couleurs::cielHaut)); 119 glVertex3f(-d,d,d); 120 glVertex3f(d,d,d); 121 glVertex3f(d,-d,d); 122 glVertex3f(-d,-d,d); 123 } 124 glEnd(); 125 glBegin(GL_QUADS); 126 { 127 glColor3ub(Couleurs::r(Couleurs::herbe),Couleurs::g(Couleurs::herbe),Couleurs::b(Couleurs::herbe)); 128 glVertex3f(-d,d,-d); 129 glVertex3f(d,d,-d); 130 glVertex3f(d,-d,-d); 131 glVertex3f(-d,-d,-d); 132 } 133 glEnd(); 134 glPopMatrix(); 135 glEnable(GL_LIGHTING); 136 glEnable(GL_FOG); 137 } 138 139 void View::renderScene(int lastTime, int currentTime) { 140 glMatrixMode(GL_MODELVIEW); 141 glLoadIdentity(); 142 143 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ; 144 145 camera.animation(std::min(100, currentTime-lastTime)); 146 camera.setCamera(); 147 lod.setCamera(camera.cameraCenter); 148 149 setLight(); 150 setSkybox(); 151 152 glBegin(GL_TRIANGLES); 153 root->display(); 154 glEnd(); 155 if (false) { // displayNormals ? 156 glDisable(GL_LIGHTING); 157 glDisable(GL_TEXTURE_2D); 158 glBegin(GL_LINES); 159 root->displayNormals(); 160 glEnd(); 161 glEnable(GL_LIGHTING); 162 glEnable(GL_TEXTURE_2D); 163 } 164 165 float fps = (int)(1000/(currentTime-lastTime)); 166 char text[100]; // Text 167 snprintf(&(text[0]), 100, "FPS: %4.2f", fps); 168 std::cerr << "\r" << fps << " "; 169 std::cerr.flush(); 170 /* 171 glLoadIdentity (); 172 glDisable(GL_LIGHTING); 173 glColor3f(0.0f, 0.0f, 0.0f); 174 //glRasterPos3f (0, 0, 0); 175 glutBitmapString(GLUT_BITMAP_TIMES_ROMAN_24, (unsigned char*)(&(text[0]))); 176 */ 177 178 glFlush(); 179 SDL_GL_SwapBuffers(); 180 } 181 182 void View::mainLoop() { 183 short continuer = 1; 184 SDL_Event event; 185 SDL_EnableKeyRepeat(40,40); 186 SDL_WM_GrabInput(SDL_GRAB_ON); 187 SDL_ShowCursor(SDL_DISABLE); 188 while ( SDL_PollEvent(&event) ); // empty queue. 189 190 int lastTime = SDL_GetTicks() - 30; 191 int currentTime = 0; 192 193 while (continuer) { 194 lastTime = currentTime; 195 currentTime = SDL_GetTicks(); 196 while ( SDL_PollEvent(&event) ) { 197 switch(event.type) { 198 case SDL_QUIT: 199 continuer = 0; 200 break; 201 case SDL_KEYDOWN: 202 case SDL_KEYUP: 203 camera.keyboard(event.key); 204 break; 205 case SDL_MOUSEMOTION: 206 camera.mouseMotion(event.motion); 207 break; 208 default: 209 break; 210 } 211 } 212 renderScene(lastTime,currentTime); 213 } 214 215 SDL_Quit(); 216 } 217 218 Camera::Camera(Vertex _cameraCenter, float _xAngle, float _yAngle, int _moveSensitivity, float _mouseSensitivity) 219 : cameraCenter(_cameraCenter), 220 cameraSight(cameraCenter + Vertex::fromSpherical(100,_yAngle,_xAngle)), 221 xAngle(_xAngle), 222 yAngle(_yAngle), 223 moveSensitivity(_moveSensitivity), 224 mouseSensitivity(_mouseSensitivity), 225 up(false), down(false), left(false), right(false), 226 pageUp(false), pageDown(false), autoPilot(false) 227 { 228 } 229 230 std::ostream& Camera::print(std::ostream& os) const { 231 return os << "Camera = " << cameraCenter << " xAngle = " 232 << xAngle << " yAngle = " << yAngle; 233 } 234 235 void Camera::setCamera() { 236 cameraSight = cameraCenter + Vertex::fromSpherical(100, yAngle, xAngle); 237 gluLookAt(cameraCenter.x,cameraCenter.y,cameraCenter.z, cameraSight.x, cameraSight.y, cameraSight.z,0,0,1); 238 } 239 240 void Camera::mouseMotion(const SDL_MouseMotionEvent &event) { 241 xAngle -= (float)(event.xrel) * mouseSensitivity; 242 yAngle += (float)(event.yrel) * mouseSensitivity; 243 xAngle = std::fmod(xAngle + 360, 360); 244 if(yAngle > 179) 245 yAngle = 179; 246 else if(yAngle < 1) 247 yAngle = 1; 248 } 249 250 void Camera::keyboard(const SDL_KeyboardEvent &eventKey) { 251 switch(eventKey.keysym.sym) { 252 case SDLK_UP: 253 case SDLK_DOWN: 254 case SDLK_LEFT: 255 case SDLK_RIGHT: 256 case SDLK_PAGEUP: 257 case SDLK_PAGEDOWN: 258 if (moveSensitivity == 0) moveSensitivity = 300; 259 break; 260 default: 261 break; 262 } 263 switch(eventKey.keysym.sym) { 264 case SDLK_UP: 265 up = (eventKey.type == SDL_KEYDOWN); 266 break; 267 case SDLK_DOWN: 268 down = (eventKey.type == SDL_KEYDOWN); 269 break; 270 case SDLK_LEFT: 271 left = (eventKey.type == SDL_KEYDOWN); 272 break; 273 case SDLK_RIGHT: 274 right = (eventKey.type == SDL_KEYDOWN); 275 break; 276 case SDLK_PAGEUP: 277 pageUp = (eventKey.type == SDL_KEYDOWN); 278 break; 279 case SDLK_PAGEDOWN: 280 pageDown = (eventKey.type == SDL_KEYDOWN); 281 break; 282 case SDLK_ESCAPE: 283 std::cout << std::endl; 284 exit(0); 285 break; 286 case SDLK_KP0: 287 moveSensitivity = 0; 288 break; 289 case SDLK_KP1: 290 moveSensitivity = 300; 291 break; 292 case SDLK_KP2: 293 moveSensitivity = 1000; 294 break; 295 case SDLK_KP3: 296 moveSensitivity = 6000; 297 break; 298 default : 299 switch(SDL_GetKeyName(eventKey.keysym.sym)[0]) { 300 case 'q': 301 std::cout << std::endl; 302 exit(0); 303 break; 304 case 'a' : 305 if (moveSensitivity == 0) moveSensitivity = 300; 306 up = true; 307 break; 308 case 'e' : 309 moveSensitivity = 1500; 310 autoPilot = true; 311 break; 312 case 'z' : 313 autoPilot = false; 314 up = false; 315 break; 316 case 's': 317 if (eventKey.type != SDL_KEYDOWN) break; 318 moveSensitivity = std::min(50000,std::max(moveSensitivity+1, moveSensitivity*10/9)); 319 break; 320 case 'x': 321 if (eventKey.type != SDL_KEYDOWN) break; 322 moveSensitivity = std::max(10, moveSensitivity*9/10); 323 break; 324 case 'p': // _Print _Position 325 if (eventKey.type != SDL_KEYDOWN) break; 326 std::cout << *this << std::endl; 327 break; 328 case 't': { 329 char* file = new char[256]; 330 memset(file,'\n',256); 331 sprintf(file,"city-builder_%d_%d.bmp",Chose::initialSeed,(int)time(NULL)); 332 takeScreenshot(file); 333 break; 334 } 335 case 'c': 336 moveSensitivity = 0; 337 break; 338 case 'v': 339 moveSensitivity = 300; 340 break; 341 case 'b': 342 moveSensitivity = 1000; 343 break; 344 case 'n': 345 moveSensitivity = 6000; 346 break; 347 default: 348 break; 349 } 350 break; 351 } 352 } 353 354 void Camera::animation(int elapsedTime) { 355 static unsigned int frame = 0; 356 frame++; 357 float diff = ((float)(elapsedTime+1)/1000.f)*(float)moveSensitivity; 358 359 if (autoPilot) { 360 float dx = floatInRange(frame/16, 42, -0.5, 0.5); 361 float olddx = floatInRange(frame/16 - 1, 42, -0.5, 0.5); 362 float mix = ((float)(frame % 16) / 16.f); 363 xAngle += dx * mix + olddx * (1-mix); 364 float oldz = cameraCenter.z; 365 cameraCenter = cameraCenter + Vertex::fromSpherical(diff, yAngle, xAngle); 366 cameraCenter.z = oldz; 367 cameraCenter.z += std::min(20.f, std::max(-20.f, 1750 - cameraCenter.z)); 368 } 369 370 if(up) 371 cameraCenter = cameraCenter + Vertex::fromSpherical(diff, yAngle, xAngle); 372 if(down) 373 cameraCenter = cameraCenter - Vertex::fromSpherical(diff, yAngle, xAngle); 374 if(left) 375 cameraCenter = cameraCenter - Vertex::fromSpherical(diff, 90, xAngle - 90); 376 if(right) 377 cameraCenter = cameraCenter + Vertex::fromSpherical(diff, 90, xAngle - 90); 378 if(pageUp) 379 cameraCenter = cameraCenter - Vertex::fromSpherical(diff, yAngle + 90, xAngle); 380 if(pageDown) 381 cameraCenter = cameraCenter + Vertex::fromSpherical(diff, yAngle + 90, xAngle); 382 } 383 384 385 386 387 SDL_Surface * flipSurface(SDL_Surface * surface) { 388 int current_line,pitch; 389 SDL_Surface * fliped_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, 390 surface->w,surface->h, 391 surface->format->BitsPerPixel, 392 surface->format->Rmask, 393 surface->format->Gmask, 394 surface->format->Bmask, 395 surface->format->Amask); 396 397 SDL_LockSurface(surface); 398 SDL_LockSurface(fliped_surface); 399 400 pitch = surface->pitch; 401 for (current_line = 0; current_line < surface->h; current_line ++) { 402 memcpy(&((unsigned char* )fliped_surface->pixels)[current_line*pitch], 403 &((unsigned char* )surface->pixels)[(surface->h - 1 - 404 current_line)*pitch], 405 pitch); 406 } 407 408 SDL_UnlockSurface(fliped_surface); 409 SDL_UnlockSurface(surface); 410 return fliped_surface; 411 } 412 413 int Camera::takeScreenshot(const char * filename) { 414 GLint viewport[4]; 415 Uint32 rmask, gmask, bmask, amask; 416 SDL_Surface * picture, * finalpicture; 417 418 glGetIntegerv(GL_VIEWPORT, viewport); 419 420 #if SDL_BYTEORDER == SDL_BIG_ENDIAN 421 422 rmask = 0xff000000; 423 gmask = 0x00ff0000; 424 bmask = 0x0000ff00; 425 amask = 0x000000ff; 426 #else 427 428 rmask = 0x000000ff; 429 gmask = 0x0000ff00; 430 bmask = 0x00ff0000; 431 amask = 0xff000000; 432 #endif 433 434 picture = SDL_CreateRGBSurface(SDL_SWSURFACE,viewport[2],viewport[3], 32, 435 rmask, gmask, bmask, amask); 436 SDL_LockSurface(picture); 437 glReadPixels(viewport[0],viewport[1],viewport[2],viewport[3],GL_RGBA, 438 GL_UNSIGNED_BYTE,picture->pixels); 439 SDL_UnlockSurface(picture); 440 441 finalpicture = flipSurface(picture); 442 443 if (SDL_SaveBMP(finalpicture, filename)) { 444 std::cout << std::endl; 445 exit(1); 446 } 447 SDL_FreeSurface(finalpicture); 448 SDL_FreeSurface(picture); 449 450 return 0; 451 }