feat: add forward+ rendering
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
#include <destrum/Components/LightComponent.h>
|
||||
|
||||
#include <destrum/Graphics/RenderContext.h>
|
||||
#include <destrum/ObjectModel/Transform.h>
|
||||
|
||||
#include <glm/gtc/constants.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
LightComponent::LightComponent(GameObject& parent, LightType type)
|
||||
: Component(parent, "LightComponent")
|
||||
, m_Type(type)
|
||||
{
|
||||
}
|
||||
|
||||
void LightComponent::SetIntensity(float intensity)
|
||||
{
|
||||
m_Intensity = std::max(intensity, 0.0f);
|
||||
}
|
||||
|
||||
void LightComponent::SetRange(float range)
|
||||
{
|
||||
m_Range = std::max(range, 0.01f);
|
||||
}
|
||||
|
||||
void LightComponent::SetConeAngles(float innerConeAngle, float outerConeAngle)
|
||||
{
|
||||
m_InnerConeAngle = std::clamp(innerConeAngle, 0.0f, glm::half_pi<float>());
|
||||
m_OuterConeAngle = std::clamp(outerConeAngle, m_InnerConeAngle, glm::half_pi<float>());
|
||||
}
|
||||
|
||||
void LightComponent::Render(const RenderContext& ctx)
|
||||
{
|
||||
auto& transform = GetTransform();
|
||||
|
||||
ctx.renderer.submitLight(Light{
|
||||
.type = m_Type,
|
||||
.position = transform.GetWorldPosition(),
|
||||
.direction = transform.GetWorldRotation() * glm::vec3{0.0f, 0.0f, -1.0f},
|
||||
.color = m_Color,
|
||||
.intensity = m_Intensity,
|
||||
.range = m_Range,
|
||||
.innerConeAngle = m_InnerConeAngle,
|
||||
.outerConeAngle = m_OuterConeAngle,
|
||||
});
|
||||
}
|
||||
|
||||
nlohmann::json LightComponent::Serialize() const {
|
||||
return {
|
||||
{"type", static_cast<std::uint32_t>(m_Type)},
|
||||
{"color", {m_Color.x, m_Color.y, m_Color.z}},
|
||||
{"intensity", m_Intensity},
|
||||
{"range", m_Range},
|
||||
{"innerConeAngle", m_InnerConeAngle},
|
||||
{"outerConeAngle", m_OuterConeAngle}
|
||||
};
|
||||
}
|
||||
|
||||
void LightComponent::Deserialize(const nlohmann::json& data) {
|
||||
if (data.contains("type")) {
|
||||
const auto type = data.at("type").get<std::uint32_t>();
|
||||
if (type <= static_cast<std::uint32_t>(LightType::Spot)) {
|
||||
m_Type = static_cast<LightType>(type);
|
||||
}
|
||||
}
|
||||
if (data.contains("color")) {
|
||||
const auto& value = data.at("color");
|
||||
m_Color = {value.at(0).get<float>(), value.at(1).get<float>(), value.at(2).get<float>()};
|
||||
}
|
||||
if (data.contains("intensity")) {
|
||||
SetIntensity(data.at("intensity").get<float>());
|
||||
}
|
||||
if (data.contains("range")) {
|
||||
SetRange(data.at("range").get<float>());
|
||||
}
|
||||
|
||||
float innerConeAngle = m_InnerConeAngle;
|
||||
float outerConeAngle = m_OuterConeAngle;
|
||||
if (data.contains("innerConeAngle")) {
|
||||
innerConeAngle = data.at("innerConeAngle").get<float>();
|
||||
}
|
||||
if (data.contains("outerConeAngle")) {
|
||||
outerConeAngle = data.at("outerConeAngle").get<float>();
|
||||
}
|
||||
SetConeAngles(innerConeAngle, outerConeAngle);
|
||||
}
|
||||
|
||||
void LightComponent::ImGuiInspector() {
|
||||
constexpr std::array typeNames{"Directional", "Point", "Spot"};
|
||||
|
||||
int type = static_cast<int>(m_Type);
|
||||
if (ImGui::Combo("Type", &type, typeNames.data(), static_cast<int>(typeNames.size()))) {
|
||||
SetType(static_cast<LightType>(type));
|
||||
}
|
||||
|
||||
ImGui::ColorEdit3("Color", &m_Color.x);
|
||||
|
||||
float intensity = m_Intensity;
|
||||
if (ImGui::DragFloat("Intensity", &intensity, 0.05f, 0.0f)) {
|
||||
SetIntensity(intensity);
|
||||
}
|
||||
|
||||
if (m_Type == LightType::Directional) {
|
||||
return;
|
||||
}
|
||||
|
||||
float range = m_Range;
|
||||
if (ImGui::DragFloat("Range", &range, 0.05f, 0.01f)) {
|
||||
SetRange(range);
|
||||
}
|
||||
|
||||
if (m_Type == LightType::Spot) {
|
||||
float innerConeAngle = m_InnerConeAngle;
|
||||
float outerConeAngle = m_OuterConeAngle;
|
||||
bool changed = ImGui::SliderAngle("Inner Cone", &innerConeAngle, 0.0f, 90.0f);
|
||||
changed |= ImGui::SliderAngle("Outer Cone", &outerConeAngle, 0.0f, 90.0f);
|
||||
if (changed) {
|
||||
SetConeAngles(innerConeAngle, outerConeAngle);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user