载入中...
搜索中...
未找到
DayNight.cpp
浏览该文件的文档.
1#include "daynight/DayNight.h"
2
3#include "graphics/Graphics.h"
4#include "graphics/Light.h"
5#include "graphics/Texture.h"
6
7#include <cmath>
8#include <cstdint>
9#include <cstring>
10#include <string>
11#include <vector>
12
13#include <simplesquirrel/simplesquirrel.hpp>
14
15namespace eve::daynight {
16
17namespace {
18
19// Solar orbit constants.
20constexpr float kPi = 3.14159265f;
21constexpr float kMaxElevationDeg = 70.f; // solar elevation at local noon
22constexpr float kSkyCubeSize = 64; // per-face resolution of the procedural sky
23constexpr int kMaxFireflies = 8;
24
25// Night light names (script-facing) — index maps to the Impl flags array.
26const char *kNames[] = {"moonlight", "starlight", "fire", "fireflies"};
27
28inline float deg2rad(float d) { return d * kPi / 180.f; }
29
30// Convert an elevation/azimuth to a unit direction pointing at the sun.
31// azimuth measured clockwise from +Z, elevation above the horizon.
32inline void sunDirection(float elevDeg, float azimDeg, float &dx, float &dy, float &dz) {
33 const float el = deg2rad(elevDeg);
34 const float az = deg2rad(azimDeg);
35 const float he = std::cos(el);
36 dx = he * std::sin(az);
37 dy = std::sin(el);
38 dz = he * std::cos(az);
39}
40
41// Tiny deterministic hash for stars (no <random> dependency).
42inline uint32_t hash13(uint32_t x) {
43 x ^= x >> 16;
44 x *= 0x7feb352du;
45 x ^= x >> 15;
46 x *= 0x846ca68bu;
47 x ^= x >> 16;
48 return x;
49}
50inline float hashUnit(uint32_t x) { return float(hash13(x) % 10000u) / 9999.f; }
51
52// Fill one cubemap face's RGBA. `face` in {0..5} order +X,-X,+Y,-Y,+Z,-Z.
53// dirAt(x,y) writes the world direction (unnormalized ok) for a pixel.
54void fillSkyFace(std::vector<uint8_t> &px, int size, int face,
55 const float sunDir[3], float sunEnergy, float nightAmount,
56 void (*dirAt)(int face, int size, int x, int y, float out[3])) {
57 const int n = size;
58 for (int y = 0; y < n; ++y) {
59 for (int x = 0; x < n; ++x) {
60 float d[3];
61 dirAt(face, n, x, y, d);
62 const float len = std::sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
63 if (len < 1e-6f) { d[0] = 0.f; d[1] = 1.f; d[2] = 0.f; }
64 else { d[0] /= len; d[1] /= len; d[2] /= len; }
65
66 const float up = d[1]; // -1 horizon .. +1 zenith
67 // Sky gradient: blue zenith, pale horizon.
68 float r, g, b;
69 if (nightAmount > 0.5f) {
70 // Deep night navy, slightly lifted at horizon.
71 const float t = 0.5f + 0.5f * up;
72 r = 0.015f + 0.03f * t;
73 g = 0.025f + 0.045f * t;
74 b = 0.07f + 0.10f * t;
75 } else {
76 const float t = 0.5f + 0.5f * up;
77 r = 0.35f + 0.30f * t;
78 g = 0.55f + 0.25f * t;
79 b = 0.75f + 0.20f * t;
80 }
81 // Blend the two regimes by night amount.
82 if (nightAmount > 0.f && nightAmount < 1.f) {
83 float nr = 0.015f + 0.03f * (0.5f + 0.5f * up);
84 float ng = 0.025f + 0.045f * (0.5f + 0.5f * up);
85 float nb = 0.07f + 0.10f * (0.5f + 0.5f * up);
86 r = r * (1.f - nightAmount) + nr * nightAmount;
87 g = g * (1.f - nightAmount) + ng * nightAmount;
88 b = b * (1.f - nightAmount) + nb * nightAmount;
89 }
90
91 // Sun disc: a tight highlight around the sun direction.
92 const float dot = d[0] * sunDir[0] + d[1] * sunDir[1] + d[2] * sunDir[2];
93 const float disc = std::pow(std::max(0.f, dot), 400.f) * sunEnergy;
94 r += disc * 1.0f;
95 g += disc * 0.95f;
96 b += disc * 0.85f;
97 // Broad glow near the sun.
98 const float glow = std::pow(std::max(0.f, dot), 8.f) * sunEnergy * 0.25f;
99 r += glow * 1.0f; g += glow * 0.9f; b += glow * 0.7f;
100
101 // Stars (only at night, only in the sky hemisphere, avoid the sun).
102 float star = 0.f;
103 if (nightAmount > 0.5f && up > 0.05f && dot < 0.98f) {
104 uint32_t h = hash13(uint32_t((x * 73856093) ^ (y * 19349663) ^ (face * 83492791)));
105 if (h % 40u == 0u) {
106 const float tw = 0.6f + 0.4f * hashUnit(h + 1u);
107 star = nightAmount * tw;
108 }
109 }
110 r += star * 0.9f; g += star * 0.95f; b += star * 1.0f;
111
112 const int i = (y * n + x) * 4;
113 px[i + 0] = uint8_t(std::min(255.f, r * 255.f));
114 px[i + 1] = uint8_t(std::min(255.f, g * 255.f));
115 px[i + 2] = uint8_t(std::min(255.f, b * 255.f));
116 px[i + 3] = 255;
117 }
118 }
119}
120
121// Standard cubemap direction mapping for each face (u,v in [0,size]).
122void cubeDir(int face, int size, int x, int y, float out[3]) {
123 const float u = (2.f * (float(x) + 0.5f) / float(size)) - 1.f; // -1..1
124 const float v = (2.f * (float(y) + 0.5f) / float(size)) - 1.f; // -1..1
125 switch (face) {
126 case 0: out[0] = 1.f; out[1] = -v; out[2] = -u; break; // +X
127 case 1: out[0] = -1.f; out[1] = -v; out[2] = u; break; // -X
128 case 2: out[0] = u; out[1] = 1.f; out[2] = v; break; // +Y
129 case 3: out[0] = u; out[1] = -1.f; out[2] = -v; break; // -Y
130 case 4: out[0] = u; out[1] = -v; out[2] = 1.f; break; // +Z
131 default: out[0] = -u; out[1] = -v; out[2] = -1.f; break; // -Z
132 }
133}
134
135} // namespace
136
139 bool built = false;
140
141 // clock
142 float timeOfDay = 9.f; // hours 0..24
143 float speed = 0.5f; // simulated hours per real second
144 bool paused = false;
145
146 // derived sun
147 float elevDeg = 0.f;
148 float azimDeg = 0.f;
149 float sunDir[3] = {0.f, 1.f, 0.f};
150 float sunEnergy = 1.f;
151
152 // sky cache (regenerate only when the sun bucket changes)
153 bool skyboxEnabled = true;
156
157 // night lights
158 bool nightLight[4] = {true, true, false, true}; // moonlight, starlight, fire, fireflies
159 float fireX = 0.f, fireY = 0.5f, fireZ = 0.f;
160
161 struct Fly {
162 float x, y, z; // base anchor
163 float seed; // animation phase
164 };
165 std::vector<Fly> flies;
168 std::vector<graphics::Light3D *> flyLights;
169};
170
171const char *const DayNight::kNamedLights[] = {"moonlight", "starlight", "fire", "fireflies"};
172const int DayNight::kNamedLightCount = 4;
173
174DayNight::DayNight() : impl_(new Impl()) {}
175DayNight::~DayNight() { delete impl_; }
176
177// ---------------------------------------------------------------------------
178// Clock / derived state
179// ---------------------------------------------------------------------------
180
181void DayNight::setTimeOfDay(float hours) {
182 float h = std::fmod(hours, 24.f);
183 if (h < 0.f) h += 24.f;
184 impl_->timeOfDay = h;
185}
186float DayNight::getTimeOfDay() const { return impl_->timeOfDay; }
187
188void DayNight::setSpeed(float hprs) { impl_->speed = hprs < 0.f ? 0.f : hprs; }
189float DayNight::getSpeed() const { return impl_->speed; }
190void DayNight::setPaused(bool p) { impl_->paused = p; }
191bool DayNight::isPaused() const { return impl_->paused; }
192
193bool DayNight::isNight() const { return impl_->elevDeg < 0.f; }
194
195float DayNight::getSunElevation() const { return impl_->elevDeg; }
196float DayNight::getSunAzimuth() const { return impl_->azimDeg; }
197float DayNight::getSunDirX() const { return impl_->sunDir[0]; }
198float DayNight::getSunDirY() const { return impl_->sunDir[1]; }
199float DayNight::getSunDirZ() const { return impl_->sunDir[2]; }
200float DayNight::getSunIntensity() const { return impl_->sunEnergy; }
201
202// Sky / ambient colors are functions of the sun energy and night amount.
203float DayNight::getSkyR() const { return impl_->sunEnergy * 0.5f + 0.02f; }
204float DayNight::getSkyG() const { return impl_->sunEnergy * 0.6f + 0.03f; }
205float DayNight::getSkyB() const { return impl_->sunEnergy * 0.8f + 0.06f; }
207 const float night = impl_->nightLight[1] ? 1.0f : 0.6f; // starlight boost
208 return 0.05f * night + impl_->sunEnergy * 0.5f;
209}
211 const float ab = getAmbientBrightness();
212 return ab * 0.95f;
213}
215 const float ab = getAmbientBrightness();
216 return ab * (0.95f + 0.05f * impl_->sunEnergy); // greener in daylight
217}
219 const float ab = getAmbientBrightness();
220 return ab * (0.95f + 0.15f * impl_->sunEnergy); // bluer in daylight
221}
222
223// ---------------------------------------------------------------------------
224// Skybox
225// ---------------------------------------------------------------------------
226
228 impl_->skyboxEnabled = enabled;
229 impl_->lastSkyBucket = -1; // force regenerate if re-enabled
230}
231bool DayNight::isSkyboxEnabled() const { return impl_->skyboxEnabled; }
232
233// ---------------------------------------------------------------------------
234// Night lights
235// ---------------------------------------------------------------------------
236
237void DayNight::setNightLight(const std::string &name, bool enabled) {
238 for (int i = 0; i < kNamedLightCount; ++i) {
239 if (name == kNamedLights[i]) {
240 impl_->nightLight[i] = enabled;
241 return;
242 }
243 }
244}
245bool DayNight::isNightLight(const std::string &name) const {
246 for (int i = 0; i < kNamedLightCount; ++i) {
247 if (name == kNamedLights[i]) return impl_->nightLight[i];
248 }
249 return false;
250}
251
252void DayNight::setFirePosition(float x, float y, float z) {
253 impl_->fireX = x; impl_->fireY = y; impl_->fireZ = z;
254 if (impl_->fireLight) {
255 impl_->fireLight->setPosition(x, y, z);
256 impl_->fireLight->setColor(1.0f, 0.55f, 0.2f, 1.2f);
257 impl_->fireLight->setRadius(6.f);
258 }
259}
260
261void DayNight::addFirefly(float x, float y, float z) {
262 if (int(impl_->flies.size()) >= kMaxFireflies) return;
263 Impl::Fly f;
264 f.x = x; f.y = y; f.z = z;
265 f.seed = float(impl_->flies.size()) * 1.7f;
266 impl_->flies.push_back(f);
267 if (impl_->built) {
269 l->setColor(0.6f, 0.9f, 0.3f, 0.9f);
270 l->setRadius(2.5f);
271 l->setEnabled(false);
272 l->setPosition(x, y, z);
273 impl_->flyLights.push_back(l);
274 }
275}
277 impl_->flies.clear();
278 impl_->flyLights.clear();
279}
280int DayNight::getFireflyCount() const { return int(impl_->flies.size()); }
281
282// ---------------------------------------------------------------------------
283// init / update
284// ---------------------------------------------------------------------------
285
287 if (impl_->built) return;
288 impl_->built = true;
289 impl_->gfx = gfx;
290 if (!gfx) return;
291
292 // Moon: a cool directional light, driven at night.
294 impl_->moonLight->setColor(0.55f, 0.65f, 0.9f, 0.35f);
295 impl_->moonLight->setDirection(0.2f, -0.8f, 0.4f);
296 impl_->moonLight->setEnabled(false);
297
298 // Fire: a warm point light (position set by setFirePosition).
300 impl_->fireLight->setColor(1.0f, 0.55f, 0.2f, 1.2f);
301 impl_->fireLight->setRadius(6.f);
302 impl_->fireLight->setPosition(impl_->fireX, impl_->fireY, impl_->fireZ);
303 impl_->fireLight->setEnabled(false);
304
305 // Fireflies.
306 for (const auto &f : impl_->flies) {
308 l->setColor(0.6f, 0.9f, 0.3f, 0.9f);
309 l->setRadius(2.5f);
310 l->setEnabled(false);
311 l->setPosition(f.x, f.y, f.z);
312 impl_->flyLights.push_back(l);
313 }
314}
315
317 if (!impl_->built) init(gfx);
318 if (!impl_->gfx) return;
319
320 if (!impl_->paused) {
321 impl_->timeOfDay += dt * impl_->speed;
322 impl_->timeOfDay = std::fmod(impl_->timeOfDay, 24.f);
323 if (impl_->timeOfDay < 0.f) impl_->timeOfDay += 24.f;
324 }
325 const float hours = impl_->timeOfDay;
326
327 // Solar elevation: sine curve peaking at noon (hours=12).
328 const float frac = (hours - 6.f) / 12.f; // -1 at 6h, 0 at 12h, +1 at 18h
329 const float elevDeg = kMaxElevationDeg * std::sin(kPi * frac);
330 const float azimDeg = (hours / 24.f) * 360.f; // full rotation per day
331 impl_->elevDeg = elevDeg;
332 impl_->azimDeg = azimDeg;
333
334 // Sun energy: ramps up a few degrees above the horizon.
335 impl_->sunEnergy = std::clamp((elevDeg + 6.f) / 14.f, 0.f, 1.f);
336 const float nightAmount = std::clamp((-elevDeg) / 12.f, 0.f, 1.f);
337
338 sunDirection(elevDeg, azimDeg, impl_->sunDir[0], impl_->sunDir[1], impl_->sunDir[2]);
339
340 // Push the directional sun (replaces the legacy directional when no other
341 // dir Light3D is active; we keep moon as a Light3D instead so it can have
342 // different color/intensity than the sun slot).
343 gfx->setDirectionalLight(impl_->sunDir[0], impl_->sunDir[1], impl_->sunDir[2],
344 1.0f * impl_->sunEnergy, 0.9f * impl_->sunEnergy,
345 0.8f * impl_->sunEnergy);
346
347 // Background matches the sky at the horizon for the clear color.
348 const float skyR = getSkyR(), skyG = getSkyG(), skyB = getSkyB();
349 gfx->setBackgroundColorRGBA(skyR, skyG, skyB, 1.f);
350
351 // --- procedural skybox (IBL env), regenerated per sun bucket ---
352 if (impl_->skyboxEnabled) {
353 const int bucket = int(elevDeg) + int(azimDeg / 4.f) * 1000;
354 if (bucket != impl_->lastSkyBucket) {
355 impl_->lastSkyBucket = bucket;
356 std::vector<uint8_t> faces(size_t(kSkyCubeSize) * kSkyCubeSize * 4 * 6);
357 for (int f = 0; f < 6; ++f) {
358 std::vector<uint8_t> face(size_t(kSkyCubeSize) * kSkyCubeSize * 4);
359 fillSkyFace(face, int(kSkyCubeSize), f, impl_->sunDir,
360 impl_->sunEnergy, nightAmount, cubeDir);
361 std::memcpy(faces.data() + size_t(f) * face.size(), face.data(), face.size());
362 }
363 // Replace the previous env cube; Graphics owns old textures.
364 impl_->skyCube = gfx->newCubemap(int(kSkyCubeSize), faces.data());
365 gfx->setMesh3DEnv(impl_->skyCube, 0.5f + 0.5f * impl_->sunEnergy);
366 }
367 }
368
369 // --- night light systems (only meaningful below the horizon) ---
370 const bool night = elevDeg < 0.f;
371
372 // Moonlight: a directional light at the opposite-ish angle of the sun.
373 if (impl_->moonLight) {
374 const bool on = night && impl_->nightLight[0];
375 impl_->moonLight->setEnabled(on);
376 if (on) {
377 impl_->moonLight->setDirection(-impl_->sunDir[0], -impl_->sunDir[1],
378 -impl_->sunDir[2]);
379 }
380 }
381
382 // Fire.
383 if (impl_->fireLight) {
384 impl_->fireLight->setEnabled(night && impl_->nightLight[2]);
385 }
386
387 // Fireflies: gentle sinusoidal drift.
388 if (impl_->flyLights.size() == impl_->flies.size()) {
389 for (size_t i = 0; i < impl_->flies.size(); ++i) {
390 graphics::Light3D *l = impl_->flyLights[i];
391 const Impl::Fly &f = impl_->flies[i];
392 const bool on = night && impl_->nightLight[3];
393 l->setEnabled(on);
394 if (on) {
395 const float t = impl_->timeOfDay + f.seed;
396 l->setPosition(f.x + std::sin(t * 0.9f) * 0.6f,
397 f.y + std::sin(t * 1.3f + 1.7f) * 0.4f,
398 f.z + std::cos(t * 0.8f) * 0.6f);
399 }
400 }
401 }
402}
403
404// ---------------------------------------------------------------------------
405// Script binding
406// ---------------------------------------------------------------------------
407
408void DayNight::expose(ssq::Table &table) {
409 auto cls = table.addClass(name, DayNight::create, false);
410 expose(cls);
411}
412
413void DayNight::expose(ssq::Class &cls) {
414 cls.addFunc("getName", &DayNight::getName);
415 cls.addFunc("init", &DayNight::init);
416 cls.addFunc("update", &DayNight::update);
417 cls.addFunc("setTimeOfDay", &DayNight::setTimeOfDay);
418 cls.addFunc("getTimeOfDay", &DayNight::getTimeOfDay);
419 cls.addFunc("setSpeed", &DayNight::setSpeed);
420 cls.addFunc("getSpeed", &DayNight::getSpeed);
421 cls.addFunc("setPaused", &DayNight::setPaused);
422 cls.addFunc("isPaused", &DayNight::isPaused);
423 cls.addFunc("isNight", &DayNight::isNight);
424 cls.addFunc("getSunElevation", &DayNight::getSunElevation);
425 cls.addFunc("getSunAzimuth", &DayNight::getSunAzimuth);
426 cls.addFunc("getSunDirX", &DayNight::getSunDirX);
427 cls.addFunc("getSunDirY", &DayNight::getSunDirY);
428 cls.addFunc("getSunDirZ", &DayNight::getSunDirZ);
429 cls.addFunc("getSunIntensity", &DayNight::getSunIntensity);
430 cls.addFunc("getSkyR", &DayNight::getSkyR);
431 cls.addFunc("getSkyG", &DayNight::getSkyG);
432 cls.addFunc("getSkyB", &DayNight::getSkyB);
433 cls.addFunc("getAmbientR", &DayNight::getAmbientR);
434 cls.addFunc("getAmbientG", &DayNight::getAmbientG);
435 cls.addFunc("getAmbientB", &DayNight::getAmbientB);
436 cls.addFunc("getAmbientBrightness", &DayNight::getAmbientBrightness);
437 cls.addFunc("setSkyboxEnabled", &DayNight::setSkyboxEnabled);
438 cls.addFunc("isSkyboxEnabled", &DayNight::isSkyboxEnabled);
439 cls.addFunc("setNightLight", &DayNight::setNightLight);
440 cls.addFunc("isNightLight", &DayNight::isNightLight);
441 cls.addFunc("setFirePosition", &DayNight::setFirePosition);
442 cls.addFunc("addFirefly", &DayNight::addFirefly);
443 cls.addFunc("clearFireflies", &DayNight::clearFireflies);
444 cls.addFunc("getFireflyCount", &DayNight::getFireflyCount);
445}
446
448
449} // namespace eve::daynight
HSQOBJECT cls
Definition ECS.cpp:21
int y
Definition Grass.cpp:135
int z
Definition Grass.cpp:135
float u
Definition Grass.cpp:234
int x
Definition Grass.cpp:135
glm::vec3 n
Definition Grass.cpp:64
int h
std::vector< Colorf > px
uint32_t b
#define Module_IMPL(ModuleName, newExpr)
Definition Module.h:24
float f
glm::vec4 p[6]
const char * name
Definition RockMesh.cpp:21
bool enabled
int d
int v
virtual std::string getName() const =0
DayNight module — a time-of-day cycle that drives the sun, sky and light.
Definition DayNight.h:39
float getSpeed() const
Definition DayNight.cpp:189
int getFireflyCount() const
Definition DayNight.cpp:280
float getSunDirY() const
Definition DayNight.cpp:198
float getSkyR() const
Definition DayNight.cpp:203
float getSkyG() const
Definition DayNight.cpp:204
float getSkyB() const
Definition DayNight.cpp:205
bool isNight() const
True when the sun is below the horizon (night).
Definition DayNight.cpp:193
float getSunDirZ() const
Definition DayNight.cpp:199
void setPaused(bool paused)
Definition DayNight.cpp:190
void setSkyboxEnabled(bool enabled)
Definition DayNight.cpp:227
void init(graphics::Graphics *gfx)
Idempotent; builds lights / sky cubemap on first call.
Definition DayNight.cpp:286
static const int kNamedLightCount
Definition DayNight.h:91
float getSunIntensity() const
0..1 sun energy; ramps to 0 below the horizon.
Definition DayNight.cpp:200
float getTimeOfDay() const
Definition DayNight.cpp:186
float getAmbientR() const
Definition DayNight.cpp:210
bool isNightLight(const std::string &name) const
Definition DayNight.cpp:245
float getAmbientB() const
Definition DayNight.cpp:218
float getSunAzimuth() const
Solar azimuth in degrees, measured clockwise from +Z.
Definition DayNight.cpp:196
bool isSkyboxEnabled() const
Definition DayNight.cpp:231
void setFirePosition(float x, float y, float z)
Position of the campfire point light (fire system).
Definition DayNight.cpp:252
void addFirefly(float x, float y, float z)
Add one firefly anchor (world space); up to kMaxFireflies.
Definition DayNight.cpp:261
float getAmbientG() const
Definition DayNight.cpp:214
static const char *const kNamedLights[]
Definition DayNight.h:90
void setSpeed(float hoursPerRealHour)
Definition DayNight.cpp:188
float getSunElevation() const
Solar elevation in degrees (max at local noon, ~70°).
Definition DayNight.cpp:195
void setNightLight(const std::string &name, bool enabled)
Enable a named light system: "moonlight"|"starlight"|"fire"|"fireflies".
Definition DayNight.cpp:237
float getAmbientBrightness() const
Definition DayNight.cpp:206
float getSunDirX() const
World-space direction pointing AT the sun (normalized).
Definition DayNight.cpp:197
void setTimeOfDay(float hours)
Definition DayNight.cpp:181
void update(float dt, graphics::Graphics *gfx)
Advance the clock and push sun/sky/light state; before gfx.render3D().
Definition DayNight.cpp:316
virtual Texture * newCubemap(int faceSize, const uint8_t *rgbaFaces)=0
Create an RGBA8 cubemap from 6 faces packed as +X,-X,+Y,-Y,+Z,-Z (each faceSize×faceSize,...
virtual void setDirectionalLight(float dx, float dy, float dz, float r=1.f, float g=1.f, float b=1.f)
Definition Graphics.cpp:167
virtual void setBackgroundColorRGBA(float r, float g, float b, float a=1.f)
Definition Graphics.cpp:867
virtual void setMesh3DEnv(Texture *cube, float intensity)=0
Specular IBL environment for subsequent default mesh draws. cube must be from newCubemap (or nullptr ...
Declarative 3D light. Collected by RenderSystem3D (max 8 per frame). type: "point" | "dir" (≤15 chars...
Definition Light.h:101
void setEnabled(bool enabled)
Definition Light.cpp:114
void setDirection(float dx, float dy, float dz)
Definition Light.cpp:92
void setPosition(float x, float y, float z)
Definition Light.cpp:81
static Light3D * createLight(const std::string &type="point")
Definition Light.cpp:63
void setRadius(float radius)
Definition Light.cpp:111
void setColor(float r, float g, float b, float intensity=1.f)
Definition Light.cpp:103
GPU texture created via Graphics::newTexture. Owns GPU resources through an opaque backend handle.
Definition Texture.h:17
std::vector< graphics::Light3D * > flyLights
Definition DayNight.cpp:168
std::vector< Fly > flies
Definition DayNight.cpp:165
graphics::Light3D * moonLight
Definition DayNight.cpp:166
graphics::Light3D * fireLight
Definition DayNight.cpp:167
graphics::Graphics * gfx
Definition DayNight.cpp:138
graphics::Texture * skyCube
Definition DayNight.cpp:154