A 3D game engine from scratch.
1// (c) 2020 Vlad-Stefan Harbuz <vlad@vladh.net>
2
3#include "logs.hpp"
4#include "lights.hpp"
5#include "engine.hpp"
6#include "intrinsics.hpp"
7
8
9lights::State *lights::state = nullptr;
10
11
12void
13lights::adjust_dir_light_angle(f32 amount)
14{
15 lights::state->dir_light_angle += amount;
16}
17
18
19char const *
20lights::light_type_to_string(LightType light_type)
21{
22 if (light_type == LightType::none) {
23 return "none";
24 } else if (light_type == LightType::point) {
25 return "point";
26 } else if (light_type == LightType::directional) {
27 return "directional";
28 } else {
29 logs::error("Don't know how to convert LightType to string: %d", light_type);
30 return "<unknown>";
31 }
32}
33
34
35lights::LightType
36lights::light_type_from_string(char const *str)
37{
38 if (strcmp(str, "none") == 0) {
39 return LightType::none;
40 } else if (strcmp(str, "point") == 0) {
41 return LightType::point;
42 } else if (strcmp(str, "directional") == 0) {
43 return LightType::directional;
44 } else {
45 logs::fatal("Could not parse LightType: %s", str);
46 return LightType::none;
47 }
48}
49
50
51u32
52lights::light_type_to_int(LightType light_type)
53{
54 if (light_type == LightType::point) {
55 return 1;
56 } else if (light_type == LightType::directional) {
57 return 2;
58 }
59 return 0;
60}
61
62
63bool
64lights::is_light_component_valid(lights::Component *light_component)
65{
66 return light_component->type != LightType::none;
67}
68
69
70void
71lights::update(v3 camera_position)
72{
73 each (light_component, *get_components()) {
74 if (light_component->entity_handle == entities::NO_ENTITY_HANDLE) {
75 continue;
76 }
77
78 spatial::Component *spatial_component =
79 spatial::get_component(light_component->entity_handle);
80
81 if (!(
82 is_light_component_valid(light_component) &&
83 spatial::is_spatial_component_valid(spatial_component)
84 )) {
85 continue;
86 }
87
88 if (light_component->type == LightType::point) {
89 light_component->color.b = ((f32)sin(engine::get_t()) + 1.0f) / 2.0f * 50.0f;
90 }
91
92 // For the sun! :)
93 if (light_component->type == LightType::directional) {
94 spatial_component->position = camera_position +
95 -light_component->direction * DIRECTIONAL_LIGHT_DISTANCE;
96 light_component->direction = v3(sin(lights::state->dir_light_angle),
97 -cos(lights::state->dir_light_angle), 0.0f);
98 }
99 }
100}
101
102
103Array<lights::Component> *
104lights::get_components()
105{
106 return &lights::state->components;
107}
108
109
110lights::Component *
111lights::get_component(entities::Handle entity_handle)
112{
113 return lights::state->components[entity_handle];
114}
115
116
117void
118lights::init(lights::State *lights_state, memory::Pool *asset_memory_pool)
119{
120 lights::state = lights_state;
121 lights::state->dir_light_angle = radians(55.0f);
122 lights::state->components = Array<lights::Component>(
123 asset_memory_pool, MAX_N_ENTITIES, "light_components", true, 1);
124}