ASW Lib
A.D.S. Games SDL Wrapper Library. A library targeted at Allegro4 users who want to switch to SDL3 and use modern c++.
Loading...
Searching...
No Matches
lighting.h
Go to the documentation of this file.
1
8
9#ifndef ASW_LIGHTING_H
10#define ASW_LIGHTING_H
11
12#include <SDL3/SDL.h>
13#include <cstddef>
14#include <cstdint>
15#include <utility>
16#include <vector>
17
18#include "./camera.h"
19#include "./color.h"
20#include "./geometry.h"
21#include "./types.h"
22
23namespace asw::lighting {
24
26enum class ShadowMode {
28 None,
29
32 Cast,
33
37};
38
42struct Light {
45
47 float radius { 128.0F };
48
50 asw::Color color { 255, 255, 255 };
51
53 float intensity { 1.0F };
54
57
60 float direction { 0.0F };
61
63 float cone { 0.0F };
64
66 bool shadows { true };
67
69 float flicker { 0.0F };
70
72 float pulse { 0.0F };
73
75 float pulse_speed { 1.0F };
76
79 int seed { 0 };
80};
81
85public:
90 explicit AmbientCycle(float length = 1.0F);
91
97 void add(float time, const asw::Color& color);
98
104 asw::Color at(float time) const;
105
108 float get_length() const;
109
110private:
111 float length;
112 std::vector<std::pair<float, asw::Color>> keys;
113};
114
122public:
129 TileLight(int width, int height, float tile_size);
130
134 void set_solid(int x, int y, bool solid);
135
138 bool is_solid(int x, int y) const;
139
142 void set_falloff(float amount);
143
146 void clear_lights();
147
154 void add_light(int x, int y, const asw::Color& color);
155
159 void compute();
160
163 asw::Color get(int x, int y) const;
164
167 const asw::Texture& get_texture() const;
168
172
173private:
174 struct Source {
175 int x;
176 int y;
178 };
179
180 bool in_grid(int x, int y) const;
181 void upload();
182
183 int width;
186 float falloff { 0.1F };
187 std::vector<uint8_t> solid;
188 std::vector<Source> sources;
189 std::vector<float> light;
191
192 // Kept between compute() calls so they do not allocate each time
193 std::vector<float> level;
194 std::vector<std::size_t> open;
195 std::vector<uint8_t> pixels;
196};
197
204class LightMap {
205public:
209 void set_ambient(const asw::Color& color);
210
213 asw::Color get_ambient() const;
214
218 void set_camera(const asw::Camera* camera);
219
222 void set_shadow_mode(ShadowMode mode);
223
227
232 void update(float dt);
233
236 void clear();
237
240 void add(const Light& light);
241
249 void add_glow(const asw::Texture& texture, const asw::Quad<float>& dest,
250 const asw::Color& tint = asw::Color(255, 255, 255));
251
258 void add_tiles(const TileLight& tile_light, const asw::Vec2<float>& position = { });
259
262 void add_occluder(const asw::Polygonf& polygon);
263
266 void add_occluder(const asw::Quad<float>& rect);
267
270 void clear_occluders();
271
274 const std::vector<asw::Polygonf>& get_occluders() const;
275
279 void draw();
280
286 const asw::Texture& render();
287
288private:
294
299
300 asw::Vec2<float> to_screen(const asw::Vec2<float>& point) const;
302 const asw::Texture& gradient(asw::Falloff falloff);
303 void prepare_occluders();
304 bool has_blockers(const asw::Quad<float>& reach) const;
305 void draw_light(const Light& light);
306 void draw_shadows(const asw::Vec2<float>& center, const asw::Quad<float>& reach);
307
308 asw::Color ambient { 0, 0, 0 };
309 const asw::Camera* camera { nullptr };
311
312 // Double, so flicker and pulse stay smooth in long sessions
313 double time { 0.0 };
314
315 std::vector<Light> lights;
316 std::vector<Glow> glows;
317 std::vector<Tiles> tiles;
318 std::vector<asw::Polygonf> occluders;
319
320 // Occluders in screen space for this frame, with their bounds and which
321 // way round their corners go. Kept between frames to reuse the memory
322 std::vector<asw::Polygonf> screen_occluders;
323 std::vector<asw::Quad<float>> screen_bounds;
324 std::vector<float> screen_winding;
325
326 // Reused each light
328 std::vector<SDL_Vertex> shadow_vertices;
329 std::vector<int> shadow_indices;
330
334 std::vector<std::pair<asw::Falloff, asw::Texture>> gradients;
335};
336
337} // namespace asw::lighting
338
339#endif // ASW_LIGHTING_H
2D camera for scrolling worlds
2D camera that follows a target, stays inside the world and shakes.
Definition camera.h:21
A 2D rectangle in space.
Definition geometry.h:504
A 2D vector in space.
Definition geometry.h:27
Ambient colour that changes over a repeating cycle, such as a day.
Definition lighting.h:84
float get_length() const
Get the length of one cycle.
Definition lighting.cpp:162
AmbientCycle(float length=1.0F)
Create a cycle.
Definition lighting.cpp:125
asw::Color at(float time) const
Get the colour at a time. Times past the length wrap around.
Definition lighting.cpp:136
void add(float time, const asw::Color &color)
Add a key colour. Colours between keys are blended.
Definition lighting.cpp:130
std::vector< std::pair< float, asw::Color > > keys
Definition lighting.h:112
A screen sized texture of light, multiplied over the scene.
Definition lighting.h:204
void clear()
Remove the lights, glows and tiles added this frame.
Definition lighting.cpp:370
void add_glow(const asw::Texture &texture, const asw::Quad< float > &dest, const asw::Color &tint=asw::Color(255, 255, 255))
Add a texture that gives off light, such as lava or a lamp sprite. Its colours are added to the light...
Definition lighting.cpp:382
std::vector< float > screen_winding
Definition lighting.h:324
void add_occluder(const asw::Polygonf &polygon)
Add a polygon that blocks light.
Definition lighting.cpp:394
void set_ambient(const asw::Color &color)
Set the colour of unlit areas. Black is pitch dark, white is fully lit.
Definition lighting.cpp:340
std::vector< Light > lights
Definition lighting.h:315
void draw_light(const Light &light)
Definition lighting.cpp:529
const asw::Texture & gradient(asw::Falloff falloff)
Definition lighting.cpp:426
std::vector< std::pair< asw::Falloff, asw::Texture > > gradients
Definition lighting.h:334
asw::Vec2< int > map_size
Definition lighting.h:333
void set_camera(const asw::Camera *camera)
Take positions in world space and convert them with a camera. The camera must outlive the light map,...
Definition lighting.cpp:350
asw::Texture scratch
Definition lighting.h:332
const std::vector< asw::Polygonf > & get_occluders() const
Get the occluders.
Definition lighting.cpp:411
std::vector< int > shadow_indices
Definition lighting.h:329
std::vector< Glow > glows
Definition lighting.h:316
bool has_blockers(const asw::Quad< float > &reach) const
Definition lighting.cpp:460
std::vector< Tiles > tiles
Definition lighting.h:317
std::vector< asw::Polygonf > screen_occluders
Definition lighting.h:322
void draw_shadows(const asw::Vec2< float > &center, const asw::Quad< float > &reach)
Definition lighting.cpp:472
std::vector< asw::Quad< float > > screen_bounds
Definition lighting.h:323
void draw()
Draw the light map and multiply it over the current render target.
Definition lighting.cpp:685
asw::Polygonf seen
Definition lighting.h:327
std::vector< asw::Polygonf > occluders
Definition lighting.h:318
void add_tiles(const TileLight &tile_light, const asw::Vec2< float > &position={ })
Add tile lighting for this frame. The grid must outlive the next render() or draw().
Definition lighting.cpp:388
void update(float dt)
Advance flicker and pulse. Call once per update.
Definition lighting.cpp:365
void clear_occluders()
Remove all occluders.
Definition lighting.cpp:406
const asw::Texture & render()
Render the light map without drawing it, to draw it yourself. The render target is the same afterward...
Definition lighting.cpp:617
std::vector< SDL_Vertex > shadow_vertices
Definition lighting.h:328
asw::Color get_ambient() const
Get the colour of unlit areas.
Definition lighting.cpp:345
asw::Vec2< float > to_screen(const asw::Vec2< float > &point) const
Definition lighting.cpp:416
void set_shadow_mode(ShadowMode mode)
Set how occluders block light.
Definition lighting.cpp:355
void add(const Light &light)
Add a light for this frame.
Definition lighting.cpp:377
const asw::Camera * camera
Definition lighting.h:309
ShadowMode get_shadow_mode() const
Get how occluders block light.
Definition lighting.cpp:360
Light that spreads across a grid of tiles and stops at solid tiles.
Definition lighting.h:121
bool is_solid(int x, int y) const
Get whether a tile blocks light. Tiles off the grid are solid.
Definition lighting.cpp:191
std::vector< uint8_t > pixels
Definition lighting.h:195
std::vector< uint8_t > solid
Definition lighting.h:187
void compute()
Spread the lights and update the texture. Call after lights or solid tiles change.
Definition lighting.cpp:213
std::vector< Source > sources
Definition lighting.h:188
void add_light(int x, int y, const asw::Color &color)
Add a light at a tile.
Definition lighting.cpp:206
asw::Color get(int x, int y) const
Get the light at a tile after compute().
Definition lighting.cpp:318
asw::Vec2< float > get_size() const
Get the size of the grid in pixels.
Definition lighting.cpp:333
std::vector< float > level
Definition lighting.h:193
const asw::Texture & get_texture() const
Get the texture, with one pixel per tile. Empty before compute().
Definition lighting.cpp:328
std::vector< std::size_t > open
Definition lighting.h:194
void clear_lights()
Remove all lights.
Definition lighting.cpp:201
bool in_grid(int x, int y) const
Definition lighting.cpp:179
TileLight(int width, int height, float tile_size)
Create a grid with no solid tiles and no lights.
Definition lighting.cpp:169
void set_falloff(float amount)
Set how much light is lost per tile, from 0 to 1.
Definition lighting.cpp:196
std::vector< float > light
Definition lighting.h:189
void set_solid(int x, int y, bool solid)
Set whether a tile blocks light. A solid tile is lit, but does not pass light on.
Definition lighting.cpp:184
Common geometry types.
ShadowMode
How lights are blocked by occluders.
Definition lighting.h:26
@ None
Light goes through occluders.
Polygon< float > Polygonf
Definition geometry.h:741
std::shared_ptr< SDL_Texture > Texture
Alias for a shared pointer to an SDL_Texture.
Definition types.h:76
Falloff
How a gradient or light fades from its centre to its edge.
Definition types.h:46
@ Smooth
Soft at the centre and at the edge.
RGBA color struct with 8-bit channels.
Definition color.h:18
asw::Quad< float > dest
Definition lighting.h:291
asw::Vec2< float > position
Definition lighting.h:297
A light. Positions are in world space when the light map has a camera, otherwise in screen space.
Definition lighting.h:42
float pulse
Size of a steady pulse from 0 to 1.
Definition lighting.h:72
asw::Color color
Colour of the light.
Definition lighting.h:50
float flicker
Random flicker from 0 to 1. 0.2 suits a torch.
Definition lighting.h:69
float cone
Width of a spot light's beam, in radians. 0 lights all round.
Definition lighting.h:63
float intensity
Brightness from 0 to 1. Scales the colour.
Definition lighting.h:53
float direction
Direction a spot light points, in radians. 0 is right, and angles turn clockwise on screen.
Definition lighting.h:60
bool shadows
Whether occluders block this light.
Definition lighting.h:66
asw::Vec2< float > position
Centre of the light.
Definition lighting.h:44
float pulse_speed
Pulses per second.
Definition lighting.h:75
float radius
Distance the light reaches, in pixels.
Definition lighting.h:47
int seed
Gives lights their own flicker and pulse timing. Use a different seed for each light.
Definition lighting.h:79
asw::Falloff falloff
How the light fades to its edge.
Definition lighting.h:56
Types used throughout the ASW library.