CSEngine
Loading...
Searching...
No Matches
LightComponent.cpp
1#include "LightComponent.h"
2#include "CameraComponent.h"
3#include "../Manager/LightMgr.h"
4#include "TransformComponent.h"
5#include "../Manager/EngineCore.h"
6#include "../Util/Render/SFrameBuffer.h"
7#include "../Util/GLProgramHandle.h"
8
9using namespace CSE;
10
11COMPONENT_CONSTRUCTOR(LightComponent) {
12 auto lightMgr = CORE->GetCore(LightMgr);
13 lightMgr->Register(this);
14
15 m_light = new SLight();
16
17 SetLightType(DIRECTIONAL);
18}
19
20LightComponent::~LightComponent() = default;
21
22void LightComponent::Exterminate() {
23 CORE->GetCore(LightMgr)->Remove(this);
24 SAFE_DELETE(m_light);
25 auto resMgr = CORE->GetCore(ResMgr);
26 if(m_frameBuffer != nullptr) resMgr->Remove(m_frameBuffer);
27}
28
29void LightComponent::Init() {
30 if(m_disableShadow) return;
31 SetDepthMap();
32}
33
34void LightComponent::Tick(float elapsedTime) {
35 auto eye = static_cast<TransformComponent*>(gameObject->GetTransform())->GetPosition();
36 auto target = *eye + vec3(-m_light->direction.x, -m_light->direction.y, -m_light->direction.z);
37 m_lightViewMatrix = mat4::LookAt(*eye, target, vec3{ 0, 1, 0 });
38
39 if (m_isSunRising && m_type == DIRECTIONAL) {
40 float value = m_light->direction.y;
41 float bright = (value < 0.2) ? (value - 0.2f) * 2 + 1 : 1;
42 if (bright < 0) bright = 0;
43 if (value < 0) value = 0;
44
45 float color0 = (0.4f * (1 - value) + 0.4f) * bright * 5;
46 float color1 = (0.3f * value + 0.3f) * bright * 5;
47
48// float color2 = (valueStr * 0.07f + 0.03f) * 10;
49
50 m_light->color = vec3{ color0, color1, color1 };
51 }
52}
53
54void LightComponent::SetLightType(LIGHT type) {
55 m_type = type;
56
57 if (m_type == POINT || m_type == SPOT) {
58 SetLightPosition();
59 }
60 else {
61 m_lightProjectionMatrix = mat4::Ortho(-3.f, 3.f, -3.f, 3.f, m_near, m_far);
62 }
63}
64
65void LightComponent::SetDirection(const vec4& direction) const {
66 switch (m_type) {
67 case DIRECTIONAL:
68 case SPOT:
69
70 m_light->direction = direction;
71 return;
72
73 default:
74 return;
75 }
76}
77
78void LightComponent::SetColor(const vec3& color) const {
79 m_light->color = color;
80}
81
82void LightComponent::SetLightRadius(float radius) const {
83 m_light->radius = radius;
84}
85
86void LightComponent::SetAttenuationFactor(const vec3& att) const {
87 m_light->att = att;
88}
89
90void LightComponent::SetAttenuationFactor(float Kc, float Kl, float Kq) const {
91 SetAttenuationFactor(vec3{ Kc, Kl, Kq });
92}
93
94void LightComponent::SetLightPosition() const {
95 m_light->position = static_cast<TransformComponent*>(gameObject->GetTransform())->GetPosition();
96}
97
98void LightComponent::SetDepthMap() {
99 if(m_frameBuffer != nullptr) return;
100
101 auto lightMgr = CORE->GetCore(LightMgr);
102 m_frameBuffer = new SFrameBuffer();
103 // 1. Generate a framebuffer.
104 // todo: 큐브 텍스쳐도 호환되도록 수정이 필요함 (for point shadow)
105 m_frameBuffer->GenerateFramebuffer(SFrameBuffer::PLANE, lightMgr->SHADOW_WIDTH, lightMgr->SHADOW_HEIGHT);
106 // 2. Generate a depth texture.
107 m_depthTexture = m_frameBuffer->GenerateTexturebuffer(SFrameBuffer::DEPTH,
108 GL_DEPTH_COMPONENT);
109 m_depthTexture->SetParameteri(GL_TEXTURE_MIN_FILTER, GL_NEAREST);
110 m_depthTexture->SetParameteri(GL_TEXTURE_MAG_FILTER, GL_NEAREST);
111#if defined(ANDROID) || defined(__EMSCRIPTEN__) || defined(IOS)
112 m_depthTexture->SetParameteri(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
113 m_depthTexture->SetParameteri(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
114#else
115 m_depthTexture->SetParameteri(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
116 m_depthTexture->SetParameteri(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
117 float borderColor[] = { 1.0, 1.0, 1.0, 1.0 };
118 m_depthTexture->SetParameterfv(GL_TEXTURE_BORDER_COLOR, borderColor);
119#endif
120 // 3. Rasterize the framebuffer.
121 m_frameBuffer->RasterizeFramebuffer();
122}
123
124LightComponent::LIGHT LightComponent::GetType() const {
125 return m_type;
126}
127
128vec4 LightComponent::GetDirection(const vec4& direction) const {
129 return m_light->direction;
130}
131
132vec3 LightComponent::GetColor() const {
133 return m_light->color;
134}
135
136void LightComponent::SetSunrising(bool active) {
137 m_isSunRising = active;
138}
139
140SComponent* LightComponent::Clone(SGameObject* object) {
141 INIT_COMPONENT_CLONE(LightComponent, clone);
142
143 clone->m_type = m_type;
144 clone->m_disableShadow = m_disableShadow;
145
146 clone->m_near = m_near;
147 clone->m_far = m_far;
148 clone->SetLightType(clone->m_type);
149
150 return clone;
151}
152
153void LightComponent::SetValue(std::string name_str, Arguments value) {
154 if (name_str == "m_type") {
155 m_type = static_cast<LIGHT>(std::stoi(value[0]));
156 } else if (name_str == "m_disableShadow") {
157 m_disableShadow = std::stoi(value[0]) == 1;
158 } else if (name_str == "m_near") {
159 m_near = std::stof(value[0]);
160 } else if (name_str == "m_far") {
161 m_far = std::stof(value[0]);
162 } else if (name_str == "m_direction") {
163 SET_VEC4(m_light->direction);
164 }
165
166 SetLightType(m_type);
167}
168
169std::string LightComponent::PrintValue() const {
170 PRINT_START("component");
171
172 PRINT_VALUE(m_type, static_cast<int>(m_type));
173 PRINT_VALUE(m_disableShadow, m_disableShadow ? 1 : 0);
174 PRINT_VALUE(m_near, m_near);
175 PRINT_VALUE(m_far, m_far);
176 vec4 m_direction = m_light->direction;
177 PRINT_VALUE_VEC4(m_direction);
178
179 PRINT_END("component");
180}
181
182const mat4& LightComponent::GetLightProjectionMatrix() const {
183 return m_lightProjectionMatrix;
184}
185
186const mat4& LightComponent::GetLightViewMatrix() const {
187 return m_lightViewMatrix;
188}
189
190void LightComponent::BindShadow(const GLProgramHandle& handle, int handleIndex, int index) const {
191 if(m_frameBuffer == nullptr || m_disableShadow) return;
192
193 m_depthTexture->Bind(handle.Uniforms.LightShadowMap + index, index);
194 auto matrix = m_lightViewMatrix * m_lightProjectionMatrix;
195 glUniformMatrix4fv(handle.Uniforms.LightMatrix + handleIndex, 1, 0, matrix.Pointer());
196}
197
198CameraMatrixStruct LightComponent::GetCameraMatrixStruct() const {
199 const auto& position = gameObject->GetTransform();
200 return { m_lightViewMatrix, m_lightProjectionMatrix, position->m_position };
201}
202
203SFrameBuffer* LightComponent::GetFrameBuffer() const {
204 return m_frameBuffer;
205}
206
207bool LightComponent::IsShadow() const {
208 return !m_disableShadow;
209}
const int SHADOW_HEIGHT
Height of the shadow map.
Definition LightMgr.h:20
const int SHADOW_WIDTH
Width of the shadow map.
Definition LightMgr.h:19
STexture * GenerateTexturebuffer(BufferType type, int channel, int level=0)
void GenerateFramebuffer(BufferDimension dimension, int width, int height)