00001
00002
00003
00004
00005
00006
00011 #include <fstream>
00012 #include <sstream>
00013 #include <GL/glut.h>
00014 #include "glui/glui.h"
00015
00016 #include "timer.h"
00017 #include "Opengl.h"
00018 #include "PhysikEngine.h"
00019 #include "ObjectManager.h"
00020 #include "Configuration.h"
00021 #include "Window.h"
00022 #include "Camera.h"
00023
00024 Opengl ourOpengl;
00025
00026
00027 int Opengl::freeLight=0;
00028
00036 int Opengl::getNextLight() {
00037 if(freeLight == 8)
00038 freeLight = 0;
00039 freeLight++;
00040
00041
00042 return GL_LIGHT0+freeLight-1;
00043 }
00044
00048 void Opengl::reloadWindow() {
00049 HandleReshape(0,0);
00050 }
00051
00057 void Opengl::redraw() {
00058 glutSetWindow(Window::getMainWindow());
00059 glutPostRedisplay();
00060 }
00061
00066 void Opengl::CreateEnvironment() {
00067
00068
00069 glEnable(GL_LINE_SMOOTH);
00070
00071
00072 glEnable(GL_POLYGON_SMOOTH);
00073
00074
00075 glShadeModel(GL_SMOOTH);
00076
00077
00078
00079
00080
00081
00082 glEnable(GL_DITHER);
00083
00084
00085
00086
00087
00088
00089
00090 glLineWidth(1.0);
00091
00092
00093 glPointSize(1.0);
00094
00095
00096 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 glFrontFace(GL_CCW);
00109
00110
00111 glClearColor(0.0, 0.0, 0.0, 0.0);
00112
00113
00114 glEnable(GL_COLOR_MATERIAL);
00115 }
00116
00120 void Opengl::RenderObjects() {
00121
00122 glLoadIdentity();
00123
00124
00125 ourCamera.loadCameraMatrix();
00126
00127
00128 GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
00129 GLfloat mat_shininess[] = { 50.0 };
00130
00131
00132
00133
00134 glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
00135
00136
00137
00138 glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 glEnable(GL_CULL_FACE);
00150
00151
00152
00153 for(int i=0; i < 8; i++)
00154 glDisable(getNextLight());
00155
00156
00157 freeLight = 0;
00158
00159
00160 ourObjectManager.drawObjects();
00161 }
00162
00166 void Opengl::RenderUniverse() {
00167
00168 static timeval startTime_;
00169 timeval startRenderingTime_;
00170 static double frameTime_=1;
00171 static int framesCount=1;
00172
00173
00174 if( timediffNow(startTime_) > 1) {
00175 frameTime_=timediffNow(startTime_)/framesCount;
00176 gettimeofday(&startTime_,0);
00177 framesCount=1;
00178 } else
00179 framesCount++;
00180 gettimeofday(&startRenderingTime_,0);
00181
00182
00183
00184 glEnable(GL_DEPTH_TEST);
00185
00186
00187
00188
00189
00190
00191 glDrawBuffer(GL_BACK);
00192
00193
00194
00195 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00196
00197
00198 if (ourConfiguration.viewModel == 0) {
00199
00200 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
00201 } else if (ourConfiguration.viewModel == 1) {
00202
00203 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00204 } else {
00205
00206 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00207 }
00208
00209
00210
00211
00212 glMatrixMode(GL_PROJECTION);
00213
00214
00215 glLoadIdentity();
00216
00217
00218
00219 ourCamera.loadCameraPerspective();
00220
00221
00222 glMatrixMode(GL_MODELVIEW);
00223
00224
00225 if(! ourConfiguration.showLighting) {
00226
00227 glDisable(GL_LIGHTING);
00228 glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
00229 } else {
00230
00231 glEnable(GL_LIGHTING);
00232 glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
00233 }
00234
00235
00236
00237
00238
00239 RenderObjects();
00240
00241
00242 glDisable(GL_LIGHTING);
00243
00244
00245
00246
00247
00248
00249 glutSwapBuffers();
00250
00251
00252
00253 stringstream fps_;
00254 fps_.precision(3);
00255 fps_ << "fps: " << 1/frameTime_ << " Rt: " <<
00256 timediffNow(startRenderingTime_);
00257 Window::setRenderDetails(fps_.str());
00258 }
00259
00260
00268 void Opengl::HandleReshape(int w, int h) {
00269
00270 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00271
00272
00273 int tx,ty,tw,th;
00274 GLUI_Master.get_viewport_area(&tx,&ty,&tw,&th);
00275
00276
00277
00278 if(! ourConfiguration.showMenu ) {
00279 tw +=tx;
00280 th +=ty;
00281 tx=0;
00282 ty=0;
00283 }
00284
00285
00286 glViewport(tx, ty, tw, th);
00287
00288
00289 ourCamera.setScreen(tw,th);
00290 }
00291
00296 void Opengl::setAnimation(bool enable) {
00297 if(ourConfiguration.freezeAnimation && enable &&
00298 ourObjectManager.getObjectCount()!=0 &&
00299 ourConfiguration.constructMode == false) {
00300
00301 Window::setAnimationControls(true);
00302 ourConfiguration.freezeAnimation = false;
00303
00304
00305 glutTimerFunc(TIMERUPDATE,& Opengl::HandleTimer,0);
00306 } else if (! enable || ourObjectManager.getObjectCount()==0
00307 || ourConfiguration.constructMode) {
00308
00309 ourConfiguration.freezeAnimation = true;
00310 glutTimerFunc(0,& Opengl::HandleTimer,0);
00311 Window::setAnimationControls(false);
00312 }
00313 }
00314
00320 void Opengl::singleStep() {
00321
00322 if( ourObjectManager.getObjectCount()==0)
00323 return;
00324 Vector oldpos_;
00325
00326
00327
00328 if (ourConfiguration.clickedObject !=0)
00329 oldpos_= ourConfiguration.clickedObject->getScaledPos();
00330
00331
00332 ourObjectManager.nextTimeStep();
00333
00334
00335 PhysikEngine::simulateGravity(ourConfiguration.getTime());
00336
00337
00338 if (ourConfiguration.clickedObject !=0 && ourConfiguration.followObject) {
00339 Object * obj=ourConfiguration.clickedObject;
00340
00341 Vector pos_ = obj->getScaledPos();
00342 if(ourConfiguration.viewToObjectsFlightDirection) {
00343
00344 double r_ = obj->getScaledRadius();
00345 Vector projCenter_ = pos_ + obj->v.getNormalised() * (r_+10.0);
00346
00347 ourCamera.setProjectionCenter(projCenter_);
00348 Vector newPos_ = pos_ + obj->v.getNormalised() * (r_+1.0);
00349
00350 ourCamera.setPosition(newPos_);
00351
00352
00353 Vector oldNormal_ = oldpos_.crossProduct(ourCamera.getUpper());
00354 Vector newUpper_ = oldNormal_.crossProduct(newPos_);
00355 if(newUpper_.length() == 0)
00356 newUpper_ = Vector(1,0,0);
00357 ourCamera.setUpper(newUpper_);
00358 } else {
00359
00360 Vector diff(pos_-oldpos_ );
00361 Vector newPos_ = ourCamera.getPosition() +diff;
00362
00363
00364 ourCamera.setProjectionCenter( ourCamera.getProjectionCenter() +
00365 diff);
00366 ourCamera.setPosition(newPos_);
00367 }
00368
00369 }
00370
00371
00372
00373
00374 if(Object::attributeWindowShown())
00375 ourConfiguration.clickedObject->refreshAttributes();
00376 else
00377 redraw();
00378 }
00379
00380
00390 int Opengl::getObjectID(int x, int y) {
00391
00392 int objectsFound = 0;
00393 int viewportCoords[4] = {0};
00394
00395
00396
00397
00398
00399
00400 unsigned int selectBuffer[32] = {0};
00401
00402
00403
00404
00405
00406 glSelectBuffer(32, selectBuffer);
00407
00408
00409
00410
00411
00412 glGetIntegerv(GL_VIEWPORT, viewportCoords);
00413
00414
00415
00416 y-=viewportCoords[1] ;
00417
00418
00419
00420 glMatrixMode(GL_PROJECTION);
00421
00422
00423
00424 glPushMatrix();
00425
00426
00427
00428 glRenderMode(GL_SELECT);
00429 glLoadIdentity();
00430
00431
00432
00433
00434
00435
00436
00437 gluPickMatrix(x, viewportCoords[3] - y, 2, 2, viewportCoords);
00438
00439
00440 ourCamera.loadCameraPerspective();
00441
00442
00443 glMatrixMode(GL_MODELVIEW);
00444
00445
00446 RenderObjects ();
00447
00448
00449
00450
00451 objectsFound = glRenderMode(GL_RENDER);
00452
00453
00454 glMatrixMode(GL_PROJECTION);
00455
00456 glPopMatrix();
00457 glMatrixMode(GL_MODELVIEW);
00458
00459 if (objectsFound > 0) {
00460
00461
00462
00463
00464
00465
00466
00467
00468 unsigned int lowestDepth = selectBuffer[1];
00469
00470
00471 int selectedObject = selectBuffer[3];
00472
00473 for(int i = 1; i < objectsFound; i++) {
00474 if(selectBuffer[(i * 4) + 1] < lowestDepth) {
00475
00476 lowestDepth = selectBuffer[(i * 4) + 1];
00477 selectedObject = selectBuffer[(i * 4) + 3];
00478 }
00479 }
00480
00481
00482
00483 if (selectedObject < 100000)
00484 return 0;
00485 else
00486
00487 return selectedObject;
00488 }
00489
00490
00491 return 0;
00492 }
00493
00499 void Opengl::HandleTimer(int value) {
00500 if(ourConfiguration.freezeAnimation || ourObjectManager.getObjectCount()==0)
00501 return;
00502
00503 singleStep();
00504 glutTimerFunc(TIMERUPDATE,& Opengl::HandleTimer,0);
00505 }
00506
00507
00516 void Opengl::init(int & argc, char **argv) {
00517
00518
00519
00520
00521 glutInit(&argc, argv);
00522
00523
00524
00525
00526
00527
00528
00529 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
00530
00531
00532 glutInitWindowSize( ourCamera.getScreenWidth(),
00533 ourCamera.getScreenHeight() );
00534
00535 int mainWindow=glutCreateWindow("Solar system construction kit");
00536
00537
00538
00539
00540
00541
00542
00543 glutDisplayFunc(& Opengl::RenderUniverse);
00544
00545
00546
00547
00548
00549
00550 GLUI_Master.set_glutReshapeFunc(& Opengl::HandleReshape);
00551
00552
00553 Window::CreateWindows(mainWindow);
00554
00555
00556 GLUI_Master.set_glutIdleFunc(NULL);
00557
00558
00559 CreateEnvironment();
00560
00561
00562
00563 glutSetCursor(GLUT_CURSOR_INHERIT);
00564
00565 }
00566
00570 void Opengl::loop() {
00571 glutMainLoop();
00572 }