1 /*
2  * Stellarium
3  * Copyright (C) 2007 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 #ifndef STELSKYDRAWER_HPP
21 #define STELSKYDRAWER_HPP
22 
23 #include "RefractionExtinction.hpp"
24 #include "StelTextureTypes.hpp"
25 #include "StelProjectorType.hpp"
26 #include "VecMath.hpp"
27 #include "StelOpenGL.hpp"
28 
29 #include <QObject>
30 #include <QImage>
31 
32 class StelToneReproducer;
33 class StelCore;
34 class StelPainter;
35 
36 //! Contains the 2 parameters necessary to draw a star on screen.
37 //! the radius and luminance of the star halo texture.
38 struct RCMag
39 {
40 	float radius;
41 	float luminance;
42 };
43 
44 //! @class StelSkyDrawer
45 //! Provide a set of methods used to draw sky objects taking into account
46 //! eyes adaptation, zoom level, instrument model and artificially set magnitude limits
47 class StelSkyDrawer : public QObject, protected QOpenGLFunctions
48 {
49 	Q_OBJECT
50 
51 	//! Sets how much brighter stars will be bigger than fainter stars
52 	Q_PROPERTY(double relativeStarScale READ getRelativeStarScale WRITE setRelativeStarScale NOTIFY relativeStarScaleChanged)
53 	//! The absolute star brightness scale
54 	Q_PROPERTY(double absoluteStarScale READ getAbsoluteStarScale WRITE setAbsoluteStarScale NOTIFY absoluteStarScaleChanged)
55 	Q_PROPERTY(double twinkleAmount READ getTwinkleAmount WRITE setTwinkleAmount NOTIFY twinkleAmountChanged)
56 	Q_PROPERTY(bool flagStarTwinkle READ getFlagTwinkle WRITE setFlagTwinkle NOTIFY flagTwinkleChanged)
57 	Q_PROPERTY(int bortleScaleIndex READ getBortleScaleIndex WRITE setBortleScaleIndex NOTIFY bortleScaleIndexChanged)
58 	Q_PROPERTY(bool flagDrawBigStarHalo READ getFlagDrawBigStarHalo WRITE setFlagDrawBigStarHalo NOTIFY flagDrawBigStarHaloChanged)
59 	Q_PROPERTY(bool flagStarSpiky READ getFlagStarSpiky WRITE setFlagStarSpiky NOTIFY flagStarSpikyChanged)
60 
61 	Q_PROPERTY(bool flagStarMagnitudeLimit READ getFlagStarMagnitudeLimit WRITE setFlagStarMagnitudeLimit NOTIFY flagStarMagnitudeLimitChanged)
62 	Q_PROPERTY(bool flagNebulaMagnitudeLimit READ getFlagNebulaMagnitudeLimit WRITE setFlagNebulaMagnitudeLimit NOTIFY flagNebulaMagnitudeLimitChanged)
63 	Q_PROPERTY(bool flagPlanetMagnitudeLimit READ getFlagPlanetMagnitudeLimit WRITE setFlagPlanetMagnitudeLimit NOTIFY flagPlanetMagnitudeLimitChanged)
64 
65 	Q_PROPERTY(double customStarMagLimit READ getCustomStarMagnitudeLimit WRITE setCustomStarMagnitudeLimit NOTIFY customStarMagLimitChanged)
66 	Q_PROPERTY(double customNebulaMagLimit READ getCustomNebulaMagnitudeLimit WRITE setCustomNebulaMagnitudeLimit NOTIFY customNebulaMagLimitChanged)
67 	Q_PROPERTY(double customPlanetMagLimit READ getCustomPlanetMagnitudeLimit WRITE setCustomPlanetMagnitudeLimit NOTIFY customPlanetMagLimitChanged)
68 
69 	Q_PROPERTY(bool flagLuminanceAdaptation READ getFlagLuminanceAdaptation WRITE setFlagLuminanceAdaptation NOTIFY flagLuminanceAdaptationChanged)
70 	Q_PROPERTY(double daylightLabelThreshold READ getDaylightLabelThreshold WRITE setDaylightLabelThreshold NOTIFY daylightLabelThresholdChanged)
71 
72 	Q_PROPERTY(double extinctionCoefficient READ getExtinctionCoefficient WRITE setExtinctionCoefficient NOTIFY extinctionCoefficientChanged)
73 	Q_PROPERTY(double atmosphereTemperature READ getAtmosphereTemperature WRITE setAtmosphereTemperature NOTIFY atmosphereTemperatureChanged)
74 	Q_PROPERTY(double atmospherePressure READ getAtmospherePressure WRITE setAtmospherePressure NOTIFY atmospherePressureChanged)
75 
76 public:
77 	//! Constructor
78 	StelSkyDrawer(StelCore* core);
79 	//! Destructor
80 	~StelSkyDrawer();
81 
82 	//! Init parameters from config file
83 	void init();
84 
85 	//! Update with respect to the time and StelProjector/StelToneReproducer state
86 	//! @param deltaTime the time increment in second since last call.
87 	void update(double deltaTime);
88 
89 	//! Set the proper openGL state before making calls to drawPointSource
90 	//! @param p a pointer to a valid instance of a Painter. The instance must be valid until postDrawPointSource() is called
91 	void preDrawPointSource(StelPainter* p);
92 
93 	//! Finalize the drawing of point sources
94 	void postDrawPointSource(StelPainter* sPainter);
95 
96 	//! Draw a point source halo.
97 	//! @param sPainter the StelPainter to use for drawing.
98 	//! @param v the 3d position of the source in J2000 reference frame
99 	//! @param rcMag the radius and luminance of the source as computed by computeRCMag()
100 	//! @param bVindex the source B-V index (into the private colorTable. This is not the astronomical B-V value.)
101 	//! @param checkInScreen whether source in screen should be checked to avoid unnecessary drawing.
102 	//! @param twinkleFactor allows height-dependent twinkling. Recommended value: min(1,1-0.9*sin(altitude)). Allowed values [0..1]
103 	//! @return true if the source was actually visible and drawn
drawPointSource(StelPainter * sPainter,const Vec3f & v,const RCMag & rcMag,int bVindex,bool checkInScreen=false,float twinkleFactor=1.0f)104 	bool drawPointSource(StelPainter* sPainter, const Vec3f& v, const RCMag &rcMag, int bVindex, bool checkInScreen=false, float twinkleFactor=1.0f)
105 	{
106 		return drawPointSource(sPainter, v, rcMag, colorTable[bVindex], checkInScreen, twinkleFactor);
107 	}
108 
109 	bool drawPointSource(StelPainter* sPainter, const Vec3f& v, const RCMag &rcMag, const Vec3f& bcolor, bool checkInScreen=false, float twinkleFactor=1.0f);
110 
111 	//! Draw an image of the solar corona onto the screen at position v.
112 	//! @param radius depends on the actually used texture and current disk size of the sun.
113 	//! @param alpha opacity value. Set 1 for full visibility, but usually keep close to 0 except during solar eclipses.
114 	//! @param angle includes parallactic angle (if alt/azimuth frame) and angle between solar polar axis and celestial equator.
115 	void drawSunCorona(StelPainter* painter, const Vec3f& v, float radius, const Vec3f& color, const float alpha, const float angle);
116 
117 	//! Terminate drawing of a 3D model, draw the halo
118 	//! @param p the StelPainter instance to use for this drawing operation
119 	//! @param v the 3d position of the source in J2000 reference frame
120 	//! @param illuminatedArea the illuminated area in arcmin^2
121 	//! @param mag the source integrated magnitude
122 	//! @param color the object halo RGB color
123 	void postDrawSky3dModel(StelPainter* p, const Vec3f& v, float illuminatedArea, float mag, const Vec3f& color = Vec3f(1.f,1.f,1.f));
124 
125 	//! Compute RMag and CMag from magnitude.
126 	//! @param mag the object integrated V magnitude
127 	//! @param rcMag array of 2 floats containing the radius and luminance
128 	//! @return false if the object is too faint to be displayed
129 	bool computeRCMag(float mag, RCMag*) const;
130 
131 	//! Report that an object of luminance lum with an on-screen area of area pixels is currently displayed
132 	//! This information is used to determine the world adaptation luminance
133 	//! This method should be called during the update operations of the main loop
134 	//! @param lum luminance in cd/m^2
135 	//! @param fastAdaptation adapt the eye quickly if true, other wise use a smooth adaptation
136 	void reportLuminanceInFov(float lum, bool fastAdaptation=false);
137 
138 	//! To be called before the drawing stage starts
139 	void preDraw();
140 
141 	//! Compute the luminance for an extended source with the given surface brightness
142 	//! @param sb surface brightness in V magnitude/arcmin^2
143 	//! @return the luminance in cd/m^2
144 	static float surfaceBrightnessToLuminance(float sb);
145 	//! Compute the surface brightness from the luminance of an extended source
146 	//! @param lum luminance in cd/m^2
147 	//! @return surface brightness in V magnitude/arcmin^2
148 	static float luminanceToSurfacebrightness(float lum);
149 
150 	//! Convert quantized B-V index to float B-V
indexToBV(unsigned char bV)151 	static inline float indexToBV(unsigned char bV)
152 	{
153 		return static_cast<float>(bV)*(4.f/127.f)-0.5f;
154 	}
155 
156 	//! Convert quantized B-V index to RGB colors
indexToColor(int bV)157 	static inline const Vec3f& indexToColor(int bV)
158 	{
159 		return colorTable[bV];
160 	}
161 
162 public slots:
163 	//! Set the way brighter stars will look bigger as the fainter ones
setRelativeStarScale(double b=1.0)164 	void setRelativeStarScale(double b=1.0) { starRelativeScale=b; emit relativeStarScaleChanged(b);}
165 	//! Get the way brighter stars will look bigger as the fainter ones
getRelativeStarScale() const166 	double getRelativeStarScale() const {return starRelativeScale;}
167 
168 	//! Set the absolute star brightness scale
setAbsoluteStarScale(double b=1.0)169 	void setAbsoluteStarScale(double b=1.0) { starAbsoluteScaleF=b; emit absoluteStarScaleChanged(b);}
170 	//! Get the absolute star brightness scale
getAbsoluteStarScale() const171 	double getAbsoluteStarScale() const {return starAbsoluteScaleF;}
172 
173 	//! Set source twinkle amount.
setTwinkleAmount(double b)174 	void setTwinkleAmount(double b) { twinkleAmount=b; emit twinkleAmountChanged(b);}
175 	//! Get source twinkle amount.
getTwinkleAmount() const176 	double getTwinkleAmount() const {return twinkleAmount;}
177 
178 	//! Set flag for source twinkling.
setFlagTwinkle(bool b)179 	void setFlagTwinkle(bool b) {if(b!=flagStarTwinkle){ flagStarTwinkle=b; emit flagTwinkleChanged(b);}}
180 	//! Get flag for source twinkling.
getFlagTwinkle() const181 	bool getFlagTwinkle() const {return flagStarTwinkle;}
182 
183 	//! Set flag for enable twinkling of stars without atmosphere.
184 	//! @note option for planetariums
setFlagForcedTwinkle(bool b)185 	void setFlagForcedTwinkle(bool b) {if(b!=flagForcedTwinkle){ flagForcedTwinkle=b;}}
186 	//! Get flag for enable twinkling of stars without atmosphere.
187 	//! @note option for planetariums
getFlagForcedTwinkle() const188 	bool getFlagForcedTwinkle() const {return flagForcedTwinkle;}
189 
190 	//! Set the parameters so that the stars disappear at about the limit given by the bortle scale
191 	//! The limit is valid only at a given zoom level (around 60 deg)
192 	//! @see https://en.wikipedia.org/wiki/Bortle_scale
193 	void setBortleScaleIndex(int index);
194 	//! Get the current Bortle scale index
195 	//! @see https://en.wikipedia.org/wiki/Bortle_scale
getBortleScaleIndex() const196 	int getBortleScaleIndex() const {return bortleScaleIndex;}
197 	//! Get the average Naked-Eye Limiting Magnitude (NELM) for current Bortle scale index:
198 	//! Class 1 = NELM 7.6-8.0; average NELM is 7.8
199 	//! Class 2 = NELM 7.1-7.5; average NELM is 7.3
200 	//! Class 3 = NELM 6.6-7.0; average NELM is 6.8
201 	//! Class 4 = NELM 6.1-6.5; average NELM is 6.3
202 	//! Class 5 = NELM 5.6-6.0; average NELM is 5.8
203 	//! Class 6 = NELM 5.1-5.5; average NELM is 5.3
204 	//! Class 7 = NELM 4.6-5.0; average NELM is 4.8
205 	//! Class 8 = NELM 4.1-4.5; average NELM is 4.3
206 	//! Class 9 = NELM 4.0
207 	float getNELMFromBortleScale() const;
208 	//! Get the average Naked-Eye Limiting Magnitude (NELM) for given Bortle scale index [1..9]
209 	//! Class 1 = NELM 7.6-8.0; average NELM is 7.8
210 	//! Class 2 = NELM 7.1-7.5; average NELM is 7.3
211 	//! Class 3 = NELM 6.6-7.0; average NELM is 6.8
212 	//! Class 4 = NELM 6.1-6.5; average NELM is 6.3
213 	//! Class 5 = NELM 5.6-6.0; average NELM is 5.8
214 	//! Class 6 = NELM 5.1-5.5; average NELM is 5.3
215 	//! Class 7 = NELM 4.6-5.0; average NELM is 4.8
216 	//! Class 8 = NELM 4.1-4.5; average NELM is 4.3
217 	//! Class 9 = NELM 4.0
218 	//! @arg idx Bortle Scale Index (valid: 1..9, will be forced to valid range)
219 	static float getNELMFromBortleScale(int idx);
220 
221 	//! Set flag for drawing a halo around bright stars.
setFlagDrawBigStarHalo(bool b)222 	void setFlagDrawBigStarHalo(bool b) {if(b!=flagDrawBigStarHalo){ flagDrawBigStarHalo=b; emit flagDrawBigStarHaloChanged(b);}}
223 	//! Get flag for drawing a halo around bright stars.
getFlagDrawBigStarHalo() const224 	bool getFlagDrawBigStarHalo() const {return flagDrawBigStarHalo;}
225 
226 	//! Set flag to draw stars with rays
227 	void setFlagStarSpiky(bool b);
228 	//! Get whether to draw stars with rays
getFlagStarSpiky() const229 	bool getFlagStarSpiky() const {return flagStarSpiky;}
230 
231 	//! Get the magnitude of the currently faintest visible point source
232 	//! It depends on the zoom level, on the eye adapation and on the point source rendering parameters
233 	//! @return the limit V mag at which a point source will be displayed
getLimitMagnitude() const234 	float getLimitMagnitude() const {return limitMagnitude;}
235 
236 	//! Toggle the application of user-defined star magnitude limit.
237 	//! If enabled, stars fainter than the magnitude set with
238 	//! setCustomStarMagnitudeLimit() will not be displayed.
setFlagStarMagnitudeLimit(bool b)239 	void setFlagStarMagnitudeLimit(bool b) {if(b!=flagStarMagnitudeLimit){ flagStarMagnitudeLimit = b; emit flagStarMagnitudeLimitChanged(b);}}
240 	//! @return true if the user-defined star magnitude limit is in force.
getFlagStarMagnitudeLimit() const241 	bool getFlagStarMagnitudeLimit() const {return flagStarMagnitudeLimit;}
242 	//! Toggle the application of user-defined deep-sky object magnitude limit.
243 	//! If enabled, deep-sky objects fainter than the magnitude set with
244 	//! setCustomNebulaMagnitudeLimit() will not be displayed.
setFlagNebulaMagnitudeLimit(bool b)245 	void setFlagNebulaMagnitudeLimit(bool b) {if(b!=flagNebulaMagnitudeLimit){ flagNebulaMagnitudeLimit = b; emit flagNebulaMagnitudeLimitChanged(b);}}
246 	//! @return true if the user-defined nebula magnitude limit is in force.
getFlagNebulaMagnitudeLimit() const247 	bool getFlagNebulaMagnitudeLimit() const {return flagNebulaMagnitudeLimit;}
248 	//! Toggle the application of user-defined solar system object magnitude limit.
249 	//! If enabled, planets, planetary moons, asteroids (KBO, ...) and comets fainter than the magnitude set with
250 	//! setCustomPlanetMagnitudeLimit() will not be displayed.
setFlagPlanetMagnitudeLimit(bool b)251 	void setFlagPlanetMagnitudeLimit(bool b) {if(b!=flagPlanetMagnitudeLimit){ flagPlanetMagnitudeLimit = b; emit flagPlanetMagnitudeLimitChanged(b);}}
252 	//! @return true if the user-defined nebula magnitude limit is in force.
getFlagPlanetMagnitudeLimit() const253 	bool getFlagPlanetMagnitudeLimit() const {return flagPlanetMagnitudeLimit;}
254 
255 	//! Get the value used for forced star magnitude limiting.
getCustomStarMagnitudeLimit() const256 	double getCustomStarMagnitudeLimit() const {return customStarMagLimit;}
257 	//! Sets a lower limit for star magnitudes (anything fainter is ignored).
258 	//! In force only if flagStarMagnitudeLimit is set.
setCustomStarMagnitudeLimit(double limit)259 	void setCustomStarMagnitudeLimit(double limit) { customStarMagLimit=limit; emit customStarMagLimitChanged(limit);}
260 	//! Get the value used for forced nebula magnitude limiting.
getCustomNebulaMagnitudeLimit() const261 	double getCustomNebulaMagnitudeLimit() const {return customNebulaMagLimit;}
262 	//! Sets a lower limit for nebula magnitudes (anything fainter is ignored).
263 	//! In force only if flagNebulaMagnitudeLimit is set.
setCustomNebulaMagnitudeLimit(double limit)264 	void setCustomNebulaMagnitudeLimit(double limit) { customNebulaMagLimit=limit; emit customNebulaMagLimitChanged(limit);}
265 	//! Get the value used for forced solar system object magnitude limiting.
getCustomPlanetMagnitudeLimit() const266 	double getCustomPlanetMagnitudeLimit() const {return customPlanetMagLimit;}
267 	//! Sets a lower limit for solar system object magnitudes (anything fainter is ignored).
268 	//! In force only if flagPlanetMagnitudeLimit is set.
setCustomPlanetMagnitudeLimit(double limit)269 	void setCustomPlanetMagnitudeLimit(double limit) { customPlanetMagLimit=limit; emit customPlanetMagLimitChanged(limit);}
270 
271 	//! Get the luminance of the faintest visible object (e.g. RGB<0.05)
272 	//! It depends on the zoom level, on the eye adapation and on the point source rendering parameters
273 	//! @return the limit V luminance at which an object will be visible
getLimitLuminance() const274 	float getLimitLuminance() const {return limitLuminance;}
275 
276 	//! Set the value of the eye adaptation flag
setFlagLuminanceAdaptation(bool b)277 	void setFlagLuminanceAdaptation(bool b) {if(b!=flagLuminanceAdaptation){ flagLuminanceAdaptation=b; emit flagLuminanceAdaptationChanged(b);}}
278 	//! Get the current value of eye adaptation flag
getFlagLuminanceAdaptation() const279 	bool getFlagLuminanceAdaptation() const {return flagLuminanceAdaptation;}
280 
281 	//! Set the label brightness threshold
setDaylightLabelThreshold(double t)282 	void setDaylightLabelThreshold(double t) { daylightLabelThreshold=t; emit daylightLabelThresholdChanged(t);}
283 	//! Get the current label brightness threshold
getDaylightLabelThreshold() const284 	double getDaylightLabelThreshold() const {return daylightLabelThreshold;}
285 	//! Return a brightness value based on objects in view (sky, sun, moon, ...)
286 	double getWorldAdaptationLuminance() const;
287 
288 	//! Informing the drawer whether atmosphere is displayed.
289 	//! This is used to avoid twinkling/simulate extinction/refraction.
setFlagHasAtmosphere(bool b)290 	void setFlagHasAtmosphere(bool b) {flagHasAtmosphere=b;}
291 	//! This is used to decide whether to apply refraction/extinction before rendering point sources et al.
getFlagHasAtmosphere() const292 	bool getFlagHasAtmosphere() const {return flagHasAtmosphere;}
293 
294 	//! Set extinction coefficient, mag/airmass (for extinction).
setExtinctionCoefficient(double extCoeff)295 	void setExtinctionCoefficient(double extCoeff) { extinction.setExtinctionCoefficient(static_cast<float>(extCoeff)); emit extinctionCoefficientChanged(static_cast<double>(extinction.getExtinctionCoefficient()));}
296 	//! Get extinction coefficient, mag/airmass (for extinction).
getExtinctionCoefficient() const297 	double getExtinctionCoefficient() const {return static_cast<double>(extinction.getExtinctionCoefficient());}
298 	//! Set atmospheric (ground) temperature in deg celsius (for refraction).
setAtmosphereTemperature(double celsius)299 	void setAtmosphereTemperature(double celsius) {refraction.setTemperature(static_cast<float>(celsius)); emit atmosphereTemperatureChanged(static_cast<double>(refraction.getTemperature()));}
300 	//! Get atmospheric (ground) temperature in deg celsius (for refraction).
getAtmosphereTemperature() const301 	double getAtmosphereTemperature() const {return static_cast<double>(refraction.getTemperature());}
302 	//! Set atmospheric (ground) pressure in mbar (for refraction).
setAtmospherePressure(double mbar)303 	void setAtmospherePressure(double mbar) { refraction.setPressure(static_cast<float>(mbar)); emit atmospherePressureChanged(static_cast<double>(refraction.getPressure()));}
304 	//! Get atmospheric (ground) pressure in mbar (for refraction).
getAtmospherePressure() const305 	double getAtmospherePressure() const {return static_cast<double>(refraction.getPressure());}
306 
307 	//! Get the current valid extinction computation object.
getExtinction() const308 	const Extinction& getExtinction() const {return extinction;}
309 	//! Get the current valid refraction computation object.
getRefraction() const310 	const Refraction& getRefraction() const {return refraction;}
311 
312 	//! Get the radius of the big halo texture used when a 3d model is very bright.
getBig3dModelHaloRadius() const313 	float getBig3dModelHaloRadius() const {return big3dModelHaloRadius;}
314 	//! Set the radius of the big halo texture used when a 3d model is very bright.
setBig3dModelHaloRadius(float r)315 	void setBig3dModelHaloRadius(float r) {big3dModelHaloRadius=r;}
316 signals:
317 	//! Emitted whenever the relative star scale changed
318 	void relativeStarScaleChanged(double b);
319 	//! Emitted whenever the absolute star scale changed
320 	void absoluteStarScaleChanged(double b);
321 	//! Emitted whenever the twinkle amount changed
322 	void twinkleAmountChanged(double b);
323 	//! Emitted whenever the twinkle flag is toggled
324 	void flagTwinkleChanged(bool b);
325 	//! Emitted whenever the Bortle scale index changed
326 	void bortleScaleIndexChanged(int index);
327 	//! Emitted when flag to draw big halo around stars changed
328 	void flagDrawBigStarHaloChanged(bool b);
329 	//! Emitted on change of star texture
330 	void flagStarSpikyChanged(bool b);
331 
332 	//! Emitted whenever the star magnitude limit flag is toggled
333 	void flagStarMagnitudeLimitChanged(bool b);
334 	//! Emitted whenever the nebula magnitude limit flag is toggled
335 	void flagNebulaMagnitudeLimitChanged(bool b);
336 	//! Emitted whenever the planet magnitude limit flag is toggled
337 	void flagPlanetMagnitudeLimitChanged(bool b);
338 
339 	//! Emitted whenever the star magnitude limit changed
340 	void customStarMagLimitChanged(double limit);
341 	//! Emitted whenever the nebula magnitude limit changed
342 	void customNebulaMagLimitChanged(double limit);
343 	//! Emitted whenever the planet magnitude limit changed
344 	void customPlanetMagLimitChanged(double limit);
345 
346 	//! Emitted whenever the luminance adaptation flag is toggled
347 	void flagLuminanceAdaptationChanged(bool b);
348 	//! Emitted when threshold value to draw info text in black is changed
349 	void daylightLabelThresholdChanged(double t);
350 
351 	void extinctionCoefficientChanged(double coeff);
352 	void atmosphereTemperatureChanged(double celsius);
353 	void atmospherePressureChanged(double mbar);
354 
355 private:
356 	// Debug
357 	float reverseComputeRCMag(float rmag) const;
358 
359 	//! Compute the current limit magnitude by dichotomy
360 	float computeLimitMagnitude() const;
361 
362 	//! Compute the current limit luminance by dichotomy
363 	float computeLimitLuminance() const;
364 
365 	//! Get StelSkyDrawer maximum FOV.
getMaxAdaptFov(void) const366 	float getMaxAdaptFov(void) const {return maxAdaptFov;}
367 	//! Set StelSkyDrawer maximum FOV.
368 	//! Usually stars/planet halos are drawn fainter when FOV gets larger,
369 	//! but when FOV gets larger than this value, the stars do not become
370 	//! fainter any more. Must be >= 60.0.
setMaxAdaptFov(float fov)371 	void setMaxAdaptFov(float fov) {maxAdaptFov = (fov < 60.f) ? 60.f : fov;}
372 
373 	//! Get StelSkyDrawer minimum FOV.
getMinAdaptFov(void) const374 	float getMinAdaptFov(void) const {return minAdaptFov;}
375 	//! Set StelSkyDrawer minimum FOV.
376 	//! Usually stars/planet halos are drawn brighter when FOV gets smaller.
377 	//! But when FOV gets smaller than this value, the stars do not become
378 	//! brighter any more. Must be <= 60.0.
setMinAdaptFov(float fov)379 	void setMinAdaptFov(float fov) {minAdaptFov = (fov > 60.f) ? 60.f : fov;}
380 
381 	//! Set the scaling applied to input luminance before they are converted by the StelToneReproducer
setInputScale(float in)382 	void setInputScale(float in) {inScale = in;}
383 	//! Get the scaling applied to input luminance before they are converted by the StelToneReproducer
getInputScale() const384 	float getInputScale() const {return inScale;}
385 
386 	//! Compute the luminance for a point source with the given mag for the current FOV
387 	//! @param mag V magnitude of the point source
388 	//! @return the luminance in log(cd/m^2)
pointSourceMagToLuminance(float mag) const389 	inline float pointSourceMagToLuminance(float mag) const {return std::exp(pointSourceMagToLnLuminance(mag));}
390 
391 	//! Compute the V magnitude for a point source with the given luminance for the current FOV
392 	//! @param lum the luminance in cd/m^2
393 	//! @return V magnitude of the point source
394 	float pointSourceLuminanceToMag(float lum) const;
395 
396 	//! Compute the log of the luminance for a point source with the given mag for the current FOV
397 	//! @param mag V magnitude of the point source
398 	//! @return the luminance in cd/m^2
399 	float pointSourceMagToLnLuminance(float mag) const;
400 
401 	//! Find the world adaptation luminance to use so that a point source of magnitude mag
402 	//! is displayed with a halo of size targetRadius
403 	float findWorldLumForMag(float mag, float targetRadius) const;
404 
405 	StelCore* core;
406 	StelToneReproducer* eye;
407 
408 	Extinction extinction;
409 	Refraction refraction;
410 
411 	float maxAdaptFov, minAdaptFov, lnfovFactor;
412 	bool flagStarTwinkle;
413 	bool flagForcedTwinkle;
414 	double twinkleAmount;
415 	bool flagDrawBigStarHalo;
416 	bool flagStarSpiky;
417 
418 	//! Informing the drawer whether atmosphere is displayed.
419 	//! This is used to avoid twinkling/simulate extinction/refraction.
420 	bool flagHasAtmosphere;
421 
422 	//! Controls the application of the user-defined star magnitude limit.
423 	//! @see customStarMagnitudeLimit
424 	bool flagStarMagnitudeLimit;
425 	//! Controls the application of the user-defined nebula magnitude limit.
426 	//! @see customNebulaMagnitudeLimit
427 	bool flagNebulaMagnitudeLimit;
428 	//! Controls the application of the user-defined planet magnitude limit.
429 	//! @see customPlanetMagnitudeLimit
430 	bool flagPlanetMagnitudeLimit;
431 
432 	double starRelativeScale;
433 	double starAbsoluteScaleF;
434 
435 	float starLinearScale;	// optimization variable
436 
437 	//! Current magnitude limit for point sources
438 	float limitMagnitude;
439 
440 	//! Current magnitude luminance
441 	float limitLuminance;
442 
443 	//! User-defined magnitude limit for stars.
444 	//! Interpreted as a lower limit - stars fainter than this value will not be displayed.
445 	//! Used if flagStarMagnitudeLimit is true.
446 	double customStarMagLimit;
447 	//! User-defined magnitude limit for deep-sky objects.
448 	//! Interpreted as a lower limit - nebulae fainter than this value will not be displayed.
449 	//! Used if flagNebulaMagnitudeLimit is true.
450 	double customNebulaMagLimit;
451 	//! User-defined magnitude limit for solar system objects.
452 	//! Interpreted as a lower limit - planets fainter than this value will not be displayed.
453 	//! Used if flagPlanetMagnitudeLimit is true.
454 	double customPlanetMagLimit;
455 
456 	//! Little halo texture
457 	QImage texImgHalo;
458 	QImage texImgHaloSpiky;
459 	StelTextureSP texHalo;
460 	StelTextureSP texHaloRayed;
461 
462 	//! Load B-V conversion parameters from config file
463 	void initColorTableFromConfigFile(class QSettings* conf);
464 
465 	//! Contains the list of colors matching a given B-V index
466 	static Vec3f colorTable[128];
467 
468 	//! The current Bortle Scale index
469 	int bortleScaleIndex;
470 
471 	//! The scaling applied to input luminance before they are converted by the StelToneReproducer
472 	float inScale;
473 
474 	// Variables used for GL optimization when displaying point sources
475 	//! Vertex format for a point source.
476 	//! Texture pos is stored in another separately.
477 	struct StarVertex {
478 		Vec2f pos;
479 		unsigned char color[4];
480 	};
481 	static_assert(sizeof(StarVertex) == 12, "Size of StarVertex must be 12 bytes");
482 
483 	//! Buffer for storing the vertex array data
484 	StarVertex* vertexArray;
485 
486 	//! Buffer for storing the texture coordinate array data.
487 	unsigned char* textureCoordArray;
488 
489 	class QOpenGLShaderProgram* starShaderProgram;
490 	struct StarShaderVars {
491 		int projectionMatrix;
492 		int texCoord;
493 		int pos;
494 		int color;
495 		int texture;
496 	};
497 	StarShaderVars starShaderVars;
498 
499 	//! Current number of sources stored in the buffers (still to display)
500 	unsigned int nbPointSources;
501 	//! Maximum number of sources which can be stored in the buffers
502 	unsigned int maxPointSources;
503 
504 	//! The maximum transformed luminance to apply at the next update
505 	float maxLum;
506 	//! The previously used world luminance
507 	float oldLum;
508 
509 	//! Big halo texture
510 	StelTextureSP texBigHalo;
511 	StelTextureSP texSunHalo;
512 	StelTextureSP texSunCorona;
513 
514 	//! Simulate the eye's luminance adaptation?
515 	bool flagLuminanceAdaptation;
516 	//! a customizable value in cd/m^2 which is used to decide when to render the InfoText in black (when sky is brighter than this)
517 	double daylightLabelThreshold;
518 
519 	float big3dModelHaloRadius;
520 };
521 
522 #endif // STELSKYDRAWER_HPP
523