$search
00001 //SOURCE: 00002 // Title: class tgEngine 00003 // File: tgEngine.cpp 00004 // 00005 // Function: Main file of Engine providing interfaces 00006 // 00007 // Author: Thomas Mörwald 00008 // Date: 20.11.2009 00009 // ---------------------------------------------------------------------------- 00010 00011 #include <blort/TomGine/tgEngine.h> 00012 00013 using namespace TomGine; 00014 using namespace blortGLWindow; 00015 00016 tgEngine::tgEngine( unsigned width, 00017 unsigned height, 00018 float far, 00019 float near, 00020 const char* name, 00021 bool bfc) 00022 { 00023 m_window = new blortGLWindow::GLWindow(width, height, name); 00024 00025 m_width = width; 00026 m_height = height; 00027 m_far = far; 00028 m_near = near; 00029 m_bfc = bfc; 00030 00031 m_frametime = 0.0; 00032 00033 m_input_rotation_speed = 1.0f; 00034 m_input_translation_speed = 1.0f; 00035 m_input_zoom_speed = 1.0f; 00036 00037 m_cor = tgVector3(0.0,0.0,0.0); 00038 00039 m_button_left = false; 00040 m_button_middle = false; 00041 m_button_right = false; 00042 00043 m_wireframe = false; 00044 m_smoothshading = false; 00045 m_show_background_image = false; 00046 00047 m_mouse_pos[0] = 0; 00048 m_mouse_pos[1] = 0; 00049 00050 float da = 0.25f*(m_far-m_near); 00051 // Setup 3D camera 00052 m_camera.Set( da, da, da, // Position of camera 00053 0.0f, 0.0f, 0.0f, // Point where camera looks at 00054 0.0f, 1.0f, 0.0f, // UP-Vector of Camera 00055 45, width, height, // field of view in degree in y, image width, image height 00056 near, far, // near clipping plane, far clipping plane 00057 GL_PERSPECTIVE); // Perspective camera 00058 UpdateCameraViews(m_camera); 00059 00060 // Setup 2D camera 00061 m_cam_ortho.Set( 0.0f, 0.0f, 1.0f, 00062 0.0f, 0.0f, 0.0f, 00063 0.0f, 1.0f, 0.0f, 00064 45, width, height, 00065 0.1f, 2.0f, 00066 GL_ORTHO); 00067 00068 tgVector3 cam_f = m_camera.GetF(); 00069 m_light0.ambient = vec4(0.4f,0.4f,0.4f,1.0f); 00070 m_light0.diffuse = vec4(1.0f,1.0f,1.0f,1.0f); 00071 m_light0.specular = vec4(1.0f,1.0f,1.0f,1.0f); 00072 m_light0.position = vec4(-cam_f.x, -cam_f.y, -cam_f.z, 1.0f); 00073 m_lighting.ApplyLight(m_light0,0); 00074 00075 #ifdef USE_FTGL_FONT 00076 // m_font_tf = new FTTextureFont(TTF_FONT); 00077 // if(m_font_tf->Error()){ 00078 // printf("[tgEngine::tgEngine] Warning Font not correct '%s'\n", TTF_FONT); 00079 // m_font_tf = 0; 00080 // }else{ 00081 // m_font_tf->FaceSize(18); 00082 // printf("[tgEngine::tgEngine] Font used: '%s'\n", TTF_FONT); 00083 // } 00084 #endif 00085 00086 m_background_image = 0; 00087 // Welcome(); 00088 } 00089 00090 tgEngine::~tgEngine(){ 00091 if(m_window) delete(m_window); 00092 if(m_background_image) delete(m_background_image); 00093 } 00094 00095 void tgEngine::Welcome(){ 00096 printf("\n *** TomGine Render Engine ***\n\n"); 00097 printf("rotate: left mouse button\n"); 00098 printf("slide: right mouse button\n"); 00099 printf("zoom: mouse wheel\n"); 00100 printf("[f]: toggle shading mode\n"); 00101 printf("[w]: draw wireframed\n"); 00102 printf("[esc]: quit\n"); 00103 printf("\n"); 00104 } 00105 00106 bool tgEngine::Update(){ 00107 float fTime; 00108 std::vector<Event> eventlist; 00109 return Update(fTime, eventlist); 00110 } 00111 00112 bool tgEngine::Update(float &fTime){ 00113 std::vector<Event> eventlist; 00114 return Update(fTime, eventlist); 00115 } 00116 00117 bool tgEngine::Update(std::vector<Event> &eventlist){ 00118 float fTime; 00119 return Update(fTime, eventlist); 00120 } 00121 00122 bool tgEngine::Update(float &fTime, std::vector<Event> &eventlist){ 00123 00124 // User input handling (keyboard, mouse) 00125 bool quit = true; 00126 Event event; 00127 while(m_window->GetEvent(event)){ 00128 quit = InputControl(event); 00129 eventlist.push_back(event); 00130 // if(quit==false) 00131 // return false; 00132 } 00133 00134 Activate3D(); 00135 // DrawCoordinates(); 00136 00137 Swap(); 00138 00139 // update frametime 00140 fTime = m_frametime = (float)m_timer.Update(); 00141 00142 // clear framebuffer and depth buffer 00143 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 00144 00145 DrawBackgroundImage(); 00146 00147 Activate3D(); 00148 00149 // Light pointing along camera viewing axis 00150 tgLight light; 00151 tgVector3 cam_f = m_camera.GetF(); 00152 light.ambient = vec4(0.4f,0.4f,0.4f,1.0f); 00153 light.diffuse = vec4(1.0f,1.0f,1.0f,1.0f); 00154 light.specular = vec4(1.0f,1.0f,1.0f,1.0f); 00155 light.position = vec4(-cam_f.x, -cam_f.y, -cam_f.z, 1.0f); 00156 m_lighting.ApplyLight(light,0); 00157 00158 return quit; 00159 } 00160 00161 bool tgEngine::InputControl(Event &event){ 00162 int x_rel = 0; 00163 int y_rel = 0; 00164 00165 switch(event.type){ 00166 00167 // ********************************************************* 00168 // KeyCode: /usr/include/X11/keysymdef.h 00169 case TMGL_Press: 00170 // printf("event.key.keysym: %x\n", event.key.keysym); 00171 switch(event.input){ 00172 case TMGL_Escape: 00173 return false; 00174 break; 00175 case TMGL_f: 00176 if(m_smoothshading) 00177 glShadeModel(GL_SMOOTH); 00178 else 00179 glShadeModel(GL_FLAT); 00180 m_smoothshading = !m_smoothshading; 00181 break; 00182 case TMGL_p: 00183 p_pressed = true; 00184 break; 00185 case TMGL_w: 00186 if(m_wireframe) 00187 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 00188 else 00189 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 00190 m_wireframe = !m_wireframe; 00191 break; 00192 case TMGL_KP_0: 00193 case TMGL_z: 00194 m_camera = m_cam[0]; 00195 break; 00196 case TMGL_KP_7: 00197 m_camera = m_cam[1]; 00198 break; 00199 case TMGL_KP_6: 00200 m_camera = m_cam[2]; 00201 break; 00202 case TMGL_KP_4: 00203 m_camera = m_cam[3]; 00204 break; 00205 case TMGL_KP_2: 00206 m_camera = m_cam[4]; 00207 break; 00208 case TMGL_KP_8: 00209 m_camera = m_cam[5]; 00210 break; 00211 default: 00212 break; 00213 00214 case TMGL_Button1: 00215 m_button_left = true; 00216 break; 00217 case TMGL_Button2: 00218 m_button_middle = true; 00219 break; 00220 case TMGL_Button3: 00221 m_button_right = true; 00222 break; 00223 case TMGL_Button4: 00224 m_camera.TranslateF(0.01f*(m_far-m_near)*m_input_translation_speed); 00225 break; 00226 case TMGL_Button5: 00227 m_camera.TranslateF(-0.01f*(m_far-m_near)*m_input_translation_speed); 00228 break; 00229 } 00230 break; 00231 00232 // ********************************************************* 00233 case TMGL_Release: 00234 switch(event.input){ 00235 case TMGL_Button1: 00236 m_button_left = false; 00237 break; 00238 case TMGL_Button2: 00239 m_button_middle = false; 00240 break; 00241 case TMGL_Button3: 00242 m_button_right = false; 00243 break; 00244 default: 00245 break; 00246 } 00247 break; 00248 00249 // ********************************************************* 00250 case TMGL_Motion: 00251 x_rel = event.motion.x - m_mouse_pos[0]; 00252 y_rel = event.motion.y - m_mouse_pos[1]; 00253 00254 if(m_button_left){ 00255 m_camera.Orbit(m_cor, m_camera.GetU(), -0.05f * x_rel * m_input_rotation_speed); 00256 m_camera.Orbit(m_cor, m_camera.GetS(), -0.05f * y_rel * m_input_rotation_speed); 00257 }else if(m_button_right){ 00258 m_camera.TranslateS(-0.0005f*(m_far-m_near)*x_rel * m_input_zoom_speed); 00259 m_camera.TranslateU(0.0005f*(m_far-m_near)*y_rel * m_input_zoom_speed); 00260 } 00261 00262 m_mouse_pos[0] = event.motion.x; 00263 m_mouse_pos[1] = event.motion.y; 00264 00265 break; 00266 00267 // ********************************************************* 00268 case TMGL_Expose: 00269 m_width = event.expose.width; m_height = event.expose.height; 00270 m_camera.SetViewport(m_width, m_height); 00271 m_cam[0].SetViewport(m_width, m_height); 00272 m_cam[1].SetViewport(m_width, m_height); 00273 m_cam[2].SetViewport(m_width, m_height); 00274 m_cam[3].SetViewport(m_width, m_height); 00275 m_cam[4].SetViewport(m_width, m_height); 00276 m_cam[5].SetViewport(m_width, m_height); 00277 m_cam_ortho.Set(0.0f, 0.0f, 1.0f, 00278 0.0f, 0.0f, 0.0f, 00279 0.0f, 1.0f, 0.0f, 00280 45, m_width, m_height, 00281 0.1f, 2.0f, 00282 GL_ORTHO); 00283 break; 00284 00285 // ********************************************************* 00286 // case ClientMessage: 00287 // if(event.clientmessage.stop) 00288 // return false; 00289 // break; 00290 default: 00291 break; 00292 00293 } // switch(event.type) 00294 return true; 00295 } 00296 00297 void tgEngine::DrawCoordinates(){ 00298 float l1 = 0.01f*(m_far-m_near); 00299 m_lighting.Deactivate(); 00300 glDisable(GL_DEPTH_TEST); 00301 glDisable(GL_TEXTURE_2D); 00302 00303 glBegin(GL_LINES); 00304 glColor3f(1.0f,0.0f,0.0f); 00305 glVertex3f(0.0f,0.0f,0.0f); glVertex3f(l1, 0.0f, 0.0f); 00306 glColor3f(0.0f,1.0f,0.0f); 00307 glVertex3f(0.0f,0.0f,0.0f); glVertex3f(0.0f, l1, 0.0f); 00308 glColor3f(0.0f,0.0f,1.0f); 00309 glVertex3f(0.0f,0.0f,0.0f); glVertex3f(0.0f, 0.0f, l1); 00310 glEnd(); 00311 00312 m_lighting.Activate(); 00313 glEnable(GL_DEPTH_TEST); 00314 } 00315 00316 void tgEngine::SetCamera(tgCamera cam){ 00317 m_camera = cam; 00318 //m_camera.Print(); 00319 } 00320 00321 void tgEngine::UpdateCameraViews(tgCamera cam){ 00322 m_cam[5] = m_cam[4] = m_cam[3] = m_cam[2] = m_cam[1] = m_cam[0] = cam; 00323 m_cam[1].Orbit(m_cor, m_cam[1].GetU(), PI); 00324 m_cam[2].Orbit(m_cor, m_cam[2].GetU(), PI*0.5); 00325 m_cam[3].Orbit(m_cor, m_cam[3].GetU(),-PI*0.5); 00326 m_cam[4].Orbit(m_cor, m_cam[4].GetS(), PI*0.5); 00327 m_cam[5].Orbit(m_cor, m_cam[5].GetS(),-PI*0.5); 00328 } 00329 00330 void tgEngine::SetCenterOfRotation(float x, float y, float z){ 00331 m_cor = tgVector3(x,y,z); 00332 } 00333 00334 void tgEngine::Activate3D(){ 00335 if(m_bfc) glEnable(GL_CULL_FACE); 00336 else glDisable(GL_CULL_FACE); 00337 m_camera.ApplyTransform(); 00338 m_camera.Activate(); 00339 m_lighting.Activate(); 00340 } 00341 00342 void tgEngine::Activate2D(){ 00343 glDisable(GL_CULL_FACE); 00344 m_cam_ortho.Activate(); 00345 m_lighting.Deactivate(); 00346 } 00347 00348 void tgEngine::Swap(){ 00349 m_window->Update(); 00350 } 00351 00352 void tgEngine::LoadBackgroundImage(unsigned char* image_data, int width, int height, GLenum format, bool flip){ 00353 00354 if(!m_background_image) 00355 m_background_image = new tgTexture(); 00356 00357 m_background_image->Load(image_data, width, height, format); 00358 m_show_background_image = true; 00359 m_flip_background_image = flip; 00360 } 00361 00362 void tgEngine::DrawBackgroundImage(){ 00363 if(m_background_image){ 00364 float w = (float)m_width; 00365 float h = (float)m_height; 00366 00367 Activate2D(); 00368 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 00369 00370 glDepthMask(0); 00371 glColor4f(1.0f, 1.0f, 1.0f, 1.0f); 00372 m_background_image->Bind(); 00373 if(m_flip_background_image){ 00374 glBegin(GL_QUADS); 00375 glTexCoord2f(0.0f,1.0f); glVertex3f(0., 0., 0.0f); 00376 glTexCoord2f(1.0f,1.0f); glVertex3f(w, 0., 0.0f); 00377 glTexCoord2f(1.0f,0.0f); glVertex3f(w, h, 0.0f); 00378 glTexCoord2f(0.0f,0.0f); glVertex3f(0., h, 0.0f); 00379 glEnd(); 00380 }else{ 00381 glBegin(GL_QUADS); 00382 glTexCoord2f(0.0f,0.0f); glVertex3f(0., 0., 0.0f); 00383 glTexCoord2f(1.0f,0.0f); glVertex3f(w*2, 0., 0.0f); 00384 glTexCoord2f(1.0f,1.0f); glVertex3f(w*2, h*2, 0.0f); 00385 glTexCoord2f(0.0f,1.0f); glVertex3f(0., h*2, 0.0f); 00386 glEnd(); 00387 } 00388 glDisable(GL_TEXTURE_2D); 00389 glDepthMask(1); 00390 00391 if(m_wireframe) 00392 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 00393 } 00394 } 00395 00396 void tgEngine::UnloadBackgroundImage(){ 00397 m_show_background_image = false; 00398 if(m_background_image) 00399 delete(m_background_image); 00400 m_background_image = 0; 00401 } 00402 00403 void tgEngine::PrintText3D(std::string text, vec3 pos, int size){ 00404 #ifdef USE_FTGL_FONT 00405 vec2 vPos = m_camera.ToImageSpace(pos); 00406 PrintText2D(text, vPos, size); 00407 #else 00408 //printf("[tgEngine::PrintText3D] Warning: ftgl fonts disabled. USE_FTGL_FONT not defined\n"); 00409 #endif 00410 } 00411 void tgEngine::PrintText2D(std::string text, vec2 pos, int size){ 00412 #ifdef USE_FTGL_FONT 00413 // if(!m_font_tf) 00414 // return; 00415 // Activate2D(); 00416 // glPushMatrix(); 00417 // glTranslatef(pos.x, pos.y, 0.0f); 00418 // m_font_tf->Render(text.c_str()); 00419 // glPopMatrix(); 00420 // Activate3D(); 00421 m_font.Print(text.c_str(), size, pos.x, pos.y); 00422 #else 00423 //printf("[tgEngine::PrintText2D] Warning: ftgl fonts disabled. USE_FTGL_FONT not defined\n"); 00424 #endif 00425 } 00426 00427 tgVector3 tgEngine::Get3DPointFrom2D(int x, int y) 00428 { 00429 tgVector3 vResult; 00430 int viewport[4]; 00431 double modelview[16]; 00432 double projection[16]; 00433 float z; 00434 int y_new; 00435 double result[3]; 00436 00437 m_camera.SetZRange(0.0,1.0); 00438 00439 glGetDoublev(GL_MODELVIEW_MATRIX, &modelview[0] ); //Aktuelle Modelview Matrix in einer Variable ablegen 00440 glGetDoublev(GL_PROJECTION_MATRIX, &projection[0] ); //Aktuelle Projection[s] Matrix in einer Variable ablegen 00441 glGetIntegerv(GL_VIEWPORT, &viewport[0] ); // Aktuellen Viewport in einer Variable ablegen 00442 y_new = viewport[3] - y; // In OpenGL steigt Y von unten (0) nach oben 00443 00444 // Auslesen des Tiefenpuffers an der Position (X/Y_new) 00445 glReadPixels(x, y_new, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z ); 00446 00447 // Errechnen des Punktes, welcher mit den beiden Matrizen multipliziert (X/Y_new/Z) ergibt: 00448 gluUnProject((double)x, (double)y_new, (double)z, modelview, projection, viewport, &result[0], &result[1], &result[2]); 00449 00450 00451 vResult.x = (float)result[0]; 00452 vResult.y = (float)result[1]; 00453 vResult.z = (float)result[2]; 00454 00455 return vResult; 00456 } 00457 00458 bool tgEngine::GetNewPoint(vec3& v){ 00459 if(!p_pressed) 00460 return false; 00461 00462 p_pressed = false; 00463 00464 tgVector3 tgv = Get3DPointFrom2D(m_mouse_pos[0], m_mouse_pos[1]); 00465 00466 v.x =tgv.x; 00467 v.y =tgv.y; 00468 v.z =tgv.z; 00469 00470 return true; 00471 } 00472