CSM Shadows

This commit is contained in:
Antoine Pilote
2021-06-20 23:08:45 -04:00
parent 08288eee16
commit 1740a5707f
29 changed files with 628 additions and 210 deletions

View File

@@ -13,145 +13,32 @@
#include <GLFW/glfw3.h>
#include <src/Vendors/glm/trigonometric.hpp>
#include <src/Scripting/ScriptingEngine.h>
#include <src/Resource/FGD/FGDFile.h>
class FPSCamScript : public ScriptableEntity
{
public:
float Pitch = 0.0f;
float Yaw = 0.0f;
float Speed = 0.0f;
float mouseLastX = 0.0f;
float mouseLastY = 0.0f;
void OnCreate()
{
Input::HideMouse();
}
void OnDestroy()
{
}
void OnUpdate(Timestep ts)
{
float x = Input::GetMouseX();
float y = Input::GetMouseY();
// mouse
float diffx = x - mouseLastX;
float diffy = mouseLastY - y;
mouseLastX = x;
mouseLastY = y;
const float sensitivity = 0.1f;
diffx *= sensitivity;
diffy *= sensitivity;
Yaw += diffx;
Pitch += diffy;
if (Pitch > 89.0f)
Pitch = 89.0f;
if (Pitch < -89.0f)
Pitch = -89.0f;
//Ref<Camera> cam = GetComponent<CameraComponent>().CameraInstance;
//cam->cameraDirection.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch));
//cam->cameraDirection.y = sin(glm::radians(Pitch));
//cam->cameraDirection.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch));
//cam->cameraFront = glm::normalize(cam->cameraDirection);
//cam->cameraRight = glm::normalize(glm::cross(cam->up, cam->cameraFront));
}
};
class MoveScript : public ScriptableEntity
{
public:
glm::vec3 velocity = glm::vec3(0.0f);
float playerHeight = 0.75f;
Ref<Camera> cam;
void OnCreate()
{
Entity ent = Engine::GetCurrentScene()->GetEntity("camEntity");
cam = ent.GetComponent<CameraComponent>().CameraInstance;
ent.GetComponent<TransformComponent>().Translation.y = playerHeight;
}
void OnDestroy() { }
void OnUpdate(Timestep ts)
{
if (Input::IsKeyDown(GLFW_KEY_W))
velocity.z = 5.0f;
else if (Input::IsKeyDown(GLFW_KEY_S))
velocity.z = -5.0f;
else
velocity.z = 0.0f;
if (Input::IsKeyDown(GLFW_KEY_A))
velocity.x = 5.0f;
else if (Input::IsKeyDown(GLFW_KEY_D))
velocity.x = -5.0f;
else
velocity.x = 0.0f;
glm::vec3 front = cam->cameraFront;
front.y = .0f;
glm::vec3 right = cam->cameraRight;
right.y = .0f;
glm::vec3 result = velocity.z * glm::normalize(front) + velocity.x * normalize(right);
}
};
class FlashingLightScript : public ScriptableEntity
{
public:
bool isOn = false;
float nextFlip = 0.f;
float strength = 10.f;
float deltaTime = 0.f;
void OnCreate() { }
void OnDestroy() { }
void OnUpdate(Timestep ts)
{
if (nextFlip < deltaTime)
{
//GetComponent<LightComponent>().Strength = isOn * strength;
isOn = !isOn;
nextFlip = deltaTime + 1.0f;
}
deltaTime += ts;
}
};
void CreateInterface()
{
//Ref<UI::UserInterface> userInterface = UI::UserInterface::New("test");
//
//Ref<UI::Rect> rectangle = UI::Rect::New(16, 16, userInterface->Width - 16, userInterface->Height - 16);
//userInterface->AddRect(rectangle);
}
int main()
{
std::string TrenchbroomPath = "F:/TrenchBroom/";
FGDFile file(TrenchbroomPath + "Games/Nuake/Nuake.fgd");
FGDClass newClass(FGDClassType::Point, "light", "a nuake light");
ClassProperty prop{
"Intensity",
ClassPropertyType::Integer,
"Changes the light intensity"
};
newClass.AddProperty(prop);
file.AddClass(newClass);
file.Save();
Engine::Init();
// ScriptingEngine::UpdateScript("test.lua");
CreateInterface();
EditorInterface editor;
editor.BuildFonts();

View File

@@ -11,11 +11,13 @@ class CamScript is ScriptableEntity {
_mouseLastX = 0
_mouseLastY = 0
_BobHeight = 0.1
_BobHeight = 0.1
_BobSpeed = 5.0
_CamHeight = 0.5
_deltaTime = 0
Input.HideMouse()
}

View File

@@ -12,13 +12,13 @@ class PlayerScript is ScriptableEntity {
construct new() {
_InputDir = Vector3.new(0, 0, 0)
_Velocity = Vector3.new(0, 0, 0)
_Accel = 25
_Deccel = 0.92
_Accel = 150
_Deccel = 0.85
_AirDeccel = 0.7
_Gravity = 10
_Gravity = 20
_MaxSpeed = 20
_Jump = 200
_Jump = 400
//Input.HideMouse()
}
@@ -58,7 +58,6 @@ class PlayerScript is ScriptableEntity {
} else {
_Velocity.y = -10
Engine.Log("Grav: %(_Velocity.y)")
if(Input.IsKeyPressed(32)) _Velocity.y = _Jump
@@ -69,7 +68,6 @@ class PlayerScript is ScriptableEntity {
_Velocity.z = _Velocity.z * _Deccel
}
Engine.Log("Grav: %(_Velocity.y)")
controller.MoveAndSlide(_Velocity * ts)
}

View File

@@ -59,6 +59,9 @@ struct Light {
float LinearAttenuation;
float QuadraticAttenuation;
mat4 LightTransform;
sampler2D ShadowMaps[4];
float CascadeDepth[4];
mat4 LightTransforms[4];
sampler2D ShadowMap;
sampler2D RSMFlux;
sampler2D RSMNormal;
@@ -221,6 +224,59 @@ vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness)
return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(max(1.0 - cosTheta, 0.0), 5.0);
}
float ShadowCalculation(Light light, vec3 FragPos, vec3 normal)
{
// Get Depth
vec3 startPosition = u_EyePosition;
vec3 rayVector = FragPos - startPosition;
float depth = length(rayVector);
int shadowmap = -1;
// Get CSM depth
for (int i = 0; i < 4; i++)
{
float CSMDepth = light.CascadeDepth[i] ;
if (depth < CSMDepth + 0.0001)
{
shadowmap = i;
break;
}
}
if (shadowmap == -1)
return 1.0;
vec4 fragPosLightSpace = light.LightTransforms[shadowmap] * vec4(FragPos, 1.0f);
//sampler2D shadowmapFB = light.ShadowMaps[shadowmap];
// perform perspective divide
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
// transform to [0,1] range
projCoords = projCoords * 0.5 + 0.5;
// get closest depth value from light's perspective (using [0,1] range fragPosLight as coords)
float closestDepth = texture(light.ShadowMaps[shadowmap], projCoords.xy).r;
// get depth of current fragment from light's perspective
float currentDepth = projCoords.z;
// check whether current frag pos is in shadow
float bias = max(0.005 * (1.0 - dot(normal, light.Direction)), 0.0005);
float shadow = 0.0;
vec2 texelSize = 1.0 / textureSize(light.ShadowMaps[shadowmap], 0);
for (int x = -1; x <= 1; ++x)
{
for (int y = -1; y <= 1; ++y)
{
float pcfDepth = texture(light.ShadowMaps[shadowmap], projCoords.xy + vec2(x, y) * texelSize).r;
shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0;
}
}
return shadow /= 9;
}
/*
float ShadowCalculation(vec4 fragPosLightSpace, sampler2D shadowMap, vec3 normal, vec3 lightDir)
{
// perform perspective divide
@@ -246,7 +302,7 @@ float ShadowCalculation(vec4 fragPosLightSpace, sampler2D shadowMap, vec3 normal
}
return shadow /= 9;
}
*/
uniform float u_FogAmount;
// Mie scaterring approximated with Henyey-Greenstein phase function.
@@ -357,7 +413,8 @@ void main()
attenuation = 1.0f;
if (Lights[i].Volumetric == 1)
Fog += ComputeVolumetric(v_FragPos, Lights[i].LightTransform, Lights[i].Color, Lights[i].ShadowMap, Lights[i].Direction);
shadow += ShadowCalculation(Lights[i].LightTransform * vec4(v_FragPos, 1.0f), Lights[i].ShadowMap, N, Lights[i].Direction);
shadow += ShadowCalculation(Lights[i], v_FragPos, N);
//shadow += ShadowCalculation(Lights[i].LightTransform * vec4(v_FragPos, 1.0f), Lights[i].ShadowMap, N, Lights[i].Direction);
}

View File

@@ -21,6 +21,7 @@
#include <src/Core/Logger.h>
#include <src/Scene/Components/WrenScriptComponent.h>
#include <src/Rendering/MSAAFramebuffer.h>
#include "ProjectInterface.h"
Ref<UI::UserInterface> userInterface;
ImFont* normalFont;
ImFont* EditorInterface::bigIconFont;
@@ -37,20 +38,25 @@ void EditorInterface::Init()
ImGui::DockSpaceOverViewport(viewport, dockspace_flags);
//this->filesystem = FileSystemUI();
}
ImVec2 LastSize = ImVec2();
void EditorInterface::DrawViewport()
{
if(ImGui::Begin("ShadowMap"))
/*
if(ImGui::Begin("ShadowMap1"))
{
ImVec2 regionAvail = ImGui::GetContentRegionAvail();
glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y);
if (m_IsEntitySelected && m_SelectedEntity.HasComponent<LightComponent>()) {
auto& light = m_SelectedEntity.GetComponent<LightComponent>();
Ref<Texture> texture = light.m_Framebuffer->GetTexture(GL_DEPTH_ATTACHMENT);
Ref<Texture> texture = light.m_Framebuffers[0]->GetTexture(GL_DEPTH_ATTACHMENT);
ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0));
}
else {
@@ -58,8 +64,59 @@ void EditorInterface::DrawViewport()
}
}
ImGui::End();
if (ImGui::Begin("ShadowMap2"))
{
ImVec2 regionAvail = ImGui::GetContentRegionAvail();
glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y);
if (m_IsEntitySelected && m_SelectedEntity.HasComponent<LightComponent>()) {
auto& light = m_SelectedEntity.GetComponent<LightComponent>();
Ref<Texture> texture = light.m_Framebuffers[1]->GetTexture(GL_DEPTH_ATTACHMENT);
ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0));
}
else {
ImGui::Text("Please select a light entity");
}
}
ImGui::End();
if (ImGui::Begin("ShadowMap3"))
{
ImVec2 regionAvail = ImGui::GetContentRegionAvail();
glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y);
if (m_IsEntitySelected && m_SelectedEntity.HasComponent<LightComponent>()) {
auto& light = m_SelectedEntity.GetComponent<LightComponent>();
Ref<Texture> texture = light.m_Framebuffers[2]->GetTexture(GL_DEPTH_ATTACHMENT);
ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0));
}
else {
ImGui::Text("Please select a light entity");
}
}
ImGui::End();
if (ImGui::Begin("ShadowMap4"))
{
ImVec2 regionAvail = ImGui::GetContentRegionAvail();
glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y);
if (m_IsEntitySelected && m_SelectedEntity.HasComponent<LightComponent>()) {
auto& light = m_SelectedEntity.GetComponent<LightComponent>();
Ref<Texture> texture = light.m_Framebuffers[3]->GetTexture(GL_DEPTH_ATTACHMENT);
ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0));
}
else {
ImGui::Text("Please select a light entity");
}
}
ImGui::End();
if (ImGui::Begin("SDF FONT"))
{
ImVec2 regionAvail = ImGui::GetContentRegionAvail();
@@ -72,8 +129,12 @@ void EditorInterface::DrawViewport()
}
ImGui::End();
*/
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
if(ImGui::Begin("Viewport"))
{
ImGui::PopStyleVar();
Overlay();
ImGuizmo::BeginFrame();
@@ -129,6 +190,7 @@ void EditorInterface::DrawViewport()
}
ImGui::End();
}
static int selected = 0;
@@ -733,7 +795,7 @@ void EditorInterface::Overlay()
{
// FIXME-VIEWPORT: Select a default viewport
const float DISTANCE = 10.0f;
static int corner = 0;
static int corner = 3;
ImGuiIO& io = ImGui::GetIO();
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav;
if (corner != -1)
@@ -988,6 +1050,8 @@ void EditorInterface::Draw()
if (!Engine::GetProject())
{
ImGui::OpenPopup("Welcome");
return;
}
if (ImGui::BeginMainMenuBar())
@@ -1139,6 +1203,9 @@ void EditorInterface::Draw()
filesystem.Draw();
filesystem.DrawDirectoryExplorer();
ProjectInterface pInterface;
pInterface.DrawEntitySettings();
if(m_ShowImGuiDemo)
ImGui::ShowDemoWindow();

View File

@@ -0,0 +1,99 @@
#include "ProjectInterface.h"
#include <src/Vendors/imgui/imgui.h>
#include "Engine.h"
void ProjectInterface::DrawProjectSettings()
{
if (ImGui::Begin("Project settings"))
{
char buffer[256];
memset(buffer, 0, sizeof(buffer));
std::strncpy(buffer, Engine::GetProject()->Name.c_str(), sizeof(buffer));
if (ImGui::InputText("##Name", buffer, sizeof(buffer)))
{
Engine::GetProject()->Name = std::string(buffer);
}
}
ImGui::End();
}
void ProjectInterface::DrawCreatePointEntity()
{
char buffer[256];
memset(buffer, 0, sizeof(buffer));
std::strncpy(buffer, Engine::GetProject()->Name.c_str(), sizeof(buffer));
if (ImGui::InputText("##Name", buffer, sizeof(buffer)))
{
Engine::GetProject()->Name = std::string(buffer);
}
}
void ProjectInterface::DrawEntitySettings()
{
if (ImGui::Begin("Entity definitions"))
{
ImGui::Text("This is the entity definition used by trenchbroom. This files allows you to see your entities inside Trenchbroom");
ImGui::Text("Trenchbroom path:");
// path here...
Ref<FGDFile> file = Engine::GetProject()->EntityDefinitionsFile;
auto flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize;
if (ImGui::BeginPopupModal("Create new point entity", NULL, flags))
{
ImGui::Button("Create");
ImGui::SameLine();
ImGui::Button("Cancel");
ImGui::EndPopup();
}
if (ImGui::BeginTabBar("##Tabs", ImGuiTabBarFlags_None))
{
if (ImGui::BeginTabItem("Point entities"))
{
if (ImGui::BeginTable("nested1", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable))
{
ImGui::TableSetupColumn("Name");
ImGui::TableSetupColumn("Desciption");
ImGui::TableSetupColumn("Settings");
ImGui::TableSetupColumn("Prefab");
ImGui::TableHeadersRow();
ImGui::TableNextColumn();
for (auto& pE : file->PointEntities)
{
ImGui::Text(pE.Name.c_str());
ImGui::TableNextColumn();
ImGui::Text(pE.Description.c_str());
ImGui::TableNextColumn();
ImGui::Button("Edit");
ImGui::TableNextColumn();
ImGui::Text(pE.Prefab.c_str());
ImGui::SameLine();
ImGui::Button("Browse");
}
ImGui::EndTable();
}
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Brush entities"))
{
ImGui::Text("ID: 0123456789");
ImGui::EndTabItem();
}
ImGui::EndTabBar();
}
}
ImGui::End();
}

View File

@@ -0,0 +1,18 @@
#pragma once
#include "src/Core/Core.h"
#include "src/Resource/Project.h"
class ProjectInterface
{
public:
Ref<Project> m_CurrentProject;
void DrawProjectSettings();
void DrawCreatePointEntity();
void DrawEntitySettings();
};

View File

@@ -1,7 +0,0 @@
#pragma once
#include <string>
class BaseClass {
public:
std::string Name;
};

View File

@@ -15,7 +15,7 @@
Ref<Project> Engine::CurrentProject;
Ref<Window> Engine::CurrentWindow;
float Engine::m_LastFrameTime = 0.0f;
float Engine::m_FixedUpdateRate = 1.0 / 60.0f;
float Engine::m_FixedUpdateRate = 1.0 / 144.0f;
float Engine::m_FixedUpdateDifference = 0.f;
bool Engine::IsPlayMode = false;

View File

@@ -1,8 +0,0 @@
#include "FDGSerializer.h"
#include <src\Core\FileSystem.h>
bool FGDSerializer::BeginFGDFile(const std::string path)
{
FileSystem::BeginWriteFile(path + ".fgd");
}

View File

@@ -1,6 +0,0 @@
#pragma once
#include "BaseClass.h"
class PointClass : public BaseClass {
};

View File

@@ -137,7 +137,7 @@ std::ofstream FileSystem::fileWriter;
bool FileSystem::BeginWriteFile(const std::string path)
{
fileWriter = std::ofstream();
fileWriter.open("example.txt");
fileWriter.open(path);
return false;
}
@@ -145,6 +145,8 @@ bool FileSystem::BeginWriteFile(const std::string path)
bool FileSystem::WriteLine(const std::string line)
{
fileWriter << line.c_str();
return true;
}
void FileSystem::EndWriteFile()

View File

@@ -61,7 +61,7 @@ glm::vec3 Camera::GetDirection() {
glm::mat4 Camera::GetPerspective()
{
//TODO: Add perspective options
m_Perspective = glm::perspectiveFov(glm::radians(Fov), 9.0f * AspectRatio, 9.0f, 0.1f, 2000.0f);
m_Perspective = glm::perspectiveFov(glm::radians(Fov), 9.0f * AspectRatio, 9.0f, 0.1f, 1000.0f);
//m_Perspective = glm::ortho(-8.0f, 8.0f, -4.5f, 4.5f, -1.0f, 1.0f);
return m_Perspective;
}

View File

@@ -130,10 +130,27 @@ void Renderer::RegisterLight(TransformComponent transform, LightComponent light,
glm::vec3 pos = transform.Translation;
glm::mat4 lightView = glm::lookAt(pos, pos - direction, glm::vec3(0.0f, 1.0f, 0.0f));
light.m_Framebuffer->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(17);
//light.m_Framebuffer->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(17);
light.m_Framebuffers[0]->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(17);
light.m_Framebuffers[1]->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(18);
light.m_Framebuffers[2]->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(19);
light.m_Framebuffers[3]->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(20);
m_Shader->SetUniform1i ("LightCount", idx);
m_Shader->SetUniform1i ("Lights[" + std::to_string(idx - 1) + "].Type" , light.Type);
m_Shader->SetUniform1i ("Lights[" + std::to_string(idx - 1) + "].ShadowMap" , 17);
m_Shader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].ShadowMaps[0]", 17);
m_Shader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].ShadowMaps[1]", 18);
m_Shader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].ShadowMaps[2]", 19);
m_Shader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].ShadowMaps[3]", 20);
m_Shader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransforms[0]", light.mViewProjections[0]);
m_Shader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransforms[1]", light.mViewProjections[1]);
m_Shader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransforms[2]", light.mViewProjections[2]);
m_Shader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransforms[3]", light.mViewProjections[3]);
m_Shader->SetUniform1f("Lights[" + std::to_string(idx - 1) + "].CascadeDepth[0]", light.mCascadeSplitDepth[0]);
m_Shader->SetUniform1f("Lights[" + std::to_string(idx - 1) + "].CascadeDepth[1]", light.mCascadeSplitDepth[1]);
m_Shader->SetUniform1f("Lights[" + std::to_string(idx - 1) + "].CascadeDepth[2]", light.mCascadeSplitDepth[2]);
m_Shader->SetUniform1f("Lights[" + std::to_string(idx - 1) + "].CascadeDepth[3]", light.mCascadeSplitDepth[3]);
m_Shader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransform", light.GetProjection() * lightView);
m_Shader->SetUniform3f ("Lights[" + std::to_string(idx - 1) + "].Position" , transform.Translation.x, transform.Translation.y, transform.Translation.z);
m_Shader->SetUniform3f ("Lights[" + std::to_string(idx - 1) + "].Direction" , direction.x, direction.y, direction.z);

View File

@@ -5,7 +5,8 @@
#include <vector>
class BrushClass : public BaseClass {
class BrushClass {
public:
std::string name;
std::vector<ClassProperty> Props;
std::string Description;

View File

@@ -1,15 +1,22 @@
#pragma once
#include <string>
enum class ClassPropertyType {
AABB,
Float,
String,
DropDown,
Integer,
Float,
Boolean,
AABB,
Choices,
Color,
Int
};
enum class FGDClassType {
Point,
Brush
};
struct ClassProperty {
std::string name;
ClassPropertyType type;
std::string description;
};

View File

@@ -1,11 +1,12 @@
#pragma once
#include "FGDClass.h"
#include <string>
class FGDSerializer
{
public:
static bool BeginFGDFile(const std::string path);
static bool RegisterEntity();
static bool SerializeClass(FGDClass fgdClass);
static bool EndFGDFile();
};

View File

@@ -0,0 +1,26 @@
#include "FGDClass.h"
FGDClass::FGDClass(FGDClassType type, const std::string& name, const std::string& desc)
{
Type = type;
Name = name;
Description = desc;
}
void FGDClass::AddProperty(ClassProperty prop)
{
Properties.push_back(prop);
}
void FGDClass::RemoveProperty(const std::string name)
{
int position = 0;
for (auto& p : Properties)
{
if (p.name == name)
Properties.erase(Properties.begin() + position);
position++;
}
}

View File

@@ -0,0 +1,47 @@
#pragma once
#include "ClassProperty.h"
#include <string>
#include <vector>
class FGDBaseEntity
{
public:
std::string Name;
std::vector<ClassProperty> Properties;
};
class FGDBrushEntity
{
public:
std::string Name;
std::string Description;
bool Transparent = false;
bool Collision = false;
bool IsTrigger = false;
std::string Script = "";
std::vector<ClassProperty> Properties;
FGDBaseEntity BaseClass;
};
class FGDPointEntity
{
public:
std::string Name;
std::string Description;
std::string Prefab;
std::vector<ClassProperty> Properties;
FGDBaseEntity BaseClass;
};
class FGDClass {
public:
FGDClassType Type;
std::string Name;
std::string Description;
std::vector<ClassProperty> Properties;
FGDClass(FGDClassType type, const std::string& name, const std::string& desc);
void AddProperty(ClassProperty prop);
void RemoveProperty(const std::string name);
};

View File

@@ -0,0 +1,67 @@
#include "FGDFile.h"
#include <src/Resource/FGD/FDGSerializer.h>
FGDFile::FGDFile(const std::string path)
{
this->path = path;
this->BaseEntities = std::vector<FGDBaseEntity>();
this->BrushEntities = std::vector<FGDBrushEntity>();
this->PointEntities = std::vector<FGDPointEntity>();
}
FGDFile::FGDFile()
{
this->path = "";
this->BaseEntities = std::vector<FGDBaseEntity>();
this->BrushEntities = std::vector<FGDBrushEntity>();
this->PointEntities = std::vector<FGDPointEntity>();
FGDPointEntity newEnt;
newEnt.Name = "Light";
newEnt.Description = "A Nuake PBR light";
this->PointEntities.push_back(newEnt);
}
bool FGDFile::Save()
{
FGDSerializer::BeginFGDFile(this->path);
for (auto& b : BaseEntities)
{
}
for (auto& p : PointEntities)
{
}
for (auto& b : BrushEntities)
{
}
//for(auto& c : Classes)
// FGDSerializer::SerializeClass(c);
FGDSerializer::EndFGDFile();
return true;
}
void FGDFile::AddClass(FGDClass fgdClass)
{
//this->Classes.push_back(fgdClass);
}
void FGDFile::RemoveClass(const std::string& name)
{
//int idx = 0;
//for (auto& c : Classes)
//{
//if (c.Name == name)
//Classes.erase(Classes.begin() + idx);
//idx++;
//}
}

View File

@@ -0,0 +1,35 @@
#pragma once
#include "FGDClass.h"
#include "../Serializable.h"
#include <string>
#include <vector>
class FGDFile : ISerializable{
public:
std::string path;
std::vector<FGDPointEntity> PointEntities;
std::vector<FGDBrushEntity> BrushEntities;
std::vector<FGDBaseEntity> BaseEntities;
FGDFile(const std::string path);
FGDFile();
bool Save();
void AddClass(FGDClass fgdClass);
void RemoveClass(const std::string& name);
json Serialize() override
{
BEGIN_SERIALIZE();
END_SERIALIZE();
}
bool Deserialize(const std::string& str)
{
return true;
}
};

View File

@@ -0,0 +1,58 @@
#include "FDGSerializer.h"
#include <src\Core\FileSystem.h>
bool FGDSerializer::BeginFGDFile(const std::string path)
{
FileSystem::BeginWriteFile(path);
return true;
}
bool FGDSerializer::SerializeClass(FGDClass fgdClass)
{
std::string line = "@";
if (fgdClass.Type == FGDClassType::Point)
line += "PointClass = ";
else if (fgdClass.Type == FGDClassType::Brush)
line += "SolidClass = ";
else // error.
return true;
line += fgdClass.Name + " : \"" + fgdClass.Description + "\"";
// Exit early
if (fgdClass.Properties.size() == 0)
{
line += " [] \n";
FileSystem::WriteLine(line);
return true;
}
// Properties here.
line += "\n [ \n";
for (auto& p : fgdClass.Properties)
{
// E.g: myProp(integer) : "description"
line += " "; // Tabulation
line += p.name;
line += "(";
if (p.type == ClassPropertyType::Integer)
line += "integer";
line += ") : ";
line += "\"" + p.description + "\"";
line += "\n";
}
line += "]";
FileSystem::WriteLine(line);
return true;
}
bool FGDSerializer::EndFGDFile()
{
FileSystem::EndWriteFile();
return false;
}

View File

@@ -0,0 +1,8 @@
#pragma once
#include "BaseClass.h"
class PointClass {
};

View File

@@ -0,0 +1,7 @@
#pragma once
class Prefab
{
};

View File

@@ -16,6 +16,8 @@ Project::Project(const std::string Name, const std::string Description, const st
scene->Deserialize(defaultScenePath);
}
this->EntityDefinitionsFile = CreateRef<FGDFile>();
SaveAs(FullPath);
}
@@ -24,6 +26,8 @@ Project::Project()
this->Name = "";
this->Description = "";
this->FullPath = "";
this->EntityDefinitionsFile = CreateRef<FGDFile>();
}
void Project::Save()

View File

@@ -3,6 +3,9 @@
#include "../Core/Core.h"
#include "../Scene/Scene.h"
#include "Serializable.h"
#include "FGD/FGDFile.h"
class Project : public ISerializable
{
public:
@@ -11,6 +14,7 @@ public:
std::string FullPath;
Ref<Scene> DefaultScene;
Ref<FGDFile> EntityDefinitionsFile;
Project(const std::string Name, const std::string Description, const std::string& FullPath, const std::string& defaultScenePath = "");
Project();

View File

@@ -12,9 +12,18 @@ LightComponent::LightComponent()
Strength = 10.0f;
Direction = glm::vec3(0, -1, 0);
//m_Framebuffers = std::vector<Ref<FrameBuffer>>();
//mViewProjections = std::vector<glm::mat4>();
//mCascadeSplitDepth = std::vector<float>();
//mCascadeSplits = std::vector<float>();
// Framebuffer used for shadow mapping.
m_Framebuffer = CreateRef<FrameBuffer>(false, glm::vec2(4096, 4096));
m_Framebuffer->SetTexture(CreateRef<Texture>(glm::vec2(4096, 4096), GL_DEPTH_COMPONENT), GL_DEPTH_ATTACHMENT);
for (int i = 0; i < 4; i++)
{
m_Framebuffers[i] = CreateRef<FrameBuffer>(false, glm::vec2(4096, 4096));
m_Framebuffers[i]->SetTexture(CreateRef<Texture>(glm::vec2(4096, 4096), GL_DEPTH_COMPONENT), GL_DEPTH_ATTACHMENT);
}
}
glm::mat4 LightComponent::GetProjection()
@@ -44,7 +53,7 @@ glm::vec3 LightComponent::GetDirection()
void LightComponent::BeginDrawShadow()
{
Renderer::m_ShadowmapShader->Bind();
m_Framebuffer->Bind();
//m_Framebuffer->Bind();
// Render scene...
@@ -52,7 +61,7 @@ void LightComponent::BeginDrawShadow()
void LightComponent::EndDrawShadow()
{
m_Framebuffer->Unbind();
//m_Framebuffer->Unbind();
}
void LightComponent::DrawShadow()

View File

@@ -30,8 +30,9 @@ public:
float LinearAttenuation = 0.0f;
float QuadraticAttenuation = 0.0f;
std::vector<glm::mat4> mViewProjections;
std::vector<float> mCascadeSplitDepth;
Ref<FrameBuffer> m_Framebuffers[4];
glm::mat4 mViewProjections[4];
float mCascadeSplitDepth[4];
LightComponent();
@@ -52,16 +53,16 @@ public:
void SetType(LightType type);
std::vector<int> mCascadeSplits;
float mCascadeSplits[4];
void CalculateViewProjection(glm::mat4& view, const glm::mat4& projection, const glm::vec3& normalizedDirection)
void CalculateViewProjection(glm::mat4& view, const glm::mat4& projection)
{
glm::mat4 viewProjection = projection * view;
glm::mat4 inverseViewProjection = glm::inverse(viewProjection);
// TODO: Automate this
const float nearClip = 0.1f;
const float nearClip = 0.01f;
const float farClip = 1000.0f;
const float clipRange = farClip - nearClip;
@@ -82,9 +83,9 @@ public:
mCascadeSplits[i] = (d - nearClip) / clipRange;
}
mCascadeSplits[0] = 0.2f;
mCascadeSplits[1] = 0.45f;
mCascadeSplits[2] = 1.0f;
//mCascadeSplits[0] = 0.2f;
//mCascadeSplits[1] = 0.45f;
//mCascadeSplits[2] = 1.0f;
float lastSplitDist = 0.0f;
// Calculate Orthographic Projection matrix for each cascade
@@ -137,7 +138,7 @@ public:
glm::vec3 minExtents = -maxExtents;
// Calculate the view and projection matrix
glm::vec3 lightDir = -normalizedDirection;
glm::vec3 lightDir = -this->Direction;
glm::mat4 lightViewMatrix = glm::lookAt(frustumCenter - lightDir * -minExtents.z, frustumCenter, glm::vec3(0.0f, 0.0f, 1.0f));
glm::mat4 lightProjectionMatrix = glm::ortho(minExtents.x, maxExtents.x, minExtents.y, maxExtents.y, 0.0f + mCascadeNearPlaneOffset, maxExtents.z - minExtents.z + mCascadeFarPlaneOffset);

View File

@@ -71,6 +71,9 @@ void Scene::Update(Timestep ts)
{
for (auto& system : m_Systems)
system->Update(ts);
}
void Scene::FixedUpdate(Timestep ts)
@@ -116,30 +119,42 @@ void Scene::DrawShadows()
if (light.Type != LightType::Directional)
continue;
light.CalculateViewProjection(cam->GetTransform(), cam->GetPerspective());
light.BeginDrawShadow();
for (auto e : modelView)
for (int i = 0; i < 4; i++)
{
auto [transform, model] = modelView.get<TransformComponent, ModelComponent>(e);
glm::vec3 pos = lightTransform.Translation;
glm::mat4 lightView = glm::lookAt(pos, pos - light.GetDirection(), glm::vec3(0.0f, 1.0f, 0.0f));
Renderer::m_ShadowmapShader->SetUniformMat4f("lightSpaceMatrix", light.GetProjection() * lightView);
Renderer::m_ShadowmapShader->SetUniformMat4f("model", transform.GetTransform());
model.Draw();
}
for (auto e : quakeView) {
auto [transform, model] = quakeView.get<TransformComponent, QuakeMapComponent>(e);
glm::vec3 pos = lightTransform.Translation;
glm::mat4 lightView = glm::lookAt(pos, pos - light.GetDirection(), glm::vec3(0.0f, 1.0f, 0.0f));
Renderer::m_ShadowmapShader->SetUniformMat4f("lightSpaceMatrix", light.GetProjection() * lightView);
Renderer::m_ShadowmapShader->SetUniformMat4f("model", transform.GetTransform());
model.Draw();
light.m_Framebuffers[i]->Bind();
for (auto e : modelView)
{
auto [transform, model] = modelView.get<TransformComponent, ModelComponent>(e);
glm::vec3 pos = lightTransform.Translation;
glm::mat4 lightView = glm::lookAt(pos, pos - light.GetDirection(), glm::vec3(0.0f, 1.0f, 0.0f));
Renderer::m_ShadowmapShader->SetUniformMat4f("lightSpaceMatrix", light.mViewProjections[i]);
Renderer::m_ShadowmapShader->SetUniformMat4f("model", transform.GetTransform());
model.Draw();
}
for (auto e : quakeView) {
auto [transform, model] = quakeView.get<TransformComponent, QuakeMapComponent>(e);
glm::vec3 pos = lightTransform.Translation;
glm::mat4 lightView = glm::lookAt(pos, pos - light.GetDirection(), glm::vec3(0.0f, 1.0f, 0.0f));
Renderer::m_ShadowmapShader->SetUniformMat4f("lightSpaceMatrix", light.mViewProjections[i]);
Renderer::m_ShadowmapShader->SetUniformMat4f("model", transform.GetTransform());
model.Draw();
}
light.m_Framebuffers[i]->Unbind();
}
light.EndDrawShadow();
}
}
@@ -182,6 +197,7 @@ void Scene::Draw()
break;
}
}
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
Ref<Environment> env = GetEnvironment();
@@ -222,7 +238,8 @@ void Scene::Draw()
light.Draw(copyT, m_EditorCamera);
}
}
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
Renderer::m_Shader->Bind();
Renderer::m_Shader->SetUniform3f("u_EyePosition", cam->GetTranslation().x, cam->GetTranslation().y, cam->GetTranslation().z);
Renderer::m_Shader->SetUniform1i("u_ShowNormal", 0);