• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Stellarium / stellarium / 5770622832

pending completion
5770622832

Pull #3348

github

gzotti
Fixed a logic error introduced by previous edit.
Pull Request #3348: Fix: orbit details

58 of 58 new or added lines in 5 files covered. (100.0%)

14813 of 124420 relevant lines covered (11.91%)

27935.46 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

2.99
/src/core/StelApp.cpp
1
/*
2
 * Stellarium
3
 * Copyright (C) 2006 Fabien Chereau
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335, USA.
18
 */
19

20
#include "StelApp.hpp"
21

22
#include "Dithering.hpp"
23
#include "StelCore.hpp"
24
#include "StelMainView.hpp"
25
#include "StelSplashScreen.hpp"
26
#include "StelUtils.hpp"
27
#include "StelTextureMgr.hpp"
28
#include "StelObjectMgr.hpp"
29
#include "ConstellationMgr.hpp"
30
#include "AsterismMgr.hpp"
31
#include "HipsMgr.hpp"
32
#include "NebulaMgr.hpp"
33
#include "LandscapeMgr.hpp"
34
#include "CustomObjectMgr.hpp"
35
#include "HighlightMgr.hpp"
36
#include "GridLinesMgr.hpp"
37
#include "MilkyWay.hpp"
38
#include "ZodiacalLight.hpp"
39
#include "LabelMgr.hpp"
40
#include "MarkerMgr.hpp"
41
#include "SolarSystem.hpp"
42
#include "NomenclatureMgr.hpp"
43
#include "SporadicMeteorMgr.hpp"
44
#include "SpecificTimeMgr.hpp"
45
#include "StarMgr.hpp"
46
#include "StelProjector.hpp"
47
#include "StelLocationMgr.hpp"
48
#include "ToastMgr.hpp"
49
#include "StelActionMgr.hpp"
50
#include "StelPropertyMgr.hpp"
51
#include "StelProgressController.hpp"
52
#include "StelModuleMgr.hpp"
53
#include "StelLocaleMgr.hpp"
54
#include "StelSkyCultureMgr.hpp"
55
#include "StelFileMgr.hpp"
56
#include "StelSkyLayerMgr.hpp"
57
#include "StelAudioMgr.hpp"
58
#include "StelVideoMgr.hpp"
59
#include "SpecialMarkersMgr.hpp"
60
#include "StelViewportEffect.hpp"
61
#include "StelGuiBase.hpp"
62
#include "StelPainter.hpp"
63
#ifdef ENABLE_SCRIPTING
64
 #include "StelScriptMgr.hpp"
65
 #include "StelMainScriptAPIProxy.hpp"
66

67
#ifdef USE_STATIC_PLUGIN_CALENDARS
68
 #include "../plugins/Calendars/src/Calendars.hpp"
69
#endif
70
#endif
71

72

73
#include <cstdlib>
74
#include <iostream>
75
#include <QDebug>
76
#include <QFile>
77
#include <QFileInfo>
78
#include <QMouseEvent>
79
#include <QNetworkAccessManager>
80
#include <QNetworkDiskCache>
81
#include <QNetworkProxy>
82
#include <QNetworkReply>
83
#include <QOpenGLBuffer>
84
#include <QOpenGLContext>
85
#include <QOpenGLShaderProgram>
86
#include <QOpenGLVertexArrayObject>
87
#include <QOpenGLFramebufferObject>
88
#include <QOpenGLFunctions_3_3_Core>
89
#include <QString>
90
#include <QStringList>
91
#include <QSysInfo>
92
#include <QTextStream>
93
#include <QTimer>
94
#include <QDir>
95
#include <QCoreApplication>
96
#include <QGuiApplication>
97
#include <QScreen>
98
#include <QDateTime>
99
#include <QRegularExpression>
100
#include <QRandomGenerator>
101
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
102
#include <QImageReader>
103
#endif
104
#ifdef ENABLE_SPOUT
105
#include <QMessageBox>
106
#include "SpoutSender.hpp"
107
#endif
108

109
#ifdef USE_STATIC_PLUGIN_HELLOSTELMODULE
110
Q_IMPORT_PLUGIN(HelloStelModuleStelPluginInterface)
111
#endif
112

113
#ifdef USE_STATIC_PLUGIN_SIMPLEDRAWLINE
114
Q_IMPORT_PLUGIN(SimpleDrawLineStelPluginInterface)
115
#endif
116

117
#ifdef USE_STATIC_PLUGIN_ANGLEMEASURE
118
Q_IMPORT_PLUGIN(AngleMeasureStelPluginInterface)
15✔
119
#endif
120

121
#ifdef USE_STATIC_PLUGIN_ARCHAEOLINES
122
Q_IMPORT_PLUGIN(ArchaeoLinesStelPluginInterface)
15✔
123
#endif
124

125
#ifdef USE_STATIC_PLUGIN_CALENDARS
126
Q_IMPORT_PLUGIN(CalendarsStelPluginInterface)
15✔
127
#endif
128

129
#ifdef USE_STATIC_PLUGIN_SATELLITES
130
Q_IMPORT_PLUGIN(SatellitesStelPluginInterface)
15✔
131
#endif
132

133
#ifdef USE_STATIC_PLUGIN_TEXTUSERINTERFACE
134
Q_IMPORT_PLUGIN(TextUserInterfaceStelPluginInterface)
135
#endif
136

137
#ifdef USE_STATIC_PLUGIN_OCULARS
138
Q_IMPORT_PLUGIN(OcularsStelPluginInterface)
15✔
139
#endif
140

141
#ifdef USE_STATIC_PLUGIN_OCULUS
142
Q_IMPORT_PLUGIN(OculusStelPluginInterface)
143
#endif
144

145
#ifdef USE_STATIC_PLUGIN_TELESCOPECONTROL
146
Q_IMPORT_PLUGIN(TelescopeControlStelPluginInterface)
15✔
147
#endif
148

149
#ifdef USE_STATIC_PLUGIN_SOLARSYSTEMEDITOR
150
Q_IMPORT_PLUGIN(SolarSystemEditorStelPluginInterface)
15✔
151
#endif
152

153
#ifdef USE_STATIC_PLUGIN_METEORSHOWERS
154
Q_IMPORT_PLUGIN(MeteorShowersStelPluginInterface)
15✔
155
#endif
156

157
#ifdef USE_STATIC_PLUGIN_NAVSTARS
158
Q_IMPORT_PLUGIN(NavStarsStelPluginInterface)
15✔
159
#endif
160

161
#ifdef USE_STATIC_PLUGIN_NOVAE
162
Q_IMPORT_PLUGIN(NovaeStelPluginInterface)
15✔
163
#endif
164

165
#ifdef USE_STATIC_PLUGIN_SUPERNOVAE
166
Q_IMPORT_PLUGIN(SupernovaeStelPluginInterface)
15✔
167
#endif
168

169
#ifdef USE_STATIC_PLUGIN_QUASARS
170
Q_IMPORT_PLUGIN(QuasarsStelPluginInterface)
15✔
171
#endif
172

173
#ifdef USE_STATIC_PLUGIN_PULSARS
174
Q_IMPORT_PLUGIN(PulsarsStelPluginInterface)
15✔
175
#endif
176

177
#ifdef USE_STATIC_PLUGIN_EXOPLANETS
178
Q_IMPORT_PLUGIN(ExoplanetsStelPluginInterface)
15✔
179
#endif
180

181
#ifdef USE_STATIC_PLUGIN_EQUATIONOFTIME
182
Q_IMPORT_PLUGIN(EquationOfTimeStelPluginInterface)
15✔
183
#endif
184

185
#ifdef USE_STATIC_PLUGIN_POINTERCOORDINATES
186
Q_IMPORT_PLUGIN(PointerCoordinatesStelPluginInterface)
15✔
187
#endif
188

189
#ifdef USE_STATIC_PLUGIN_OBSERVABILITY
190
Q_IMPORT_PLUGIN(ObservabilityStelPluginInterface)
15✔
191
#endif
192

193
#ifdef USE_STATIC_PLUGIN_SCENERY3D
194
Q_IMPORT_PLUGIN(Scenery3dStelPluginInterface)
15✔
195
#endif
196

197
#ifdef USE_STATIC_PLUGIN_REMOTECONTROL
198
Q_IMPORT_PLUGIN(RemoteControlStelPluginInterface)
15✔
199
#endif
200

201
#ifdef USE_STATIC_PLUGIN_REMOTESYNC
202
Q_IMPORT_PLUGIN(RemoteSyncStelPluginInterface)
15✔
203
#endif
204

205
#ifdef USE_STATIC_PLUGIN_VTS
206
Q_IMPORT_PLUGIN(VtsStelPluginInterface)
207
#endif
208

209
#ifdef USE_STATIC_PLUGIN_ONLINEQUERIES
210
Q_IMPORT_PLUGIN(OnlineQueriesPluginInterface)
15✔
211
#endif
212

213
// Initialize static variables
214
StelApp* StelApp::singleton = Q_NULLPTR;
215
qint64 StelApp::startMSecs = 0;
216
double StelApp::animationScale = 1.;
217

218
void StelApp::initStatic()
×
219
{
220
        StelApp::startMSecs = QDateTime::currentMSecsSinceEpoch();
×
221
}
×
222

223
void StelApp::deinitStatic()
×
224
{
225
        StelApp::startMSecs = 0;
×
226
}
×
227

228
/*************************************************************************
229
 Create and initialize the main Stellarium application.
230
*************************************************************************/
231
StelApp::StelApp(StelMainView *parent)
×
232
        : QObject(parent)
233
        , randomGenerator(Q_NULLPTR)
×
234
        , mainWin(parent)
×
235
        , core(Q_NULLPTR)
×
236
        , moduleMgr(Q_NULLPTR)
×
237
        , localeMgr(Q_NULLPTR)
×
238
        , skyCultureMgr(Q_NULLPTR)
×
239
        , actionMgr(Q_NULLPTR)
×
240
        , propMgr(Q_NULLPTR)
×
241
        , textureMgr(Q_NULLPTR)
×
242
        , stelObjectMgr(Q_NULLPTR)
×
243
        , planetLocationMgr(Q_NULLPTR)
×
244
        , networkAccessManager(Q_NULLPTR)
×
245
        , audioMgr(Q_NULLPTR)
×
246
        , videoMgr(Q_NULLPTR)
×
247
        , skyImageMgr(Q_NULLPTR)
×
248
#ifdef ENABLE_SCRIPTING
249
        , scriptAPIProxy(Q_NULLPTR)
×
250
        , scriptMgr(Q_NULLPTR)
×
251
#endif
252
        , stelGui(Q_NULLPTR)
×
253
        , devicePixelsPerPixel(1.)
×
254
        , globalScalingRatio(1.f)
×
255
        , fps(0)
×
256
        , frame(0)
×
257
        , frameTimeAccum(0.)
×
258
        , flagNightVision(false)
×
259
        , confSettings(Q_NULLPTR)
×
260
        , initialized(false)
×
261
        , saveProjW(-1.)
×
262
        , saveProjH(-1.)
×
263
        , nbDownloadedFiles(0)
×
264
        , totalDownloadedSize(0)
×
265
        , nbUsedCache(0)
×
266
        , totalUsedCacheSize(0)
×
267
        , screenFontSize(13)
×
268
        , renderBuffer(Q_NULLPTR)
×
269
        , viewportEffect(Q_NULLPTR)
×
270
        , gl(Q_NULLPTR)
×
271
        , flagShowDecimalDegrees(false)
×
272
        , flagUseAzimuthFromSouth(false)
×
273
        , flagUseFormattingOutput(false)
×
274
        , flagUseCCSDesignation(false)
×
275
        , flagOverwriteInfoColor(false)
×
276
        , overwriteInfoColor(Vec3f(1.f))
×
277
        , daylightInfoColor(Vec3f(0.f))
×
278
        #ifdef ENABLE_SPOUT
279
        , spoutSender(Q_NULLPTR)
280
        #endif
281
        , currentFbo(0)
×
282
{
283
        setObjectName("StelApp");
×
284

285
        // Can't create 2 StelApp instances
286
        Q_ASSERT(!singleton);
×
287
        singleton = this;
×
288

289
        moduleMgr = new StelModuleMgr();
×
290
        randomGenerator = new QRandomGenerator(static_cast<quint32>(QDateTime::currentMSecsSinceEpoch()));
×
291
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
292
        // QImageReader has a new limitation. For super-large landscapes or other textures, we need to circumvent this.
293
        QImageReader::setAllocationLimit(1024); // Allow max texture size 16k x 16k
294
#endif
295
}
×
296

297
/*************************************************************************
298
 Deinitialize and destroy the main Stellarium application.
299
*************************************************************************/
300
StelApp::~StelApp()
×
301
{
302
        qDebug() << qPrintable(QString("Downloaded %1 files (%2 kbytes) in a session of %3 sec (average of %4 kB/s + %5 files from cache (%6 kB)).").arg(nbDownloadedFiles).arg(totalDownloadedSize/1024).arg(getTotalRunTime()).arg(static_cast<double>(totalDownloadedSize/1024)/getTotalRunTime()).arg(nbUsedCache).arg(totalUsedCacheSize/1024));
×
303

304
        stelObjectMgr->unSelect();
×
305
        moduleMgr->unloadModule("StelVideoMgr", false);  // We need to delete it afterward
×
306
        moduleMgr->unloadModule("StelSkyLayerMgr", false);  // We need to delete it afterward
×
307
        moduleMgr->unloadModule("StelObjectMgr", false);// We need to delete it afterward
×
308
        StelModuleMgr* tmp = moduleMgr;
×
309
        moduleMgr = new StelModuleMgr(); // Create a secondary instance to avoid crashes at other deinit
×
310
        delete tmp; tmp=Q_NULLPTR;
×
311
        delete skyImageMgr; skyImageMgr=Q_NULLPTR;
×
312
        delete core; core=Q_NULLPTR;
×
313
        delete skyCultureMgr; skyCultureMgr=Q_NULLPTR;
×
314
        delete localeMgr; localeMgr=Q_NULLPTR;
×
315
        delete audioMgr; audioMgr=Q_NULLPTR;
×
316
        delete videoMgr; videoMgr=Q_NULLPTR;
×
317
        delete stelObjectMgr; stelObjectMgr=Q_NULLPTR; // Delete the module by hand afterward
×
318
        delete textureMgr; textureMgr=Q_NULLPTR;
×
319
        delete planetLocationMgr; planetLocationMgr=Q_NULLPTR;
×
320
        delete moduleMgr; moduleMgr=Q_NULLPTR; // Delete the secondary instance
×
321
        delete actionMgr; actionMgr = Q_NULLPTR;
×
322
        delete propMgr; propMgr = Q_NULLPTR;
×
323
        delete renderBuffer; renderBuffer = Q_NULLPTR;
×
324
        delete randomGenerator; randomGenerator=Q_NULLPTR;
×
325
        Q_ASSERT(singleton);
×
326
        singleton = Q_NULLPTR;
×
327
}
×
328

329
void StelApp::setupNetworkProxy()
×
330
{
331
        QString proxyHost = confSettings->value("proxy/host_name").toString();
×
332
        QString proxyPort = confSettings->value("proxy/port").toString();
×
333
        QString proxyUser = confSettings->value("proxy/user").toString();
×
334
        QString proxyPass = confSettings->value("proxy/password").toString();
×
335
        QString proxyType = confSettings->value("proxy/type").toString();
×
336

337
        // If proxy settings not found in config, use environment variable
338
        // if it is defined.  (Config file over-rides environment).
339
        if (proxyHost.isEmpty() && proxyUser.isEmpty() && proxyPass.isEmpty() && proxyPort.isEmpty())
×
340
        {
341
                char *httpProxyEnv;
342
                httpProxyEnv = std::getenv("http_proxy");
×
343
                if (!httpProxyEnv)
×
344
                {
345
                        httpProxyEnv = std::getenv("HTTP_PROXY");
×
346
                }
347
                if (httpProxyEnv)
×
348
                {
349
                        QString proxyString = QString(httpProxyEnv);
×
350
                        if (!proxyString.isEmpty())
×
351
                        {
352
                                // Handle http_proxy of the form
353
                                // proto://username:password@fqdn:port
354
                                // e.g.:
355
                                // http://usr:pass@proxy.loc:3128/
356
                                // http://proxy.loc:3128/
357
                                // http://2001:62a:4:203:6ab5:99ff:fef2:560b:3128/
358
                                // http://foo:bar@2001:62a:4:203:6ab5:99ff:fef2:560b:3128/
359
                                static const QRegularExpression pre("^([^:]+://)?(?:([^:]+):([^@]*)@)?(.+):([\\d]+)");
×
360
                                QRegularExpressionMatch preMatch=pre.match(proxyString);
×
361
                                if (proxyString.indexOf(pre) >= 0)
×
362
                                {
363
                                        proxyType = preMatch.captured(1);
×
364
                                        proxyUser = preMatch.captured(2);
×
365
                                        proxyPass = preMatch.captured(3);
×
366
                                        proxyHost = preMatch.captured(4);
×
367
                                        proxyPort = preMatch.captured(5);
×
368
                                }
369
                                else
370
                                {
371
                                        qDebug() << "indecipherable environment variable http_proxy:" << proxyString;
×
372
                                        return;
×
373
                                }
374
                        }
×
375
                }
×
376
        }
377

378
        bool useSocksProxy = proxyType.contains("socks", Qt::CaseInsensitive);
×
379

380
        if (!proxyHost.isEmpty())
×
381
        {
382
                QNetworkProxy proxy;
×
383
                if (useSocksProxy)
×
384
                        proxy.setType(QNetworkProxy::Socks5Proxy);
×
385
                else
386
                        proxy.setType(QNetworkProxy::HttpProxy);
×
387
                proxy.setHostName(proxyHost);
×
388
                if (!proxyPort.isEmpty())
×
389
                        proxy.setPort(proxyPort.toUShort());
×
390

391
                if (!proxyUser.isEmpty())
×
392
                        proxy.setUser(proxyUser);
×
393

394
                if (!proxyPass.isEmpty())
×
395
                        proxy.setPassword(proxyPass);
×
396

397
                QString ppDisp = proxyPass;
×
398
                ppDisp.fill('*');
×
399
                if (useSocksProxy)
×
400
                        qDebug() << "Using SOCKS proxy:" << proxyUser << ppDisp << proxyHost << proxyPort;
×
401
                else
402
                        qDebug() << "Using HTTP proxy:" << proxyUser << ppDisp << proxyHost << proxyPort;
×
403
                QNetworkProxy::setApplicationProxy(proxy);
×
404
        }
×
405
}
×
406

407
#ifdef ENABLE_SCRIPTING
408
void StelApp::initScriptMgr()
×
409
{
410
        scriptMgr->addModules();
×
411

412
#ifdef USE_STATIC_PLUGIN_CALENDARS
413
        Calendars *cal=GETSTELMODULE_SILENT(Calendars);
×
414
        if (cal)
×
415
                cal->makeCalendarsScriptable(scriptMgr);
×
416
#endif
417
        QString startupScript;
×
418
        if (qApp->property("onetime_startup_script").isValid())
×
419
                startupScript = qApp->property("onetime_startup_script").toString();
×
420
        else
421
                startupScript = confSettings->value("scripts/startup_script", "startup.ssc").toString();
×
422
        // Use a queued slot call to start the script only once the main qApp event loop is running...
423
        QMetaObject::invokeMethod(scriptMgr,
×
424
                                  "runScript",
425
                                  Qt::QueuedConnection,
426
                                  Q_ARG(QString, startupScript));
×
427
}
×
428
#else
429
void StelApp::initScriptMgr() {}
430
#endif
431

432
QStringList StelApp::getCommandlineArguments()
×
433
{
434
        return qApp->property("stelCommandLine").toStringList();
×
435
}
436

437
void StelApp::init(QSettings* conf)
×
438
{
439
        gl = QOpenGLContext::currentContext()->functions();
×
440
        confSettings = conf;
×
441

442
        devicePixelsPerPixel = QOpenGLContext::currentContext()->screen()->devicePixelRatio();
×
443
        if (devicePixelsPerPixel>1)
×
444
                qDebug() << "Detected a high resolution device! Device pixel ratio:" << devicePixelsPerPixel;
×
445

446
        setScreenFontSize(confSettings->value("gui/screen_font_size", 13).toInt());
×
447
        setGuiFontSize(confSettings->value("gui/gui_font_size", 13).toInt());
×
448
        setFlagImmediateSave(confSettings->value("gui/immediate_save_details", false).toBool());
×
449

450
        core = new StelCore();
×
451
        if (!fuzzyEquals(saveProjW, -1.) && !fuzzyEquals(saveProjH, -1.))
×
452
                core->windowHasBeenResized(0, 0, saveProjW, saveProjH);
×
453
        
454
        //Initializing locale at the beginning to show all strings translated
455
        localeMgr = new StelLocaleMgr();
×
456
        localeMgr->init();
×
457
        //SplashScreen::showMessage(q_("Initializing locales..."));
458

459
        SplashScreen::showMessage(q_("Initializing textures..."));
×
460
        // Initialize AFTER creation of openGL context
461
        textureMgr = new StelTextureMgr();
×
462

463
        SplashScreen::showMessage(q_("Initializing network access..."));
×
464
        networkAccessManager = new QNetworkAccessManager(this);
×
465
        networkAccessManager->setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
×
466
        SplashScreen::showMessage(q_("Initializing network disk cache..."));
×
467
        // Activate http cache if Qt version >= 4.5
468
        QNetworkDiskCache* cache = new QNetworkDiskCache(networkAccessManager);
×
469
        //make maximum cache size configurable (in MB)
470
        //the default Qt value (50 MB) is quite low, especially for DSS
471
        cache->setMaximumCacheSize(confSettings->value("main/network_cache_size",300).toInt() * 1024 * 1024);
×
472
        QString cachePath = StelFileMgr::getCacheDir();
×
473

474
        qDebug().noquote() << "Cache directory:" << QDir::toNativeSeparators(cachePath);
×
475
        cache->setCacheDirectory(cachePath);
×
476
        networkAccessManager->setCache(cache);        
×
477
        connect(networkAccessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(reportFileDownloadFinished(QNetworkReply*)));
×
478

479
        // Proxy Initialisation
480
        SplashScreen::showMessage(q_("Initializing network proxy..."));
×
481
        setupNetworkProxy();
×
482

483
        //create non-StelModule managers
484
        propMgr = new StelPropertyMgr();
×
485
        skyCultureMgr = new StelSkyCultureMgr();
×
486
        propMgr->registerObject(skyCultureMgr);
×
487
        planetLocationMgr = new StelLocationMgr();
×
488
        actionMgr = new StelActionMgr();
×
489

490
        // register non-modules for StelProperty tracking
491
        propMgr->registerObject(this);
×
492
        propMgr->registerObject(mainWin);
×
493

494
        // Stel Object Data Base manager
495
        SplashScreen::showMessage(q_("Initializing Object Database..."));
×
496
        stelObjectMgr = new StelObjectMgr();
×
497
        stelObjectMgr->init();
×
498
        getModuleMgr().registerModule(stelObjectMgr);        
×
499

500
        // Hips surveys
501
        SplashScreen::showMessage(q_("Initializing HiPS survey..."));
×
502
        HipsMgr* hipsMgr = new HipsMgr();
×
503
        hipsMgr->init();
×
504
        getModuleMgr().registerModule(hipsMgr);
×
505

506
        // Init the solar system first
507
        SplashScreen::showMessage(q_("Initializing Solar System objects..."));
×
508
        SolarSystem* ssystem = new SolarSystem();
×
509
        ssystem->init();
×
510
        getModuleMgr().registerModule(ssystem);
×
511

512
        // Init the nomenclature for Solar system bodies
513
        SplashScreen::showMessage(q_("Initializing planetary nomenclature..."));
×
514
        NomenclatureMgr* nomenclature = new NomenclatureMgr();
×
515
        nomenclature->init();
×
516
        getModuleMgr().registerModule(nomenclature);
×
517

518
        // Load stars & their names
519
        SplashScreen::showMessage(q_("Initializing stars..."));
×
520
        StarMgr* hip_stars = new StarMgr();
×
521
        hip_stars->init();
×
522
        getModuleMgr().registerModule(hip_stars);
×
523

524
        SplashScreen::showMessage(q_("Initializing core..."));
×
525
        core->init();
×
526

527
        // Init nebulas
528
        SplashScreen::showMessage(q_("Initializing deep-sky objects..."));
×
529
        NebulaMgr* nebulas = new NebulaMgr();
×
530
        nebulas->init();
×
531
        getModuleMgr().registerModule(nebulas);
×
532

533
        // Init milky way
534
        SplashScreen::showMessage(q_("Initializing Milky Way..."));
×
535
        MilkyWay* milky_way = new MilkyWay();
×
536
        milky_way->init();
×
537
        getModuleMgr().registerModule(milky_way);
×
538

539
        // Init zodiacal light
540
        SplashScreen::showMessage(q_("Initializing zodiacal light..."));
×
541
        ZodiacalLight* zodiacal_light = new ZodiacalLight();
×
542
        zodiacal_light->init();
×
543
        getModuleMgr().registerModule(zodiacal_light);
×
544

545
        // Init sky image manager
546
        SplashScreen::showMessage(q_("Initializing sky image layer..."));
×
547
        skyImageMgr = new StelSkyLayerMgr();
×
548
        skyImageMgr->init();
×
549
        getModuleMgr().registerModule(skyImageMgr);
×
550

551
        // Toast surveys
552
        SplashScreen::showMessage(q_("Initializing TOAST surveys..."));
×
553
        ToastMgr* toasts = new ToastMgr();
×
554
        toasts->init();
×
555
        getModuleMgr().registerModule(toasts);
×
556

557
        // Init audio manager
558
        SplashScreen::showMessage(q_("Initializing audio..."));
×
559
        audioMgr = new StelAudioMgr();
×
560

561
        // Init video manager
562
        SplashScreen::showMessage(q_("Initializing video..."));
×
563
        videoMgr = new StelVideoMgr();
×
564
        videoMgr->init();
×
565
        getModuleMgr().registerModule(videoMgr);
×
566

567
        // Constellations
568
        SplashScreen::showMessage(q_("Initializing constellations..."));
×
569
        ConstellationMgr* constellations = new ConstellationMgr(hip_stars);
×
570
        constellations->init();
×
571
        getModuleMgr().registerModule(constellations);
×
572

573
        // Asterisms
574
        SplashScreen::showMessage(q_("Initializing asterisms..."));
×
575
        AsterismMgr* asterisms = new AsterismMgr(hip_stars);
×
576
        asterisms->init();
×
577
        getModuleMgr().registerModule(asterisms);
×
578

579
        // Landscape, atmosphere & cardinal points section
580
        SplashScreen::showMessage(q_("Initializing landscape..."));
×
581
        LandscapeMgr* landscape = new LandscapeMgr();
×
582
        landscape->init();
×
583
        getModuleMgr().registerModule(landscape);
×
584

585
        SplashScreen::showMessage(q_("Initializing grid lines..."));
×
586
        GridLinesMgr* gridLines = new GridLinesMgr();
×
587
        gridLines->init();
×
588
        getModuleMgr().registerModule(gridLines);
×
589
        
590
        SplashScreen::showMessage(q_("Initializing special markers..."));
×
591
        SpecialMarkersMgr* specialMarkers = new SpecialMarkersMgr();
×
592
        specialMarkers->init();
×
593
        getModuleMgr().registerModule(specialMarkers);
×
594

595
        // Sporadic Meteors
596
        SplashScreen::showMessage(q_("Initializing sporadic meteors..."));
×
597
        SporadicMeteorMgr* meteors = new SporadicMeteorMgr(10, 72);
×
598
        meteors->init();
×
599
        getModuleMgr().registerModule(meteors);
×
600

601
        // User labels
602
        SplashScreen::showMessage(q_("Initializing user labels..."));
×
603
        LabelMgr* skyLabels = new LabelMgr();
×
604
        skyLabels->init();
×
605
        getModuleMgr().registerModule(skyLabels);
×
606

607
        SplashScreen::showMessage(q_("Initializing sky cultures..."));
×
608
        skyCultureMgr->init();
×
609

610
        // User markers
611
        SplashScreen::showMessage(q_("Initializing user markers..."));
×
612
        MarkerMgr* skyMarkers = new MarkerMgr();
×
613
        skyMarkers->init();
×
614
        getModuleMgr().registerModule(skyMarkers);
×
615

616
        // Init custom objects
617
        SplashScreen::showMessage(q_("Initializing custom objects..."));
×
618
        CustomObjectMgr* custObj = new CustomObjectMgr();
×
619
        custObj->init();
×
620
        getModuleMgr().registerModule(custObj);
×
621

622
        // Init highlights
623
        SplashScreen::showMessage(q_("Initializing highlights..."));
×
624
        HighlightMgr* hlMgr = new HighlightMgr();
×
625
        hlMgr->init();
×
626
        getModuleMgr().registerModule(hlMgr);
×
627

628
        // Init specific time
629
        SplashScreen::showMessage(q_("Initializing specific time..."));
×
630
        SpecificTimeMgr* specificTime = new SpecificTimeMgr();
×
631
        specificTime->init();
×
632
        getModuleMgr().registerModule(specificTime);
×
633

634
        //Create the script manager here, maybe some modules/plugins may want to connect to it
635
        //It has to be initialized later after all modules have been loaded by calling initScriptMgr
636
#ifdef ENABLE_SCRIPTING
637
        SplashScreen::showMessage(q_("Initializing scripting..."));
×
638
        scriptAPIProxy = new StelMainScriptAPIProxy(this);
×
639
        scriptMgr = new StelScriptMgr(this);
×
640
#endif
641

642
        SplashScreen::showMessage(q_("Initializing color scheme..."));
×
643
        // Initialisation of the color scheme
644
        emit colorSchemeChanged("default");
×
645
        setVisionModeNight(confSettings->value("viewing/flag_night", false).toBool());
×
646

647
        // Enable viewport effect at startup if he set
648
        setViewportEffect(confSettings->value("video/viewport_effect", "none").toString());
×
649

650
        SplashScreen::clearMessage();
×
651
        updateI18n();
×
652

653
        // Init actions.
654
        actionMgr->addAction("actionShow_Night_Mode", N_("Display Options"), N_("Night mode"), this, "nightMode", "Ctrl+N");
×
655

656
        setFlagShowDecimalDegrees(confSettings->value("gui/flag_show_decimal_degrees", false).toBool());
×
657
        setFlagSouthAzimuthUsage(confSettings->value("gui/flag_use_azimuth_from_south", false).toBool());
×
658
        setFlagUseFormattingOutput(confSettings->value("gui/flag_use_formatting_output", false).toBool());
×
659
        setFlagUseCCSDesignation(confSettings->value("gui/flag_use_ccs_designations", false).toBool());
×
660
        setFlagOverwriteInfoColor(confSettings->value("gui/flag_overwrite_info_color", false).toBool());        
×
661
        setOverwriteInfoColor(Vec3f(confSettings->value("color/info_text_color", "1.0,1.0,1.0").toString()));
×
662
        setDaylightInfoColor(Vec3f(confSettings->value("color/daylight_text_color", "0.0,0.0,0.0").toString()));
×
663

664
        // Animation
665
        animationScale = confSettings->value("gui/pointer_animation_speed", 1.).toDouble();
×
666

667
        ditherPatternTex = StelApp::getInstance().getTextureManager().getDitheringTexture(0);
×
668
        setupPostProcessor();
×
669
        
670
#ifdef ENABLE_SPOUT
671
        //qDebug() << "Property spout is" << qApp->property("spout").toString();
672
        //qDebug() << "Property spoutName is" << qApp->property("spoutName").toString();
673
        if (qApp->property("spout").toString() != "none")
674
        {
675
                //if we are on windows and we have GLES, we are most likely on ANGLE
676
                bool isANGLE=QOpenGLContext::currentContext()->isOpenGLES();
677

678
                if (isANGLE)
679
                {
680
                        qCritical() << "SPOUT: Does not run in ANGLE/OpenGL ES mode!";
681
                }
682
                else
683
                {
684
                        SplashScreen::showMessage(q_("Initializing SPOUT sender..."));
685
                        // Create the SpoutSender object.
686
                        QString spoutName = qApp->property("spoutName").toString();
687
                        if(spoutName.isEmpty())
688
                                spoutName = "stellarium";
689

690
                        spoutSender = new SpoutSender(spoutName);
691

692
                        if (!spoutSender->isValid())
693
                        {
694
                                QMessageBox::warning(&StelMainView::getInstance(), "Stellarium SPOUT", q_("Cannot create Spout sender. See log for details."), QMessageBox::Ok);
695
                                delete spoutSender;
696
                                spoutSender = Q_NULLPTR;
697
                                qApp->setProperty("spout", "");
698
                        }
699
                        SplashScreen::clearMessage();
700
                }
701
        }
702
        else
703
        {
704
                qApp->setProperty("spout", "");
705
        }
706
#endif
707

708
        initialized = true;
×
709
}
×
710

711
// Load and initialize external modules (plugins)
712
void StelApp::initPlugIns()
×
713
{
714
        // Load dynamically all the modules found in the modules/ directories
715
        // which are configured to be loaded at startup
716
        const QList<StelModuleMgr::PluginDescriptor> pluginList=moduleMgr->getPluginsList();
×
717
        for (const auto& i : pluginList)
×
718
        {
719
                if (i.loadAtStartup==false)
×
720
                        continue;
×
721
                SplashScreen::showMessage(QString("%1 \"%2\"...").arg(q_("Loading plugin"), q_(i.info.displayedName)));
×
722
                StelModule* m = moduleMgr->loadPlugin(i.info.id);
×
723
                if (m!=Q_NULLPTR)
×
724
                {
725
                        moduleMgr->registerModule(m, true);
×
726
                        //load extensions after the module is registered
727
                        moduleMgr->loadExtensions(i.info.id);
×
728
                        m->init();
×
729
                }
730
        }
731
        SplashScreen::clearMessage();
×
732
}
×
733

734
void StelApp::deinit()
×
735
{
736
#ifdef         ENABLE_SPOUT
737
        delete spoutSender;
738
        spoutSender = Q_NULLPTR;
739
#endif
740
#ifdef ENABLE_SCRIPTING
741
        if (scriptMgr->scriptIsRunning())
×
742
                scriptMgr->stopScript();
×
743
#endif
744
        QCoreApplication::processEvents();
×
745
        getModuleMgr().unloadAllPlugins();
×
746
        QCoreApplication::processEvents();
×
747
        StelPainter::deinitGLShaders();
×
748
}
×
749

750

751
StelProgressController* StelApp::addProgressBar()
×
752
{
753
        StelProgressController* p = new StelProgressController(this);
×
754
        progressControllers.append(p);
×
755
        emit progressBarAdded(p);
×
756
        return p;
×
757
}
758

759
void StelApp::removeProgressBar(StelProgressController* p)
×
760
{
761
        progressControllers.removeOne(p);        
×
762
        emit progressBarRemoved(p);
×
763
        delete p;
×
764
}
×
765

766

767
void StelApp::update(double deltaTime)
×
768
{
769
        if (!initialized)
×
770
                return;
×
771

772
        ++frame;
×
773
        frameTimeAccum+=deltaTime;
×
774
        if (frameTimeAccum > 1.)
×
775
        {
776
                // Calc the FPS rate every seconds
777
                fps=static_cast<float>(frame)/static_cast<float>(frameTimeAccum);
×
778
                frame = 0;
×
779
                frameTimeAccum=0.;
×
780
        }
781
                
782
        core->update(deltaTime);
×
783

784
        moduleMgr->update();
×
785

786
        // Send the event to every StelModule
787
        for (auto* i : moduleMgr->getCallOrders(StelModule::ActionUpdate))
×
788
        {
789
                i->update(deltaTime);
×
790
        }
791

792
        stelObjectMgr->update(deltaTime);
×
793
}
794

795
void StelApp::prepareRenderBuffer()
×
796
{
797
        if (!viewportEffect) return;
×
798
        if (!renderBuffer)
×
799
        {
800
                StelProjector::StelProjectorParams params = core->getCurrentStelProjectorParams();
×
801
                int w = params.viewportXywh[2];
×
802
                int h = params.viewportXywh[3];
×
803
                renderBuffer = new QOpenGLFramebufferObject(w, h, QOpenGLFramebufferObject::Depth); // we only need depth here
×
804
        }
805
        renderBuffer->bind();
×
806
}
807

808
void StelApp::applyRenderBuffer(GLuint drawFbo)
×
809
{
810
        if (!renderBuffer) return;
×
811
        GL(gl->glBindFramebuffer(GL_FRAMEBUFFER, drawFbo));
×
812
        viewportEffect->paintViewportBuffer(renderBuffer);
×
813
}
814

815
void StelApp::setupPostProcessor()
×
816
{
817
        postProcessorVBO.reset(new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer));
×
818
        postProcessorVBO->create();
×
819
        postProcessorVBO->bind();
×
820
        const GLfloat vertices[]=
×
821
        {
822
                // full screen quad
823
                -1, -1,
824
                 1, -1,
825
                -1,  1,
826
                 1,  1,
827
        };
828
        GL(gl->glBufferData(GL_ARRAY_BUFFER, sizeof vertices, vertices, GL_STATIC_DRAW));
×
829

830
        postProcessorVAO.reset(new QOpenGLVertexArrayObject);
×
831
        postProcessorVAO->create();
×
832
        postProcessorVAO->bind();
×
833
        gl->glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
×
834
        postProcessorVBO->release();
×
835
        gl->glEnableVertexAttribArray(0);
×
836
        postProcessorVAO->release();
×
837

838
        postProcessorProgram.reset(new QOpenGLShaderProgram);
×
839
        postProcessorProgram->addShaderFromSourceCode(QOpenGLShader::Vertex,
×
840
                StelOpenGL::globalShaderPrefix(StelOpenGL::VERTEX_SHADER) + R"(
×
841
ATTRIBUTE vec3 vertex;
842
VARYING vec2 texcoord;
843
void main()
844
{
845
        gl_Position = vec4(vertex, 1.);
846
        texcoord = 0.5*vertex.xy+0.5;
847
}
848
)");
849
        postProcessorProgram->addShaderFromSourceCode(QOpenGLShader::Fragment,
×
850
                StelOpenGL::globalShaderPrefix(StelOpenGL::FRAGMENT_SHADER) +
×
851
                makeDitheringShader() + R"(
×
852
VARYING vec2 texcoord;
853
uniform sampler2D tex;
854

855
void main()
856
{
857
        vec4 rgba = texture2D(tex, texcoord);
858
        FRAG_COLOR = vec4(dither(rgba.rgb), rgba.a);
859
}
860
)");
861
        StelPainter::linkProg(postProcessorProgram.get(), "Post-processing program");
×
862
        postProcessorProgram->bind();
×
863
        postProcessorUniformLocations.tex           = postProcessorProgram->uniformLocation("tex");
×
864
        postProcessorUniformLocations.rgbMaxValue   = postProcessorProgram->uniformLocation("rgbMaxValue");
×
865
        postProcessorUniformLocations.ditherPattern = postProcessorProgram->uniformLocation("ditherPattern");
×
866
        postProcessorProgram->release();
×
867

868
        if(StelMainView::getInstance().getGLInformation().isHighGraphicsMode)
×
869
        {
870
                postProcessorProgramMS.reset(new QOpenGLShaderProgram);
×
871
                postProcessorProgramMS->addShaderFromSourceCode(QOpenGLShader::Vertex,
×
872
                        StelOpenGL::globalShaderPrefix(StelOpenGL::VERTEX_SHADER) + R"(
×
873
ATTRIBUTE vec3 vertex;
874
void main()
875
{
876
        gl_Position = vec4(vertex, 1.);
877
}
878
)");
879
                postProcessorProgramMS->addShaderFromSourceCode(QOpenGLShader::Fragment,
×
880
                        StelOpenGL::globalShaderPrefix(StelOpenGL::FRAGMENT_SHADER) +
×
881
                        makeDitheringShader() + R"(
×
882
uniform sampler2DMS tex;
883
uniform int numMultiSamples;
884

885
void main()
886
{
887
        vec4 rgba = vec4(0);
888
        for(int n = 0; n < numMultiSamples; ++n)
889
                rgba += texelFetch(tex, ivec2(gl_FragCoord.xy), n);
890
        rgba /= float(numMultiSamples);
891
        FRAG_COLOR = vec4(dither(rgba.rgb), rgba.a);
892
}
893
)");
894
                StelPainter::linkProg(postProcessorProgramMS.get(), "Multisampled post-processing program");
×
895
                postProcessorProgramMS->bind();
×
896
                postProcessorUniformLocationsMS.tex               = postProcessorProgramMS->uniformLocation("tex");
×
897
                postProcessorUniformLocationsMS.rgbMaxValue       = postProcessorProgramMS->uniformLocation("rgbMaxValue");
×
898
                postProcessorUniformLocationsMS.ditherPattern     = postProcessorProgramMS->uniformLocation("ditherPattern");
×
899
                postProcessorUniformLocationsMS.numMultiSamples   = postProcessorProgramMS->uniformLocation("numMultiSamples");
×
900
                postProcessorProgramMS->release();
×
901
        }
902
}
×
903

904
void StelApp::highGraphicsModeDraw()
×
905
{
906
#if !QT_CONFIG(opengles2)
907
        const auto targetFBO = currentFbo;
×
908
        StelProjector::StelProjectorParams params = core->getCurrentStelProjectorParams();
×
909
        const auto w = params.viewportXywh[2] * params.devicePixelsPerPixel;
×
910
        const auto h = params.viewportXywh[3] * params.devicePixelsPerPixel;
×
911
        StelOpenGL::checkGLErrors(__FILE__, __LINE__);
×
912
        if(!sceneFBO || sceneFBO->size() != QSize(w,h))
×
913
        {
914
                qDebug().nospace() << "Creating scene FBO with size " << w << "x" << h;
×
915
                const auto internalFormat = GL_RGBA16;
×
916
                QOpenGLFramebufferObjectFormat format;
×
917
                format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
×
918
                format.setInternalTextureFormat(internalFormat);
×
919
                sceneFBO.reset(new QOpenGLFramebufferObject(w, h, format));
×
920
                GLint maxSamples = 1;
×
921
                GL(gl->glGetIntegerv(GL_MAX_SAMPLES, &maxSamples));
×
922
                const auto samples = confSettings->value("video/multisampling", 0).toInt();
×
923
                numMultiSamples = std::min(samples, maxSamples);
×
924
                if(numMultiSamples > 1)
×
925
                {
926
                        const auto gl = StelOpenGL::highGraphicsFunctions();
×
927
                        if(sceneMultisampledFBO)
×
928
                        {
929
                                GL(gl->glDeleteFramebuffers(1, &sceneMultisampledFBO));
×
930
                                GL(gl->glDeleteTextures(1, &sceneMultisampledTex));
×
931
                                GL(gl->glDeleteRenderbuffers(1, &sceneMultisampledRenderbuffer));
×
932
                        }
933
                        GL(gl->glGenFramebuffers(1, &sceneMultisampledFBO));
×
934
                        GL(gl->glGenTextures(1, &sceneMultisampledTex));
×
935
                        GL(gl->glGenRenderbuffers(1, &sceneMultisampledRenderbuffer));
×
936

937
                        GL(gl->glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, sceneMultisampledTex));
×
938
                        GL(gl->glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, numMultiSamples,
×
939
                                                                internalFormat, w, h, true));
940

941
                        GL(gl->glBindRenderbuffer(GL_RENDERBUFFER, sceneMultisampledRenderbuffer));
×
942
                        GL(gl->glRenderbufferStorageMultisample(GL_RENDERBUFFER, numMultiSamples,
×
943
                                                                         GL_DEPTH24_STENCIL8, w, h));
944

945
                        GL(gl->glBindFramebuffer(GL_FRAMEBUFFER, sceneMultisampledFBO));
×
946
                        GL(gl->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
×
947
                                                      GL_TEXTURE_2D_MULTISAMPLE, sceneMultisampledTex, 0));
948
                        GL(gl->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
×
949
                                                         GL_RENDERBUFFER, sceneMultisampledRenderbuffer));
950
                        const auto status = gl->glCheckFramebufferStatus(GL_FRAMEBUFFER);
×
951
                        if(status != GL_FRAMEBUFFER_COMPLETE)
×
952
                        {
953
                                qCritical().nospace() << __FILE__ << ":" << __LINE__
×
954
                                                      << ": warning: framebuffer incomplete, status: "
×
955
                                                      << status;
×
956
                        }
957
                }
958
        }
×
959

960
        if(sceneMultisampledFBO)
×
961
        {
962
                GL(gl->glBindFramebuffer(GL_FRAMEBUFFER, sceneMultisampledFBO));
×
963
                currentFbo = sceneMultisampledFBO;
×
964
        }
965
        else
966
        {
967
                sceneFBO->bind();
×
968
                currentFbo = sceneFBO->handle();
×
969
        }
970
        StelOpenGL::checkGLErrors(__FILE__, __LINE__);
×
971

972
        GL(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));
×
973

974
        const QList<StelModule*> modules = moduleMgr->getCallOrders(StelModule::ActionDraw);
×
975

976
        for(auto* module : modules)
×
977
        {
978
                module->draw(core);
×
979
        }
980

981
        if(sceneMultisampledFBO)
×
982
        {
983
                GL(gl->glBindFramebuffer(GL_FRAMEBUFFER, targetFBO));
×
984
                postProcessorProgramMS->bind();
×
985

986
                const int sceneTexSampler = 0;
×
987
                GL(gl->glActiveTexture(GL_TEXTURE0 + sceneTexSampler));
×
988
                GL(gl->glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, sceneMultisampledTex));
×
989
                postProcessorProgramMS->setUniformValue(postProcessorUniformLocationsMS.tex, sceneTexSampler);
×
990

991
                const int ditherTexSampler = 1;
×
992
                ditherPatternTex->bind(ditherTexSampler);
×
993
                postProcessorProgramMS->setUniformValue(postProcessorUniformLocationsMS.ditherPattern, ditherTexSampler);
×
994
                const auto rgbMaxValue=calcRGBMaxValue(core->getDitheringMode());
×
995
                postProcessorProgramMS->setUniformValue(postProcessorUniformLocationsMS.rgbMaxValue,
×
996
                                                        rgbMaxValue[0], rgbMaxValue[1], rgbMaxValue[2]);
×
997
                postProcessorProgramMS->setUniformValue(postProcessorUniformLocationsMS.numMultiSamples, numMultiSamples);
×
998
        }
999
        else
1000
        {
1001
                GL(gl->glBindFramebuffer(GL_FRAMEBUFFER, targetFBO));
×
1002
                postProcessorProgram->bind();
×
1003

1004
                const int sceneTexSampler = 0;
×
1005
                GL(gl->glActiveTexture(GL_TEXTURE0 + sceneTexSampler));
×
1006
                GL(gl->glBindTexture(GL_TEXTURE_2D, sceneFBO->texture()));
×
1007
                postProcessorProgram->setUniformValue(postProcessorUniformLocations.tex, sceneTexSampler);
×
1008

1009
                const int ditherTexSampler = 1;
×
1010
                ditherPatternTex->bind(ditherTexSampler);
×
1011
                postProcessorProgram->setUniformValue(postProcessorUniformLocations.ditherPattern, ditherTexSampler);
×
1012
                const auto rgbMaxValue=calcRGBMaxValue(core->getDitheringMode());
×
1013
                postProcessorProgram->setUniformValue(postProcessorUniformLocations.rgbMaxValue,
×
1014
                                                      rgbMaxValue[0], rgbMaxValue[1], rgbMaxValue[2]);
×
1015

1016
        }
1017

1018
        postProcessorVAO->bind();
×
1019
        GL(gl->glEnable(GL_BLEND));
×
1020
        GL(gl->glBlendFunc(GL_ONE,GL_ONE));
×
1021
        GL(gl->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
×
1022
        GL(gl->glDisable(GL_BLEND));
×
1023
        postProcessorVAO->release();
×
1024
#endif
1025
}
×
1026

1027
//! Main drawing function called at each frame
1028
void StelApp::draw()
×
1029
{
1030
        if (!initialized)
×
1031
                return;
×
1032

1033
        //find out which framebuffer is the current one
1034
        //this is usually NOT the "zero" FBO, but one provided by QOpenGLWidget
1035
        GLint drawFbo;
1036
        GL(gl->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &drawFbo));
×
1037

1038
        prepareRenderBuffer();
×
1039
        currentFbo = renderBuffer ? renderBuffer->handle() : static_cast<GLuint>(drawFbo);
×
1040

1041
        core->preDraw();
×
1042

1043
        if(StelMainView::getInstance().getGLInformation().isHighGraphicsMode)
×
1044
        {
1045
                highGraphicsModeDraw();
×
1046
        }
1047
        else
1048
        {
1049
                const QList<StelModule*> modules = moduleMgr->getCallOrders(StelModule::ActionDraw);
×
1050
                for (auto* module : modules)
×
1051
                {
1052
                        module->draw(core);
×
1053
                }
1054
        }
×
1055

1056
        core->postDraw();
×
1057
#ifdef ENABLE_SPOUT
1058
        // At this point, the sky scene has been drawn, but no GUI panels.
1059
        if(spoutSender)
1060
                spoutSender->captureAndSendFrame(static_cast<GLuint>(drawFbo));
1061
#endif
1062
        applyRenderBuffer(static_cast<GLuint>(drawFbo));
×
1063
}
1064

1065
/*************************************************************************
1066
 Call this when the size of the GL window has changed
1067
*************************************************************************/
1068
void StelApp::glWindowHasBeenResized(const QRectF& rect)
×
1069
{
1070
        // Remove the effect before resizing the core, or things get messy.
1071
        QString effect = getViewportEffect();
×
1072
        setViewportEffect("none");
×
1073
        if (core)
×
1074
        {
1075
                core->windowHasBeenResized(rect.x(), rect.y(), rect.width(), rect.height());
×
1076
        }
1077
        else
1078
        {
1079
                saveProjW = rect.width();
×
1080
                saveProjH = rect.height();
×
1081
        }
1082
        // Force to recreate the viewport effect if any.
1083
        setViewportEffect(effect);
×
1084
#ifdef ENABLE_SPOUT
1085
        if (spoutSender)
1086
                spoutSender->resize(static_cast<uint>(rect.width()),static_cast<uint>(rect.height()));
1087
#endif
1088
}
×
1089

1090
// Handle mouse clics
1091
void StelApp::handleClick(QMouseEvent* inputEvent)
×
1092
{
1093
        QPointF pos = inputEvent->pos();
×
1094
        qreal x, y;
1095
        x = pos.x();
×
1096
        y = pos.y();
×
1097
        if (viewportEffect)
×
1098
                viewportEffect->distortXY(x, y);
×
1099

1100
        QMouseEvent event(inputEvent->type(), QPoint(qRound(x*devicePixelsPerPixel), qRound(y*devicePixelsPerPixel)), inputEvent->button(), inputEvent->buttons(), inputEvent->modifiers());
×
1101
        event.setAccepted(false);
×
1102
        
1103
        // Send the event to every StelModule
1104
        for (auto* i : moduleMgr->getCallOrders(StelModule::ActionHandleMouseClicks))
×
1105
        {
1106
                i->handleMouseClicks(&event);
×
1107
                if (event.isAccepted())
×
1108
                {
1109
                        inputEvent->setAccepted(true);
×
1110
                        return;
×
1111
                }
1112
        }
1113
}
×
1114

1115
// Handle mouse wheel.
1116
void StelApp::handleWheel(QWheelEvent* event)
×
1117
{
1118
        event->setAccepted(false);
×
1119
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
1120
        QWheelEvent deltaEvent(event->position()*devicePixelsPerPixel,
×
1121
                               event->globalPosition()*devicePixelsPerPixel,
×
1122
                               event->pixelDelta(), event->angleDelta(), event->buttons(), event->modifiers(), Qt::ScrollUpdate, false);
×
1123
#else
1124
        QWheelEvent deltaEvent(QPoint(qRound(event->pos().x()*devicePixelsPerPixel), qRound(event->pos().y()*devicePixelsPerPixel)),
1125
                               QPoint(qRound(event->globalPos().x()*devicePixelsPerPixel), qRound(event->globalPos().y()*devicePixelsPerPixel)),
1126
                               event->delta(), event->buttons(), event->modifiers(), event->orientation());
1127
#endif
1128
        deltaEvent.setAccepted(false);
×
1129
        // Send the event to every StelModule
1130
        for (auto* i : moduleMgr->getCallOrders(StelModule::ActionHandleMouseClicks)) {
×
1131
                i->handleMouseWheel(&deltaEvent);
×
1132
                if (deltaEvent.isAccepted()) {
×
1133
                        event->accept();
×
1134
                        break;
×
1135
                }
1136
        }
1137
}
×
1138

1139
// Handle mouse move
1140
bool StelApp::handleMove(qreal x, qreal y, Qt::MouseButtons b)
×
1141
{
1142
        if (viewportEffect)
×
1143
                viewportEffect->distortXY(x, y);
×
1144
        // Send the event to every StelModule
1145
        for (auto* i : moduleMgr->getCallOrders(StelModule::ActionHandleMouseMoves))
×
1146
        {
1147
                if (i->handleMouseMoves(qRound(x*devicePixelsPerPixel), qRound(y*devicePixelsPerPixel), b))
×
1148
                        return true;
×
1149
        }
1150
        return false;
×
1151
}
1152

1153
// Handle key press and release
1154
void StelApp::handleKeys(QKeyEvent* event)
×
1155
{
1156
        event->setAccepted(false);
×
1157
        // First try to trigger a shortcut.
1158
        if (event->type() == QEvent::KeyPress)
×
1159
        {
1160
                if (getStelActionManager()->pushKey(event->key() + int(event->modifiers())))
×
1161
                {
1162
                        event->setAccepted(true);
×
1163
                        return;
×
1164
                }
1165
        }
1166
        // Send the event to every StelModule
1167
        for (auto* i : moduleMgr->getCallOrders(StelModule::ActionHandleKeys))
×
1168
        {
1169
                i->handleKeys(event);
×
1170
                if (event->isAccepted())
×
1171
                        return;
×
1172
        }
1173
}
1174

1175
// Handle pinch on multi touch devices
1176
void StelApp::handlePinch(qreal scale, bool started)
×
1177
{
1178
        // Send the event to every StelModule
1179
        for (auto* i : moduleMgr->getCallOrders(StelModule::ActionHandleMouseMoves))
×
1180
        {
1181
                if (i->handlePinch(scale, started))
×
1182
                        return;
×
1183
        }
1184
}
1185

1186
//! Set flag for activating night vision mode
1187
void StelApp::setVisionModeNight(bool b)
×
1188
{
1189
        if (flagNightVision!=b)
×
1190
        {
1191
                flagNightVision=b;
×
1192
                emit visionNightModeChanged(b);
×
1193
        }
1194
}
×
1195

1196
void StelApp::setFlagOverwriteInfoColor(bool b)
×
1197
{
1198
        if (flagOverwriteInfoColor!=b)
×
1199
        {
1200
                flagOverwriteInfoColor=b;
×
1201
                emit flagOverwriteInfoColorChanged(b);
×
1202
        }
1203
}
×
1204

1205
void StelApp::setFlagShowDecimalDegrees(bool b)
×
1206
{
1207
        if (flagShowDecimalDegrees!=b)
×
1208
        {
1209
                flagShowDecimalDegrees = b;
×
1210
                emit flagShowDecimalDegreesChanged(b);
×
1211
        }
1212
}
×
1213

1214
void StelApp::setFlagUseFormattingOutput(bool b)
×
1215
{
1216
        if (flagUseFormattingOutput!=b)
×
1217
        {
1218
                flagUseFormattingOutput = b;
×
1219
                emit flagUseFormattingOutputChanged(b);
×
1220
        }
1221
}
×
1222

1223
void StelApp::setFlagUseCCSDesignation(bool b)
×
1224
{
1225
        if (flagUseCCSDesignation!=b)
×
1226
        {
1227
                flagUseCCSDesignation = b;
×
1228
                emit flagUseCCSDesignationChanged(b);
×
1229
        }
1230
}
×
1231

1232
void StelApp::setOverwriteInfoColor(const Vec3f& color)
×
1233
{
1234
        if (color != overwriteInfoColor)
×
1235
        {
1236
                overwriteInfoColor = color;
×
1237
                emit overwriteInfoColorChanged(color);
×
1238
        }
1239
}
×
1240

1241
Vec3f StelApp::getOverwriteInfoColor() const
×
1242
{
1243
        return overwriteInfoColor;
×
1244
}
1245

1246
void StelApp::setDaylightInfoColor(const Vec3f& color)
×
1247
{
1248
        if (color != daylightInfoColor)
×
1249
        {
1250
                daylightInfoColor = color;
×
1251
                emit daylightInfoColorChanged(color);
×
1252
        }
1253
}
×
1254

1255
Vec3f StelApp::getDaylightInfoColor() const
×
1256
{
1257
        return daylightInfoColor;
×
1258
}
1259

1260
void StelApp::setFlagImmediateSave(bool b)
×
1261
{
1262
        if (flagImmediateSave!=b)
×
1263
        {
1264
                flagImmediateSave = b;
×
1265
                emit flagImmediateSaveChanged(b);
×
1266
        }
1267
}
×
1268

1269
void StelApp::immediateSave(const QString &key, const QVariant &value)
×
1270
{
1271
        if (getInstance().getFlagImmediateSave())
×
1272
                getInstance().getSettings()->setValue(key, value);
×
1273
}
×
1274

1275

1276
// Update translations and font for sky everywhere in the program
1277
void StelApp::updateI18n()
×
1278
{
1279
#ifdef ENABLE_NLS
1280
        emit languageChanged();
1281
#endif
1282
}
×
1283

1284
void StelApp::ensureGLContextCurrent()
×
1285
{
1286
        mainWin->glContextMakeCurrent();
×
1287
}
×
1288

1289
// Return the time since when stellarium is running in second.
1290
double StelApp::getTotalRunTime()
×
1291
{
1292
        return static_cast<double>(QDateTime::currentMSecsSinceEpoch() - StelApp::startMSecs)/1000.;
×
1293
}
1294

1295
// Return the scaled time since when stellarium is running in second.
1296
double StelApp::getAnimationTime()
×
1297
{
1298
        return static_cast<double>(QDateTime::currentMSecsSinceEpoch() - StelApp::startMSecs)*StelApp::animationScale/1000.;
×
1299
}
1300

1301
void StelApp::reportFileDownloadFinished(QNetworkReply* reply)
×
1302
{
1303
        bool fromCache = reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool();
×
1304
        if (fromCache)
×
1305
        {
1306
                ++nbUsedCache;
×
1307
                totalUsedCacheSize+=reply->bytesAvailable();
×
1308
        }
1309
        else
1310
        {
1311
                ++nbDownloadedFiles;
×
1312
                totalDownloadedSize+=reply->bytesAvailable();
×
1313
        }
1314
}
×
1315

1316
void StelApp::quit()
×
1317
{
1318
        emit aboutToQuit();
×
1319
        // Let's allow exit from Stellarium via startup script!
1320
        QMetaObject::invokeMethod(qApp, "quit", Qt::QueuedConnection);
×
1321
}
×
1322

1323
void StelApp::setDevicePixelsPerPixel(qreal dppp)
×
1324
{
1325
        // Check that the device-independent pixel size didn't change
1326
        if (!viewportEffect && !fuzzyEquals(devicePixelsPerPixel, dppp))
×
1327
        {
1328
                devicePixelsPerPixel = dppp;
×
1329
                StelProjector::StelProjectorParams params = core->getCurrentStelProjectorParams();
×
1330
                params.devicePixelsPerPixel = devicePixelsPerPixel;
×
1331
                core->setCurrentStelProjectorParams(params);
×
1332
        }
1333
}
×
1334

1335
void StelApp::setViewportEffect(const QString& name)
×
1336
{
1337
        if (name == getViewportEffect()) return;
×
1338
        if (renderBuffer)
×
1339
        {
1340
                ensureGLContextCurrent();
×
1341
                delete renderBuffer;
×
1342
                renderBuffer = Q_NULLPTR;
×
1343
        }
1344
        if (viewportEffect)
×
1345
        {
1346
                delete viewportEffect;
×
1347
                viewportEffect = Q_NULLPTR;
×
1348
        }
1349
        if (name == "none") return;
×
1350

1351
        if (!core)
×
1352
        {
1353
                qDebug() << "No core to set viewport effect";
×
1354
                return;
×
1355
        }
1356
        StelProjector::StelProjectorParams params = core->getCurrentStelProjectorParams();
×
1357
        int w = params.viewportXywh[2];
×
1358
        int h = params.viewportXywh[3];
×
1359
        if (name == "sphericMirrorDistorter")
×
1360
        {
1361
                viewportEffect = new StelViewportDistorterFisheyeToSphericMirror(w, h);
×
1362
        }
1363
        else
1364
        {
1365
                qDebug() << "unknown viewport effect name:" << name;
×
1366
                Q_ASSERT(false);
×
1367
        }
1368
}
1369

1370
QString StelApp::getViewportEffect() const
×
1371
{
1372
        if (viewportEffect)
×
1373
                return viewportEffect->getName();
×
1374
        return "none";
×
1375
}
1376

1377
// Diagnostics
1378
void StelApp::dumpModuleActionPriorities(StelModule::StelModuleActionName actionName) const
×
1379
{
1380
        const QList<StelModule*> modules = moduleMgr->getCallOrders(actionName);
×
1381
        QMetaEnum me = QMetaEnum::fromType<StelModule::StelModuleActionName>();
×
1382
        qDebug() << "Module Priorities for action named" << me.valueToKey(actionName);
×
1383

1384
        for (auto* module : modules)
×
1385
        {
1386
                module->draw(core);
×
1387
                qDebug() << " -- " << module->getCallOrder(actionName) << "Module: " << module->objectName();
×
1388
        }
1389
}
×
1390

1391
StelModule* StelApp::getModule(const QString& moduleID) const
×
1392
{
1393
        return getModuleMgr().getModule(moduleID);
×
1394
}
1395
void StelApp::setScreenFontSize(int s)
×
1396
{
1397
        if (screenFontSize!=s)
×
1398
        {
1399
                screenFontSize=s;
×
1400
                emit screenFontSizeChanged(s);
×
1401
        }
1402
}
×
1403
void StelApp::setGuiFontSize(int s)
×
1404
{
1405
        if (getGuiFontSize()!=s)
×
1406
        {
1407
                QFont font=QGuiApplication::font();
×
1408
                font.setPixelSize(s);
×
1409
                QGuiApplication::setFont(font);
×
1410
                emit guiFontSizeChanged(s);
×
1411
        }
×
1412
}
×
1413
int StelApp::getGuiFontSize() const
×
1414
{
1415
        return QGuiApplication::font().pixelSize();
×
1416
}
1417

1418
void StelApp::setAppFont(QFont font)
×
1419
{
1420
        int oldSize=QGuiApplication::font().pixelSize();
×
1421
        font.setPixelSize(oldSize);
×
1422
        #if (QT_VERSION>=QT_VERSION_CHECK(5,15,0))
1423
        font.setStyleHint(QFont::AnyStyle, QFont::PreferAntialias);
×
1424
        #else
1425
        font.setStyleHint(QFont::AnyStyle, QFont::OpenGLCompatible);
1426
        #endif
1427
        QGuiApplication::setFont(font);
×
1428
        emit fontChanged(font);
×
1429
}
×
1430

1431
QString StelApp::getVersion() const
×
1432
{
1433
        QStringList ver = StelUtils::getApplicationVersion().split(".");
×
1434
        return QString("%1.%2.%3").arg(ver[0], ver[1], ver[2]);
×
1435
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc