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

Stellarium / stellarium / 11620555824

31 Oct 2024 10:03PM UTC coverage: 12.058% (-0.004%) from 12.062%
11620555824

Pull #3945

github

gzotti
Cleanup
Pull Request #3945: Allow dimming of DSO hints and labels

0 of 102 new or added lines in 6 files covered. (0.0%)

17 existing lines in 3 files now uncovered.

14434 of 119703 relevant lines covered (12.06%)

18852.99 hits per line

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

3.33
/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 "StelGui.hpp"
63
#include "StelGuiItems.hpp"
64
#include "StelPainter.hpp"
65
#ifdef ENABLE_SCRIPTING
66
 #include "StelScriptMgr.hpp"
67
 #include "StelMainScriptAPIProxy.hpp"
68

69
#ifdef USE_STATIC_PLUGIN_CALENDARS
70
 #include "../plugins/Calendars/src/Calendars.hpp"
71
#endif
72
#endif
73

74

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

111
#ifdef USE_STATIC_PLUGIN_HELLOSTELMODULE
112
Q_IMPORT_PLUGIN(HelloStelModuleStelPluginInterface)
113
#endif
114

115
#ifdef USE_STATIC_PLUGIN_SIMPLEDRAWLINE
116
Q_IMPORT_PLUGIN(SimpleDrawLineStelPluginInterface)
117
#endif
118

119
#ifdef USE_STATIC_PLUGIN_ANGLEMEASURE
120
Q_IMPORT_PLUGIN(AngleMeasureStelPluginInterface)
15✔
121
#endif
122

123
#ifdef USE_STATIC_PLUGIN_ARCHAEOLINES
124
Q_IMPORT_PLUGIN(ArchaeoLinesStelPluginInterface)
15✔
125
#endif
126

127
#ifdef USE_STATIC_PLUGIN_CALENDARS
128
Q_IMPORT_PLUGIN(CalendarsStelPluginInterface)
15✔
129
#endif
130

131
#ifdef USE_STATIC_PLUGIN_SATELLITES
132
Q_IMPORT_PLUGIN(SatellitesStelPluginInterface)
15✔
133
#endif
134

135
#ifdef USE_STATIC_PLUGIN_TEXTUSERINTERFACE
136
Q_IMPORT_PLUGIN(TextUserInterfaceStelPluginInterface)
15✔
137
#endif
138

139
#ifdef USE_STATIC_PLUGIN_OCULARS
140
Q_IMPORT_PLUGIN(OcularsStelPluginInterface)
15✔
141
#endif
142

143
#ifdef USE_STATIC_PLUGIN_OCULUS
144
Q_IMPORT_PLUGIN(OculusStelPluginInterface)
145
#endif
146

147
#ifdef USE_STATIC_PLUGIN_TELESCOPECONTROL
148
Q_IMPORT_PLUGIN(TelescopeControlStelPluginInterface)
15✔
149
#endif
150

151
#ifdef USE_STATIC_PLUGIN_SOLARSYSTEMEDITOR
152
Q_IMPORT_PLUGIN(SolarSystemEditorStelPluginInterface)
15✔
153
#endif
154

155
#ifdef USE_STATIC_PLUGIN_LENSDISTORTIONESTIMATOR
156
Q_IMPORT_PLUGIN(LensDistortionEstimatorStelPluginInterface)
15✔
157
#endif
158

159
#ifdef USE_STATIC_PLUGIN_METEORSHOWERS
160
Q_IMPORT_PLUGIN(MeteorShowersStelPluginInterface)
15✔
161
#endif
162

163
#ifdef USE_STATIC_PLUGIN_MISSINGSTARS
164
Q_IMPORT_PLUGIN(MissingStarsStelPluginInterface)
15✔
165
#endif
166

167
#ifdef USE_STATIC_PLUGIN_NAVSTARS
168
Q_IMPORT_PLUGIN(NavStarsStelPluginInterface)
15✔
169
#endif
170

171
#ifdef USE_STATIC_PLUGIN_NOVAE
172
Q_IMPORT_PLUGIN(NovaeStelPluginInterface)
15✔
173
#endif
174

175
#ifdef USE_STATIC_PLUGIN_SUPERNOVAE
176
Q_IMPORT_PLUGIN(SupernovaeStelPluginInterface)
15✔
177
#endif
178

179
#ifdef USE_STATIC_PLUGIN_QUASARS
180
Q_IMPORT_PLUGIN(QuasarsStelPluginInterface)
15✔
181
#endif
182

183
#ifdef USE_STATIC_PLUGIN_PULSARS
184
Q_IMPORT_PLUGIN(PulsarsStelPluginInterface)
15✔
185
#endif
186

187
#ifdef USE_STATIC_PLUGIN_EXOPLANETS
188
Q_IMPORT_PLUGIN(ExoplanetsStelPluginInterface)
15✔
189
#endif
190

191
#ifdef USE_STATIC_PLUGIN_EQUATIONOFTIME
192
Q_IMPORT_PLUGIN(EquationOfTimeStelPluginInterface)
15✔
193
#endif
194

195
#ifdef USE_STATIC_PLUGIN_POINTERCOORDINATES
196
Q_IMPORT_PLUGIN(PointerCoordinatesStelPluginInterface)
15✔
197
#endif
198

199
#ifdef USE_STATIC_PLUGIN_OBSERVABILITY
200
Q_IMPORT_PLUGIN(ObservabilityStelPluginInterface)
15✔
201
#endif
202

203
#ifdef USE_STATIC_PLUGIN_SCENERY3D
204
Q_IMPORT_PLUGIN(Scenery3dStelPluginInterface)
15✔
205
#endif
206

207
#ifdef USE_STATIC_PLUGIN_REMOTECONTROL
208
Q_IMPORT_PLUGIN(RemoteControlStelPluginInterface)
15✔
209
#endif
210

211
#ifdef USE_STATIC_PLUGIN_REMOTESYNC
212
Q_IMPORT_PLUGIN(RemoteSyncStelPluginInterface)
15✔
213
#endif
214

215
#ifdef USE_STATIC_PLUGIN_VTS
216
Q_IMPORT_PLUGIN(VtsStelPluginInterface)
217
#endif
218

219
#ifdef USE_STATIC_PLUGIN_ONLINEQUERIES
220
Q_IMPORT_PLUGIN(OnlineQueriesPluginInterface)
15✔
221
#endif
222

223
// Initialize static variables
224
StelApp* StelApp::singleton = Q_NULLPTR;
225
qint64 StelApp::startMSecs = 0;
226
double StelApp::animationScale = 1.;
227

228
void StelApp::initStatic()
×
229
{
230
        StelApp::startMSecs = QDateTime::currentMSecsSinceEpoch();
×
231
}
×
232

233
void StelApp::deinitStatic()
×
234
{
235
        StelApp::startMSecs = 0;
×
236
}
×
237

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

294
        // Can't create 2 StelApp instances
295
        Q_ASSERT(!singleton);
×
296
        singleton = this;
×
297

298
        moduleMgr = new StelModuleMgr();
×
299
        randomGenerator = new QRandomGenerator(static_cast<quint32>(QDateTime::currentMSecsSinceEpoch()));
×
300
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
301
        // QImageReader has a new limitation. For super-large landscapes or other textures, we need to circumvent this.
302
        QImageReader::setAllocationLimit(1024); // Allow max texture size 16k x 16k
×
303
#endif
304
}
×
305

306
/*************************************************************************
307
 Deinitialize and destroy the main Stellarium application.
308
*************************************************************************/
309
StelApp::~StelApp()
×
310
{
311
        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));
×
312

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

338
void StelApp::setupNetworkProxy()
×
339
{
340
        QString proxyHost = confSettings->value("proxy/host_name").toString();
×
341
        QString proxyPort = confSettings->value("proxy/port").toString();
×
342
        QString proxyUser = confSettings->value("proxy/user").toString();
×
343
        QString proxyPass = confSettings->value("proxy/password").toString();
×
344
        QString proxyType = confSettings->value("proxy/type").toString();
×
345

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

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

389
        if (!proxyHost.isEmpty())
×
390
        {
391
                QNetworkProxy proxy;
×
392
                if (useSocksProxy)
×
393
                        proxy.setType(QNetworkProxy::Socks5Proxy);
×
394
                else
395
                        proxy.setType(QNetworkProxy::HttpProxy);
×
396
                proxy.setHostName(proxyHost);
×
397
                if (!proxyPort.isEmpty())
×
398
                        proxy.setPort(proxyPort.toUShort());
×
399

400
                if (!proxyUser.isEmpty())
×
401
                        proxy.setUser(proxyUser);
×
402

403
                if (!proxyPass.isEmpty())
×
404
                        proxy.setPassword(proxyPass);
×
405

406
                QString ppDisp = proxyPass;
×
407
                ppDisp.fill('*');
×
408
                if (useSocksProxy)
×
409
                        qDebug() << "Using SOCKS proxy:" << proxyUser << ppDisp << proxyHost << proxyPort;
×
410
                else
411
                        qDebug() << "Using HTTP proxy:" << proxyUser << ppDisp << proxyHost << proxyPort;
×
412
                QNetworkProxy::setApplicationProxy(proxy);
×
413
        }
×
414
}
×
415

416
#ifdef ENABLE_SCRIPTING
417
void StelApp::initScriptMgr()
×
418
{
419
        scriptMgr->addModules();
×
420

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

441
QStringList StelApp::getCommandlineArguments()
×
442
{
443
        return qApp->property("stelCommandLine").toStringList();
×
444
}
445

446
void StelApp::init(QSettings* conf)
×
447
{
448
        gl = QOpenGLContext::currentContext()->functions();
×
449
        confSettings = conf;
×
450

451
        devicePixelsPerPixel = QOpenGLContext::currentContext()->screen()->devicePixelRatio();
×
452
        if (devicePixelsPerPixel>1)
×
453
                qDebug() << "Detected a high resolution device! Device pixel ratio:" << devicePixelsPerPixel;
×
454

455
        setScreenFontSize(confSettings->value("gui/screen_font_size", getDefaultGuiFontSize()).toInt());
×
456
        setGuiFontSize(confSettings->value("gui/gui_font_size", getDefaultGuiFontSize()).toInt());
×
457
        setFlagImmediateSave(confSettings->value("gui/immediate_save_details", false).toBool());
×
458

459
        core = new StelCore();
×
460
        if (!fuzzyEquals(saveProjW, -1.) && !fuzzyEquals(saveProjH, -1.))
×
461
                core->windowHasBeenResized(0, 0, saveProjW, saveProjH);
×
462
        
463
        //Initializing locale at the beginning to show all strings translated
464
        localeMgr = new StelLocaleMgr();
×
465
        localeMgr->init();
×
466
        //SplashScreen::showMessage(q_("Initializing locales..."));
467

468
        SplashScreen::showMessage(q_("Initializing textures..."));
×
469
        // Initialize AFTER creation of openGL context
470
        textureMgr = new StelTextureMgr();
×
471

472
        SplashScreen::showMessage(q_("Initializing network access..."));
×
473
        networkAccessManager = new QNetworkAccessManager(this);
×
474
        networkAccessManager->setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
×
475
        SplashScreen::showMessage(q_("Initializing network disk cache..."));
×
476
        // Activate http cache if Qt version >= 4.5
477
        QNetworkDiskCache* cache = new QNetworkDiskCache(networkAccessManager);
×
478
        //make maximum cache size configurable (in MB)
479
        //the default Qt value (50 MB) is quite low, especially for DSS
480
        cache->setMaximumCacheSize(confSettings->value("main/network_cache_size",300).toInt() * 1024 * 1024);
×
481
        QString cachePath = StelFileMgr::getCacheDir();
×
482

483
        qDebug().noquote() << "Cache directory:" << QDir::toNativeSeparators(cachePath);
×
484
        cache->setCacheDirectory(cachePath);
×
485
        networkAccessManager->setCache(cache);        
×
486
        connect(networkAccessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(reportFileDownloadFinished(QNetworkReply*)));
×
487

488
        // Proxy Initialisation
489
        SplashScreen::showMessage(q_("Initializing network proxy..."));
×
490
        setupNetworkProxy();
×
491

492
        //create non-StelModule managers
493
        propMgr = new StelPropertyMgr();
×
494
        skyCultureMgr = new StelSkyCultureMgr();
×
495
        propMgr->registerObject(skyCultureMgr);
×
496
        planetLocationMgr = new StelLocationMgr();
×
497
        actionMgr = new StelActionMgr();
×
498

499
        // register non-modules for StelProperty tracking
500
        propMgr->registerObject(this);
×
501
        propMgr->registerObject(mainWin);
×
502

503
        // Stel Object Data Base manager
504
        SplashScreen::showMessage(q_("Initializing Object Database..."));
×
505
        stelObjectMgr = new StelObjectMgr();
×
506
        stelObjectMgr->init();
×
507
        getModuleMgr().registerModule(stelObjectMgr);        
×
508

509
        // Hips surveys
510
        SplashScreen::showMessage(q_("Initializing HiPS survey..."));
×
511
        HipsMgr* hipsMgr = new HipsMgr();
×
512
        hipsMgr->init();
×
513
        getModuleMgr().registerModule(hipsMgr);
×
514

515
        // Init the solar system first
516
        SplashScreen::showMessage(q_("Initializing Solar System objects..."));
×
517
        SolarSystem* ssystem = new SolarSystem();
×
518
        ssystem->init();
×
519
        getModuleMgr().registerModule(ssystem);
×
520

521
        // Init the nomenclature for Solar system bodies
522
        SplashScreen::showMessage(q_("Initializing planetary nomenclature..."));
×
523
        NomenclatureMgr* nomenclature = new NomenclatureMgr();
×
524
        nomenclature->init();
×
525
        getModuleMgr().registerModule(nomenclature);
×
526

527
        // Load stars & their names
528
        SplashScreen::showMessage(q_("Initializing stars..."));
×
529
        StarMgr* hip_stars = new StarMgr();
×
530
        hip_stars->init();
×
531
        getModuleMgr().registerModule(hip_stars);
×
532

533
        SplashScreen::showMessage(q_("Initializing core..."));
×
534
        core->init();
×
535

536
        // Init nebulas
537
        SplashScreen::showMessage(q_("Initializing deep-sky objects..."));
×
538
        NebulaMgr* nebulas = new NebulaMgr();
×
539
        nebulas->init();
×
540
        getModuleMgr().registerModule(nebulas);
×
541

542
        // Init milky way
543
        SplashScreen::showMessage(q_("Initializing Milky Way..."));
×
544
        MilkyWay* milky_way = new MilkyWay();
×
545
        milky_way->init();
×
546
        getModuleMgr().registerModule(milky_way);
×
547

548
        // Init zodiacal light
549
        SplashScreen::showMessage(q_("Initializing zodiacal light..."));
×
550
        ZodiacalLight* zodiacal_light = new ZodiacalLight();
×
551
        zodiacal_light->init();
×
552
        getModuleMgr().registerModule(zodiacal_light);
×
553

554
        // Init sky image manager
555
        SplashScreen::showMessage(q_("Initializing sky image layer..."));
×
556
        skyImageMgr = new StelSkyLayerMgr();
×
557
        skyImageMgr->init();
×
558
        getModuleMgr().registerModule(skyImageMgr);
×
559

560
        // Toast surveys
561
        SplashScreen::showMessage(q_("Initializing TOAST surveys..."));
×
562
        ToastMgr* toasts = new ToastMgr();
×
563
        toasts->init();
×
564
        getModuleMgr().registerModule(toasts);
×
565

566
        // Init audio manager. When media support is disabled,
567
        // we silently create dummy managers.
568
#ifdef ENABLE_MEDIA
569
        const bool audioOK = !(qApp->property("onetime_no-audio").toBool())
×
570
                        && confSettings->value("audio/enabled", true).toBool();
×
571
#else
572
        const bool audioOK = false;
573
#endif
574
        if (audioOK)
×
575
                SplashScreen::showMessage(q_("Initializing audio..."));
×
576
        audioMgr = new StelAudioMgr(audioOK);
×
577

578
        // Init video manager
579
#ifdef ENABLE_MEDIA
580
        SplashScreen::showMessage(q_("Initializing video..."));
×
581
#endif
582
        videoMgr = new StelVideoMgr(audioOK);
×
583
        videoMgr->init();
×
584
        getModuleMgr().registerModule(videoMgr);
×
585

586
        // Constellations
587
        SplashScreen::showMessage(q_("Initializing constellations..."));
×
588
        ConstellationMgr* constellations = new ConstellationMgr(hip_stars);
×
589
        constellations->init();
×
590
        getModuleMgr().registerModule(constellations);
×
591

592
        // Asterisms
593
        SplashScreen::showMessage(q_("Initializing asterisms..."));
×
594
        AsterismMgr* asterisms = new AsterismMgr(hip_stars);
×
595
        asterisms->init();
×
596
        getModuleMgr().registerModule(asterisms);
×
597

598
        // Landscape, atmosphere & cardinal points section
599
        SplashScreen::showMessage(q_("Initializing landscape..."));
×
600
        LandscapeMgr* landscape = new LandscapeMgr();
×
601
        landscape->init();
×
602
        getModuleMgr().registerModule(landscape);
×
603
        // Only now we can switch to auto-landscape. (GH:#3550)
604
        if (landscape->getFlagLandscapeAutoSelection() && (confSettings->value("init_location/location", "auto").toString() == "auto"))
×
605
        {
606
                StelLocation loc=core->getCurrentLocation();
×
607
                QColor color=planetLocationMgr->getColorForCoordinates(loc.getLongitude(), loc.getLatitude());
×
608
                QString landscapeAutoName=QString("ZeroColor(%1)").arg(Vec3f(color).toStr());
×
609
                emit core->targetLocationChanged(loc, landscapeAutoName); // inform others about our next location. E.g., let LandscapeMgr load a new landscape.
×
610
        }
×
611

612
        SplashScreen::showMessage(q_("Initializing grid lines..."));
×
613
        GridLinesMgr* gridLines = new GridLinesMgr();
×
614
        gridLines->init();
×
615
        getModuleMgr().registerModule(gridLines);
×
616
        
617
        SplashScreen::showMessage(q_("Initializing special markers..."));
×
618
        SpecialMarkersMgr* specialMarkers = new SpecialMarkersMgr();
×
619
        specialMarkers->init();
×
620
        getModuleMgr().registerModule(specialMarkers);
×
621

622
        // Sporadic Meteors
623
        SplashScreen::showMessage(q_("Initializing sporadic meteors..."));
×
624
        SporadicMeteorMgr* meteors = new SporadicMeteorMgr(10, 72);
×
625
        meteors->init();
×
626
        getModuleMgr().registerModule(meteors);
×
627

628
        // User labels
629
        SplashScreen::showMessage(q_("Initializing user labels..."));
×
630
        LabelMgr* skyLabels = new LabelMgr();
×
631
        skyLabels->init();
×
632
        getModuleMgr().registerModule(skyLabels);
×
633

634
        SplashScreen::showMessage(q_("Initializing sky cultures..."));
×
635
        skyCultureMgr->init();
×
636

637
        // User markers
638
        SplashScreen::showMessage(q_("Initializing user markers..."));
×
639
        MarkerMgr* skyMarkers = new MarkerMgr();
×
640
        skyMarkers->init();
×
641
        getModuleMgr().registerModule(skyMarkers);
×
642

643
        // Init custom objects
644
        SplashScreen::showMessage(q_("Initializing custom objects..."));
×
645
        CustomObjectMgr* custObj = new CustomObjectMgr();
×
646
        custObj->init();
×
647
        getModuleMgr().registerModule(custObj);
×
648

649
        // Init highlights
650
        SplashScreen::showMessage(q_("Initializing highlights..."));
×
651
        HighlightMgr* hlMgr = new HighlightMgr();
×
652
        hlMgr->init();
×
653
        getModuleMgr().registerModule(hlMgr);
×
654

655
        // Init specific time
656
        SplashScreen::showMessage(q_("Initializing specific time..."));
×
657
        SpecificTimeMgr* specificTime = new SpecificTimeMgr();
×
658
        specificTime->init();
×
659
        getModuleMgr().registerModule(specificTime);
×
660

661
        //Create the script manager here, maybe some modules/plugins may want to connect to it
662
        //It has to be initialized later after all modules have been loaded by calling initScriptMgr
663
#ifdef ENABLE_SCRIPTING
664
        SplashScreen::showMessage(q_("Initializing scripting..."));
×
665
        scriptAPIProxy = new StelMainScriptAPIProxy(this);
×
666
        scriptMgr = new StelScriptMgr(this);
×
667
#endif
668

669
        SplashScreen::showMessage(q_("Initializing color scheme..."));
×
670
        // Initialisation of the color scheme
671
        emit colorSchemeChanged("default");
×
672
        setVisionModeNight(confSettings->value("viewing/flag_night", false).toBool());
×
673

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

677
        SplashScreen::clearMessage();
×
678
        updateI18n();
×
679

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

683
        setFlagShowDecimalDegrees(confSettings->value("gui/flag_show_decimal_degrees", false).toBool());
×
684
        setFlagSouthAzimuthUsage(confSettings->value("gui/flag_use_azimuth_from_south", false).toBool());
×
685
        setFlagUseFormattingOutput(confSettings->value("gui/flag_use_formatting_output", false).toBool());
×
686
        setFlagUseCCSDesignation(confSettings->value("gui/flag_use_ccs_designations", false).toBool());
×
687
        setFlagOverwriteInfoColor(confSettings->value("gui/flag_overwrite_info_color", false).toBool());        
×
688
        setOverwriteInfoColor(Vec3f(confSettings->value("color/info_text_color", "1.0,1.0,1.0").toString()));
×
689
        setDaylightInfoColor(Vec3f(confSettings->value("color/daylight_text_color", "0.0,0.0,0.0").toString()));
×
690

691
        // Animation
692
        animationScale = confSettings->value("gui/pointer_animation_speed", 1.).toDouble();
×
693

694
        ditherPatternTex = StelApp::getInstance().getTextureManager().getDitheringTexture(0);
×
695
        setupPostProcessor();
×
696
        
697
#ifdef ENABLE_SPOUT
698
        //qDebug() << "Property spout is" << qApp->property("spout").toString();
699
        //qDebug() << "Property spoutName is" << qApp->property("spoutName").toString();
700
        if (qApp->property("spout").toString() != "none")
701
        {
702
                //if we are on windows and we have GLES, we are most likely on ANGLE
703
                bool isANGLE=QOpenGLContext::currentContext()->isOpenGLES();
704

705
                if (isANGLE)
706
                {
707
                        qCritical() << "SPOUT: Does not run in ANGLE/OpenGL ES mode!";
708
                }
709
                else
710
                {
711
                        SplashScreen::showMessage(q_("Initializing SPOUT sender..."));
712
                        // Create the SpoutSender object.
713
                        QString spoutName = qApp->property("spoutName").toString();
714
                        if(spoutName.isEmpty())
715
                                spoutName = "stellarium";
716

717
                        spoutSender = new SpoutSender(spoutName);
718

719
                        if (!spoutSender->isValid())
720
                        {
721
                                QMessageBox::warning(&StelMainView::getInstance(), "Stellarium SPOUT", q_("Cannot create Spout sender. See log for details."), QMessageBox::Ok);
722
                                delete spoutSender;
723
                                spoutSender = Q_NULLPTR;
724
                                qApp->setProperty("spout", "");
725
                        }
726
                        SplashScreen::clearMessage();
727
                }
728
        }
729
        else
730
        {
731
                qApp->setProperty("spout", "");
732
        }
733
#endif
734

735
        initialized = true;
×
736
}
×
737

738
// Load and initialize external modules (plugins)
739
void StelApp::initPlugIns()
×
740
{
741
        // Load dynamically all the modules found in the modules/ directories
742
        // which are configured to be loaded at startup
743
        const QList<StelModuleMgr::PluginDescriptor> pluginList=moduleMgr->getPluginsList();
×
744
        for (const auto& i : pluginList)
×
745
        {
746
                if (i.loadAtStartup==false)
×
747
                        continue;
×
748
                SplashScreen::showMessage(QString("%1 \"%2\"...").arg(q_("Loading plugin"), q_(i.info.displayedName)));
×
749
                StelModule* m = moduleMgr->loadPlugin(i.info.id);
×
750
                if (m!=Q_NULLPTR)
×
751
                {
752
                        moduleMgr->registerModule(m, true);
×
753
                        //load extensions after the module is registered
754
                        moduleMgr->loadExtensions(i.info.id);
×
755
                        m->init();
×
756
                }
757
        }
758
        SplashScreen::clearMessage();
×
759
}
×
760

761
void StelApp::deinit()
×
762
{
763
#ifdef         ENABLE_SPOUT
764
        delete spoutSender;
765
        spoutSender = Q_NULLPTR;
766
#endif
767
#ifdef ENABLE_SCRIPTING
768
        if (scriptMgr->scriptIsRunning())
×
769
                scriptMgr->stopScript();
×
770
#endif
771
        QCoreApplication::processEvents();
×
772
        getModuleMgr().unloadAllPlugins();
×
773
        QCoreApplication::processEvents();
×
774
        StelPainter::deinitGLShaders();
×
775
}
×
776

777

778
StelProgressController* StelApp::addProgressBar()
×
779
{
780
        StelProgressController* p = new StelProgressController(this);
×
781
        progressControllers.append(p);
×
782
        emit progressBarAdded(p);
×
783
        return p;
×
784
}
785

786
void StelApp::removeProgressBar(StelProgressController* p)
×
787
{
788
        progressControllers.removeOne(p);        
×
789
        emit progressBarRemoved(p);
×
790
        delete p;
×
791
}
×
792

793

794
void StelApp::update(double deltaTime)
×
795
{
796
        if (!initialized)
×
797
                return;
×
798

799
        ++frame;
×
800
        frameTimeAccum+=deltaTime;
×
801
        if (frameTimeAccum > 1.)
×
802
        {
803
                // Calc the FPS rate every seconds
804
                fps=static_cast<float>(frame)/static_cast<float>(frameTimeAccum);
×
805
                frame = 0;
×
806
                frameTimeAccum=0.;
×
807
        }
808
                
809
        core->update(deltaTime);
×
810

811
        moduleMgr->update();
×
812

813
        // Send the event to every StelModule
814
        for (auto* i : moduleMgr->getCallOrders(StelModule::ActionUpdate))
×
815
        {
816
                i->update(deltaTime);
×
817
        }
818

819
        stelObjectMgr->update(deltaTime);
×
820
}
821

822
void StelApp::prepareRenderBuffer()
×
823
{
824
        if (!viewportEffect) return;
×
825
        if (!renderBuffer)
×
826
        {
827
                StelProjector::StelProjectorParams params = core->getCurrentStelProjectorParams();
×
828
                int w = params.viewportXywh[2];
×
829
                int h = params.viewportXywh[3];
×
830
                renderBuffer = new QOpenGLFramebufferObject(w, h, QOpenGLFramebufferObject::Depth); // we only need depth here
×
831
        }
832
        renderBuffer->bind();
×
833
}
834

835
void StelApp::applyRenderBuffer(GLuint drawFbo)
×
836
{
837
        if (!renderBuffer) return;
×
838
        GL(gl->glBindFramebuffer(GL_FRAMEBUFFER, drawFbo));
×
839
        viewportEffect->paintViewportBuffer(renderBuffer);
×
840
}
841

842
void StelApp::setupPostProcessor()
×
843
{
844
        postProcessorVBO.reset(new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer));
×
845
        postProcessorVBO->create();
×
846
        postProcessorVBO->bind();
×
847
        const GLfloat vertices[]=
×
848
        {
849
                // full screen quad
850
                -1, -1,
851
                 1, -1,
852
                -1,  1,
853
                 1,  1,
854
        };
855
        GL(gl->glBufferData(GL_ARRAY_BUFFER, sizeof vertices, vertices, GL_STATIC_DRAW));
×
856

857
        postProcessorVAO.reset(new QOpenGLVertexArrayObject);
×
858
        postProcessorVAO->create();
×
859
        postProcessorVAO->bind();
×
860
        gl->glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
×
861
        postProcessorVBO->release();
×
862
        gl->glEnableVertexAttribArray(0);
×
863
        postProcessorVAO->release();
×
864

865
        postProcessorProgram.reset(new QOpenGLShaderProgram);
×
866
        postProcessorProgram->addShaderFromSourceCode(QOpenGLShader::Vertex,
×
867
                StelOpenGL::globalShaderPrefix(StelOpenGL::VERTEX_SHADER) + R"(
×
868
ATTRIBUTE vec3 vertex;
869
VARYING vec2 texcoord;
870
void main()
871
{
872
        gl_Position = vec4(vertex, 1.);
873
        texcoord = 0.5*vertex.xy+0.5;
874
}
875
)");
876
        postProcessorProgram->addShaderFromSourceCode(QOpenGLShader::Fragment,
×
877
                StelOpenGL::globalShaderPrefix(StelOpenGL::FRAGMENT_SHADER) +
×
878
                makeDitheringShader() + R"(
×
879
VARYING vec2 texcoord;
880
uniform sampler2D tex;
881

882
void main()
883
{
884
        vec4 rgba = texture2D(tex, texcoord);
885
        FRAG_COLOR = vec4(dither(rgba.rgb), rgba.a);
886
}
887
)");
888
        StelPainter::linkProg(postProcessorProgram.get(), "Post-processing program");
×
889
        postProcessorProgram->bind();
×
890
        postProcessorUniformLocations.tex           = postProcessorProgram->uniformLocation("tex");
×
891
        postProcessorUniformLocations.rgbMaxValue   = postProcessorProgram->uniformLocation("rgbMaxValue");
×
892
        postProcessorUniformLocations.ditherPattern = postProcessorProgram->uniformLocation("ditherPattern");
×
893
        postProcessorProgram->release();
×
894

895
        if(StelMainView::getInstance().getGLInformation().isHighGraphicsMode)
×
896
        {
897
                postProcessorProgramMS.reset(new QOpenGLShaderProgram);
×
898
                postProcessorProgramMS->addShaderFromSourceCode(QOpenGLShader::Vertex,
×
899
                        StelOpenGL::globalShaderPrefix(StelOpenGL::VERTEX_SHADER) + R"(
×
900
ATTRIBUTE vec3 vertex;
901
void main()
902
{
903
        gl_Position = vec4(vertex, 1.);
904
}
905
)");
906
                postProcessorProgramMS->addShaderFromSourceCode(QOpenGLShader::Fragment,
×
907
                        StelOpenGL::globalShaderPrefix(StelOpenGL::FRAGMENT_SHADER) +
×
908
                        makeDitheringShader() + R"(
×
909
uniform sampler2DMS tex;
910
uniform int numMultiSamples;
911

912
void main()
913
{
914
        vec4 rgba = vec4(0);
915
        for(int n = 0; n < numMultiSamples; ++n)
916
                rgba += texelFetch(tex, ivec2(gl_FragCoord.xy), n);
917
        rgba /= float(numMultiSamples);
918
        FRAG_COLOR = vec4(dither(rgba.rgb), rgba.a);
919
}
920
)");
921
                StelPainter::linkProg(postProcessorProgramMS.get(), "Multisampled post-processing program");
×
922
                postProcessorProgramMS->bind();
×
923
                postProcessorUniformLocationsMS.tex               = postProcessorProgramMS->uniformLocation("tex");
×
924
                postProcessorUniformLocationsMS.rgbMaxValue       = postProcessorProgramMS->uniformLocation("rgbMaxValue");
×
925
                postProcessorUniformLocationsMS.ditherPattern     = postProcessorProgramMS->uniformLocation("ditherPattern");
×
926
                postProcessorUniformLocationsMS.numMultiSamples   = postProcessorProgramMS->uniformLocation("numMultiSamples");
×
927
                postProcessorProgramMS->release();
×
928
        }
929
}
×
930

931
void StelApp::highGraphicsModeDraw()
×
932
{
933
#if !QT_CONFIG(opengles2)
934
        const auto targetFBO = currentFbo;
×
935
        StelProjector::StelProjectorParams params = core->getCurrentStelProjectorParams();
×
936
        const auto w = params.viewportXywh[2] * params.devicePixelsPerPixel;
×
937
        const auto h = params.viewportXywh[3] * params.devicePixelsPerPixel;
×
938
        StelOpenGL::checkGLErrors(__FILE__, __LINE__);
×
939
        if(!sceneFBO || sceneFBO->size() != QSize(w,h))
×
940
        {
941
                qDebug().nospace() << "Creating scene FBO with size " << w << "x" << h;
×
942
                const auto internalFormat = GL_RGBA16;
×
943
                QOpenGLFramebufferObjectFormat format;
×
944
                format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
×
945
                format.setInternalTextureFormat(internalFormat);
×
946
                sceneFBO.reset(new QOpenGLFramebufferObject(w, h, format));
×
947
                GLint maxSamples = 1;
×
948
                GL(gl->glGetIntegerv(GL_MAX_SAMPLES, &maxSamples));
×
949
                const auto samples = confSettings->value("video/multisampling", 0).toInt();
×
950
                numMultiSamples = std::min(samples, maxSamples);
×
951
                if(numMultiSamples > 1)
×
952
                {
953
                        const auto gl = StelOpenGL::highGraphicsFunctions();
×
954
                        if(sceneMultisampledFBO)
×
955
                        {
956
                                GL(gl->glDeleteFramebuffers(1, &sceneMultisampledFBO));
×
957
                                GL(gl->glDeleteTextures(1, &sceneMultisampledTex));
×
958
                                GL(gl->glDeleteRenderbuffers(1, &sceneMultisampledRenderbuffer));
×
959
                        }
960
                        GL(gl->glGenFramebuffers(1, &sceneMultisampledFBO));
×
961
                        GL(gl->glGenTextures(1, &sceneMultisampledTex));
×
962
                        GL(gl->glGenRenderbuffers(1, &sceneMultisampledRenderbuffer));
×
963

964
                        GL(gl->glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, sceneMultisampledTex));
×
965
                        GL(gl->glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, numMultiSamples,
×
966
                                                                internalFormat, w, h, true));
967

968
                        GL(gl->glBindRenderbuffer(GL_RENDERBUFFER, sceneMultisampledRenderbuffer));
×
969
                        GL(gl->glRenderbufferStorageMultisample(GL_RENDERBUFFER, numMultiSamples,
×
970
                                                                         GL_DEPTH24_STENCIL8, w, h));
971

972
                        GL(gl->glBindFramebuffer(GL_FRAMEBUFFER, sceneMultisampledFBO));
×
973
                        GL(gl->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
×
974
                                                      GL_TEXTURE_2D_MULTISAMPLE, sceneMultisampledTex, 0));
975
                        GL(gl->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
×
976
                                                         GL_RENDERBUFFER, sceneMultisampledRenderbuffer));
977
                        const auto status = gl->glCheckFramebufferStatus(GL_FRAMEBUFFER);
×
978
                        if(status != GL_FRAMEBUFFER_COMPLETE)
×
979
                        {
980
                                qCritical().nospace() << __FILE__ << ":" << __LINE__
×
981
                                                      << ": warning: framebuffer incomplete, status: "
×
982
                                                      << status;
×
983
                        }
984
                }
985
        }
×
986

987
        if(sceneMultisampledFBO)
×
988
        {
989
                GL(gl->glBindFramebuffer(GL_FRAMEBUFFER, sceneMultisampledFBO));
×
990
                currentFbo = sceneMultisampledFBO;
×
991
        }
992
        else
993
        {
994
                sceneFBO->bind();
×
995
                currentFbo = sceneFBO->handle();
×
996
        }
997
        StelOpenGL::checkGLErrors(__FILE__, __LINE__);
×
998

999
        GL(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));
×
1000

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

1003
        for(auto* module : modules)
×
1004
        {
1005
                module->draw(core);
×
1006
        }
1007

1008
        if(sceneMultisampledFBO)
×
1009
        {
1010
                GL(gl->glBindFramebuffer(GL_FRAMEBUFFER, targetFBO));
×
1011
                postProcessorProgramMS->bind();
×
1012

1013
                const int sceneTexSampler = 0;
×
1014
                GL(gl->glActiveTexture(GL_TEXTURE0 + sceneTexSampler));
×
1015
                GL(gl->glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, sceneMultisampledTex));
×
1016
                postProcessorProgramMS->setUniformValue(postProcessorUniformLocationsMS.tex, sceneTexSampler);
×
1017

1018
                const int ditherTexSampler = 1;
×
1019
                ditherPatternTex->bind(ditherTexSampler);
×
1020
                postProcessorProgramMS->setUniformValue(postProcessorUniformLocationsMS.ditherPattern, ditherTexSampler);
×
1021
                const auto rgbMaxValue=calcRGBMaxValue(core->getDitheringMode());
×
1022
                postProcessorProgramMS->setUniformValue(postProcessorUniformLocationsMS.rgbMaxValue,
×
1023
                                                        rgbMaxValue[0], rgbMaxValue[1], rgbMaxValue[2]);
×
1024
                postProcessorProgramMS->setUniformValue(postProcessorUniformLocationsMS.numMultiSamples, numMultiSamples);
×
1025
        }
1026
        else
1027
        {
1028
                GL(gl->glBindFramebuffer(GL_FRAMEBUFFER, targetFBO));
×
1029
                postProcessorProgram->bind();
×
1030

1031
                const int sceneTexSampler = 0;
×
1032
                GL(gl->glActiveTexture(GL_TEXTURE0 + sceneTexSampler));
×
1033
                GL(gl->glBindTexture(GL_TEXTURE_2D, sceneFBO->texture()));
×
1034
                postProcessorProgram->setUniformValue(postProcessorUniformLocations.tex, sceneTexSampler);
×
1035

1036
                const int ditherTexSampler = 1;
×
1037
                ditherPatternTex->bind(ditherTexSampler);
×
1038
                postProcessorProgram->setUniformValue(postProcessorUniformLocations.ditherPattern, ditherTexSampler);
×
1039
                const auto rgbMaxValue=calcRGBMaxValue(core->getDitheringMode());
×
1040
                postProcessorProgram->setUniformValue(postProcessorUniformLocations.rgbMaxValue,
×
1041
                                                      rgbMaxValue[0], rgbMaxValue[1], rgbMaxValue[2]);
×
1042

1043
        }
1044

1045
        postProcessorVAO->bind();
×
1046
        GL(gl->glEnable(GL_BLEND));
×
1047
        GL(gl->glBlendFunc(GL_ONE,GL_ONE));
×
1048
        GL(gl->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
×
1049
        GL(gl->glDisable(GL_BLEND));
×
1050
        postProcessorVAO->release();
×
1051
#endif
1052
}
×
1053

1054
//! Main drawing function called at each frame
1055
void StelApp::draw()
×
1056
{
1057
        if (!initialized)
×
1058
                return;
×
1059

1060
        //find out which framebuffer is the current one
1061
        //this is usually NOT the "zero" FBO, but one provided by QOpenGLWidget
1062
        GLint drawFbo;
1063
        GL(gl->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &drawFbo));
×
1064

1065
        prepareRenderBuffer();
×
1066
        currentFbo = renderBuffer ? renderBuffer->handle() : static_cast<GLuint>(drawFbo);
×
1067

1068
        core->preDraw();
×
1069

1070
        if(StelMainView::getInstance().getGLInformation().isHighGraphicsMode)
×
1071
        {
1072
                highGraphicsModeDraw();
×
1073
        }
1074
        else
1075
        {
1076
                const QList<StelModule*> modules = moduleMgr->getCallOrders(StelModule::ActionDraw);
×
1077
                for (auto* module : modules)
×
1078
                {
1079
                        module->draw(core);
×
1080
                }
1081
        }
×
1082

1083
        core->postDraw();
×
1084
#ifdef ENABLE_SPOUT
1085
        // At this point, the sky scene has been drawn, but no GUI panels.
1086
        if(spoutSender)
1087
                spoutSender->captureAndSendFrame(static_cast<GLuint>(drawFbo));
1088
#endif
1089
        applyRenderBuffer(static_cast<GLuint>(drawFbo));
×
1090
}
1091

1092
/*************************************************************************
1093
 Call this when the virtual size of the GL window has changed
1094
*************************************************************************/
1095
void StelApp::glWindowHasBeenResized(const QRectF& rect)
×
1096
{
1097
        // Remove the effect before resizing the core, or things get messy.
1098
        QString effect = getViewportEffect();
×
1099
        setViewportEffect("none");
×
1100
        if (core)
×
1101
        {
1102
                core->windowHasBeenResized(rect.x(), rect.y(), rect.width(), rect.height());
×
1103
        }
1104
        else
1105
        {
1106
                saveProjW = rect.width();
×
1107
                saveProjH = rect.height();
×
1108
        }
1109
        // Force to recreate the viewport effect if any.
1110
        setViewportEffect(effect);
×
1111
#ifdef ENABLE_SPOUT
1112
        if (spoutSender)
1113
                spoutSender->resize(static_cast<uint>(rect.width()),static_cast<uint>(rect.height()));
1114
#endif
1115
}
×
1116

1117
/*************************************************************************
1118
 Call this when the physical size of the GL window has changed
1119
*************************************************************************/
1120
void StelApp::glPhysicalWindowHasBeenResized(const QRectF& rect)
×
1121
{
1122
#ifdef ENABLE_SPOUT
1123
        if (spoutSender)
1124
                spoutSender->resize(static_cast<uint>(rect.width()),static_cast<uint>(rect.height()));
1125
#else
1126
        Q_UNUSED(rect)
1127
#endif
1128
}
×
1129

1130
// Handle mouse clics
1131
void StelApp::handleClick(QMouseEvent* inputEvent)
×
1132
{
1133
        QPointF pos = inputEvent->pos();
×
1134
        qreal x, y;
1135
        x = pos.x();
×
1136
        y = pos.y();
×
1137
        if (viewportEffect)
×
1138
                viewportEffect->distortXY(x, y);
×
1139

1140
        QMouseEvent event(inputEvent->type(), QPoint(qRound(x*devicePixelsPerPixel), qRound(y*devicePixelsPerPixel)), inputEvent->button(), inputEvent->buttons(), inputEvent->modifiers());
×
1141
        event.setAccepted(false);
×
1142
        
1143
        // Send the event to every StelModule
1144
        for (auto* i : moduleMgr->getCallOrders(StelModule::ActionHandleMouseClicks))
×
1145
        {
1146
                i->handleMouseClicks(&event);
×
1147
                if (event.isAccepted())
×
1148
                {
1149
                        inputEvent->setAccepted(true);
×
1150
                        return;
×
1151
                }
1152
        }
1153
}
×
1154

1155
// Handle mouse wheel.
1156
void StelApp::handleWheel(QWheelEvent* event)
×
1157
{
1158
        event->setAccepted(false);
×
1159
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
1160
        QWheelEvent deltaEvent(event->position()*devicePixelsPerPixel,
×
1161
                               event->globalPosition()*devicePixelsPerPixel,
×
1162
                               event->pixelDelta(), event->angleDelta(), event->buttons(), event->modifiers(), Qt::ScrollUpdate, false);
×
1163
#else
1164
        QWheelEvent deltaEvent(QPoint(qRound(event->pos().x()*devicePixelsPerPixel), qRound(event->pos().y()*devicePixelsPerPixel)),
1165
                               QPoint(qRound(event->globalPos().x()*devicePixelsPerPixel), qRound(event->globalPos().y()*devicePixelsPerPixel)),
1166
                               event->delta(), event->buttons(), event->modifiers(), event->orientation());
1167
#endif
1168
        deltaEvent.setAccepted(false);
×
1169
        // Send the event to every StelModule
1170
        for (auto* i : moduleMgr->getCallOrders(StelModule::ActionHandleMouseClicks)) {
×
1171
                i->handleMouseWheel(&deltaEvent);
×
1172
                if (deltaEvent.isAccepted()) {
×
1173
                        event->accept();
×
1174
                        break;
×
1175
                }
1176
        }
1177
}
×
1178

1179
// Handle mouse move
1180
bool StelApp::handleMove(qreal x, qreal y, Qt::MouseButtons b)
×
1181
{
1182
        if (viewportEffect)
×
1183
                viewportEffect->distortXY(x, y);
×
1184
        // Send the event to every StelModule
1185
        for (auto* i : moduleMgr->getCallOrders(StelModule::ActionHandleMouseMoves))
×
1186
        {
1187
                if (i->handleMouseMoves(qRound(x*devicePixelsPerPixel), qRound(y*devicePixelsPerPixel), b))
×
1188
                        return true;
×
1189
        }
1190
        return false;
×
1191
}
1192

1193
// Handle key press and release
1194
void StelApp::handleKeys(QKeyEvent* event)
×
1195
{
1196
        event->setAccepted(false);
×
1197
        // First try to trigger a shortcut.
1198
        if (event->type() == QEvent::KeyPress)
×
1199
        {
1200
                if (getStelActionManager()->pushKey(event->key() + int(event->modifiers())))
×
1201
                {
1202
                        event->setAccepted(true);
×
1203
                        return;
×
1204
                }
1205
        }
1206
        // Send the event to every StelModule
1207
        for (auto* i : moduleMgr->getCallOrders(StelModule::ActionHandleKeys))
×
1208
        {
1209
                i->handleKeys(event);
×
1210
                if (event->isAccepted())
×
1211
                        return;
×
1212
        }
1213
}
1214

1215
// Handle pinch on multi touch devices
1216
void StelApp::handlePinch(qreal scale, bool started)
×
1217
{
1218
        // Send the event to every StelModule
1219
        for (auto* i : moduleMgr->getCallOrders(StelModule::ActionHandleMouseMoves))
×
1220
        {
1221
                if (i->handlePinch(scale, started))
×
1222
                        return;
×
1223
        }
1224
}
1225

1226
//! Set flag for activating night vision mode
1227
void StelApp::setVisionModeNight(bool b)
×
1228
{
1229
        if (flagNightVision!=b)
×
1230
        {
1231
                flagNightVision=b;
×
1232
                emit visionNightModeChanged(b);
×
1233
        }
1234
}
×
1235

1236
void StelApp::setFlagOverwriteInfoColor(bool b)
×
1237
{
1238
        if (flagOverwriteInfoColor!=b)
×
1239
        {
1240
                flagOverwriteInfoColor=b;
×
1241
                emit flagOverwriteInfoColorChanged(b);
×
1242
        }
1243
}
×
1244

1245
void StelApp::setFlagShowDecimalDegrees(bool b)
×
1246
{
1247
        if (flagShowDecimalDegrees!=b)
×
1248
        {
1249
                flagShowDecimalDegrees = b;
×
1250
                emit flagShowDecimalDegreesChanged(b);
×
1251
        }
1252
}
×
1253

1254
void StelApp::setFlagUseFormattingOutput(bool b)
×
1255
{
1256
        if (flagUseFormattingOutput!=b)
×
1257
        {
1258
                flagUseFormattingOutput = b;
×
NEW
1259
                StelApp::immediateSave("gui/flag_use_formatting_output", flagUseFormattingOutput);
×
UNCOV
1260
                emit flagUseFormattingOutputChanged(b);
×
1261
        }
1262
}
×
1263

1264
void StelApp::setFlagUseCCSDesignation(bool b)
×
1265
{
1266
        if (flagUseCCSDesignation!=b)
×
1267
        {
1268
                flagUseCCSDesignation = b;
×
NEW
1269
                StelApp::immediateSave("gui/flag_use_ccs_designations", flagUseCCSDesignation);
×
UNCOV
1270
                emit flagUseCCSDesignationChanged(b);
×
1271
        }
1272
}
×
1273

1274
void StelApp::setOverwriteInfoColor(const Vec3f& color)
×
1275
{
1276
        if (color != overwriteInfoColor)
×
1277
        {
1278
                overwriteInfoColor = color;
×
1279
                emit overwriteInfoColorChanged(color);
×
1280
        }
1281
}
×
1282

1283
Vec3f StelApp::getOverwriteInfoColor() const
×
1284
{
1285
        return overwriteInfoColor;
×
1286
}
1287

1288
void StelApp::setDaylightInfoColor(const Vec3f& color)
×
1289
{
1290
        if (color != daylightInfoColor)
×
1291
        {
1292
                daylightInfoColor = color;
×
1293
                emit daylightInfoColorChanged(color);
×
1294
        }
1295
}
×
1296

1297
Vec3f StelApp::getDaylightInfoColor() const
×
1298
{
1299
        return daylightInfoColor;
×
1300
}
1301

1302
void StelApp::setFlagImmediateSave(bool b)
×
1303
{
1304
        if (flagImmediateSave!=b)
×
1305
        {
1306
                flagImmediateSave = b;
×
1307
                emit flagImmediateSaveChanged(b);
×
1308
        }
1309
}
×
1310

1311
void StelApp::immediateSave(const QString &key, const QVariant &value)
×
1312
{
1313
        if (getInstance().getFlagImmediateSave())
×
1314
                getInstance().getSettings()->setValue(key, value);
×
1315
}
×
1316

1317

1318
// Update translations and font for sky everywhere in the program
1319
void StelApp::updateI18n()
×
1320
{
1321
#ifdef ENABLE_NLS
1322
        emit languageChanged();
1323
#endif
1324
}
×
1325

1326
void StelApp::ensureGLContextCurrent()
×
1327
{
1328
        mainWin->glContextMakeCurrent();
×
1329
}
×
1330

1331
// Return the time since when stellarium is running in second.
1332
double StelApp::getTotalRunTime()
×
1333
{
1334
        return static_cast<double>(QDateTime::currentMSecsSinceEpoch() - StelApp::startMSecs)/1000.;
×
1335
}
1336

1337
// Return the scaled time since when stellarium is running in second.
1338
double StelApp::getAnimationTime()
×
1339
{
1340
        return static_cast<double>(QDateTime::currentMSecsSinceEpoch() - StelApp::startMSecs)*StelApp::animationScale/1000.;
×
1341
}
1342

1343
void StelApp::reportFileDownloadFinished(QNetworkReply* reply)
×
1344
{
1345
        bool fromCache = reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool();
×
1346
        if (fromCache)
×
1347
        {
1348
                ++nbUsedCache;
×
1349
                totalUsedCacheSize+=reply->bytesAvailable();
×
1350
        }
1351
        else
1352
        {
1353
                ++nbDownloadedFiles;
×
1354
                totalDownloadedSize+=reply->bytesAvailable();
×
1355
        }
1356
}
×
1357

1358
void StelApp::quit()
×
1359
{
1360
        emit aboutToQuit();
×
1361
        // Let's allow exit from Stellarium via startup script!
1362
        QMetaObject::invokeMethod(qApp, "quit", Qt::QueuedConnection);
×
1363
}
×
1364

1365
void StelApp::setDevicePixelsPerPixel(qreal dppp)
×
1366
{
1367
        // Check that the device-independent pixel size didn't change
1368
        if (!viewportEffect && !fuzzyEquals(devicePixelsPerPixel, dppp))
×
1369
        {
1370
                devicePixelsPerPixel = dppp;
×
1371
                StelProjector::StelProjectorParams params = core->getCurrentStelProjectorParams();
×
1372
                params.devicePixelsPerPixel = devicePixelsPerPixel;
×
1373
                core->setCurrentStelProjectorParams(params);
×
1374
        }
1375
}
×
1376

1377
void StelApp::setViewportEffect(const QString& name)
×
1378
{
1379
        if (name == getViewportEffect()) return;
×
1380
        if (renderBuffer)
×
1381
        {
1382
                ensureGLContextCurrent();
×
1383
                delete renderBuffer;
×
1384
                renderBuffer = Q_NULLPTR;
×
1385
        }
1386
        if (viewportEffect)
×
1387
        {
1388
                delete viewportEffect;
×
1389
                viewportEffect = Q_NULLPTR;
×
1390
        }
1391
        if (name == "none") return;
×
1392

1393
        if (!core)
×
1394
        {
1395
                qDebug() << "No core to set viewport effect";
×
1396
                return;
×
1397
        }
1398
        StelProjector::StelProjectorParams params = core->getCurrentStelProjectorParams();
×
1399
        int w = params.viewportXywh[2];
×
1400
        int h = params.viewportXywh[3];
×
1401
        if (name == "sphericMirrorDistorter")
×
1402
        {
1403
                viewportEffect = new StelViewportDistorterFisheyeToSphericMirror(w, h);
×
1404
        }
1405
        else
1406
        {
1407
                qDebug() << "unknown viewport effect name:" << name;
×
1408
                Q_ASSERT(false);
×
1409
        }
1410
}
1411

1412
QString StelApp::getViewportEffect() const
×
1413
{
1414
        if (viewportEffect)
×
1415
                return viewportEffect->getName();
×
1416
        return "none";
×
1417
}
1418

1419
// Diagnostics
1420
void StelApp::dumpModuleActionPriorities(StelModule::StelModuleActionName actionName) const
×
1421
{
1422
        const QList<StelModule*> modules = moduleMgr->getCallOrders(actionName);
×
1423
        QMetaEnum me = QMetaEnum::fromType<StelModule::StelModuleActionName>();
×
1424
        qDebug() << "Module Priorities for action named" << me.valueToKey(actionName);
×
1425

1426
        for (auto* module : modules)
×
1427
        {
1428
                module->draw(core);
×
1429
                qDebug() << " -- " << module->getCallOrder(actionName) << "Module: " << module->objectName();
×
1430
        }
1431
}
×
1432

1433
StelModule* StelApp::getModule(const QString& moduleID) const
×
1434
{
1435
        return getModuleMgr().getModule(moduleID);
×
1436
}
1437
void StelApp::setScreenFontSize(int s)
×
1438
{
1439
        if (screenFontSize!=s)
×
1440
        {
1441
                screenFontSize=s;
×
1442
                emit screenFontSizeChanged(s);
×
1443
        }
1444
}
×
1445
void StelApp::setGuiFontSize(int s)
×
1446
{
1447
        if (getGuiFontSize()!=s)
×
1448
        {
1449
                QFont font=QGuiApplication::font();
×
1450
                font.setPixelSize(s);
×
1451
                QGuiApplication::setFont(font);
×
1452
                emit guiFontSizeChanged(s);
×
1453
        }
×
1454
}
×
1455
int StelApp::getGuiFontSize() const
×
1456
{
1457
        return QGuiApplication::font().pixelSize();
×
1458
}
1459

1460
void StelApp::setAppFont(QFont font)
×
1461
{
1462
        int oldSize=QGuiApplication::font().pixelSize();
×
1463
        font.setPixelSize(oldSize);
×
1464
        #if (QT_VERSION>=QT_VERSION_CHECK(5,15,0))
1465
        font.setStyleHint(QFont::AnyStyle, QFont::PreferAntialias);
×
1466
        #else
1467
        font.setStyleHint(QFont::AnyStyle, QFont::OpenGLCompatible);
1468
        #endif
1469
        QGuiApplication::setFont(font);
×
1470
        emit fontChanged(font);
×
1471
}
×
1472

1473
QString StelApp::getVersion() const
×
1474
{
1475
        return StelUtils::getApplicationVersion();
×
1476
}
1477

1478
void StelApp::enableBottomStelBarUpdates(bool enable)
×
1479
{
1480
        StelGui *gui=dynamic_cast<StelGui*>(getGui());
×
1481
        gui->getButtonBar()->enableTopoCentricUpdate(enable);
×
1482
}
×
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