00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "kdeglwidget.h"
00019 #include <kaccel.h>
00020
00021 #include <unistd.h>
00022 #include <celengine/gl.h>
00023
00024 #include <celengine/celestia.h>
00025 #include <celengine/starbrowser.h>
00026 #include <kmainwindow.h>
00027 #include <kconfig.h>
00028 #include <qcursor.h>
00029 #include <qpaintdevicemetrics.h>
00030
00031 #ifndef DEBUG
00032 # define G_DISABLE_ASSERT
00033 #endif
00034
00035 #include "celmath/vecmath.h"
00036 #include "celmath/quaternion.h"
00037 #include "celmath/mathlib.h"
00038 #include "celengine/astro.h"
00039 #include "celutil/util.h"
00040 #include "celutil/filetype.h"
00041 #include "celutil/debug.h"
00042 #include "imagecapture.h"
00043 #include "celestiacore.h"
00044 #include "celengine/simulation.h"
00045 #include "celengine/glcontext.h"
00046
00047 #include "kdeapp.h"
00048
00049 #include <math.h>
00050 #include <vector>
00051
00052 KdeGlWidget::KdeGlWidget( QWidget* parent, const char* name, CelestiaCore* core)
00053 : QGLWidget( parent, name )
00054 {
00055
00056
00057 actionColl = ((KdeApp*)parent)->actionCollection();
00058
00059 setFocusPolicy(QWidget::ClickFocus);
00060
00061 appCore = core;
00062 appRenderer=appCore->getRenderer();
00063 appSim = appCore->getSimulation();
00064
00065 setCursor(QCursor(Qt::CrossCursor));
00066 currentCursor = CelestiaCore::CrossCursor;
00067 setMouseTracking(true);
00068
00069 appCore->setCursorHandler(this);
00070
00071 lastX = lastY = 0;
00072 }
00073
00074
00079 KdeGlWidget::~KdeGlWidget()
00080 {
00081 }
00082
00083
00089 void KdeGlWidget::paintGL()
00090 {
00091 appCore->draw();
00092 }
00093
00094
00099 void KdeGlWidget::initializeGL()
00100 {
00101 if (!appCore->initRenderer())
00102 {
00103
00104 exit(1);
00105 }
00106
00107 time_t curtime=time(NULL);
00108 appCore->start((double) curtime / 86400.0 + (double) astro::Date(1970, 1, 1));
00109 localtime(&curtime);
00110 appCore->setTimeZoneBias(-timezone+3600*daylight);
00111 appCore->setTimeZoneName(tzname[daylight?0:1]);
00112
00113 KGlobal::config()->setGroup("Preferences");
00114 if (KGlobal::config()->hasKey("RendererFlags"))
00115 appRenderer->setRenderFlags(KGlobal::config()->readNumEntry("RendererFlags"));
00116 if (KGlobal::config()->hasKey("OrbitMask"))
00117 appRenderer->setOrbitMask(KGlobal::config()->readNumEntry("OrbitMask"));
00118 if (KGlobal::config()->hasKey("LabelMode"))
00119 appRenderer->setLabelMode(KGlobal::config()->readNumEntry("LabelMode"));
00120 if (KGlobal::config()->hasKey("AmbientLightLevel"))
00121 appRenderer->setAmbientLightLevel(KGlobal::config()->readDoubleNumEntry("AmbientLightLevel"));
00122 if (KGlobal::config()->hasKey("FaintestVisible"))
00123 appCore->setFaintest(KGlobal::config()->readDoubleNumEntry("FaintestVisible"));
00124 if (KGlobal::config()->hasKey("HudDetail"))
00125 appCore->setHudDetail(KGlobal::config()->readNumEntry("HudDetail"));
00126 if (KGlobal::config()->hasKey("TimeZoneBias"))
00127 appCore->setTimeZoneBias(KGlobal::config()->readNumEntry("TimeZoneBias"));
00128 if (KGlobal::config()->hasKey("MinFeatureSize"))
00129 appRenderer->setMinimumFeatureSize(KGlobal::config()->readNumEntry("MinFeatureSize"));
00130
00131
00132 if (!appCore->getRenderer()->getGLContext()->renderPathSupported(GLContext::GLPath_Basic))
00133 ((KToggleAction*)(((KdeApp*)parentWidget())->action("renderPathBasic")))->setEnabled(false);
00134 if (!appCore->getRenderer()->getGLContext()->renderPathSupported(GLContext::GLPath_Multitexture))
00135 ((KToggleAction*)(((KdeApp*)parentWidget())->action("renderPathMultitexture")))->setEnabled(false);
00136 if (!appCore->getRenderer()->getGLContext()->renderPathSupported(GLContext::GLPath_NvCombiner))
00137 ((KToggleAction*)(((KdeApp*)parentWidget())->action("renderPathNvCombiner")))->setEnabled(false);
00138 if (!appCore->getRenderer()->getGLContext()->renderPathSupported(GLContext::GLPath_DOT3_ARBVP))
00139 ((KToggleAction*)(((KdeApp*)parentWidget())->action("renderPathDOT3ARBVP")))->setEnabled(false);
00140 if (!appCore->getRenderer()->getGLContext()->renderPathSupported(GLContext::GLPath_NvCombiner_NvVP))
00141 ((KToggleAction*)(((KdeApp*)parentWidget())->action("renderPathNvCombinerNvVP")))->setEnabled(false);
00142 if (!appCore->getRenderer()->getGLContext()->renderPathSupported(GLContext::GLPath_NvCombiner_ARBVP))
00143 ((KToggleAction*)(((KdeApp*)parentWidget())->action("renderPathNvCombinerARBVP")))->setEnabled(false);
00144 if (!appCore->getRenderer()->getGLContext()->renderPathSupported(GLContext::GLPath_ARBFP_ARBVP))
00145 ((KToggleAction*)(((KdeApp*)parentWidget())->action("renderPathARBFPARBVP")))->setEnabled(false);
00146 if (!appCore->getRenderer()->getGLContext()->renderPathSupported(GLContext::GLPath_NV30))
00147 ((KToggleAction*)(((KdeApp*)parentWidget())->action("renderPathNV30")))->setEnabled(false);
00148 if (!appCore->getRenderer()->getGLContext()->renderPathSupported(GLContext::GLPath_GLSL))
00149 ((KToggleAction*)(((KdeApp*)parentWidget())->action("renderPathGLSL")))->setEnabled(false);
00150
00151 if (KGlobal::config()->hasKey("RenderPath")) {
00152 GLContext::GLRenderPath path = (GLContext::GLRenderPath)KGlobal::config()->readNumEntry("RenderPath");
00153 if (appCore->getRenderer()->getGLContext()->renderPathSupported(path)) {
00154 appCore->getRenderer()->getGLContext()->setRenderPath(path);
00155 }
00156 }
00157
00158 switch (appCore->getRenderer()->getGLContext()->getRenderPath()) {
00159 case GLContext::GLPath_Basic:
00160 ((KToggleAction*)(((KdeApp*)parentWidget())->action("renderPathBasic")))->setChecked(true);
00161 break;
00162 case GLContext::GLPath_Multitexture:
00163 ((KToggleAction*)(((KdeApp*)parentWidget())->action("renderPathMultitexture")))->setChecked(true);
00164 break;
00165 case GLContext::GLPath_NvCombiner:
00166 ((KToggleAction*)(((KdeApp*)parentWidget())->action("renderPathNvCombiner")))->setChecked(true);
00167 break;
00168 case GLContext::GLPath_DOT3_ARBVP:
00169 ((KToggleAction*)(((KdeApp*)parentWidget())->action("renderPathDOT3ARBVP")))->setChecked(true);
00170 break;
00171 case GLContext::GLPath_NvCombiner_NvVP:
00172 ((KToggleAction*)(((KdeApp*)parentWidget())->action("renderPathNvCombinerNvVP")))->setChecked(true);
00173 break;
00174 case GLContext::GLPath_NvCombiner_ARBVP:
00175 ((KToggleAction*)(((KdeApp*)parentWidget())->action("renderPathNvCombinerARBVP")))->setChecked(true);
00176 break;
00177 case GLContext::GLPath_ARBFP_ARBVP:
00178 ((KToggleAction*)(((KdeApp*)parentWidget())->action("renderPathARBFPARBVP")))->setChecked(true);
00179 break;
00180 case GLContext::GLPath_NV30:
00181 ((KToggleAction*)(((KdeApp*)parentWidget())->action("renderPathNV30")))->setChecked(true);
00182 break;
00183 case GLContext::GLPath_GLSL:
00184 ((KToggleAction*)(((KdeApp*)parentWidget())->action("renderPathGLSL")))->setChecked(true);
00185 break;
00186 }
00187
00188 KGlobal::config()->setGroup(0);
00189
00190 QPaintDeviceMetrics pdm(this);
00191 appCore->setScreenDpi(pdm.logicalDpiY());
00192
00193 }
00194
00195 void KdeGlWidget::resizeGL( int w, int h )
00196 {
00197
00198
00199
00200
00201 appCore->resize(w, h);
00202 }
00203
00204 void KdeGlWidget::mouseMoveEvent( QMouseEvent* m )
00205 {
00206 int x = (int) m->x();
00207 int y = (int) m->y();
00208
00209 int buttons = 0;
00210 if (m->state() & LeftButton)
00211 buttons |= CelestiaCore::LeftButton;
00212 if (m->state() & MidButton)
00213 buttons |= CelestiaCore::MiddleButton;
00214 if (m->state() & RightButton)
00215 buttons |= CelestiaCore::RightButton;
00216 if (m->state() & ShiftButton)
00217 buttons |= CelestiaCore::ShiftKey;
00218 if (m->state() & ControlButton)
00219 buttons |= CelestiaCore::ControlKey;
00220
00221 if (buttons != 0)
00222 appCore->mouseMove(x - lastX, y - lastY, buttons);
00223 else
00224 appCore->mouseMove(x, y);
00225
00226 lastX = x;
00227 lastY = y;
00228 }
00229
00230 void KdeGlWidget::mousePressEvent( QMouseEvent* m )
00231 {
00232 lastX = (int) m->x();
00233 lastY = (int) m->y();
00234
00235 if (m->button() == LeftButton)
00236 appCore->mouseButtonDown(m->x(), m->y(), CelestiaCore::LeftButton);
00237 else if (m->button() == MidButton)
00238 appCore->mouseButtonDown(m->x(), m->y(), CelestiaCore::MiddleButton);
00239 else if (m->button() == RightButton)
00240 appCore->mouseButtonDown(m->x(), m->y(), CelestiaCore::RightButton);
00241
00242 }
00243
00244 void KdeGlWidget::mouseReleaseEvent( QMouseEvent* m )
00245 {
00246 lastX = (int) m->x();
00247 lastY = (int) m->y();
00248 if (m->button() == LeftButton)
00249 appCore->mouseButtonUp(m->x(), m->y(), CelestiaCore::LeftButton);
00250 else if (m->button() == MidButton)
00251 appCore->mouseButtonUp(m->x(), m->y(), CelestiaCore::MiddleButton);
00252 else if (m->button() == RightButton)
00253 appCore->mouseButtonUp(m->x(), m->y(), CelestiaCore::RightButton);
00254 }
00255
00256 void KdeGlWidget::wheelEvent( QWheelEvent* w )
00257 {
00258 if (w->delta() > 0 )
00259 {
00260 appCore->mouseWheel(-1.0f, 0);
00261 }
00262 else if (w->delta() < 0)
00263 {
00264 appCore->mouseWheel(1.0f, 0);
00265 }
00266 }
00267
00268
00269 bool KdeGlWidget::handleSpecialKey(QKeyEvent* e, bool down)
00270 {
00271 int k = -1;
00272 switch (e->key())
00273 {
00274 case Key_Up:
00275 k = CelestiaCore::Key_Up;
00276 break;
00277 case Key_Down:
00278 k = CelestiaCore::Key_Down;
00279 break;
00280 case Key_Left:
00281 k = CelestiaCore::Key_Left;
00282 break;
00283 case Key_Right:
00284 k = CelestiaCore::Key_Right;
00285 break;
00286 case Key_Home:
00287 k = CelestiaCore::Key_Home;
00288 break;
00289 case Key_End:
00290 k = CelestiaCore::Key_End;
00291 break;
00292 case Key_F1:
00293 k = CelestiaCore::Key_F1;
00294 break;
00295 case Key_F2:
00296 k = CelestiaCore::Key_F2;
00297 break;
00298 case Key_F3:
00299 k = CelestiaCore::Key_F3;
00300 break;
00301 case Key_F4:
00302 k = CelestiaCore::Key_F4;
00303 break;
00304 case Key_F5:
00305 k = CelestiaCore::Key_F5;
00306 break;
00307 case Key_F6:
00308 k = CelestiaCore::Key_F6;
00309 break;
00310 case Key_F7:
00311 k = CelestiaCore::Key_F7;
00312 break;
00313 case Key_PageDown:
00314 k = CelestiaCore::Key_PageDown;
00315 break;
00316 case Key_PageUp:
00317 k = CelestiaCore::Key_PageUp;
00318 break;
00319
00320
00321
00322
00323 case Key_0:
00324 if (e->state() & Qt::Keypad)
00325 k = CelestiaCore::Key_NumPad0;
00326 break;
00327 case Key_1:
00328 if (e->state() & Qt::Keypad)
00329 k = CelestiaCore::Key_NumPad1;
00330 break;
00331 case Key_2:
00332 if (e->state() & Qt::Keypad)
00333 k = CelestiaCore::Key_NumPad2;
00334 break;
00335 case Key_3:
00336 if (e->state() & Qt::Keypad)
00337 k = CelestiaCore::Key_NumPad3;
00338 break;
00339 case Key_4:
00340 if (e->state() & Qt::Keypad)
00341 k = CelestiaCore::Key_NumPad4;
00342 break;
00343 case Key_5:
00344 if (e->state() & Qt::Keypad)
00345 k = CelestiaCore::Key_NumPad5;
00346 break;
00347 case Key_6:
00348 if (e->state() & Qt::Keypad)
00349 k = CelestiaCore::Key_NumPad6;
00350 break;
00351 case Key_7:
00352 if (e->state() & Qt::Keypad)
00353 k = CelestiaCore::Key_NumPad7;
00354 break;
00355 case Key_8:
00356 if (e->state() & Qt::Keypad)
00357 k = CelestiaCore::Key_NumPad8;
00358 break;
00359 case Key_9:
00360 if (e->state() & Qt::Keypad)
00361 k = CelestiaCore::Key_NumPad9;
00362 break;
00363 case Key_A:
00364 k = 'A';
00365 break;
00366 case Key_Z:
00367 k = 'Z';
00368 break;
00369 }
00370
00371 if (k >= 0)
00372 {
00373 int buttons = 0;
00374 if (e->state() & ShiftButton)
00375 buttons |= CelestiaCore::ShiftKey;
00376
00377 if (down)
00378 appCore->keyDown(k, buttons);
00379 else
00380 appCore->keyUp(k);
00381 return (k < 'A' || k > 'Z');
00382 }
00383 else
00384 {
00385 return false;
00386 }
00387 }
00388
00389
00390 void KdeGlWidget::keyPressEvent( QKeyEvent* e )
00391 {
00392 static bool inputMode = false;
00393 switch (e->key())
00394 {
00395 case Key_Escape:
00396 appCore->charEntered('\033');
00397 break;
00398 case Key_BackTab:
00399 appCore->charEntered(CelestiaCore::Key_BackTab);
00400 break;
00401 case Key_Q:
00402 if( e->state() == ControlButton )
00403 {
00404 parentWidget()->close();
00405 }
00406
00407
00408 default:
00409 if (appCore->getTextEnterMode() != CelestiaCore::KbNormal || !handleSpecialKey(e, true))
00410 {
00411 if ((e->text() != 0) && (e->text() != ""))
00412 {
00413 appCore->charEntered(e->text().utf8().data());
00414 }
00415 }
00416 }
00417 }
00418
00419
00420 void KdeGlWidget::keyReleaseEvent( QKeyEvent* e )
00421 {
00422 handleSpecialKey(e, false);
00423 }
00424
00425 void KdeGlWidget::setCursorShape(CelestiaCore::CursorShape shape)
00426 {
00427 int cursor;
00428 if (currentCursor != shape)
00429 {
00430 switch(shape)
00431 {
00432 case CelestiaCore::ArrowCursor:
00433 cursor = Qt::ArrowCursor;
00434 break;
00435 case CelestiaCore::UpArrowCursor:
00436 cursor = Qt::UpArrowCursor;
00437 break;
00438 case CelestiaCore::CrossCursor:
00439 cursor = Qt::CrossCursor;
00440 break;
00441 case CelestiaCore::InvertedCrossCursor:
00442 cursor = Qt::CrossCursor;
00443 break;
00444 case CelestiaCore::WaitCursor:
00445 cursor = Qt::WaitCursor;
00446 break;
00447 case CelestiaCore::BusyCursor:
00448 cursor = Qt::WaitCursor;
00449 break;
00450 case CelestiaCore::IbeamCursor:
00451 cursor = Qt::IbeamCursor;
00452 break;
00453 case CelestiaCore::SizeVerCursor:
00454 cursor = Qt::SizeVerCursor;
00455 break;
00456 case CelestiaCore::SizeHorCursor:
00457 cursor = Qt::SizeHorCursor;
00458 break;
00459 case CelestiaCore::SizeBDiagCursor:
00460 cursor = Qt::SizeBDiagCursor;
00461 break;
00462 case CelestiaCore::SizeFDiagCursor:
00463 cursor = Qt::SizeFDiagCursor;
00464 break;
00465 case CelestiaCore::SizeAllCursor:
00466 cursor = Qt::SizeAllCursor;
00467 break;
00468 case CelestiaCore::SplitVCursor:
00469 cursor = Qt::SplitVCursor;
00470 break;
00471 case CelestiaCore::SplitHCursor:
00472 cursor = Qt::SplitHCursor;
00473 break;
00474 case CelestiaCore::PointingHandCursor:
00475 cursor = Qt::PointingHandCursor;
00476 break;
00477 case CelestiaCore::ForbiddenCursor:
00478 cursor = Qt::ForbiddenCursor;
00479 break;
00480 case CelestiaCore::WhatsThisCursor:
00481 cursor = Qt::WhatsThisCursor;
00482 break;
00483 default:
00484 cursor = Qt::CrossCursor;
00485 break;
00486 }
00487 setCursor(QCursor(cursor));
00488 currentCursor = shape;
00489 }
00490 }
00491
00492 CelestiaCore::CursorShape KdeGlWidget::getCursorShape() const
00493 {
00494 return currentCursor;
00495 }