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

Stellarium / stellarium / 13149582607

03 Feb 2025 11:24AM UTC coverage: 12.101% (-0.04%) from 12.141%
13149582607

push

github

web-flow
Translate po/stellarium/stellarium.pot in zh_CN

100% translated source file: 'po/stellarium/stellarium.pot'
on 'zh_CN'.

14603 of 120671 relevant lines covered (12.1%)

18593.62 hits per line

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

3.07
/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)
19✔
121
#endif
122

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

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

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

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

139
#ifdef USE_STATIC_PLUGIN_OCULARS
140
Q_IMPORT_PLUGIN(OcularsStelPluginInterface)
19✔
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)
19✔
149
#endif
150

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

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

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

163
#ifdef USE_STATIC_PLUGIN_NAVSTARS
164
Q_IMPORT_PLUGIN(NavStarsStelPluginInterface)
19✔
165
#endif
166

167
#ifdef USE_STATIC_PLUGIN_NOVAE
168
Q_IMPORT_PLUGIN(NovaeStelPluginInterface)
19✔
169
#endif
170

171
#ifdef USE_STATIC_PLUGIN_SUPERNOVAE
172
Q_IMPORT_PLUGIN(SupernovaeStelPluginInterface)
19✔
173
#endif
174

175
#ifdef USE_STATIC_PLUGIN_QUASARS
176
Q_IMPORT_PLUGIN(QuasarsStelPluginInterface)
19✔
177
#endif
178

179
#ifdef USE_STATIC_PLUGIN_PULSARS
180
Q_IMPORT_PLUGIN(PulsarsStelPluginInterface)
19✔
181
#endif
182

183
#ifdef USE_STATIC_PLUGIN_EXOPLANETS
184
Q_IMPORT_PLUGIN(ExoplanetsStelPluginInterface)
19✔
185
#endif
186

187
#ifdef USE_STATIC_PLUGIN_EQUATIONOFTIME
188
Q_IMPORT_PLUGIN(EquationOfTimeStelPluginInterface)
19✔
189
#endif
190

191
#ifdef USE_STATIC_PLUGIN_POINTERCOORDINATES
192
Q_IMPORT_PLUGIN(PointerCoordinatesStelPluginInterface)
19✔
193
#endif
194

195
#ifdef USE_STATIC_PLUGIN_OBSERVABILITY
196
Q_IMPORT_PLUGIN(ObservabilityStelPluginInterface)
19✔
197
#endif
198

199
#ifdef USE_STATIC_PLUGIN_SCENERY3D
200
Q_IMPORT_PLUGIN(Scenery3dStelPluginInterface)
19✔
201
#endif
202

203
#ifdef USE_STATIC_PLUGIN_REMOTECONTROL
204
Q_IMPORT_PLUGIN(RemoteControlStelPluginInterface)
19✔
205
#endif
206

207
#ifdef USE_STATIC_PLUGIN_REMOTESYNC
208
Q_IMPORT_PLUGIN(RemoteSyncStelPluginInterface)
19✔
209
#endif
210

211
#ifdef USE_STATIC_PLUGIN_VTS
212
Q_IMPORT_PLUGIN(VtsStelPluginInterface)
213
#endif
214

215
#ifdef USE_STATIC_PLUGIN_ONLINEQUERIES
216
Q_IMPORT_PLUGIN(OnlineQueriesPluginInterface)
19✔
217
#endif
218

219
// Initialize static variables
220
StelApp* StelApp::singleton = Q_NULLPTR;
221
qint64 StelApp::startMSecs = 0;
222
double StelApp::animationScale = 1.;
223

224
void StelApp::initStatic()
×
225
{
226
        StelApp::startMSecs = QDateTime::currentMSecsSinceEpoch();
×
227
}
×
228

229
void StelApp::deinitStatic()
×
230
{
231
        StelApp::startMSecs = 0;
×
232
}
×
233

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

290
        // Can't create 2 StelApp instances
291
        Q_ASSERT(!singleton);
×
292
        singleton = this;
×
293

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

302
/*************************************************************************
303
 Deinitialize and destroy the main Stellarium application.
304
*************************************************************************/
305
StelApp::~StelApp()
×
306
{
307
        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));
×
308

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

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

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

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

385
        if (!proxyHost.isEmpty())
×
386
        {
387
                QNetworkProxy proxy;
×
388
                if (useSocksProxy)
×
389
                        proxy.setType(QNetworkProxy::Socks5Proxy);
×
390
                else
391
                        proxy.setType(QNetworkProxy::HttpProxy);
×
392
                proxy.setHostName(proxyHost);
×
393
                if (!proxyPort.isEmpty())
×
394
                        proxy.setPort(proxyPort.toUShort());
×
395

396
                if (!proxyUser.isEmpty())
×
397
                        proxy.setUser(proxyUser);
×
398

399
                if (!proxyPass.isEmpty())
×
400
                        proxy.setPassword(proxyPass);
×
401

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

412
#ifdef ENABLE_SCRIPTING
413
void StelApp::initScriptMgr()
×
414
{
415
        scriptMgr->addModules();
×
416

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

437
QStringList StelApp::getCommandlineArguments()
×
438
{
439
        return qApp->property("stelCommandLine").toStringList();
×
440
}
441

442
void StelApp::init(QSettings* conf)
×
443
{
444
        gl = QOpenGLContext::currentContext()->functions();
×
445
        confSettings = conf;
×
446

447
        devicePixelsPerPixel = StelMainView::getInstance().devicePixelRatioF();
×
448
        qDebug() << "Initial high-DPI scaling factor:" << devicePixelsPerPixel;
×
449

450
        setScreenFontSize(confSettings->value("gui/screen_font_size", getDefaultGuiFontSize()).toInt());
×
451
        setGuiFontSize(confSettings->value("gui/gui_font_size", getDefaultGuiFontSize()).toInt());
×
452
        setScreenButtonScale(confSettings->value("gui/screen_button_scale", 100).toDouble());
×
453

454
        SplashScreen::present(guiFontSizeRatio());
×
455

456
        setFlagImmediateSave(confSettings->value("gui/immediate_save_details", false).toBool());
×
457

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

716
                        spoutSender = new SpoutSender(spoutName);
717

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

734
        initialized = true;
×
735
}
×
736

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

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

776

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

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

792

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

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

810
        moduleMgr->update();
×
811

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

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

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

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

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

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

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

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

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

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

930
void StelApp::highGraphicsModeDraw()
×
931
{
932
#if !QT_CONFIG(opengles2)
933
        const auto targetFBO = currentFbo;
×
934
        StelProjector::StelProjectorParams params = core->getCurrentStelProjectorParams();
×
935
        const auto w = params.viewportXywh[2] * params.devicePixelsPerPixel;
×
936
        const auto h = params.viewportXywh[3] * params.devicePixelsPerPixel;
×
937
        StelOpenGL::checkGLErrors(__FILE__, __LINE__);
×
938
        if(!sceneFBO || sceneFBO->size() != QSize(w,h))
×
939
        {
940
                GLint viewport[4] = {};
×
941
                GL(gl->glGetIntegerv(GL_VIEWPORT, viewport));
×
942
                qDebug() << "OpenGL viewport size:" << viewport[2] << "x" << viewport[3];
×
943

944
                qDebug().nospace() << "Creating scene FBO with size " << w << "x" << h;
×
945
                const auto internalFormat = GL_RGBA16;
×
946
                QOpenGLFramebufferObjectFormat format;
×
947
                format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
×
948
                format.setInternalTextureFormat(internalFormat);
×
949
                sceneFBO.reset(new QOpenGLFramebufferObject(w, h, format));
×
950
                GLint maxSamples = 1;
×
951
                GL(gl->glGetIntegerv(GL_MAX_SAMPLES, &maxSamples));
×
952
                const auto samples = confSettings->value("video/multisampling", 0).toInt();
×
953
                numMultiSamples = std::min(samples, maxSamples);
×
954
                if(numMultiSamples > 1)
×
955
                {
956
                        const auto gl = StelOpenGL::highGraphicsFunctions();
×
957
                        if(sceneMultisampledFBO)
×
958
                        {
959
                                GL(gl->glDeleteFramebuffers(1, &sceneMultisampledFBO));
×
960
                                GL(gl->glDeleteTextures(1, &sceneMultisampledTex));
×
961
                                GL(gl->glDeleteRenderbuffers(1, &sceneMultisampledRenderbuffer));
×
962
                        }
963
                        GL(gl->glGenFramebuffers(1, &sceneMultisampledFBO));
×
964
                        GL(gl->glGenTextures(1, &sceneMultisampledTex));
×
965
                        GL(gl->glGenRenderbuffers(1, &sceneMultisampledRenderbuffer));
×
966

967
                        GL(gl->glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, sceneMultisampledTex));
×
968
                        GL(gl->glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, numMultiSamples,
×
969
                                                                internalFormat, w, h, true));
970

971
                        GL(gl->glBindRenderbuffer(GL_RENDERBUFFER, sceneMultisampledRenderbuffer));
×
972
                        GL(gl->glRenderbufferStorageMultisample(GL_RENDERBUFFER, numMultiSamples,
×
973
                                                                         GL_DEPTH24_STENCIL8, w, h));
974

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

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

1002
        GL(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));
×
1003

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

1006
        for(auto* module : modules)
×
1007
        {
1008
                module->draw(core);
×
1009
        }
1010

1011
        if(sceneMultisampledFBO)
×
1012
        {
1013
                GL(gl->glBindFramebuffer(GL_FRAMEBUFFER, targetFBO));
×
1014
                postProcessorProgramMS->bind();
×
1015

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

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

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

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

1046
        }
1047

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

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

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

1068
        prepareRenderBuffer();
×
1069
        currentFbo = renderBuffer ? renderBuffer->handle() : static_cast<GLuint>(drawFbo);
×
1070

1071
        core->preDraw();
×
1072

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

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

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

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

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

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

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

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

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

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

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

1239
void StelApp::setFlagOverwriteInfoColor(bool b)
×
1240
{
1241
        if (flagOverwriteInfoColor!=b)
×
1242
        {
1243
                flagOverwriteInfoColor=b;
×
1244
                StelApp::immediateSave("gui/flag_overwrite_info_color", b);
×
1245
                emit flagOverwriteInfoColorChanged(b);
×
1246
        }
1247
}
×
1248

1249
void StelApp::setFlagShowDecimalDegrees(bool b)
×
1250
{
1251
        if (flagShowDecimalDegrees!=b)
×
1252
        {
1253
                flagShowDecimalDegrees = b;
×
1254
                StelApp::immediateSave("gui/flag_show_decimal_degrees", b);
×
1255
                emit flagShowDecimalDegreesChanged(b);
×
1256
        }
1257
}
×
1258

1259
void StelApp::setFlagSouthAzimuthUsage(bool use)
×
1260
{
1261
        if (flagUseAzimuthFromSouth!=use)
×
1262
        {
1263
                flagUseAzimuthFromSouth=use;
×
1264
                StelApp::immediateSave("gui/flag_use_azimuth_from_south", use);
×
1265
                emit flagUseAzimuthFromSouthChanged(use);
×
1266
        }
1267
}
×
1268

1269

1270
void StelApp::setFlagUseFormattingOutput(bool b)
×
1271
{
1272
        if (flagUseFormattingOutput!=b)
×
1273
        {
1274
                flagUseFormattingOutput = b;
×
1275
                StelApp::immediateSave("gui/flag_use_formatting_output", flagUseFormattingOutput);
×
1276
                emit flagUseFormattingOutputChanged(b);
×
1277
        }
1278
}
×
1279

1280
void StelApp::setFlagUseCCSDesignation(bool b)
×
1281
{
1282
        if (flagUseCCSDesignation!=b)
×
1283
        {
1284
                flagUseCCSDesignation = b;
×
1285
                StelApp::immediateSave("gui/flag_use_ccs_designations", flagUseCCSDesignation);
×
1286
                emit flagUseCCSDesignationChanged(b);
×
1287
        }
1288
}
×
1289

1290
void StelApp::setOverwriteInfoColor(const Vec3f& color)
×
1291
{
1292
        if (color != overwriteInfoColor)
×
1293
        {
1294
                overwriteInfoColor = color;
×
1295
                emit overwriteInfoColorChanged(color);
×
1296
        }
1297
}
×
1298

1299
Vec3f StelApp::getOverwriteInfoColor() const
×
1300
{
1301
        return overwriteInfoColor;
×
1302
}
1303

1304
void StelApp::setDaylightInfoColor(const Vec3f& color)
×
1305
{
1306
        if (color != daylightInfoColor)
×
1307
        {
1308
                daylightInfoColor = color;
×
1309
                emit daylightInfoColorChanged(color);
×
1310
        }
1311
}
×
1312

1313
Vec3f StelApp::getDaylightInfoColor() const
×
1314
{
1315
        return daylightInfoColor;
×
1316
}
1317

1318
void StelApp::setFlagImmediateSave(bool b)
×
1319
{
1320
        if (flagImmediateSave!=b)
×
1321
        {
1322
                flagImmediateSave = b;
×
1323
                // To not accidentally activate this mode permanently, you must use the "save settings" button to activate!
1324
                if (!b)
×
1325
                        StelApp::immediateSave("gui/immediate_save_details", false);
×
1326
                emit flagImmediateSaveChanged(b);
×
1327
        }
1328
}
×
1329

1330
void StelApp::immediateSave(const QString &key, const QVariant &value)
×
1331
{
1332
        if (getInstance().getFlagImmediateSave())
×
1333
                getInstance().getSettings()->setValue(key, value);
×
1334
}
×
1335

1336

1337
// Update translations and font for sky everywhere in the program
1338
void StelApp::updateI18n()
×
1339
{
1340
#ifdef ENABLE_NLS
1341
        emit languageChanged();
1342
#endif
1343
}
×
1344

1345
void StelApp::ensureGLContextCurrent()
×
1346
{
1347
        mainWin->glContextMakeCurrent();
×
1348
}
×
1349

1350
// Return the time since when stellarium is running in second.
1351
double StelApp::getTotalRunTime()
×
1352
{
1353
        return static_cast<double>(QDateTime::currentMSecsSinceEpoch() - StelApp::startMSecs)/1000.;
×
1354
}
1355

1356
// Return the scaled time since when stellarium is running in second.
1357
double StelApp::getAnimationTime()
×
1358
{
1359
        return static_cast<double>(QDateTime::currentMSecsSinceEpoch() - StelApp::startMSecs)*StelApp::animationScale/1000.;
×
1360
}
1361

1362
void StelApp::reportFileDownloadFinished(QNetworkReply* reply)
×
1363
{
1364
        bool fromCache = reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool();
×
1365
        if (fromCache)
×
1366
        {
1367
                ++nbUsedCache;
×
1368
                totalUsedCacheSize+=reply->bytesAvailable();
×
1369
        }
1370
        else
1371
        {
1372
                ++nbDownloadedFiles;
×
1373
                totalDownloadedSize+=reply->bytesAvailable();
×
1374
        }
1375
}
×
1376

1377
void StelApp::quit()
×
1378
{
1379
        emit aboutToQuit();
×
1380
        // Let's allow exit from Stellarium via startup script!
1381
        QMetaObject::invokeMethod(qApp, "quit", Qt::QueuedConnection);
×
1382
}
×
1383

1384
void StelApp::setDevicePixelsPerPixel(qreal dppp)
×
1385
{
1386
        // Check that the device-independent pixel size didn't change
1387
        if (!viewportEffect && !fuzzyEquals(devicePixelsPerPixel, dppp))
×
1388
        {
1389
                qDebug() << "Changing high-DPI scaling factor from" << devicePixelsPerPixel << "to" << dppp;
×
1390
                devicePixelsPerPixel = dppp;
×
1391
                StelProjector::StelProjectorParams params = core->getCurrentStelProjectorParams();
×
1392
                params.devicePixelsPerPixel = devicePixelsPerPixel;
×
1393
                core->setCurrentStelProjectorParams(params);
×
1394
        }
1395
}
×
1396

1397
void StelApp::setViewportEffect(const QString& name)
×
1398
{
1399
        if (name == getViewportEffect()) return;
×
1400
        StelApp::immediateSave("video/viewport_effect", name);
×
1401
        if (renderBuffer)
×
1402
        {
1403
                ensureGLContextCurrent();
×
1404
                delete renderBuffer;
×
1405
                renderBuffer = Q_NULLPTR;
×
1406
        }
1407
        if (viewportEffect)
×
1408
        {
1409
                delete viewportEffect;
×
1410
                viewportEffect = Q_NULLPTR;
×
1411
        }
1412
        if (name == "none") return;
×
1413

1414
        if (!core)
×
1415
        {
1416
                qDebug() << "No core to set viewport effect";
×
1417
                return;
×
1418
        }
1419
        StelProjector::StelProjectorParams params = core->getCurrentStelProjectorParams();
×
1420
        int w = params.viewportXywh[2];
×
1421
        int h = params.viewportXywh[3];
×
1422
        if (name == "sphericMirrorDistorter")
×
1423
        {
1424
                viewportEffect = new StelViewportDistorterFisheyeToSphericMirror(w, h);
×
1425
        }
1426
        else
1427
        {
1428
                qDebug() << "unknown viewport effect name:" << name;
×
1429
                Q_ASSERT(false);
×
1430
        }
1431
}
1432

1433
QString StelApp::getViewportEffect() const
×
1434
{
1435
        if (viewportEffect)
×
1436
                return viewportEffect->getName();
×
1437
        return "none";
×
1438
}
1439

1440
// Diagnostics
1441
void StelApp::dumpModuleActionPriorities(StelModule::StelModuleActionName actionName) const
×
1442
{
1443
        const QList<StelModule*> modules = moduleMgr->getCallOrders(actionName);
×
1444
        QMetaEnum me = QMetaEnum::fromType<StelModule::StelModuleActionName>();
×
1445
        qDebug() << "Module Priorities for action named" << me.valueToKey(actionName);
×
1446

1447
        for (auto* module : modules)
×
1448
        {
1449
                module->draw(core);
×
1450
                qDebug() << " -- " << module->getCallOrder(actionName) << "Module: " << module->objectName();
×
1451
        }
1452
}
×
1453

1454
StelModule* StelApp::getModule(const QString& moduleID) const
×
1455
{
1456
        return getModuleMgr().getModule(moduleID);
×
1457
}
1458
void StelApp::setScreenFontSize(int s)
×
1459
{
1460
        if (screenFontSize!=s)
×
1461
        {
1462
                screenFontSize=s;
×
1463
                StelApp::immediateSave("gui/screen_font_size", s);
×
1464
                emit screenFontSizeChanged(s);
×
1465
        }
1466
}
×
1467

1468
void StelApp::setScreenButtonScale(const double s)
×
1469
{
1470
        if (screenButtonScale!=s)
×
1471
        {
1472
                screenButtonScale = s;
×
1473
                StelApp::immediateSave("gui/screen_button_scale", s);
×
1474
                emit screenButtonScaleChanged(s);
×
1475
        }
1476
}
×
1477

1478
double StelApp::screenFontSizeRatio() const
×
1479
{
1480
        return double(getScreenFontSize()) / getDefaultGuiFontSize();
×
1481
}
1482

1483
void StelApp::setGuiFontSize(int s)
×
1484
{
1485
        if (getGuiFontSize()!=s)
×
1486
        {
1487
                QFont font=QGuiApplication::font();
×
1488
                font.setPixelSize(s);
×
1489
                QGuiApplication::setFont(font);
×
1490
                StelApp::immediateSave("gui/gui_font_size", s);
×
1491
                emit guiFontSizeChanged(s);
×
1492
        }
×
1493
}
×
1494
int StelApp::getGuiFontSize() const
×
1495
{
1496
        return QGuiApplication::font().pixelSize();
×
1497
}
1498

1499
float StelApp::getScreenScale() const
×
1500
{
1501
        const float dppRatio = StelApp::getInstance().getDevicePixelsPerPixel();
×
1502
        const float fontRatio = StelApp::getInstance().screenFontSizeRatio();
×
1503
        return dppRatio * fontRatio;
×
1504
}
1505

1506
void StelApp::setAppFont(QFont font)
×
1507
{
1508
        int oldSize=QGuiApplication::font().pixelSize();
×
1509
        font.setPixelSize(oldSize);
×
1510
        #if (QT_VERSION>=QT_VERSION_CHECK(5,15,0))
1511
        font.setStyleHint(QFont::AnyStyle, QFont::PreferAntialias);
×
1512
        #else
1513
        font.setStyleHint(QFont::AnyStyle, QFont::OpenGLCompatible);
1514
        #endif
1515
        QGuiApplication::setFont(font);
×
1516
        emit fontChanged(font);
×
1517
}
×
1518

1519
QString StelApp::getVersion() const
×
1520
{
1521
        return StelUtils::getApplicationVersion();
×
1522
}
1523

1524
void StelApp::enableBottomStelBarUpdates(bool enable)
×
1525
{
1526
        StelGui *gui=dynamic_cast<StelGui*>(getGui());
×
1527
        gui->getButtonBar()->enableTopoCentricUpdate(enable);
×
1528
}
×
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