Game of Ur 0.3.3
This is a computer adaptation of Game of Ur, written in C++ mainly using SDL and OpenGL.
Loading...
Searching...
No Matches
light.hpp
Go to the documentation of this file.
1
11
12#ifndef FOOLSENGINE_LIGHT_H
13#define FOOLSENGINE_LIGHT_H
14
15#include <utility>
16#include <queue>
17#include <map>
18
19#include <GL/glew.h>
20
21#include <glm/glm.hpp>
22#include <glm/gtc/matrix_transform.hpp>
23#include <glm/gtc/type_ptr.hpp>
24
25#include <nlohmann/json.hpp>
26
27#include "core/ecs_world.hpp"
28#include "shapegen.hpp"
29#include "instance.hpp"
30#include "scene_components.hpp"
31
32namespace ToyMaker {
33 struct LightEmissionData;
34
40 using LightPackedData = std::pair<std::pair<glm::vec4, glm::vec4>, LightEmissionData>;
41
77 static LightEmissionData MakeDirectionalLight(const glm::vec3& diffuse, const glm::vec3& specular, const glm::vec3& ambient);
78
89 static LightEmissionData MakePointLight(const glm::vec3& diffuse, const glm::vec3& specular, const glm::vec3& ambient, float linearConst, float quadraticConst);
90
104 float innerAngle, float outerAngle, const glm::vec3& diffuse, const glm::vec3& specular, const glm::vec3& ambient,
105 float linearConst, float quadraticConst
106 );
107
112 enum LightType:int {
113 directional=0, //< No attenuation, no position, only direction
114 point=1, //< Has attenuation, has position, but no direction
115 spot=2, //< Has attenuation, position, and direction
116 };
117
123
129 glm::vec4 mDiffuseColor;
130
137 glm::vec4 mSpecularColor;
138
145 glm::vec4 mAmbientColor;
146
147
153
159
160
166
172
178 GLfloat mRadius {0.f};
179
189 static float CalculateRadius(const glm::vec4& diffuseColor, float decayLinear, float decayQuadratic, float intensityCutoff);
190
198 inline static std::string getComponentTypeName() { return "LightEmissionData"; }
199 };
200
202 NLOHMANN_JSON_SERIALIZE_ENUM( LightEmissionData::LightType, {
203 {LightEmissionData::LightType::directional, "directional"},
204 {LightEmissionData::LightType::point, "point"},
205 {LightEmissionData::LightType::spot, "spot"},
206 });
207
209 inline void from_json(const nlohmann::json& json, LightEmissionData& lightEmissionData) {
210 assert(json.at("type") == LightEmissionData::getComponentTypeName() && "Type mismatch. Light component json must have type LightEmissionData");
211 json.at("lightType").get_to(lightEmissionData.mType);
212 switch(lightEmissionData.mType) {
213 case LightEmissionData::LightType::directional:
214 lightEmissionData = LightEmissionData::MakeDirectionalLight(
215 glm::vec3{
216 json.at("diffuse")[0].get<float>(),
217 json.at("diffuse")[1].get<float>(),
218 json.at("diffuse")[2].get<float>(),
219 },
220 glm::vec3{
221 json.at("specular")[0].get<float>(),
222 json.at("specular")[1].get<float>(),
223 json.at("specular")[2].get<float>(),
224 },
225 glm::vec3{
226 json.at("ambient")[0].get<float>(),
227 json.at("ambient")[1].get<float>(),
228 json.at("ambient")[2].get<float>(),
229 }
230 );
231 break;
232 case LightEmissionData::LightType::point:
233 lightEmissionData = LightEmissionData::MakePointLight(
234 glm::vec3{
235 json.at("diffuse")[0].get<float>(),
236 json.at("diffuse")[1].get<float>(),
237 json.at("diffuse")[2].get<float>(),
238 },
239 glm::vec3{
240 json.at("specular")[0].get<float>(),
241 json.at("specular")[1].get<float>(),
242 json.at("specular")[2].get<float>(),
243 },
244 glm::vec3{
245 json.at("ambient")[0].get<float>(),
246 json.at("ambient")[1].get<float>(),
247 json.at("ambient")[2].get<float>(),
248 },
249 json.at("linearConst").get<float>(),
250 json.at("quadraticConst").get<float>()
251 );
252 break;
253 case LightEmissionData::LightType::spot:
254 lightEmissionData = LightEmissionData::MakeSpotLight(
255 json.at("innerAngle").get<float>(),
256 json.at("outerAngle").get<float>(),
257 glm::vec3{
258 json.at("diffuse")[0].get<float>(),
259 json.at("diffuse")[1].get<float>(),
260 json.at("diffuse")[2].get<float>(),
261 },
262 glm::vec3{
263 json.at("specular")[0].get<float>(),
264 json.at("specular")[1].get<float>(),
265 json.at("specular")[2].get<float>(),
266 },
267 glm::vec3{
268 json.at("ambient")[0].get<float>(),
269 json.at("ambient")[1].get<float>(),
270 json.at("ambient")[2].get<float>(),
271 },
272 json.at("linearConst").get<float>(),
273 json.at("quadraticConst").get<float>()
274 );
275 break;
276 }
277 }
279 inline void to_json(nlohmann::json& json, const LightEmissionData& lightEmissionData) {
280 switch(lightEmissionData.mType) {
281 case LightEmissionData::LightType::directional:
282 json = {
284 {"lightType", lightEmissionData.mType},
285 {"diffuse", {
286 lightEmissionData.mDiffuseColor.r,
287 lightEmissionData.mDiffuseColor.g,
288 lightEmissionData.mDiffuseColor.b,
289 }},
290 {"specular", {
291 lightEmissionData.mSpecularColor.r,
292 lightEmissionData.mSpecularColor.g,
293 lightEmissionData.mSpecularColor.b,
294 }},
295 {"ambient", {
296 lightEmissionData.mAmbientColor.r,
297 lightEmissionData.mAmbientColor.g,
298 lightEmissionData.mAmbientColor.b,
299 }},
300 };
301 break;
302 case LightEmissionData::LightType::point:
303 json = {
305 {"lightType", lightEmissionData.mType},
306 {"diffuse", {
307 lightEmissionData.mDiffuseColor.r,
308 lightEmissionData.mDiffuseColor.g,
309 lightEmissionData.mDiffuseColor.b,
310 }},
311 {"specular", {
312 lightEmissionData.mSpecularColor.r,
313 lightEmissionData.mSpecularColor.g,
314 lightEmissionData.mSpecularColor.b,
315 }},
316 {"ambient", {
317 lightEmissionData.mAmbientColor.r,
318 lightEmissionData.mAmbientColor.g,
319 lightEmissionData.mAmbientColor.b,
320 }},
321 {"linearConst", lightEmissionData.mDecayLinear},
322 {"quadraticConst", lightEmissionData.mDecayQuadratic},
323 };
324 break;
325 case LightEmissionData::LightType::spot:
326 json = {
328 {"lightType", lightEmissionData.mType},
329 {"diffuse", {
330 lightEmissionData.mDiffuseColor.r,
331 lightEmissionData.mDiffuseColor.g,
332 lightEmissionData.mDiffuseColor.b,
333 }},
334 {"specular", {
335 lightEmissionData.mSpecularColor.r,
336 lightEmissionData.mSpecularColor.g,
337 lightEmissionData.mSpecularColor.b,
338 }},
339 {"ambient", {
340 lightEmissionData.mAmbientColor.r,
341 lightEmissionData.mAmbientColor.g,
342 lightEmissionData.mAmbientColor.b,
343 }},
344 {"linearConst", lightEmissionData.mDecayLinear},
345 {"quadraticConst", lightEmissionData.mDecayQuadratic},
346 {"innerAngle", glm::degrees(glm::acos(lightEmissionData.mCosCutoffInner))},
347 {"outerAngle", glm::degrees(glm::acos(lightEmissionData.mCosCutoffOuter))},
348 };
349 break;
350 }
351 }
352
359 {"attrLightPlacement_mPosition", RUNTIME, 4, GL_FLOAT},
360 {"attrLightPlacement_mDirection", RUNTIME, 4, GL_FLOAT},
361
362 {"attrLightEmission_mType", RUNTIME, 1, GL_INT},
363 {"attrLightEmission_mDiffuseColor", RUNTIME, 4, GL_FLOAT},
364 {"attrLightEmission_mSpecularColor", RUNTIME, 4, GL_FLOAT},
365 {"attrLightEmission_mAmbientColor", RUNTIME, 4, GL_FLOAT},
366 {"attrLightEmission_mDecayLinear", RUNTIME, 1, GL_FLOAT},
367 {"attrLightEmission_mDecayQuadratic", RUNTIME, 1, GL_FLOAT},
368 {"attrLightEmission_mCosCutoffInner", RUNTIME, 1, GL_FLOAT},
369 {"attrLightEmission_mCosCutoffOuter", RUNTIME, 1, GL_FLOAT},
370 {"attrLightEmission_mRadius", RUNTIME, 1, GL_FLOAT}
371 }};
372
373
379 class LightInstanceAllocator : public BaseInstanceAllocator {
380 public:
381 LightInstanceAllocator(const std::vector<LightEmissionData>& lightEmissionDataList, const std::vector<glm::mat4>& lightModelMatrices);
382
383 protected:
384 virtual void upload() override;
385
386 private:
387 std::vector<LightPackedData> mLightData;
388 };
389
400 template<>
402 const LightEmissionData& previousState,
403 const LightEmissionData& nextState,
404 float simulationProgress
405 ) const {
406 simulationProgress = mProgressLimits(simulationProgress);
407 LightEmissionData interpolatedState { previousState };
408
409 interpolatedState.mDiffuseColor += simulationProgress * (nextState.mDiffuseColor - previousState.mDiffuseColor);
410 interpolatedState.mSpecularColor += simulationProgress * (nextState.mSpecularColor - previousState.mSpecularColor);
411 interpolatedState.mAmbientColor += simulationProgress * (nextState.mAmbientColor - previousState.mAmbientColor);
412 interpolatedState.mDecayLinear += simulationProgress * (nextState.mDecayLinear - previousState.mDecayLinear);
413 interpolatedState.mDecayQuadratic += simulationProgress * (nextState.mDecayQuadratic - previousState.mDecayQuadratic);
414 interpolatedState.mCosCutoffInner += simulationProgress * (nextState.mCosCutoffInner - previousState.mCosCutoffInner);
415 interpolatedState.mCosCutoffOuter += simulationProgress * (nextState.mCosCutoffOuter - previousState.mCosCutoffOuter);
416
417 return interpolatedState;
418 }
419}
420
421#endif
BaseInstanceAllocator(const InstanceLayout &instanceLayout)
Construct a new base instance allocator object.
Definition instance.hpp:224
RangeMapperLinear mProgressLimits
a functor that performs the actual interpolation in the default case
Definition ecs_world.hpp:354
virtual void upload() override
Uploads this object's attribute data to GPU memory.
Definition light.cpp:85
ToyMaker Engine's implementation of an ECS system.
T operator()(const T &previousState, const T &nextState, float simulationProgress=1.f) const
Returns an interpolated value for a component between two given states.
Definition ecs_world.hpp:2346
static InstanceLayout LightInstanceLayout
The layout for built-in light sources when used as instance attributes.
Definition light.hpp:358
std::pair< std::pair< glm::vec4, glm::vec4 >, LightEmissionData > LightPackedData
A version of light data where the first element represents the light's position and direction,...
Definition light.hpp:40
A wrapper over regular shader attributes intended to be used as "instance" attributes,...
Namespace containing all class definitions and functions related to the ToyMaker engine.
Definition camera_system.hpp:20
Stores structs and classes for common components used by the SceneSystem and other related Systems.
Contains classes used to construct some common procedurally generated meshes and models.
Object representing the layout of one set of related attributes representing (presumably) one object ...
Definition instance.hpp:135
A struct, used as a component, describing the emissive properties of the light it represents per the ...
Definition light.hpp:65
LightType
Integers representing different types of light sources.
Definition light.hpp:112
glm::vec4 mDiffuseColor
The color of the diffuse component of the light represented by this object.
Definition light.hpp:129
GLfloat mDecayQuadratic
A quadractic factor governing the attenuation in light intensity with distance from source,...
Definition light.hpp:158
glm::vec4 mSpecularColor
The color of the specular component of the light represented by this object.
Definition light.hpp:137
glm::vec4 mAmbientColor
The color of the ambient component of the light represented by this object.
Definition light.hpp:145
GLfloat mDecayLinear
A linear factor governing the attenuation in light intensity with distance from source,...
Definition light.hpp:152
LightType mType
The type of light described by this object.
Definition light.hpp:122
GLfloat mCosCutoffInner
The cos of the angle between the surface of the inner cone of a spot light (within which light intens...
Definition light.hpp:165
static std::string getComponentTypeName()
The component type string associated with this object.
Definition light.hpp:198
static float CalculateRadius(const glm::vec4 &diffuseColor, float decayLinear, float decayQuadratic, float intensityCutoff)
A function that computes the cutoff radius for a light source based on its emissive properties.
Definition light.cpp:10
GLfloat mRadius
The computed radius of the light beyond which the light is no longer active, based on its emission da...
Definition light.hpp:178
static LightEmissionData MakePointLight(const glm::vec3 &diffuse, const glm::vec3 &specular, const glm::vec3 &ambient, float linearConst, float quadraticConst)
Creates a point source of light which has a position and experiences attenuation, but has no directio...
Definition light.cpp:39
GLfloat mCosCutoffOuter
The cos of the angle between the surface of the outer cone of a spot light (beyond which light intens...
Definition light.hpp:171
static LightEmissionData MakeSpotLight(float innerAngle, float outerAngle, const glm::vec3 &diffuse, const glm::vec3 &specular, const glm::vec3 &ambient, float linearConst, float quadraticConst)
Creates a spotlight which has a position, experiences attenuation, and has a direction.
Definition light.cpp:53
static LightEmissionData MakeDirectionalLight(const glm::vec3 &diffuse, const glm::vec3 &specular, const glm::vec3 &ambient)
Creates a directional source of light, which (in a scene) faces one direction and experiences no atte...
Definition light.cpp:26