www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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 }