Zappy GUI
C++ graphic client: renderer, camera, network
Loading...
Searching...
No Matches
SpaceSkybox.cpp
Go to the documentation of this file.
1#include "SpaceSkybox.hpp"
2
3#include <cmath>
4#include <random>
5
6#include "raymath.h"
7#include "rlgl.h"
8
10{
11 Mesh sphere = _generateCustomSphere(500.0f, 32, 32);
12 _sphereModel = LoadModelFromMesh(sphere);
15}
16
18{
19 int width = 1024;
20 int height = 512;
21
22 Image img = GenImageColor(width, height, BLANK);
23 for (int y = 0; y < height; y++) {
24 float t = static_cast<float>(y) / (height - 1);
25 unsigned char r = static_cast<unsigned char>(10 * (1.0f - t));
26 unsigned char g = static_cast<unsigned char>(5 * (1.0f - t));
27 unsigned char b = static_cast<unsigned char>(20 * (1.0f - t));
28 ImageDrawRectangle(&img, 0, y, width, 1, {r, g, b, 255});
29 }
30
31 std::random_device rd;
32 std::mt19937 gen(rd());
33 std::uniform_int_distribution<> distX(0, width - 1);
34 std::uniform_int_distribution<> distY(0, height - 1);
35 std::uniform_int_distribution<> distIntensity(100, 255);
36
37 // Add scattered stars
38 for (int i = 0; i < 2000; ++i) {
39 int x = distX(gen);
40 int y = distY(gen);
41
42 int intensity = distIntensity(gen);
43 unsigned char c = static_cast<unsigned char>(intensity);
44
45 ImageDrawPixel(&img, x, y, {c, c, static_cast<unsigned char>(c > 200 ? 255 : c), 255});
46 }
47
48 _nightTexture = LoadTextureFromImage(img);
49 SetTextureWrap(_nightTexture, TEXTURE_WRAP_CLAMP);
50 UnloadImage(img);
51}
52
54{
55 int width = 1024;
56 int height = 512;
57
58 Image img = GenImageColor(width, height, BLANK);
59 for (int y = 0; y < height; y++) {
60 float t = static_cast<float>(y) / (height - 1);
61 unsigned char r = static_cast<unsigned char>(80 * (1.0f - t) + 180 * t);
62 unsigned char g = static_cast<unsigned char>(150 * (1.0f - t) + 210 * t);
63 unsigned char b = static_cast<unsigned char>(220 * (1.0f - t) + 240 * t);
64 ImageDrawRectangle(&img, 0, y, width, 1, {r, g, b, 255});
65 }
66
67 _dayTexture = LoadTextureFromImage(img);
68 SetTextureWrap(_dayTexture, TEXTURE_WRAP_CLAMP);
69 UnloadImage(img);
70}
71
72void SpaceSkybox::update(float deltaTime)
73{
74 // Advance time. Full cycle every 20 seconds of scaled time
75 _timeOfDay += deltaTime * 0.05f;
76 if (_timeOfDay > 1.0f) _timeOfDay -= 1.0f;
77
78 // Slowly rotate the skybox
79 _sphereModel.transform = MatrixMultiply(_sphereModel.transform, MatrixRotateY(0.0002f));
80}
81
82void SpaceSkybox::draw(const Camera3D& camera)
83{
84 rlDisableBackfaceCulling();
85 rlDisableDepthMask();
86 rlEnableColorBlend();
87
88 _sphereModel.materials[0].maps[MATERIAL_MAP_ALBEDO].texture = _nightTexture;
89 DrawModel(_sphereModel, camera.position, 1.0f, WHITE);
90
91 // Day intensity (smooth sine wave 0.0 to 1.0)
92 float dayFactor = std::sin(_timeOfDay * 2.0f * PI) * 0.5f + 0.5f;
93
94 if (dayFactor > 0.01f) {
95 unsigned char alpha = static_cast<unsigned char>(dayFactor * 255.0f);
96 _sphereModel.materials[0].maps[MATERIAL_MAP_ALBEDO].texture = _dayTexture;
97 DrawModel(_sphereModel, camera.position, 1.0f, {255, 255, 255, alpha});
98 }
99
100 rlEnableDepthMask();
101 rlEnableBackfaceCulling();
102}
103
105{
106 UnloadTexture(_nightTexture);
107 UnloadTexture(_dayTexture);
108 UnloadModel(_sphereModel);
109}
110
111Mesh SpaceSkybox::_generateCustomSphere(float radius, int rings, int slices)
112{
113 Mesh mesh = {};
114 int numVertices = (rings + 1) * (slices + 1);
115 int numIndices = rings * slices * 6;
116
117 mesh.vertexCount = numVertices;
118 mesh.triangleCount = numIndices / 3;
119 mesh.vertices = (float*)MemAlloc(numVertices * 3 * sizeof(float));
120 mesh.texcoords = (float*)MemAlloc(numVertices * 2 * sizeof(float));
121 mesh.normals = (float*)MemAlloc(numVertices * 3 * sizeof(float));
122 mesh.indices = (unsigned short*)MemAlloc(numIndices * sizeof(unsigned short));
123
124 int vIndex = 0;
125 for (int i = 0; i <= rings; i++) {
126 float v = static_cast<float>(i) / rings;
127 float phi = v * PI;
128
129 for (int j = 0; j <= slices; j++) {
130 float u = static_cast<float>(j) / slices;
131 float theta = u * PI * 2.0f;
132
133 float x = std::cos(theta) * std::sin(phi);
134 float y = std::cos(phi);
135 float z = std::sin(theta) * std::sin(phi);
136
137 mesh.vertices[vIndex * 3 + 0] = radius * x;
138 mesh.vertices[vIndex * 3 + 1] = radius * y;
139 mesh.vertices[vIndex * 3 + 2] = radius * z;
140
141 mesh.normals[vIndex * 3 + 0] = x;
142 mesh.normals[vIndex * 3 + 1] = y;
143 mesh.normals[vIndex * 3 + 2] = z;
144
145 mesh.texcoords[vIndex * 2 + 0] = u;
146 mesh.texcoords[vIndex * 2 + 1] = v;
147 vIndex++;
148 }
149 }
150
151 int iIndex = 0;
152 for (int i = 0; i < rings; i++) {
153 for (int j = 0; j < slices; j++) {
154 int current = i * (slices + 1) + j;
155 int next = current + slices + 1;
156
157 mesh.indices[iIndex++] = current;
158 mesh.indices[iIndex++] = next;
159 mesh.indices[iIndex++] = current + 1;
160
161 mesh.indices[iIndex++] = current + 1;
162 mesh.indices[iIndex++] = next;
163 mesh.indices[iIndex++] = next + 1;
164 }
165 }
166
167 UploadMesh(&mesh, false);
168 return mesh;
169}
void draw(const Camera3D &camera) override
void _generateDayTexture()
Texture2D _nightTexture
void unload() override
Texture2D _dayTexture
Mesh _generateCustomSphere(float radius, int rings, int slices)
void update(float deltaTime) override
void _generateNightTexture()
void init() override
Model _sphereModel