Major cleanup.
Moved to namespace Cleanup includes
This commit is contained in:
@@ -17,39 +17,40 @@
|
||||
#include <src/Rendering/Shaders/ShaderManager.h>
|
||||
#include <src/Rendering/Renderer.h>
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
Engine::Init();
|
||||
Nuake::Engine::Init();
|
||||
|
||||
EditorInterface editor;
|
||||
Nuake::EditorInterface editor;
|
||||
editor.BuildFonts();
|
||||
|
||||
// Register Gizmo textures
|
||||
Ref<Texture> lightTexture = TextureManager::Get()->GetTexture("resources/Icons/Gizmo/Light.png");
|
||||
Ref<Texture> camTexture = TextureManager::Get()->GetTexture("resources/Icons/Gizmo/Camera.png");
|
||||
Ref<Shader> GuizmoShader = ShaderManager::GetShader("resources/Shaders/gizmo.shader");
|
||||
Ref<Nuake::Texture> lightTexture = Nuake::TextureManager::Get()->GetTexture("resources/Icons/Gizmo/Light.png");
|
||||
Ref<Nuake::Texture> camTexture = Nuake::TextureManager::Get()->GetTexture("resources/Icons/Gizmo/Camera.png");
|
||||
Ref<Nuake::Shader> GuizmoShader = Nuake::ShaderManager::GetShader("resources/Shaders/gizmo.shader");
|
||||
|
||||
while (!Engine::GetCurrentWindow()->ShouldClose())
|
||||
while (!Nuake::Engine::GetCurrentWindow()->ShouldClose())
|
||||
{
|
||||
Engine::Tick();
|
||||
Engine::Draw();
|
||||
Nuake::Engine::Tick();
|
||||
Nuake::Engine::Draw();
|
||||
|
||||
if (Input::IsKeyPressed(GLFW_KEY_F8))
|
||||
Engine::ExitPlayMode();
|
||||
if (Nuake::Input::IsKeyPressed(GLFW_KEY_F8))
|
||||
Nuake::Engine::ExitPlayMode();
|
||||
|
||||
Ref<FrameBuffer> sceneFramebuffer = Engine::GetCurrentWindow()->GetFrameBuffer();
|
||||
Ref<Nuake::FrameBuffer> sceneFramebuffer = Nuake::Engine::GetCurrentWindow()->GetFrameBuffer();
|
||||
sceneFramebuffer->Bind();
|
||||
|
||||
Ref<Scene> currentScene = Engine::GetCurrentScene();
|
||||
if (currentScene && !Engine::IsPlayMode)
|
||||
Ref<Nuake::Scene> currentScene = Nuake::Engine::GetCurrentScene();
|
||||
if (currentScene && !Nuake::Engine::IsPlayMode)
|
||||
{
|
||||
GuizmoShader->Bind();
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
auto camView = currentScene->m_Registry.view<TransformComponent, CameraComponent>();
|
||||
auto camView = currentScene->m_Registry.view<Nuake::TransformComponent, Nuake::CameraComponent>();
|
||||
for (auto e : camView) {
|
||||
auto [transformComponent, cam] = camView.get<TransformComponent, CameraComponent>(e);
|
||||
auto [transformComponent, cam] = camView.get<Nuake::TransformComponent, Nuake::CameraComponent>(e);
|
||||
|
||||
GuizmoShader->SetUniformMat4f("model", transformComponent.GetTransform());
|
||||
GuizmoShader->SetUniformMat4f("view", currentScene->m_EditorCamera->GetTransform());
|
||||
@@ -58,12 +59,12 @@ int main()
|
||||
camTexture->Bind(2);
|
||||
GuizmoShader->SetUniform1i("gizmo_texture", 2);
|
||||
|
||||
Renderer::DrawQuad(transformComponent.GetTransform());
|
||||
Nuake::Renderer::DrawQuad(transformComponent.GetTransform());
|
||||
}
|
||||
|
||||
auto view = currentScene->m_Registry.view<TransformComponent, LightComponent>();
|
||||
auto view = currentScene->m_Registry.view<Nuake::TransformComponent, Nuake::LightComponent>();
|
||||
for (auto e : view) {
|
||||
auto [transformComponent, light] = view.get<TransformComponent, LightComponent>(e);
|
||||
auto [transformComponent, light] = view.get<Nuake::TransformComponent, Nuake::LightComponent>(e);
|
||||
|
||||
GuizmoShader->SetUniformMat4f("model", transformComponent.GetTransform());
|
||||
GuizmoShader->SetUniformMat4f("view", currentScene->m_EditorCamera->GetTransform());
|
||||
@@ -72,7 +73,7 @@ int main()
|
||||
lightTexture->Bind(2);
|
||||
GuizmoShader->SetUniform1i("gizmo_texture", 2);
|
||||
|
||||
Renderer::DrawQuad(transformComponent.GetTransform());
|
||||
Nuake::Renderer::DrawQuad(transformComponent.GetTransform());
|
||||
}
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
@@ -81,9 +82,9 @@ int main()
|
||||
|
||||
sceneFramebuffer->Unbind();
|
||||
editor.Draw();
|
||||
Engine::EndDraw();
|
||||
Nuake::Engine::EndDraw();
|
||||
}
|
||||
|
||||
Engine::Close();
|
||||
Nuake::Engine::Close();
|
||||
}
|
||||
|
||||
|
||||
@@ -240,6 +240,5 @@ void main()
|
||||
// gamma correct
|
||||
color = pow(color, vec3(1.0 / u_Exposure));
|
||||
|
||||
|
||||
FragColor = vec4(color, 1.0); // so If i wanted to implement other stuff like SSR and bloom. I would need another render texture? using this same shader?
|
||||
FragColor = vec4(color, 1.0);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,43 +4,47 @@
|
||||
#include <src/Vendors/imgui/ImGuizmo.h>
|
||||
#include "src/Core/FileSystem.h"
|
||||
#include "FileSystemUI.h"
|
||||
class Material;
|
||||
|
||||
class EditorInterface
|
||||
{
|
||||
private:
|
||||
FileSystemUI filesystem = FileSystemUI();
|
||||
Entity m_SelectedEntity;
|
||||
bool m_IsEntitySelected = false;
|
||||
bool m_DrawGrid = false;
|
||||
bool m_ShowImGuiDemo = false;
|
||||
bool m_DebugCollisions = false;
|
||||
bool m_ShowOverlay = true;
|
||||
ImGuizmo::OPERATION CurrentOperation = ImGuizmo::TRANSLATE;
|
||||
ImGuizmo::MODE CurrentMode = ImGuizmo::WORLD;
|
||||
Ref<Material> m_SelectedMaterial;
|
||||
Ref<Directory> m_CurrentDirectory;
|
||||
|
||||
bool m_IsMaterialSelected = false;
|
||||
|
||||
public:
|
||||
static ImFont* bigIconFont;
|
||||
void BuildFonts();
|
||||
void Init();
|
||||
void Draw();
|
||||
void DrawViewport();
|
||||
void DrawEntityTree(Entity ent);
|
||||
void DrawSceneTree();
|
||||
void DrawEntityPropreties();
|
||||
void DrawGizmos();
|
||||
void DrawFileSystem();
|
||||
void DrawDirectoryExplorer();
|
||||
void DrawLogger();
|
||||
void DrawDirectory(Ref<Directory> directory);
|
||||
bool EntityContainsItself(Entity ent1, Entity ent2);
|
||||
void DrawFile(Ref<File> file);
|
||||
void DrawRessourceWindow();
|
||||
void DrawInit();
|
||||
void EditorInterfaceDrawFiletree(Ref<Directory> dir);
|
||||
void Overlay();
|
||||
};
|
||||
namespace Nuake {
|
||||
class Material;
|
||||
class EditorInterface
|
||||
{
|
||||
private:
|
||||
FileSystemUI filesystem = FileSystemUI();
|
||||
Entity m_SelectedEntity;
|
||||
bool m_IsEntitySelected = false;
|
||||
bool m_DrawGrid = false;
|
||||
bool m_ShowImGuiDemo = false;
|
||||
bool m_DebugCollisions = false;
|
||||
bool m_ShowOverlay = true;
|
||||
ImGuizmo::OPERATION CurrentOperation = ImGuizmo::TRANSLATE;
|
||||
ImGuizmo::MODE CurrentMode = ImGuizmo::WORLD;
|
||||
Ref<Material> m_SelectedMaterial;
|
||||
Ref<Directory> m_CurrentDirectory;
|
||||
|
||||
bool m_IsMaterialSelected = false;
|
||||
|
||||
public:
|
||||
static ImFont* bigIconFont;
|
||||
void BuildFonts();
|
||||
void Init();
|
||||
void Draw();
|
||||
void DrawViewport();
|
||||
void DrawEntityTree(Entity ent);
|
||||
void DrawSceneTree();
|
||||
void DrawEntityPropreties();
|
||||
void DrawGizmos();
|
||||
void DrawFileSystem();
|
||||
void DrawDirectoryExplorer();
|
||||
void DrawLogger();
|
||||
void DrawDirectory(Ref<Directory> directory);
|
||||
bool EntityContainsItself(Entity ent1, Entity ent2);
|
||||
void DrawFile(Ref<File> file);
|
||||
void DrawRessourceWindow();
|
||||
void DrawInit();
|
||||
void EditorInterfaceDrawFiletree(Ref<Directory> dir);
|
||||
void Overlay();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,344 +8,339 @@
|
||||
#include <src/Rendering/Textures/Texture.h>
|
||||
#include <src/Core/TextureManager.h>
|
||||
#include "EditorInterface.h"
|
||||
// TODO: add filetree in same panel
|
||||
void FileSystemUI::Draw()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FileSystemUI::DrawDirectoryContent()
|
||||
{
|
||||
}
|
||||
|
||||
void FileSystemUI::DrawFiletree()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void FileSystemUI::EditorInterfaceDrawFiletree(Ref<Directory> dir)
|
||||
{
|
||||
for (auto d : dir->Directories)
|
||||
namespace Nuake {
|
||||
// TODO: add filetree in same panel
|
||||
void FileSystemUI::Draw()
|
||||
{
|
||||
ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanAvailWidth;
|
||||
bool is_selected = m_CurrentDirectory == d;
|
||||
if (is_selected)
|
||||
base_flags |= ImGuiTreeNodeFlags_Selected;
|
||||
|
||||
if (d->Directories.size() == 0)
|
||||
{
|
||||
base_flags = ImGuiTreeNodeFlags_Leaf;
|
||||
}
|
||||
std::string icon = ICON_FA_FOLDER;
|
||||
if (is_selected)
|
||||
icon = ICON_FA_FOLDER_OPEN;
|
||||
bool open = ImGui::TreeNodeEx((icon + " " + d->name).c_str(), base_flags);
|
||||
|
||||
if (ImGui::IsItemClicked())
|
||||
m_CurrentDirectory = d;
|
||||
if (open)
|
||||
{
|
||||
if (d->Directories.size() > 0)
|
||||
EditorInterfaceDrawFiletree(d);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FileSystemUI::DrawDirectory(Ref<Directory> directory)
|
||||
{
|
||||
ImGui::PushFont(EditorInterface::bigIconFont);
|
||||
std::string id = ICON_FA_FOLDER + std::string("##") + directory->name;
|
||||
if (ImGui::Button(id.c_str(), ImVec2(100, 100)))
|
||||
m_CurrentDirectory = directory;
|
||||
if (ImGui::BeginPopupContextWindow())
|
||||
void FileSystemUI::DrawDirectoryContent()
|
||||
{
|
||||
if (ImGui::MenuItem("Htest"));
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::Text(directory->name.c_str());
|
||||
ImGui::PopFont();
|
||||
}
|
||||
|
||||
bool FileSystemUI::EntityContainsItself(Entity source, Entity target)
|
||||
{
|
||||
ParentComponent& targeParentComponent = target.GetComponent<ParentComponent>();
|
||||
if (!targeParentComponent.HasParent)
|
||||
return false;
|
||||
|
||||
Entity currentParent = target.GetComponent<ParentComponent>().Parent;
|
||||
while (currentParent != source)
|
||||
void FileSystemUI::DrawFiletree()
|
||||
{
|
||||
if (currentParent.GetComponent<ParentComponent>().HasParent)
|
||||
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
|
||||
else
|
||||
return false;
|
||||
|
||||
if (currentParent == source)
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileSystemUI::DrawFile(Ref<File> file)
|
||||
{
|
||||
ImGui::PushFont(EditorInterface::bigIconFont);
|
||||
if (file->Type == ".png" || file->Type == ".jpg")
|
||||
{
|
||||
Ref<Texture> texture = TextureManager::Get()->GetTexture(file->fullPath);
|
||||
ImGui::ImageButton((void*)texture->GetID(), ImVec2(100, 100), ImVec2(0, 1), ImVec2(1, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* icon = ICON_FA_FILE;
|
||||
if (file->Type == ".shader")
|
||||
icon = ICON_FA_FILE_CODE;
|
||||
if (file->Type == ".map")
|
||||
icon = ICON_FA_BROOM;
|
||||
if (file->Type == ".ogg" || file->Type == ".mp3" || file->Type == ".wav" || file->Type == ".flac")
|
||||
icon = ICON_FA_FILE_AUDIO;
|
||||
if (file->Type == ".wren")
|
||||
icon = ICON_FA_FILE_CODE;
|
||||
if (file->Type == ".md3" || file->Type == ".obj")
|
||||
icon = ICON_FA_FILE_IMAGE;
|
||||
|
||||
std::string fullName = icon + std::string("##") + file->fullPath;
|
||||
if (ImGui::Button(fullName.c_str(), ImVec2(100, 100)))
|
||||
void FileSystemUI::EditorInterfaceDrawFiletree(Ref<Directory> dir)
|
||||
{
|
||||
for (auto d : dir->Directories)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (ImGui::BeginDragDropSource())
|
||||
{
|
||||
char pathBuffer[256];
|
||||
std::strncpy(pathBuffer, file->fullPath.c_str(), sizeof(pathBuffer));
|
||||
std::string dragType;
|
||||
if (file->Type == ".wren")
|
||||
dragType = "_Script";
|
||||
else if (file->Type == ".map")
|
||||
dragType = "_Map";
|
||||
else if (file->Type == ".obj" || file->Type == ".mdl" || file->Type == ".gltf" || file->Type == ".md3" || file->Type == "fbx")
|
||||
dragType = "_Model";
|
||||
|
||||
ImGui::SetDragDropPayload(dragType.c_str(), (void*)(pathBuffer), sizeof(pathBuffer));
|
||||
ImGui::Text(file->name.c_str());
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
}
|
||||
ImGui::Text(file->name.c_str());
|
||||
ImGui::PopFont();
|
||||
|
||||
}
|
||||
|
||||
bool Splitter(bool split_vertically, float thickness, float* size1, float* size2, float min_size1, float min_size2, float splitter_long_axis_size = -1.0f)
|
||||
{
|
||||
using namespace ImGui;
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImGuiID id = window->GetID("##Splitter");
|
||||
ImRect bb;
|
||||
bb.Min = window->DC.CursorPos + (split_vertically ? ImVec2(*size1, 0.0f) : ImVec2(0.0f, *size1));
|
||||
bb.Max = bb.Min + CalcItemSize(split_vertically ? ImVec2(thickness, splitter_long_axis_size) : ImVec2(splitter_long_axis_size, thickness), 0.0f, 0.0f);
|
||||
return SplitterBehavior(bb, id, split_vertically ? ImGuiAxis_X : ImGuiAxis_Y, size1, size2, min_size1, min_size2, 0.0f);
|
||||
}
|
||||
float h = 200;
|
||||
static float sz1 = 300;
|
||||
static float sz2 = 300;
|
||||
void FileSystemUI::DrawDirectoryExplorer()
|
||||
{
|
||||
if (ImGui::Begin("File browser"))
|
||||
{
|
||||
Ref<Directory> rootDirectory = FileSystem::GetFileTree();
|
||||
if (!rootDirectory)
|
||||
return;
|
||||
|
||||
ImVec2 avail = ImGui::GetContentRegionAvail();
|
||||
Splitter(true, 4.0f, &sz1, &sz2, 100, 8, avail.y);
|
||||
|
||||
if (ImGui::BeginChild("Tree browser", ImVec2(sz1, avail.y)))
|
||||
{
|
||||
if (ImGui::BeginPopupContextItem("item context menu"))
|
||||
{
|
||||
if (ImGui::Selectable("Set to zero"));
|
||||
if (ImGui::Selectable("Set to PI"));
|
||||
ImGui::SetNextItemWidth(-1);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanAvailWidth;
|
||||
|
||||
bool is_selected = m_CurrentDirectory == FileSystem::RootDirectory;
|
||||
bool is_selected = m_CurrentDirectory == d;
|
||||
if (is_selected)
|
||||
base_flags |= ImGuiTreeNodeFlags_Selected | ImGuiTreeNodeFlags_DefaultOpen;
|
||||
std::string icon = ICON_FA_FOLDER;
|
||||
base_flags |= ImGuiTreeNodeFlags_Selected;
|
||||
|
||||
bool open = ImGui::TreeNodeEx((icon + " " + rootDirectory->name).c_str(), base_flags);
|
||||
if (ImGui::IsItemClicked())
|
||||
if (d->Directories.size() == 0)
|
||||
{
|
||||
m_CurrentDirectory = FileSystem::RootDirectory;
|
||||
base_flags = ImGuiTreeNodeFlags_Leaf;
|
||||
}
|
||||
std::string icon = ICON_FA_FOLDER;
|
||||
if (is_selected)
|
||||
icon = ICON_FA_FOLDER_OPEN;
|
||||
bool open = ImGui::TreeNodeEx((icon + " " + d->name).c_str(), base_flags);
|
||||
|
||||
if (ImGui::IsItemClicked())
|
||||
m_CurrentDirectory = d;
|
||||
if (open)
|
||||
{
|
||||
EditorInterfaceDrawFiletree(rootDirectory);
|
||||
if (d->Directories.size() > 0)
|
||||
EditorInterfaceDrawFiletree(d);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
}
|
||||
ImGui::EndChild();
|
||||
ImGui::SameLine();
|
||||
|
||||
avail = ImGui::GetContentRegionAvail();
|
||||
|
||||
std::vector<Ref<Directory>> paths = std::vector<Ref<Directory>>();
|
||||
|
||||
Ref<Directory> currentParent = m_CurrentDirectory;
|
||||
paths.push_back(m_CurrentDirectory);
|
||||
while (currentParent != nullptr) {
|
||||
paths.push_back(currentParent);
|
||||
currentParent = currentParent->Parent;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
avail = ImGui::GetContentRegionAvail();
|
||||
if (ImGui::BeginChild("Wrapper", avail))
|
||||
|
||||
void FileSystemUI::DrawDirectory(Ref<Directory> directory)
|
||||
{
|
||||
ImGui::PushFont(EditorInterface::bigIconFont);
|
||||
std::string id = ICON_FA_FOLDER + std::string("##") + directory->name;
|
||||
if (ImGui::Button(id.c_str(), ImVec2(100, 100)))
|
||||
m_CurrentDirectory = directory;
|
||||
if (ImGui::BeginPopupContextWindow())
|
||||
{
|
||||
avail.y = 30;
|
||||
if (ImGui::BeginChild("ariane", avail))
|
||||
if (ImGui::MenuItem("Htest"));
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::Text(directory->name.c_str());
|
||||
ImGui::PopFont();
|
||||
}
|
||||
|
||||
bool FileSystemUI::EntityContainsItself(Entity source, Entity target)
|
||||
{
|
||||
ParentComponent& targeParentComponent = target.GetComponent<ParentComponent>();
|
||||
if (!targeParentComponent.HasParent)
|
||||
return false;
|
||||
|
||||
Entity currentParent = target.GetComponent<ParentComponent>().Parent;
|
||||
while (currentParent != source)
|
||||
{
|
||||
if (currentParent.GetComponent<ParentComponent>().HasParent)
|
||||
currentParent = currentParent.GetComponent<ParentComponent>().Parent;
|
||||
else
|
||||
return false;
|
||||
|
||||
if (currentParent == source)
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileSystemUI::DrawFile(Ref<File> file)
|
||||
{
|
||||
ImGui::PushFont(EditorInterface::bigIconFont);
|
||||
if (file->Type == ".png" || file->Type == ".jpg")
|
||||
{
|
||||
Ref<Texture> texture = TextureManager::Get()->GetTexture(file->fullPath);
|
||||
ImGui::ImageButton((void*)texture->GetID(), ImVec2(100, 100), ImVec2(0, 1), ImVec2(1, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* icon = ICON_FA_FILE;
|
||||
if (file->Type == ".shader")
|
||||
icon = ICON_FA_FILE_CODE;
|
||||
if (file->Type == ".map")
|
||||
icon = ICON_FA_BROOM;
|
||||
if (file->Type == ".ogg" || file->Type == ".mp3" || file->Type == ".wav" || file->Type == ".flac")
|
||||
icon = ICON_FA_FILE_AUDIO;
|
||||
if (file->Type == ".wren")
|
||||
icon = ICON_FA_FILE_CODE;
|
||||
if (file->Type == ".md3" || file->Type == ".obj")
|
||||
icon = ICON_FA_FILE_IMAGE;
|
||||
|
||||
std::string fullName = icon + std::string("##") + file->fullPath;
|
||||
if (ImGui::Button(fullName.c_str(), ImVec2(100, 100)))
|
||||
{
|
||||
if (ImGui::Button("Refresh"))
|
||||
FileSystem::Scan();
|
||||
ImGui::SameLine();
|
||||
for (int i = paths.size() - 1; i > 0; i--) {
|
||||
if (i != paths.size())
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(paths[i]->name.c_str())) {
|
||||
m_CurrentDirectory = paths[i];
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("/");
|
||||
|
||||
}
|
||||
|
||||
if (ImGui::BeginDragDropSource())
|
||||
{
|
||||
char pathBuffer[256];
|
||||
std::strncpy(pathBuffer, file->fullPath.c_str(), sizeof(pathBuffer));
|
||||
std::string dragType;
|
||||
if (file->Type == ".wren")
|
||||
dragType = "_Script";
|
||||
else if (file->Type == ".map")
|
||||
dragType = "_Map";
|
||||
else if (file->Type == ".obj" || file->Type == ".mdl" || file->Type == ".gltf" || file->Type == ".md3" || file->Type == "fbx")
|
||||
dragType = "_Model";
|
||||
|
||||
ImGui::SetDragDropPayload(dragType.c_str(), (void*)(pathBuffer), sizeof(pathBuffer));
|
||||
ImGui::Text(file->name.c_str());
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
}
|
||||
ImGui::Text(file->name.c_str());
|
||||
ImGui::PopFont();
|
||||
|
||||
}
|
||||
|
||||
bool Splitter(bool split_vertically, float thickness, float* size1, float* size2, float min_size1, float min_size2, float splitter_long_axis_size = -1.0f)
|
||||
{
|
||||
using namespace ImGui;
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImGuiID id = window->GetID("##Splitter");
|
||||
ImRect bb;
|
||||
bb.Min = window->DC.CursorPos + (split_vertically ? ImVec2(*size1, 0.0f) : ImVec2(0.0f, *size1));
|
||||
bb.Max = bb.Min + CalcItemSize(split_vertically ? ImVec2(thickness, splitter_long_axis_size) : ImVec2(splitter_long_axis_size, thickness), 0.0f, 0.0f);
|
||||
return SplitterBehavior(bb, id, split_vertically ? ImGuiAxis_X : ImGuiAxis_Y, size1, size2, min_size1, min_size2, 0.0f);
|
||||
}
|
||||
float h = 200;
|
||||
static float sz1 = 300;
|
||||
static float sz2 = 300;
|
||||
void FileSystemUI::DrawDirectoryExplorer()
|
||||
{
|
||||
if (ImGui::Begin("File browser"))
|
||||
{
|
||||
Ref<Directory> rootDirectory = FileSystem::GetFileTree();
|
||||
if (!rootDirectory)
|
||||
return;
|
||||
|
||||
ImVec2 avail = ImGui::GetContentRegionAvail();
|
||||
Splitter(true, 4.0f, &sz1, &sz2, 100, 8, avail.y);
|
||||
|
||||
if (ImGui::BeginChild("Tree browser", ImVec2(sz1, avail.y)))
|
||||
{
|
||||
if (ImGui::BeginPopupContextItem("item context menu"))
|
||||
{
|
||||
if (ImGui::Selectable("Set to zero"));
|
||||
if (ImGui::Selectable("Set to PI"));
|
||||
ImGui::SetNextItemWidth(-1);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanAvailWidth;
|
||||
|
||||
bool is_selected = m_CurrentDirectory == FileSystem::RootDirectory;
|
||||
if (is_selected)
|
||||
base_flags |= ImGuiTreeNodeFlags_Selected | ImGuiTreeNodeFlags_DefaultOpen;
|
||||
std::string icon = ICON_FA_FOLDER;
|
||||
|
||||
bool open = ImGui::TreeNodeEx((icon + " " + rootDirectory->name).c_str(), base_flags);
|
||||
if (ImGui::IsItemClicked())
|
||||
{
|
||||
m_CurrentDirectory = FileSystem::RootDirectory;
|
||||
}
|
||||
if (open)
|
||||
{
|
||||
EditorInterfaceDrawFiletree(rootDirectory);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
ImGui::SameLine();
|
||||
|
||||
avail = ImGui::GetContentRegionAvail();
|
||||
|
||||
if (ImGui::BeginChild("Content", avail))
|
||||
std::vector<Ref<Directory>> paths = std::vector<Ref<Directory>>();
|
||||
|
||||
Ref<Directory> currentParent = m_CurrentDirectory;
|
||||
paths.push_back(m_CurrentDirectory);
|
||||
while (currentParent != nullptr) {
|
||||
paths.push_back(currentParent);
|
||||
currentParent = currentParent->Parent;
|
||||
}
|
||||
|
||||
|
||||
avail = ImGui::GetContentRegionAvail();
|
||||
if (ImGui::BeginChild("Wrapper", avail))
|
||||
{
|
||||
// Wrapping.
|
||||
int width = ImGui::GetWindowWidth() * 0.8f;
|
||||
ImVec2 buttonSize = ImVec2(80, 80);
|
||||
int amount = (width / 100); // -2 because button overflow width + ... button.
|
||||
int i = 1; // current amount of item per row.
|
||||
if (ImGui::BeginTable("ssss", amount))
|
||||
avail.y = 30;
|
||||
if (ImGui::BeginChild("ariane", avail))
|
||||
{
|
||||
// Button to go up a level.
|
||||
if (m_CurrentDirectory != FileSystem::RootDirectory)
|
||||
{
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("..", ImVec2(100, 100)))
|
||||
m_CurrentDirectory = m_CurrentDirectory->Parent;
|
||||
ImGui::TableNextColumn();
|
||||
// Increment item per row tracker.
|
||||
i++;
|
||||
if (ImGui::Button("Refresh"))
|
||||
FileSystem::Scan();
|
||||
ImGui::SameLine();
|
||||
for (int i = paths.size() - 1; i > 0; i--) {
|
||||
if (i != paths.size())
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(paths[i]->name.c_str())) {
|
||||
m_CurrentDirectory = paths[i];
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("/");
|
||||
}
|
||||
|
||||
// Exit if no current directory.
|
||||
if (!m_CurrentDirectory) {
|
||||
ImGui::EndTable();
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_CurrentDirectory && m_CurrentDirectory->Directories.size() > 0)
|
||||
{
|
||||
for (auto d : m_CurrentDirectory->Directories)
|
||||
{
|
||||
DrawDirectory(d);
|
||||
if (i - 1 % amount != 0)
|
||||
ImGui::TableNextColumn();
|
||||
else
|
||||
ImGui::TableNextRow();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (m_CurrentDirectory && m_CurrentDirectory->Files.size() > 0)
|
||||
{
|
||||
for (auto f : m_CurrentDirectory->Files)
|
||||
{
|
||||
DrawFile(f);
|
||||
if (i - 1 % amount != 0)
|
||||
ImGui::TableNextColumn();
|
||||
else
|
||||
ImGui::TableNextRow();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (ImGui::BeginPopupContextItem("item context menu"))
|
||||
{
|
||||
float value;
|
||||
if (ImGui::Selectable("Set to zero")) value = 0.0f;
|
||||
if (ImGui::Selectable("Set to PI")) value = 3.1415f;
|
||||
ImGui::SetNextItemWidth(-1);
|
||||
ImGui::DragFloat("##Value", &value, 0.1f, 0.0f, 0.0f);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
if (ImGui::BeginPopupContextWindow())
|
||||
{
|
||||
if (ImGui::Button("New Wren script"))
|
||||
{
|
||||
ImGui::OpenPopup("CreateNewFile");
|
||||
|
||||
}
|
||||
if (ImGui::MenuItem("New interface script"))
|
||||
{
|
||||
}
|
||||
if (ImGui::MenuItem("New Scene"))
|
||||
{
|
||||
}
|
||||
if (ImGui::MenuItem("New folder"))
|
||||
{
|
||||
}
|
||||
if (ImGui::MenuItem("New interface"))
|
||||
{
|
||||
}
|
||||
if (ImGui::MenuItem("New stylesheet"))
|
||||
{
|
||||
}
|
||||
if (ImGui::BeginPopup("CreateNewFile"))
|
||||
{
|
||||
static char name[32] = "Label1";
|
||||
char buf[64];
|
||||
sprintf(buf, "Button: %s###Button", name); // ### operator override ID ignoring the preceding label
|
||||
|
||||
ImGui::Text("Edit name:");
|
||||
ImGui::InputText("##edit", name, IM_ARRAYSIZE(name));
|
||||
if (ImGui::Button("Close"))
|
||||
ImGui::CloseCurrentPopup();
|
||||
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Enter)))
|
||||
ImGui::CloseCurrentPopup();
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
|
||||
ImGui::EndTable();
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
|
||||
avail = ImGui::GetContentRegionAvail();
|
||||
|
||||
if (ImGui::BeginChild("Content", avail))
|
||||
{
|
||||
// Wrapping.
|
||||
int width = ImGui::GetWindowWidth() * 0.8f;
|
||||
ImVec2 buttonSize = ImVec2(80, 80);
|
||||
int amount = (width / 100); // -2 because button overflow width + ... button.
|
||||
int i = 1; // current amount of item per row.
|
||||
if (ImGui::BeginTable("ssss", amount))
|
||||
{
|
||||
// Button to go up a level.
|
||||
if (m_CurrentDirectory != FileSystem::RootDirectory)
|
||||
{
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("..", ImVec2(100, 100)))
|
||||
m_CurrentDirectory = m_CurrentDirectory->Parent;
|
||||
ImGui::TableNextColumn();
|
||||
// Increment item per row tracker.
|
||||
i++;
|
||||
}
|
||||
|
||||
// Exit if no current directory.
|
||||
if (!m_CurrentDirectory) {
|
||||
ImGui::EndTable();
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_CurrentDirectory && m_CurrentDirectory->Directories.size() > 0)
|
||||
{
|
||||
for (auto d : m_CurrentDirectory->Directories)
|
||||
{
|
||||
DrawDirectory(d);
|
||||
if (i - 1 % amount != 0)
|
||||
ImGui::TableNextColumn();
|
||||
else
|
||||
ImGui::TableNextRow();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (m_CurrentDirectory && m_CurrentDirectory->Files.size() > 0)
|
||||
{
|
||||
for (auto f : m_CurrentDirectory->Files)
|
||||
{
|
||||
DrawFile(f);
|
||||
if (i - 1 % amount != 0)
|
||||
ImGui::TableNextColumn();
|
||||
else
|
||||
ImGui::TableNextRow();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (ImGui::BeginPopupContextItem("item context menu"))
|
||||
{
|
||||
float value;
|
||||
if (ImGui::Selectable("Set to zero")) value = 0.0f;
|
||||
if (ImGui::Selectable("Set to PI")) value = 3.1415f;
|
||||
ImGui::SetNextItemWidth(-1);
|
||||
ImGui::DragFloat("##Value", &value, 0.1f, 0.0f, 0.0f);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
if (ImGui::BeginPopupContextWindow())
|
||||
{
|
||||
if (ImGui::Button("New Wren script"))
|
||||
{
|
||||
ImGui::OpenPopup("CreateNewFile");
|
||||
|
||||
}
|
||||
if (ImGui::MenuItem("New interface script"))
|
||||
{
|
||||
}
|
||||
if (ImGui::MenuItem("New Scene"))
|
||||
{
|
||||
}
|
||||
if (ImGui::MenuItem("New folder"))
|
||||
{
|
||||
}
|
||||
if (ImGui::MenuItem("New interface"))
|
||||
{
|
||||
}
|
||||
if (ImGui::MenuItem("New stylesheet"))
|
||||
{
|
||||
}
|
||||
if (ImGui::BeginPopup("CreateNewFile"))
|
||||
{
|
||||
static char name[32] = "Label1";
|
||||
char buf[64];
|
||||
sprintf(buf, "Button: %s###Button", name); // ### operator override ID ignoring the preceding label
|
||||
|
||||
ImGui::Text("Edit name:");
|
||||
ImGui::InputText("##edit", name, IM_ARRAYSIZE(name));
|
||||
if (ImGui::Button("Close"))
|
||||
ImGui::CloseCurrentPopup();
|
||||
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Enter)))
|
||||
ImGui::CloseCurrentPopup();
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <src/Core/FileSystem.h>
|
||||
|
||||
#include <src/Scene/Entities/Entity.h>
|
||||
class FileSystemUI
|
||||
{
|
||||
private:
|
||||
|
||||
|
||||
public:
|
||||
Ref<Directory> m_CurrentDirectory;
|
||||
FileSystemUI() {
|
||||
m_CurrentDirectory = FileSystem::RootDirectory;
|
||||
}
|
||||
void Draw();
|
||||
void DrawDirectoryContent();
|
||||
void DrawFiletree();
|
||||
void EditorInterfaceDrawFiletree(Ref<Directory> dir);
|
||||
void DrawDirectory(Ref<Directory> directory);
|
||||
bool EntityContainsItself(Entity source, Entity target);
|
||||
void DrawFile(Ref<File> file);
|
||||
void DrawDirectoryExplorer();
|
||||
};
|
||||
namespace Nuake {
|
||||
class FileSystemUI
|
||||
{
|
||||
private:
|
||||
|
||||
|
||||
public:
|
||||
Ref<Directory> m_CurrentDirectory;
|
||||
FileSystemUI() {
|
||||
m_CurrentDirectory = FileSystem::RootDirectory;
|
||||
}
|
||||
void Draw();
|
||||
void DrawDirectoryContent();
|
||||
void DrawFiletree();
|
||||
void EditorInterfaceDrawFiletree(Ref<Directory> dir);
|
||||
void DrawDirectory(Ref<Directory> directory);
|
||||
bool EntityContainsItself(Entity source, Entity target);
|
||||
void DrawFile(Ref<File> file);
|
||||
void DrawDirectoryExplorer();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,11 +3,25 @@
|
||||
#include "Engine.h"
|
||||
#include "ImGuiTextHelper.h"
|
||||
|
||||
void ProjectInterface::DrawProjectSettings()
|
||||
{
|
||||
if (ImGui::Begin("Project settings"))
|
||||
{
|
||||
|
||||
namespace Nuake {
|
||||
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));
|
||||
@@ -15,242 +29,230 @@ void ProjectInterface::DrawProjectSettings()
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
FGDPointEntity newEntity;
|
||||
FGDPointEntity newEntity;
|
||||
|
||||
const char* items[] = { "String", "Integer", "Float", "Boolean"};
|
||||
void ProjectInterface::DrawEntitySettings()
|
||||
{
|
||||
if (!m_CurrentProject)
|
||||
return;
|
||||
|
||||
if (ImGui::Begin("Entity definitions"))
|
||||
const char* items[] = { "String", "Integer", "Float", "Boolean" };
|
||||
void ProjectInterface::DrawEntitySettings()
|
||||
{
|
||||
ImGui::Text("This is the entity definition used by trenchbroom. This files allows you to see your entities inside Trenchbroom");
|
||||
|
||||
ImGui::Text("Trenchbroom path:");
|
||||
ImGui::SameLine();
|
||||
ImGuiTextSTD("", m_CurrentProject->TrenchbroomPath);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Browse"))
|
||||
if (!m_CurrentProject)
|
||||
return;
|
||||
|
||||
if (ImGui::Begin("Entity definitions"))
|
||||
{
|
||||
std::string path = FileDialog::OpenFile("*.exe");
|
||||
if (path != "")
|
||||
{
|
||||
path += "/../";
|
||||
m_CurrentProject->TrenchbroomPath = path;
|
||||
}
|
||||
}
|
||||
ImGui::Text("This is the entity definition used by trenchbroom. This files allows you to see your entities inside Trenchbroom");
|
||||
|
||||
Ref<FGDFile> file = Engine::GetProject()->EntityDefinitionsFile;
|
||||
|
||||
auto flags = ImGuiWindowFlags_NoTitleBar;
|
||||
if (ImGui::BeginPopupModal("Create new point entity", NULL, flags))
|
||||
{
|
||||
ImGuiTextSTD("Name", newEntity.Name);
|
||||
ImGuiTextMultiline("Description", newEntity.Description);
|
||||
|
||||
if (ImGui::BeginTable("DictCreate", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable))
|
||||
{
|
||||
ImGui::TableSetupColumn("Name");
|
||||
ImGui::TableSetupColumn("Type");
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
int idx = 0;
|
||||
for (auto& p : newEntity.Properties)
|
||||
{
|
||||
ImGuiTextSTD("Name", p.name);
|
||||
ImGui::TableNextColumn();
|
||||
std::string current_item = NULL;
|
||||
if(ImGui::BeginCombo(("TypeSelection" + std::to_string(idx)).c_str(), current_item.c_str()))
|
||||
{
|
||||
for (int n = 0; n < IM_ARRAYSIZE(items); n++)
|
||||
{
|
||||
bool is_selected = (p.type == (ClassPropertyType)n); // You can store your selection however you want, outside or inside your objects
|
||||
if (ImGui::Selectable(items[n], is_selected))
|
||||
if (is_selected)
|
||||
{
|
||||
p.type = (ClassPropertyType)n;
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
idx++;
|
||||
ImGui::TableNextColumn();
|
||||
}
|
||||
if (ImGui::Button("Add new property"))
|
||||
{
|
||||
newEntity.Properties.push_back(ClassProperty());
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::Button("Create");
|
||||
ImGui::Text("Trenchbroom path:");
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Cancel"))
|
||||
ImGui::CloseCurrentPopup();
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
|
||||
if (ImGui::Button("Export"))
|
||||
{
|
||||
file->Export();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("Save"))
|
||||
{
|
||||
file->Save();
|
||||
}
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0, 100));
|
||||
if (ImGui::BeginTabBar("##Tabs", ImGuiTabBarFlags_None))
|
||||
{
|
||||
if (ImGui::BeginTabItem("Point entities"))
|
||||
ImGuiTextSTD("", m_CurrentProject->TrenchbroomPath);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Browse"))
|
||||
{
|
||||
ImVec2 avail = ImGui::GetContentRegionAvail();
|
||||
avail.y *= .8;
|
||||
std::string path = FileDialog::OpenFile("*.exe");
|
||||
if (path != "")
|
||||
{
|
||||
path += "/../";
|
||||
m_CurrentProject->TrenchbroomPath = path;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::BeginChild("table_child", avail, false);
|
||||
if (ImGui::BeginTable("nested1", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable))
|
||||
Ref<FGDFile> file = Engine::GetProject()->EntityDefinitionsFile;
|
||||
|
||||
auto flags = ImGuiWindowFlags_NoTitleBar;
|
||||
if (ImGui::BeginPopupModal("Create new point entity", NULL, flags))
|
||||
{
|
||||
ImGuiTextSTD("Name", newEntity.Name);
|
||||
ImGuiTextMultiline("Description", newEntity.Description);
|
||||
|
||||
if (ImGui::BeginTable("DictCreate", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable))
|
||||
{
|
||||
ImGui::TableSetupColumn("Name");
|
||||
ImGui::TableSetupColumn("Desciption");
|
||||
ImGui::TableSetupColumn("Settings");
|
||||
ImGui::TableSetupColumn("Prefab");
|
||||
ImGui::TableSetupColumn("Type");
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
for (auto& pE : file->PointEntities)
|
||||
int idx = 0;
|
||||
for (auto& p : newEntity.Properties)
|
||||
{
|
||||
ImGui::Text(pE.Name.c_str());
|
||||
ImGuiTextSTD("Name", p.name);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text(pE.Description.c_str());
|
||||
std::string current_item = NULL;
|
||||
if (ImGui::BeginCombo(("TypeSelection" + std::to_string(idx)).c_str(), current_item.c_str()))
|
||||
{
|
||||
for (int n = 0; n < IM_ARRAYSIZE(items); n++)
|
||||
{
|
||||
bool is_selected = (p.type == (ClassPropertyType)n); // You can store your selection however you want, outside or inside your objects
|
||||
if (ImGui::Selectable(items[n], is_selected))
|
||||
if (is_selected)
|
||||
{
|
||||
p.type = (ClassPropertyType)n;
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
idx++;
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Button("Edit");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text(pE.Prefab.c_str());
|
||||
ImGui::SameLine();
|
||||
ImGui::Button("Browse");
|
||||
}
|
||||
if (ImGui::Button("Add new property"))
|
||||
{
|
||||
newEntity.Properties.push_back(ClassProperty());
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
ImGui::EndTabItem();
|
||||
|
||||
ImGui::Button("Create");
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Cancel"))
|
||||
ImGui::CloseCurrentPopup();
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTabItem("Brush entities"))
|
||||
|
||||
if (ImGui::Button("Export"))
|
||||
{
|
||||
ImVec2 avail = ImGui::GetContentRegionAvail();
|
||||
avail.y *= .8;
|
||||
ImGui::BeginChild("table_child", avail, false);
|
||||
if (ImGui::BeginTable("nested1", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable))
|
||||
file->Export();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("Save"))
|
||||
{
|
||||
file->Save();
|
||||
}
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0, 100));
|
||||
if (ImGui::BeginTabBar("##Tabs", ImGuiTabBarFlags_None))
|
||||
{
|
||||
if (ImGui::BeginTabItem("Point entities"))
|
||||
{
|
||||
ImGui::TableSetupColumn("Name");
|
||||
ImGui::TableSetupColumn("Desciption");
|
||||
ImGui::TableSetupColumn("Settings");
|
||||
ImGui::TableSetupColumn("Script");
|
||||
ImGui::TableHeadersRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImVec2 avail = ImGui::GetContentRegionAvail();
|
||||
avail.y *= .8;
|
||||
|
||||
int i = 0;
|
||||
for (auto& pE : file->BrushEntities)
|
||||
ImGui::BeginChild("table_child", avail, false);
|
||||
if (ImGui::BeginTable("nested1", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable))
|
||||
{
|
||||
ImGuiTextSTD("##Name" + std::to_string(i), pE.Name);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TableSetupColumn("Name");
|
||||
ImGui::TableSetupColumn("Desciption");
|
||||
ImGui::TableSetupColumn("Settings");
|
||||
ImGui::TableSetupColumn("Prefab");
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
ImGuiTextSTD("Desc" + std::to_string(i), pE.Description);
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::Checkbox(std::string("Visible##" + std::to_string(i)).c_str(), &pE.Visible);
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox(std::string("Solid##" + std::to_string(i)).c_str(), &pE.Solid);
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox(std::string("Trigger##" + std::to_string(i)).c_str(), &pE.IsTrigger);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGuiTextSTD("Script##" + std::to_string(i), pE.Script);
|
||||
if (ImGui::BeginDragDropTarget())
|
||||
for (auto& pE : file->PointEntities)
|
||||
{
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Script"))
|
||||
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::EndChild();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTabItem("Brush entities"))
|
||||
{
|
||||
ImVec2 avail = ImGui::GetContentRegionAvail();
|
||||
avail.y *= .8;
|
||||
ImGui::BeginChild("table_child", avail, false);
|
||||
if (ImGui::BeginTable("nested1", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable))
|
||||
{
|
||||
ImGui::TableSetupColumn("Name");
|
||||
ImGui::TableSetupColumn("Desciption");
|
||||
ImGui::TableSetupColumn("Settings");
|
||||
ImGui::TableSetupColumn("Script");
|
||||
ImGui::TableHeadersRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
int i = 0;
|
||||
for (auto& pE : file->BrushEntities)
|
||||
{
|
||||
ImGuiTextSTD("##Name" + std::to_string(i), pE.Name);
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGuiTextSTD("Desc" + std::to_string(i), pE.Description);
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::Checkbox(std::string("Visible##" + std::to_string(i)).c_str(), &pE.Visible);
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox(std::string("Solid##" + std::to_string(i)).c_str(), &pE.Solid);
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox(std::string("Trigger##" + std::to_string(i)).c_str(), &pE.IsTrigger);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGuiTextSTD("Script##" + std::to_string(i), pE.Script);
|
||||
if (ImGui::BeginDragDropTarget())
|
||||
{
|
||||
char* file = (char*)payload->Data;
|
||||
std::string fullPath = std::string(file, 256);
|
||||
pE.Script = FileSystem::AbsoluteToRelative(fullPath);
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Script"))
|
||||
{
|
||||
char* file = (char*)payload->Data;
|
||||
std::string fullPath = std::string(file, 256);
|
||||
pE.Script = FileSystem::AbsoluteToRelative(fullPath);
|
||||
}
|
||||
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
ImGuiTextSTD("Class##" + std::to_string(i), pE.Class);
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::EndTable();
|
||||
|
||||
if (ImGui::BeginPopupModal("CreateBrush", NULL, flags))
|
||||
{
|
||||
ImGuiTextSTD("Name", newEntity.Name);
|
||||
ImGuiTextMultiline("Description", newEntity.Description);
|
||||
|
||||
bool isSolid = true;
|
||||
bool isTrigger = false;
|
||||
bool isVisible = true;
|
||||
ImGui::Checkbox("Is Solid", &isSolid);
|
||||
ImGui::Checkbox("Is Trigger", &isTrigger);
|
||||
ImGui::Checkbox("Is Visible", &isVisible);
|
||||
|
||||
if (ImGui::Button("Create"))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ImGui::EndDragDropTarget();
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("Cancel"))
|
||||
ImGui::CloseCurrentPopup();
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGuiTextSTD("Class##" + std::to_string(i), pE.Class);
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::EndTable();
|
||||
|
||||
if (ImGui::BeginPopupModal("CreateBrush", NULL, flags))
|
||||
{
|
||||
ImGuiTextSTD("Name", newEntity.Name);
|
||||
ImGuiTextMultiline("Description", newEntity.Description);
|
||||
|
||||
bool isSolid = true;
|
||||
bool isTrigger = false;
|
||||
bool isVisible = true;
|
||||
ImGui::Checkbox("Is Solid", &isSolid);
|
||||
ImGui::Checkbox("Is Trigger", &isTrigger);
|
||||
ImGui::Checkbox("Is Visible", &isVisible);
|
||||
|
||||
if (ImGui::Button("Create"))
|
||||
if (ImGui::Button("Add new"))
|
||||
{
|
||||
|
||||
file->BrushEntities.push_back(FGDBrushEntity("New brush"));
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("Cancel"))
|
||||
ImGui::CloseCurrentPopup();
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
if (ImGui::Button("Add new"))
|
||||
{
|
||||
file->BrushEntities.push_back(FGDBrushEntity("New brush"));
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
ImGui::EndTabItem();
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
ImGui::EndTabBar();
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::End();
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,17 +2,14 @@
|
||||
#include "src/Core/Core.h"
|
||||
#include "src/Resource/Project.h"
|
||||
|
||||
namespace Nuake {
|
||||
class ProjectInterface
|
||||
{
|
||||
public:
|
||||
Ref<Project> m_CurrentProject;
|
||||
|
||||
class ProjectInterface
|
||||
{
|
||||
public:
|
||||
Ref<Project> m_CurrentProject;
|
||||
|
||||
|
||||
void DrawProjectSettings();
|
||||
|
||||
void DrawCreatePointEntity();
|
||||
void DrawEntitySettings();
|
||||
|
||||
|
||||
};
|
||||
void DrawProjectSettings();
|
||||
void DrawCreatePointEntity();
|
||||
void DrawEntitySettings();
|
||||
};
|
||||
}
|
||||
|
||||
243
Nuake/Engine.cpp
243
Nuake/Engine.cpp
@@ -12,135 +12,138 @@
|
||||
#include <imgui/imgui_impl_glfw.h>
|
||||
#include <imgui/imgui_impl_opengl3.h>
|
||||
|
||||
Ref<Project> Engine::CurrentProject;
|
||||
Ref<Window> Engine::CurrentWindow;
|
||||
|
||||
float Engine::m_LastFrameTime = 0.0f;
|
||||
float Engine::m_FixedUpdateRate = 1.0 / 144.0f;
|
||||
float Engine::m_FixedUpdateDifference = 0.f;
|
||||
bool Engine::IsPlayMode = false;
|
||||
|
||||
void Engine::Init()
|
||||
namespace Nuake
|
||||
{
|
||||
Logger::Log("Engine initialization...");
|
||||
Ref<Project> Engine::CurrentProject;
|
||||
Ref<Window> Engine::CurrentWindow;
|
||||
|
||||
PhysicsManager::Get()->Init();
|
||||
Logger::Log("Physics initialized");
|
||||
float Engine::m_LastFrameTime = 0.0f;
|
||||
float Engine::m_FixedUpdateRate = 1.0 / 144.0f;
|
||||
float Engine::m_FixedUpdateDifference = 0.f;
|
||||
bool Engine::IsPlayMode = false;
|
||||
|
||||
// Creates the window
|
||||
CurrentWindow = Window::Get();
|
||||
Logger::Log("Window initialized");
|
||||
|
||||
Renderer2D::Init();
|
||||
Logger::Log("2D renderer initialized");
|
||||
|
||||
Logger::Log("Engine initialized succesfully!");
|
||||
}
|
||||
|
||||
void Engine::Tick()
|
||||
{
|
||||
// Dont update if no scene is loaded.
|
||||
if (!CurrentWindow->GetScene())
|
||||
return;
|
||||
|
||||
// Calculate delta time
|
||||
float time = (float)glfwGetTime();
|
||||
Timestep timestep = time - m_LastFrameTime;
|
||||
m_LastFrameTime = time;
|
||||
|
||||
// Play mode update all the entities, Editor does not.
|
||||
if (Engine::IsPlayMode)
|
||||
void Engine::Init()
|
||||
{
|
||||
CurrentWindow->Update(timestep);
|
||||
m_FixedUpdateDifference += timestep;
|
||||
Logger::Log("Engine initialization...");
|
||||
|
||||
// Fixed update
|
||||
if (m_FixedUpdateDifference >= m_FixedUpdateRate)
|
||||
PhysicsManager::Get()->Init();
|
||||
Logger::Log("Physics initialized");
|
||||
|
||||
// Creates the window
|
||||
CurrentWindow = Window::Get();
|
||||
Logger::Log("Window initialized");
|
||||
|
||||
Renderer2D::Init();
|
||||
Logger::Log("2D renderer initialized");
|
||||
|
||||
Logger::Log("Engine initialized succesfully!");
|
||||
}
|
||||
|
||||
void Engine::Tick()
|
||||
{
|
||||
// Dont update if no scene is loaded.
|
||||
if (!CurrentWindow->GetScene())
|
||||
return;
|
||||
|
||||
// Calculate delta time
|
||||
float time = (float)glfwGetTime();
|
||||
Timestep timestep = time - m_LastFrameTime;
|
||||
m_LastFrameTime = time;
|
||||
|
||||
// Play mode update all the entities, Editor does not.
|
||||
if (Engine::IsPlayMode)
|
||||
{
|
||||
CurrentWindow->FixedUpdate(m_FixedUpdateRate);
|
||||
m_FixedUpdateDifference = 0.f;
|
||||
CurrentWindow->Update(timestep);
|
||||
m_FixedUpdateDifference += timestep;
|
||||
|
||||
// Fixed update
|
||||
if (m_FixedUpdateDifference >= m_FixedUpdateRate)
|
||||
{
|
||||
CurrentWindow->FixedUpdate(m_FixedUpdateRate);
|
||||
m_FixedUpdateDifference = 0.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GetCurrentScene()->EditorUpdate(timestep);
|
||||
}
|
||||
|
||||
Input::Update();
|
||||
}
|
||||
|
||||
void Engine::EnterPlayMode()
|
||||
{
|
||||
// Dont trigger init if already in player mode.
|
||||
if (!IsPlayMode)
|
||||
if(GetCurrentScene()->OnInit())
|
||||
IsPlayMode = true;
|
||||
else
|
||||
GetCurrentScene()->OnExit();
|
||||
}
|
||||
{
|
||||
GetCurrentScene()->EditorUpdate(timestep);
|
||||
}
|
||||
|
||||
void Engine::ExitPlayMode()
|
||||
{
|
||||
// Dont trigger exit if already not in play mode.
|
||||
if (IsPlayMode) {
|
||||
GetCurrentScene()->OnExit();
|
||||
Input::ShowMouse();
|
||||
Input::Update();
|
||||
}
|
||||
|
||||
Input::ShowMouse();
|
||||
|
||||
IsPlayMode = false;
|
||||
void Engine::EnterPlayMode()
|
||||
{
|
||||
// Dont trigger init if already in player mode.
|
||||
if (!IsPlayMode)
|
||||
if (GetCurrentScene()->OnInit())
|
||||
IsPlayMode = true;
|
||||
else
|
||||
GetCurrentScene()->OnExit();
|
||||
}
|
||||
|
||||
void Engine::ExitPlayMode()
|
||||
{
|
||||
// Dont trigger exit if already not in play mode.
|
||||
if (IsPlayMode) {
|
||||
GetCurrentScene()->OnExit();
|
||||
Input::ShowMouse();
|
||||
}
|
||||
|
||||
Input::ShowMouse();
|
||||
|
||||
IsPlayMode = false;
|
||||
}
|
||||
|
||||
void Engine::Draw()
|
||||
{
|
||||
// Start imgui frame
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
// Draw scene
|
||||
Window::Get()->Draw();
|
||||
}
|
||||
|
||||
void Engine::EndDraw()
|
||||
{
|
||||
// Swap buffer and draw imgui
|
||||
Window::Get()->EndDraw();
|
||||
}
|
||||
|
||||
void Engine::Close()
|
||||
{
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
Ref<Scene> Engine::GetCurrentScene()
|
||||
{
|
||||
return CurrentWindow->GetScene();
|
||||
}
|
||||
|
||||
bool Engine::LoadScene(Ref<Scene> scene)
|
||||
{
|
||||
return CurrentWindow->SetScene(scene);
|
||||
}
|
||||
|
||||
Ref<Project> Engine::GetProject()
|
||||
{
|
||||
return CurrentProject;
|
||||
}
|
||||
|
||||
bool Engine::LoadProject(Ref<Project> project)
|
||||
{
|
||||
CurrentProject = project;
|
||||
|
||||
if (!Engine::LoadScene(CurrentProject->DefaultScene))
|
||||
return false;
|
||||
|
||||
FileSystem::SetRootDirectory(project->FullPath + "/../");
|
||||
return true;
|
||||
}
|
||||
|
||||
Ref<Window> Engine::GetCurrentWindow()
|
||||
{
|
||||
return CurrentWindow;
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::Draw()
|
||||
{
|
||||
// Start imgui frame
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
// Draw scene
|
||||
Window::Get()->Draw();
|
||||
}
|
||||
|
||||
void Engine::EndDraw()
|
||||
{
|
||||
// Swap buffer and draw imgui
|
||||
Window::Get()->EndDraw();
|
||||
}
|
||||
|
||||
void Engine::Close()
|
||||
{
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
Ref<Scene> Engine::GetCurrentScene()
|
||||
{
|
||||
return CurrentWindow->GetScene();
|
||||
}
|
||||
|
||||
bool Engine::LoadScene(Ref<Scene> scene)
|
||||
{
|
||||
return CurrentWindow->SetScene(scene);
|
||||
}
|
||||
|
||||
Ref<Project> Engine::GetProject()
|
||||
{
|
||||
return CurrentProject;
|
||||
}
|
||||
|
||||
bool Engine::LoadProject(Ref<Project> project)
|
||||
{
|
||||
CurrentProject = project;
|
||||
|
||||
if (!Engine::LoadScene(CurrentProject->DefaultScene))
|
||||
return false;
|
||||
|
||||
FileSystem::SetRootDirectory(project->FullPath + "/../");
|
||||
return true;
|
||||
}
|
||||
|
||||
Ref<Window> Engine::GetCurrentWindow()
|
||||
{
|
||||
return CurrentWindow;
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "src/Core/Core.h"
|
||||
#include "src/Window.h"
|
||||
#include "src/Scene/Scene.h"
|
||||
#include "src/Resource/Project.h"
|
||||
#include "src/Scripting/ScriptLoader.h"
|
||||
#include "src/Core/Logger.h"
|
||||
|
||||
/* TODOS:
|
||||
@@ -20,37 +18,40 @@
|
||||
*/
|
||||
|
||||
// Welcome to the Nuake source code. This is the entry point for the engine.
|
||||
namespace Nuake
|
||||
{
|
||||
class Engine {
|
||||
private:
|
||||
static Ref<Window> CurrentWindow;
|
||||
static Ref<Project> CurrentProject;
|
||||
static Ref<Scene> CurrentScene;
|
||||
|
||||
class Engine {
|
||||
private:
|
||||
static Ref<Window> CurrentWindow;
|
||||
static Ref<Project> CurrentProject;
|
||||
static Ref<Scene> CurrentScene;
|
||||
static float m_LastFrameTime;
|
||||
static float m_FixedUpdateRate;
|
||||
static float m_FixedUpdateDifference;
|
||||
public:
|
||||
static bool IsPlayMode; // True if currently playing the game.
|
||||
|
||||
static float m_LastFrameTime;
|
||||
static float m_FixedUpdateRate;
|
||||
static float m_FixedUpdateDifference;
|
||||
public:
|
||||
static bool IsPlayMode; // True if currently playing the game.
|
||||
static void Init(); // Initialize the engine.
|
||||
static void Tick(); // Updates everything, called everyframe.
|
||||
static void Close(); // Shutdown the engine.
|
||||
|
||||
static void Init(); // Initialize the engine.
|
||||
static void Tick(); // Updates everything, called everyframe.
|
||||
static void Close(); // Shutdown the engine.
|
||||
|
||||
static void EnterPlayMode(); // Start the game
|
||||
static void ExitPlayMode(); // Stops the game
|
||||
static void EnterPlayMode(); // Start the game
|
||||
static void ExitPlayMode(); // Stops the game
|
||||
|
||||
// Custom drawing should happen in between these two
|
||||
static void Draw(); // Start new frame
|
||||
static void EndDraw(); // Swap buffer
|
||||
// Custom drawing should happen in between these two
|
||||
static void Draw(); // Start new frame
|
||||
static void EndDraw(); // Swap buffer
|
||||
|
||||
static Ref<Window> GetCurrentWindow();
|
||||
static Ref<Window> GetCurrentWindow();
|
||||
|
||||
// Load a specific scene
|
||||
static bool LoadScene(Ref<Scene> scene);
|
||||
static Ref<Scene> GetCurrentScene();
|
||||
// Load a specific scene
|
||||
static bool LoadScene(Ref<Scene> scene);
|
||||
static Ref<Scene> GetCurrentScene();
|
||||
|
||||
// Loads a project and the default scene.
|
||||
static bool LoadProject(Ref<Project> project);
|
||||
static Ref<Project> GetProject();
|
||||
};
|
||||
}
|
||||
|
||||
// Loads a project and the default scene.
|
||||
static bool LoadProject(Ref<Project> project);
|
||||
static Ref<Project> GetProject();
|
||||
};
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
template<typename T>
|
||||
using Scope = std::unique_ptr<T>;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "FileSystem.h"
|
||||
#include <filesystem>
|
||||
|
||||
#include "../../Engine.h"
|
||||
#include "Engine.h"
|
||||
|
||||
#define GLFW_EXPOSE_NATIVE_WIN32
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
@@ -10,150 +10,154 @@
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
|
||||
std::string FileDialog::OpenFile(const char* filter)
|
||||
namespace Nuake
|
||||
{
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
OPENFILENAMEA ofn;
|
||||
CHAR szFile[260] = { 0 };
|
||||
ZeroMemory(&ofn, sizeof(OPENFILENAME));
|
||||
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||
ofn.hwndOwner = glfwGetWin32Window(Engine::GetCurrentWindow()->GetHandle());
|
||||
ofn.lpstrFile = szFile;
|
||||
ofn.nMaxFile = sizeof(szFile);
|
||||
ofn.lpstrFilter = filter;
|
||||
ofn.nFilterIndex = 1;
|
||||
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
|
||||
if (GetOpenFileNameA(&ofn) == TRUE)
|
||||
std::string FileDialog::OpenFile(const char* filter)
|
||||
{
|
||||
return ofn.lpstrFile;
|
||||
}
|
||||
return std::string();
|
||||
|
||||
}
|
||||
std::string FileDialog::SaveFile(const char* filter)
|
||||
{
|
||||
OPENFILENAMEA ofn;
|
||||
CHAR szFile[260] = { 0 };
|
||||
ZeroMemory(&ofn, sizeof(OPENFILENAME));
|
||||
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||
ofn.hwndOwner = glfwGetWin32Window(Engine::GetCurrentWindow()->GetHandle());
|
||||
ofn.lpstrFile = szFile;
|
||||
ofn.nMaxFile = sizeof(szFile);
|
||||
ofn.lpstrFilter = filter;
|
||||
ofn.nFilterIndex = 1;
|
||||
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
|
||||
if (GetSaveFileNameA(&ofn) == TRUE)
|
||||
{
|
||||
return ofn.lpstrFile;
|
||||
}
|
||||
return std::string();
|
||||
|
||||
}
|
||||
std::string FileSystem::Root = "";
|
||||
|
||||
Ref<Directory> FileSystem::RootDirectory;
|
||||
|
||||
void FileSystem::ScanDirectory(Ref<Directory> directory)
|
||||
{
|
||||
for (const auto& entry : std::filesystem::directory_iterator(directory->fullPath))
|
||||
{
|
||||
if (entry.is_directory())
|
||||
OPENFILENAMEA ofn;
|
||||
CHAR szFile[260] = { 0 };
|
||||
ZeroMemory(&ofn, sizeof(OPENFILENAME));
|
||||
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||
ofn.hwndOwner = glfwGetWin32Window(Engine::GetCurrentWindow()->GetHandle());
|
||||
ofn.lpstrFile = szFile;
|
||||
ofn.nMaxFile = sizeof(szFile);
|
||||
ofn.lpstrFilter = filter;
|
||||
ofn.nFilterIndex = 1;
|
||||
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
|
||||
if (GetOpenFileNameA(&ofn) == TRUE)
|
||||
{
|
||||
Ref<Directory> newDir = CreateRef<Directory>();
|
||||
newDir->fullPath = entry.path().string();
|
||||
newDir->name = entry.path().filename().string();
|
||||
|
||||
newDir->Parent = directory;
|
||||
ScanDirectory(newDir);
|
||||
|
||||
directory->Directories.push_back(newDir);
|
||||
return ofn.lpstrFile;
|
||||
}
|
||||
else if (entry.is_regular_file())
|
||||
return std::string();
|
||||
|
||||
}
|
||||
|
||||
std::string FileDialog::SaveFile(const char* filter)
|
||||
{
|
||||
OPENFILENAMEA ofn;
|
||||
CHAR szFile[260] = { 0 };
|
||||
ZeroMemory(&ofn, sizeof(OPENFILENAME));
|
||||
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||
ofn.hwndOwner = glfwGetWin32Window(Engine::GetCurrentWindow()->GetHandle());
|
||||
ofn.lpstrFile = szFile;
|
||||
ofn.nMaxFile = sizeof(szFile);
|
||||
ofn.lpstrFilter = filter;
|
||||
ofn.nFilterIndex = 1;
|
||||
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
|
||||
if (GetSaveFileNameA(&ofn) == TRUE)
|
||||
{
|
||||
Ref<File> newFile = CreateRef<File>();
|
||||
newFile->Type = entry.path().extension().string();
|
||||
newFile->name = entry.path().filename().string();
|
||||
newFile->Parent = directory;
|
||||
newFile->fullPath = entry.path().string();
|
||||
directory->Files.push_back(newFile);
|
||||
return ofn.lpstrFile;
|
||||
}
|
||||
return std::string();
|
||||
|
||||
}
|
||||
|
||||
std::string FileSystem::Root = "";
|
||||
|
||||
Ref<Directory> FileSystem::RootDirectory;
|
||||
|
||||
void FileSystem::ScanDirectory(Ref<Directory> directory)
|
||||
{
|
||||
for (const auto& entry : std::filesystem::directory_iterator(directory->fullPath))
|
||||
{
|
||||
if (entry.is_directory())
|
||||
{
|
||||
Ref<Directory> newDir = CreateRef<Directory>();
|
||||
newDir->fullPath = entry.path().string();
|
||||
newDir->name = entry.path().filename().string();
|
||||
|
||||
newDir->Parent = directory;
|
||||
ScanDirectory(newDir);
|
||||
|
||||
directory->Directories.push_back(newDir);
|
||||
}
|
||||
else if (entry.is_regular_file())
|
||||
{
|
||||
Ref<File> newFile = CreateRef<File>();
|
||||
newFile->Type = entry.path().extension().string();
|
||||
newFile->name = entry.path().filename().string();
|
||||
newFile->Parent = directory;
|
||||
newFile->fullPath = entry.path().string();
|
||||
directory->Files.push_back(newFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool FileSystem::DirectoryExists(const std::string path)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void FileSystem::SetRootDirectory(const std::string path)
|
||||
{
|
||||
Root = path;
|
||||
Scan();
|
||||
}
|
||||
|
||||
void FileSystem::Scan()
|
||||
{
|
||||
RootDirectory = CreateRef<Directory>();
|
||||
RootDirectory->Files = std::vector<Ref<File>>();
|
||||
RootDirectory->Directories = std::vector<Ref<Directory>>();
|
||||
RootDirectory->name = FileSystem::AbsoluteToRelative(Root);
|
||||
RootDirectory->fullPath = Root;
|
||||
ScanDirectory(RootDirectory);
|
||||
}
|
||||
|
||||
std::string FileSystem::AbsoluteToRelative(const std::string& path)
|
||||
{
|
||||
const fs::path rootPath(Root);
|
||||
const fs::path absolutePath(path);
|
||||
return fs::relative(absolutePath, rootPath).generic_string();
|
||||
}
|
||||
|
||||
std::string FileSystem::ReadFile(const std::string& path, bool absolute)
|
||||
{
|
||||
std::string finalPath = path;
|
||||
if (!absolute)
|
||||
finalPath = Root + path;
|
||||
|
||||
std::ifstream MyReadFile(finalPath);
|
||||
std::string fileContent = "";
|
||||
std::string allFile = "";
|
||||
|
||||
// Use a while loop together with the getline() function to read the file line by line
|
||||
while (getline(MyReadFile, fileContent))
|
||||
bool FileSystem::DirectoryExists(const std::string path)
|
||||
{
|
||||
allFile.append(fileContent + "\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
void FileSystem::SetRootDirectory(const std::string path)
|
||||
{
|
||||
Root = path;
|
||||
Scan();
|
||||
}
|
||||
|
||||
void FileSystem::Scan()
|
||||
{
|
||||
RootDirectory = CreateRef<Directory>();
|
||||
RootDirectory->Files = std::vector<Ref<File>>();
|
||||
RootDirectory->Directories = std::vector<Ref<Directory>>();
|
||||
RootDirectory->name = FileSystem::AbsoluteToRelative(Root);
|
||||
RootDirectory->fullPath = Root;
|
||||
ScanDirectory(RootDirectory);
|
||||
}
|
||||
|
||||
std::string FileSystem::AbsoluteToRelative(const std::string& path)
|
||||
{
|
||||
const fs::path rootPath(Root);
|
||||
const fs::path absolutePath(path);
|
||||
return fs::relative(absolutePath, rootPath).generic_string();
|
||||
}
|
||||
|
||||
std::string FileSystem::ReadFile(const std::string& path, bool absolute)
|
||||
{
|
||||
std::string finalPath = path;
|
||||
if (!absolute)
|
||||
finalPath = Root + path;
|
||||
|
||||
std::ifstream MyReadFile(finalPath);
|
||||
std::string fileContent = "";
|
||||
std::string allFile = "";
|
||||
|
||||
// Use a while loop together with the getline() function to read the file line by line
|
||||
while (getline(MyReadFile, fileContent))
|
||||
{
|
||||
allFile.append(fileContent + "\n");
|
||||
}
|
||||
|
||||
// Close the file
|
||||
MyReadFile.close();
|
||||
return allFile;
|
||||
}
|
||||
|
||||
std::ofstream FileSystem::fileWriter;
|
||||
bool FileSystem::BeginWriteFile(const std::string path)
|
||||
{
|
||||
fileWriter = std::ofstream();
|
||||
fileWriter.open(path);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FileSystem::WriteLine(const std::string line)
|
||||
{
|
||||
fileWriter << line.c_str();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileSystem::EndWriteFile()
|
||||
{
|
||||
fileWriter.close();
|
||||
}
|
||||
|
||||
Ref<Directory> FileSystem::GetFileTree()
|
||||
{
|
||||
return RootDirectory;
|
||||
}
|
||||
|
||||
// Close the file
|
||||
MyReadFile.close();
|
||||
return allFile;
|
||||
}
|
||||
|
||||
std::ofstream FileSystem::fileWriter;
|
||||
bool FileSystem::BeginWriteFile(const std::string path)
|
||||
{
|
||||
fileWriter = std::ofstream();
|
||||
fileWriter.open(path);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FileSystem::WriteLine(const std::string line)
|
||||
{
|
||||
fileWriter << line.c_str();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileSystem::EndWriteFile()
|
||||
{
|
||||
fileWriter.close();
|
||||
}
|
||||
|
||||
Ref<Directory> FileSystem::GetFileTree()
|
||||
{
|
||||
return RootDirectory;
|
||||
}
|
||||
|
||||
@@ -4,54 +4,58 @@
|
||||
#include "Core.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
class FileDialog
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
public:
|
||||
static std::string OpenFile(const char* filter);
|
||||
static std::string SaveFile(const char* filter);
|
||||
};
|
||||
class FileDialog
|
||||
{
|
||||
public:
|
||||
static std::string OpenFile(const char* filter);
|
||||
static std::string SaveFile(const char* filter);
|
||||
};
|
||||
|
||||
struct Directory;
|
||||
struct File
|
||||
{
|
||||
std::string Type;
|
||||
std::string name;
|
||||
struct Directory;
|
||||
struct File
|
||||
{
|
||||
std::string Type;
|
||||
std::string name;
|
||||
|
||||
std::string fullPath;
|
||||
Ref<Directory> Parent;
|
||||
};
|
||||
std::string fullPath;
|
||||
Ref<Directory> Parent;
|
||||
};
|
||||
|
||||
struct Directory
|
||||
{
|
||||
std::string name;
|
||||
std::string fullPath;
|
||||
Ref<Directory> Parent;
|
||||
std::vector<Ref<Directory>> Directories;
|
||||
std::vector<Ref<File>> Files;
|
||||
};
|
||||
struct Directory
|
||||
{
|
||||
std::string name;
|
||||
std::string fullPath;
|
||||
Ref<Directory> Parent;
|
||||
std::vector<Ref<Directory>> Directories;
|
||||
std::vector<Ref<File>> Files;
|
||||
};
|
||||
|
||||
class FileSystem
|
||||
{
|
||||
public:
|
||||
static std::string Root;
|
||||
class FileSystem
|
||||
{
|
||||
public:
|
||||
static std::string Root;
|
||||
|
||||
static Ref<Directory> RootDirectory;
|
||||
static Ref<Directory> RootDirectory;
|
||||
|
||||
static void SetRootDirectory(const std::string path);
|
||||
static void SetRootDirectory(const std::string path);
|
||||
|
||||
static void Scan();
|
||||
static std::string AbsoluteToRelative(const std::string& path);
|
||||
static Ref<Directory> GetFileTree();
|
||||
static void ScanDirectory(Ref<Directory> directory);
|
||||
static void GetDirectories();
|
||||
static void Scan();
|
||||
static std::string AbsoluteToRelative(const std::string& path);
|
||||
static Ref<Directory> GetFileTree();
|
||||
static void ScanDirectory(Ref<Directory> directory);
|
||||
static void GetDirectories();
|
||||
|
||||
static bool DirectoryExists(const std::string path);
|
||||
static bool FileExists(const std::string path);
|
||||
static bool DirectoryExists(const std::string path);
|
||||
static bool FileExists(const std::string path);
|
||||
|
||||
static std::string ReadFile(const std::string& path, bool absolute = false);
|
||||
static std::string ReadFile(const std::string& path, bool absolute = false);
|
||||
|
||||
static std::ofstream fileWriter;
|
||||
static bool BeginWriteFile(const std::string path);
|
||||
static bool WriteLine(const std::string line);
|
||||
static void EndWriteFile();
|
||||
};
|
||||
static std::ofstream fileWriter;
|
||||
static bool BeginWriteFile(const std::string path);
|
||||
static bool WriteLine(const std::string line);
|
||||
static void EndWriteFile();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,166 +2,170 @@
|
||||
#include "../Window.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
Input* Input::s_Instance;
|
||||
std::map<int, bool> Input::m_Keys = std::map<int, bool>();
|
||||
bool Input::m_MouseButtons[5] = { false, false, false, false, false };
|
||||
namespace Nuake
|
||||
{
|
||||
Input* Input::s_Instance;
|
||||
std::map<int, bool> Input::m_Keys = std::map<int, bool>();
|
||||
bool Input::m_MouseButtons[5] = { false, false, false, false, false };
|
||||
|
||||
#pragma region Keys
|
||||
// Only true if the key is currently being pressed
|
||||
bool Input::IsKeyDown(int keycode)
|
||||
{
|
||||
auto window = Window::Get()->GetHandle();
|
||||
int state = glfwGetKey(window, keycode);
|
||||
bool result = state == GLFW_PRESS;
|
||||
|
||||
m_Keys[keycode] = state;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Only true if the key is pressed for the first frame. no repeat.
|
||||
bool Input::IsKeyPressed(int keycode)
|
||||
{
|
||||
auto window = Window::Get()->GetHandle();
|
||||
int state = glfwGetKey(window, keycode);
|
||||
bool result = state == GLFW_PRESS;
|
||||
|
||||
// First time pressed?
|
||||
if (m_Keys.find(keycode) == m_Keys.end() || m_Keys[keycode] == true)
|
||||
// Only true if the key is currently being pressed
|
||||
bool Input::IsKeyDown(int keycode)
|
||||
{
|
||||
if (result)
|
||||
m_Keys[keycode] = true;
|
||||
auto window = Window::Get()->GetHandle();
|
||||
int state = glfwGetKey(window, keycode);
|
||||
bool result = state == GLFW_PRESS;
|
||||
|
||||
m_Keys[keycode] = state;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Input::IsKeyReleased(int keycode)
|
||||
{
|
||||
auto window = Window::Get()->GetHandle();
|
||||
int state = glfwGetKey(window, keycode);
|
||||
bool result = state == GLFW_RELEASE;
|
||||
|
||||
// First time pressed?
|
||||
if (m_Keys.find(keycode) == m_Keys.end())
|
||||
return result;
|
||||
|
||||
if (result && m_Keys[keycode] == true)
|
||||
// Only true if the key is pressed for the first frame. no repeat.
|
||||
bool Input::IsKeyPressed(int keycode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
auto window = Window::Get()->GetHandle();
|
||||
int state = glfwGetKey(window, keycode);
|
||||
bool result = state == GLFW_PRESS;
|
||||
|
||||
return false;
|
||||
}
|
||||
// First time pressed?
|
||||
if (m_Keys.find(keycode) == m_Keys.end() || m_Keys[keycode] == true)
|
||||
{
|
||||
if (result)
|
||||
m_Keys[keycode] = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Input::IsKeyReleased(int keycode)
|
||||
{
|
||||
auto window = Window::Get()->GetHandle();
|
||||
int state = glfwGetKey(window, keycode);
|
||||
bool result = state == GLFW_RELEASE;
|
||||
|
||||
// First time pressed?
|
||||
if (m_Keys.find(keycode) == m_Keys.end())
|
||||
return result;
|
||||
|
||||
if (result && m_Keys[keycode] == true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Mouse
|
||||
|
||||
// Visibility
|
||||
void Input::HideMouse() {
|
||||
auto window = Window::Get()->GetHandle();
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
}
|
||||
|
||||
bool Input::IsMouseHidden() {
|
||||
auto window = Window::Get()->GetHandle();
|
||||
return glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED;
|
||||
}
|
||||
|
||||
void Input::ShowMouse() {
|
||||
auto window = Window::Get()->GetHandle();
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
}
|
||||
|
||||
|
||||
// Action
|
||||
bool Input::IsMouseButtonDown(int button)
|
||||
{
|
||||
auto window = Window::Get()->GetHandle();
|
||||
auto state = glfwGetMouseButton(window, button);
|
||||
|
||||
return state == GLFW_PRESS;
|
||||
}
|
||||
|
||||
bool Input::IsMouseButtonPressed(int button)
|
||||
{
|
||||
auto window = Window::Get()->GetHandle();
|
||||
auto state = glfwGetMouseButton(window, button);
|
||||
|
||||
if (m_MouseButtons[button] == false && state == GLFW_PRESS)
|
||||
{
|
||||
m_MouseButtons[button] = true;
|
||||
return true;
|
||||
// Visibility
|
||||
void Input::HideMouse() {
|
||||
auto window = Window::Get()->GetHandle();
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
bool Input::IsMouseHidden() {
|
||||
auto window = Window::Get()->GetHandle();
|
||||
return glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED;
|
||||
}
|
||||
|
||||
bool Input::IsMouseButtonReleased(int button)
|
||||
{
|
||||
auto window = Window::Get()->GetHandle();
|
||||
auto state = glfwGetMouseButton(window, button);
|
||||
void Input::ShowMouse() {
|
||||
auto window = Window::Get()->GetHandle();
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
}
|
||||
|
||||
return state == GLFW_RELEASE && m_MouseButtons[button] == true;
|
||||
}
|
||||
|
||||
// Position
|
||||
float Input::GetMouseX()
|
||||
{
|
||||
auto window = Window::Get()->GetHandle();
|
||||
// Action
|
||||
bool Input::IsMouseButtonDown(int button)
|
||||
{
|
||||
auto window = Window::Get()->GetHandle();
|
||||
auto state = glfwGetMouseButton(window, button);
|
||||
|
||||
double xpos, ypos;
|
||||
glfwGetCursorPos(window, &xpos, &ypos);
|
||||
return state == GLFW_PRESS;
|
||||
}
|
||||
|
||||
return (float)xpos;
|
||||
}
|
||||
bool Input::IsMouseButtonPressed(int button)
|
||||
{
|
||||
auto window = Window::Get()->GetHandle();
|
||||
auto state = glfwGetMouseButton(window, button);
|
||||
|
||||
float Input::GetMouseY()
|
||||
{
|
||||
auto window = Window::Get()->GetHandle();
|
||||
if (m_MouseButtons[button] == false && state == GLFW_PRESS)
|
||||
{
|
||||
m_MouseButtons[button] = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
double xpos, ypos;
|
||||
glfwGetCursorPos(window, &xpos, &ypos);
|
||||
return false;
|
||||
}
|
||||
|
||||
return (float)ypos;
|
||||
}
|
||||
bool Input::IsMouseButtonReleased(int button)
|
||||
{
|
||||
auto window = Window::Get()->GetHandle();
|
||||
auto state = glfwGetMouseButton(window, button);
|
||||
|
||||
Vector2 Input::GetMousePosition()
|
||||
{
|
||||
auto window = Window::Get()->GetHandle();
|
||||
return state == GLFW_RELEASE && m_MouseButtons[button] == true;
|
||||
}
|
||||
|
||||
double xpos, ypos;
|
||||
glfwGetCursorPos(window, &xpos, &ypos);
|
||||
// Position
|
||||
float Input::GetMouseX()
|
||||
{
|
||||
auto window = Window::Get()->GetHandle();
|
||||
|
||||
return Vector2(xpos, ypos);
|
||||
}
|
||||
double xpos, ypos;
|
||||
glfwGetCursorPos(window, &xpos, &ypos);
|
||||
|
||||
return (float)xpos;
|
||||
}
|
||||
|
||||
float Input::GetMouseY()
|
||||
{
|
||||
auto window = Window::Get()->GetHandle();
|
||||
|
||||
double xpos, ypos;
|
||||
glfwGetCursorPos(window, &xpos, &ypos);
|
||||
|
||||
return (float)ypos;
|
||||
}
|
||||
|
||||
Vector2 Input::GetMousePosition()
|
||||
{
|
||||
auto window = Window::Get()->GetHandle();
|
||||
|
||||
double xpos, ypos;
|
||||
glfwGetCursorPos(window, &xpos, &ypos);
|
||||
|
||||
return Vector2(xpos, ypos);
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
bool Input::Init()
|
||||
{
|
||||
//auto window = Application::Get().GetWindow()->GetNative();
|
||||
//glfwSetKeyCallback(window, Input::HandleInputCallback);
|
||||
return false;
|
||||
}
|
||||
|
||||
void Input::Update()
|
||||
{
|
||||
// Reset all input to false.
|
||||
for (auto& k : m_Keys)
|
||||
bool Input::Init()
|
||||
{
|
||||
if(!IsKeyDown(k.first))
|
||||
k.second = false;
|
||||
//auto window = Application::Get().GetWindow()->GetNative();
|
||||
//glfwSetKeyCallback(window, Input::HandleInputCallback);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
void Input::Update()
|
||||
{
|
||||
if(!IsMouseButtonDown(i))
|
||||
m_MouseButtons[i] = false;
|
||||
// Reset all input to false.
|
||||
for (auto& k : m_Keys)
|
||||
{
|
||||
if (!IsKeyDown(k.first))
|
||||
k.second = false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
if (!IsMouseButtonDown(i))
|
||||
m_MouseButtons[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,33 +2,37 @@
|
||||
#include <utility>
|
||||
#include "../Core/Maths.h"
|
||||
#include <map>
|
||||
class Input
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
private:
|
||||
static bool m_MouseButtons[5];
|
||||
static std::map<int, bool> m_Keys;
|
||||
public:
|
||||
static bool IsKeyPressed(int keycode);
|
||||
static bool IsKeyDown(int keycode);
|
||||
static bool IsKeyReleased(int keycode);
|
||||
class Input
|
||||
{
|
||||
private:
|
||||
static bool m_MouseButtons[5];
|
||||
static std::map<int, bool> m_Keys;
|
||||
public:
|
||||
static bool IsKeyPressed(int keycode);
|
||||
static bool IsKeyDown(int keycode);
|
||||
static bool IsKeyReleased(int keycode);
|
||||
|
||||
|
||||
static void HideMouse();
|
||||
static void ShowMouse();
|
||||
static bool IsMouseHidden();
|
||||
static bool IsMouseButtonPressed(int button);
|
||||
static bool IsMouseButtonDown(int button);
|
||||
static bool IsMouseButtonReleased(int button);
|
||||
|
||||
static float GetMouseX();
|
||||
static float GetMouseY();
|
||||
static Vector2 GetMousePosition();
|
||||
static void HideMouse();
|
||||
static void ShowMouse();
|
||||
static bool IsMouseHidden();
|
||||
static bool IsMouseButtonPressed(int button);
|
||||
static bool IsMouseButtonDown(int button);
|
||||
static bool IsMouseButtonReleased(int button);
|
||||
|
||||
static bool Init();
|
||||
static void Update();
|
||||
static float GetMouseX();
|
||||
static float GetMouseY();
|
||||
static Vector2 GetMousePosition();
|
||||
|
||||
Input* Get() { return s_Instance; }
|
||||
static bool Init();
|
||||
static void Update();
|
||||
|
||||
private:
|
||||
static Input* s_Instance;
|
||||
};
|
||||
Input* Get() { return s_Instance; }
|
||||
|
||||
private:
|
||||
static Input* s_Instance;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,30 +4,33 @@
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
|
||||
std::vector<LogEntry> Logger::m_Logs = std::vector<LogEntry>();
|
||||
|
||||
void Logger::Log(std::string log, LOG_TYPE type)
|
||||
namespace Nuake
|
||||
{
|
||||
char buff[100];
|
||||
time_t now = time(0);
|
||||
strftime(buff, 100, "%Y-%m-%d %H:%M:%S.000", localtime(&now));
|
||||
std::vector<LogEntry> Logger::m_Logs = std::vector<LogEntry>();
|
||||
|
||||
LogEntry newLog = {
|
||||
type,
|
||||
buff,
|
||||
log
|
||||
};
|
||||
void Logger::Log(std::string log, LOG_TYPE type)
|
||||
{
|
||||
char buff[100];
|
||||
time_t now = time(0);
|
||||
strftime(buff, 100, "%Y-%m-%d %H:%M:%S.000", localtime(&now));
|
||||
|
||||
std::string msg = "[" + std::string(buff) + "]" + std::string(" - ") + log;
|
||||
printf((msg + "\n").c_str());
|
||||
LogEntry newLog = {
|
||||
type,
|
||||
buff,
|
||||
log
|
||||
};
|
||||
|
||||
if (m_Logs.size() >= MAX_LOG)
|
||||
m_Logs.erase(m_Logs.begin());
|
||||
std::string msg = "[" + std::string(buff) + "]" + std::string(" - ") + log;
|
||||
printf((msg + "\n").c_str());
|
||||
|
||||
m_Logs.push_back(newLog);
|
||||
if (m_Logs.size() >= MAX_LOG)
|
||||
m_Logs.erase(m_Logs.begin());
|
||||
|
||||
m_Logs.push_back(newLog);
|
||||
}
|
||||
|
||||
std::vector<LogEntry> Logger::GetLogs()
|
||||
{
|
||||
return m_Logs;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<LogEntry> Logger::GetLogs()
|
||||
{
|
||||
return m_Logs;
|
||||
}
|
||||
@@ -2,25 +2,29 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
enum LOG_TYPE
|
||||
namespace Nuake
|
||||
{
|
||||
VERBOSE,
|
||||
WARNING,
|
||||
CRITICAL
|
||||
};
|
||||
enum LOG_TYPE
|
||||
{
|
||||
VERBOSE,
|
||||
WARNING,
|
||||
CRITICAL
|
||||
};
|
||||
|
||||
struct LogEntry
|
||||
{
|
||||
LOG_TYPE type;
|
||||
std::string time;
|
||||
std::string message;
|
||||
};
|
||||
struct LogEntry
|
||||
{
|
||||
LOG_TYPE type;
|
||||
std::string time;
|
||||
std::string message;
|
||||
};
|
||||
|
||||
class Logger
|
||||
{
|
||||
static const int MAX_LOG = 64;
|
||||
static std::vector<LogEntry> m_Logs; // TODO: Use log struct.
|
||||
public:
|
||||
static void Log(std::string log, LOG_TYPE type = VERBOSE);
|
||||
static std::vector<LogEntry> GetLogs();
|
||||
};
|
||||
class Logger
|
||||
{
|
||||
public:
|
||||
static void Log(std::string log, LOG_TYPE type = VERBOSE);
|
||||
static std::vector<LogEntry> GetLogs();
|
||||
private:
|
||||
static const int MAX_LOG = 64;
|
||||
static std::vector<LogEntry> m_Logs; // TODO: Use log struct.
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,91 +7,100 @@
|
||||
#include "json/json.hpp"
|
||||
|
||||
#include "../Rendering/Textures/Material.h"
|
||||
using json = nlohmann::json;
|
||||
|
||||
Ref<MaterialManager> MaterialManager::s_Instance;
|
||||
|
||||
MaterialManager::MaterialManager()
|
||||
namespace Nuake
|
||||
{
|
||||
m_Materials = std::map<std::string, Ref<Material>>();
|
||||
}
|
||||
using json = nlohmann::json;
|
||||
|
||||
Ref<Material> MaterialManager::GetMaterial(const std::string name)
|
||||
{
|
||||
if (!IsMaterialLoaded(name))
|
||||
Ref<MaterialManager> MaterialManager::s_Instance;
|
||||
|
||||
MaterialManager::MaterialManager()
|
||||
{
|
||||
Ref<Material> newMaterial = CreateRef<Material>(name);
|
||||
RegisterMaterial(newMaterial);
|
||||
m_Materials = std::map<std::string, Ref<Material>>();
|
||||
}
|
||||
|
||||
Ref<Material> MaterialManager::GetMaterial(const std::string name)
|
||||
{
|
||||
if (!IsMaterialLoaded(name))
|
||||
{
|
||||
Ref<Material> newMaterial = CreateRef<Material>(name);
|
||||
RegisterMaterial(newMaterial);
|
||||
return newMaterial;
|
||||
}
|
||||
return m_Materials[name];
|
||||
}
|
||||
|
||||
void MaterialManager::RegisterMaterial(Ref<Material> material)
|
||||
{
|
||||
m_Materials[material->GetName()] = material;
|
||||
}
|
||||
|
||||
// Gets a material from path and load file if not already loaded.
|
||||
//
|
||||
// NOTE: The path passed as param is relative to Res/Materials and
|
||||
// shouldn't contain the '.material' extension.
|
||||
Ref<Material> MaterialManager::LoadMaterial(const std::string materialPath)
|
||||
{
|
||||
if (IsMaterialLoaded(materialPath))
|
||||
return (m_Materials)[materialPath];
|
||||
|
||||
std::string finalPath = "Res/Materials/" + materialPath + ".material";
|
||||
std::ifstream i(finalPath);
|
||||
json j;
|
||||
i >> j;
|
||||
|
||||
std::string matName;
|
||||
if (!j.contains("name"))
|
||||
{
|
||||
std::string msg = "Error: Cannot load material file: " + materialPath +
|
||||
" - Material file must have a name. \n";
|
||||
printf(msg.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
matName = j["name"];
|
||||
}
|
||||
|
||||
std::string albedoPath;
|
||||
std::string normalPath;
|
||||
std::string aoPath;
|
||||
std::string metalPath;
|
||||
std::string roughnessPath;
|
||||
std::string displacementPath;
|
||||
|
||||
Ref<Material> newMaterial = CreateRef<Material>(j["albedo"]);
|
||||
//if (j.contains("albedo"))
|
||||
// newMaterial = new Material(albedoPath);
|
||||
//else
|
||||
// newMaterial = new Material(glm::vec3(1, 1, 1));
|
||||
newMaterial->SetName(matName);
|
||||
|
||||
if (j.contains("normal"))
|
||||
newMaterial->SetNormal(j["normal"]);
|
||||
if (j.contains("ao"))
|
||||
newMaterial->SetAO(j["ao"]);
|
||||
if (j.contains("metal"))
|
||||
newMaterial->SetMetalness(j["metal"]);
|
||||
if (j.contains("roughness"))
|
||||
newMaterial->SetRoughness(j["roughness"]);
|
||||
if (j.contains("displacement"))
|
||||
newMaterial->SetDisplacement(j["displacement"]);
|
||||
|
||||
return newMaterial;
|
||||
}
|
||||
return m_Materials[name];
|
||||
}
|
||||
|
||||
void MaterialManager::RegisterMaterial(Ref<Material> material)
|
||||
{
|
||||
m_Materials[material->GetName()] = material;
|
||||
}
|
||||
|
||||
// Gets a material from path and load file if not already loaded.
|
||||
//
|
||||
// NOTE: The path passed as param is relative to Res/Materials and
|
||||
// shouldn't contain the '.material' extension.
|
||||
Ref<Material> MaterialManager::LoadMaterial(const std::string materialPath) {
|
||||
if (IsMaterialLoaded(materialPath))
|
||||
return (m_Materials)[materialPath];
|
||||
|
||||
std::string finalPath = "Res/Materials/" + materialPath + ".material";
|
||||
std::ifstream i(finalPath);
|
||||
json j;
|
||||
i >> j;
|
||||
|
||||
std::string matName;
|
||||
if (!j.contains("name")) {
|
||||
std::string msg = "Error: Cannot load material file: " + materialPath +
|
||||
" - Material file must have a name. \n";
|
||||
printf(msg.c_str());
|
||||
return nullptr;
|
||||
std::map<std::string, Ref<Material>> MaterialManager::GetAllMaterials()
|
||||
{
|
||||
return m_Materials;
|
||||
}
|
||||
else {
|
||||
matName = j["name"];
|
||||
|
||||
bool MaterialManager::IsMaterialLoaded(const std::string materialPath)
|
||||
{
|
||||
return m_Materials.find(materialPath) != m_Materials.end();
|
||||
}
|
||||
|
||||
std::string albedoPath;
|
||||
std::string normalPath;
|
||||
std::string aoPath;
|
||||
std::string metalPath;
|
||||
std::string roughnessPath;
|
||||
std::string displacementPath;
|
||||
|
||||
Ref<Material> newMaterial = CreateRef<Material>(j["albedo"]);
|
||||
//if (j.contains("albedo"))
|
||||
// newMaterial = new Material(albedoPath);
|
||||
//else
|
||||
// newMaterial = new Material(glm::vec3(1, 1, 1));
|
||||
newMaterial->SetName(matName);
|
||||
|
||||
if (j.contains("normal"))
|
||||
newMaterial->SetNormal(j["normal"]);
|
||||
if (j.contains("ao"))
|
||||
newMaterial->SetAO(j["ao"]);
|
||||
if (j.contains("metal"))
|
||||
newMaterial->SetMetalness(j["metal"]);
|
||||
if (j.contains("roughness"))
|
||||
newMaterial->SetRoughness(j["roughness"]);
|
||||
if (j.contains("displacement"))
|
||||
newMaterial->SetDisplacement(j["displacement"]);
|
||||
|
||||
return newMaterial;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::map<std::string, Ref<Material>> MaterialManager::GetAllMaterials()
|
||||
{
|
||||
return m_Materials;
|
||||
}
|
||||
|
||||
bool MaterialManager::IsMaterialLoaded(const std::string materialPath) {
|
||||
return m_Materials.find(materialPath) != m_Materials.end();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,41 +1,46 @@
|
||||
#pragma once
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "../Core/Core.h"
|
||||
#include "src/Core/Core.h"
|
||||
|
||||
class Material;
|
||||
namespace Nuake
|
||||
{
|
||||
class Material;
|
||||
|
||||
// TODO: Should probably be static.
|
||||
class MaterialManager {
|
||||
private:
|
||||
static Ref<MaterialManager> s_Instance;
|
||||
|
||||
std::map<std::string, Ref<Material>> m_Materials;
|
||||
|
||||
// TODO: Pile of crap
|
||||
Material* ParseMaterialFile(const std::string path);
|
||||
void SaveMaterialFile(const std::string path, Material* material);
|
||||
bool IsMaterialLoaded(const std::string path);
|
||||
|
||||
|
||||
public:
|
||||
std::string CurrentlyBoundedMaterial = "";
|
||||
MaterialManager();
|
||||
|
||||
void LoadMaterials();
|
||||
|
||||
void RegisterMaterial(Ref<Material> material);
|
||||
|
||||
Ref<Material> LoadMaterial(const std::string path);
|
||||
|
||||
Ref<Material> GetMaterial(const std::string name);
|
||||
|
||||
std::map<std::string, Ref<Material>> GetAllMaterials();
|
||||
static Ref<MaterialManager> Get()
|
||||
// TODO: Should probably be static.
|
||||
class MaterialManager
|
||||
{
|
||||
if (!s_Instance)
|
||||
s_Instance = CreateRef<MaterialManager>();
|
||||
private:
|
||||
static Ref<MaterialManager> s_Instance;
|
||||
|
||||
return s_Instance;
|
||||
}
|
||||
};
|
||||
std::map<std::string, Ref<Material>> m_Materials;
|
||||
|
||||
// TODO: Pile of crap
|
||||
Material* ParseMaterialFile(const std::string path);
|
||||
void SaveMaterialFile(const std::string path, Material* material);
|
||||
bool IsMaterialLoaded(const std::string path);
|
||||
|
||||
|
||||
public:
|
||||
std::string CurrentlyBoundedMaterial = "";
|
||||
MaterialManager();
|
||||
|
||||
void LoadMaterials();
|
||||
|
||||
void RegisterMaterial(Ref<Material> material);
|
||||
|
||||
Ref<Material> LoadMaterial(const std::string path);
|
||||
|
||||
Ref<Material> GetMaterial(const std::string name);
|
||||
|
||||
std::map<std::string, Ref<Material>> GetAllMaterials();
|
||||
|
||||
static Ref<MaterialManager> Get()
|
||||
{
|
||||
if (!s_Instance)
|
||||
s_Instance = CreateRef<MaterialManager>();
|
||||
|
||||
return s_Instance;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
#pragma once
|
||||
#include <glm\ext\vector_float4.hpp>
|
||||
#include <glm\ext\vector_float3.hpp>
|
||||
#include <glm\ext\matrix_transform.hpp>
|
||||
#include <src/Vendors/glm/ext/vector_float2.hpp>
|
||||
#include <src/Vendors/glm/ext/matrix_float4x4.hpp>
|
||||
|
||||
#include <glm\ext\matrix_transform.hpp>
|
||||
|
||||
using Vector3 = glm::vec3;
|
||||
using Vector2 = glm::vec2;
|
||||
using Vector4 = glm::vec4;
|
||||
using Color = glm::vec4;
|
||||
using Matrix4 = glm::mat4;
|
||||
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
using Vector3 = glm::vec3;
|
||||
using Vector2 = glm::vec2;
|
||||
using Vector4 = glm::vec4;
|
||||
using Color = glm::vec4;
|
||||
using Matrix4 = glm::mat4;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
class OS {
|
||||
public:
|
||||
static int GetTime() {
|
||||
return std::chrono::system_clock::now().time_since_epoch().count();
|
||||
}
|
||||
};
|
||||
namespace Nuake
|
||||
{
|
||||
class OS
|
||||
{
|
||||
public:
|
||||
static int GetTime()
|
||||
{
|
||||
return std::chrono::system_clock::now().time_since_epoch().count();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,30 +2,32 @@
|
||||
#include "../../Rendering/Renderer.h"
|
||||
#include <GL/glew.h>
|
||||
|
||||
void BulletDebugDrawer::drawLine(const btVector3& from, const btVector3& to, const btVector3& color)
|
||||
namespace Nuake
|
||||
{
|
||||
TransformComponent tc = TransformComponent();
|
||||
void BulletDebugDrawer::drawLine(const btVector3& from, const btVector3& to, const btVector3& color)
|
||||
{
|
||||
TransformComponent tc = TransformComponent();
|
||||
|
||||
tc.Translation = glm::vec3(from.x(), from.y(), from.z());
|
||||
tc.Scale = glm::vec3(1.0f);
|
||||
tc.Rotation = glm::vec3(0.0f);
|
||||
tc.Translation = glm::vec3(from.x(), from.y(), from.z());
|
||||
tc.Scale = glm::vec3(1.0f);
|
||||
tc.Rotation = glm::vec3(0.0f);
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glColor3f((float)(color.x()), (float)(color.y()), (float)(color.z()));
|
||||
glVertex3f((float)(from.x()), (float)(from.y()), (float)(from.z()));
|
||||
glVertex3f((float)(to.x()), (float)(to.y()), (float)(to.z()));
|
||||
glEnd();
|
||||
glBegin(GL_LINES);
|
||||
glColor3f((float)(color.x()), (float)(color.y()), (float)(color.z()));
|
||||
glVertex3f((float)(from.x()), (float)(from.y()), (float)(from.z()));
|
||||
glVertex3f((float)(to.x()), (float)(to.y()), (float)(to.z()));
|
||||
glEnd();
|
||||
|
||||
//Renderer::DrawCube(tc, glm::vec4(color.x(), color.y(), color.z(), 1.0f));
|
||||
//Renderer::DrawCube(tc, glm::vec4(color.x(), color.y(), color.z(), 1.0f));
|
||||
}
|
||||
|
||||
void BulletDebugDrawer::drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color)
|
||||
{
|
||||
if (lifeTime > 3.0f)
|
||||
return;
|
||||
glBegin(GL_POINTS);
|
||||
glColor3f(color.x(), color.y(), color.z());
|
||||
glVertex3f(PointOnB.x(), PointOnB.y(), PointOnB.z());
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
||||
void BulletDebugDrawer::drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color)
|
||||
{
|
||||
if (lifeTime > 3.0f)
|
||||
return;
|
||||
glBegin(GL_POINTS);
|
||||
glColor3f(color.x(), color.y(), color.z());
|
||||
glVertex3f(PointOnB.x(), PointOnB.y(), PointOnB.z());
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
#pragma once
|
||||
#include "btBulletCollisionCommon.h"
|
||||
class BulletDebugDrawer : public btIDebugDraw
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
void drawLine(const btVector3& from, const btVector3& to, const btVector3& color) override;
|
||||
class BulletDebugDrawer : public btIDebugDraw
|
||||
{
|
||||
void drawLine(const btVector3& from, const btVector3& to, const btVector3& color) override;
|
||||
|
||||
int getDebugMode() const override { return 1; }
|
||||
int getDebugMode() const override { return 1; }
|
||||
|
||||
void draw3dText(const btVector3& location, const char* textString) override {}
|
||||
void draw3dText(const btVector3& location, const char* textString) override {}
|
||||
|
||||
void reportErrorWarning(const char* warningString) override { };
|
||||
void reportErrorWarning(const char* warningString) override { };
|
||||
|
||||
void setDebugMode(int debugMode) {};
|
||||
void setDebugMode(int debugMode) {};
|
||||
|
||||
void drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color) override;
|
||||
};
|
||||
void drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color) override;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,211 +1,216 @@
|
||||
#include "CharacterController.h"
|
||||
#include "../Core/Physics/PhysicsManager.h"
|
||||
#include "../Core/Physics/RaycastResult.h"
|
||||
namespace Physics
|
||||
#include "src/Core/Physics/PhysicsManager.h"
|
||||
#include "src/Core/Physics/RaycastResult.h"
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
CharacterController::CharacterController(float height, float radius, float mass, Vector3 position)
|
||||
namespace Physics
|
||||
{
|
||||
m_surfaceHitNormals = std::vector<glm::vec3>();
|
||||
|
||||
m_bottomRoundedRegionYOffset = (height + radius) / 2.0f;
|
||||
m_bottomYOffset = height / 2.0f + radius;
|
||||
m_CollisionShape = new btCapsuleShape(radius, height);
|
||||
|
||||
btQuaternion quat = btQuaternion(0, 0, 0);
|
||||
m_Transform = new btTransform();
|
||||
m_Transform->setOrigin(btVector3(position.x, position.y, position.z));
|
||||
m_Transform->setRotation(quat);
|
||||
m_MotionState = new btDefaultMotionState(*m_Transform);
|
||||
|
||||
btVector3 inertia;
|
||||
//m_CollisionShape->calculateLocalInertia(mass, inertia);
|
||||
|
||||
btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(mass, m_MotionState, m_CollisionShape, inertia);
|
||||
|
||||
rigidBodyCI.m_friction = 0.0f;
|
||||
//rigidBodyCI.m_additionalDamping = true;
|
||||
//rigidBodyCI.m_additionalLinearDampingThresholdSqr= 1.0f;
|
||||
//rigidBodyCI.m_additionalLinearDampingThresholdSqr = 0.5f;
|
||||
rigidBodyCI.m_restitution = 0.0f;
|
||||
|
||||
rigidBodyCI.m_linearDamping = 0.0f;
|
||||
m_Rigidbody = new btRigidBody(rigidBodyCI);
|
||||
m_Rigidbody->setGravity(btVector3(0, 0, 0));
|
||||
// Keep upright
|
||||
m_Rigidbody->setAngularFactor(0.0f);
|
||||
|
||||
// No sleeping (or else setLinearVelocity won't work)
|
||||
m_Rigidbody->setActivationState(DISABLE_DEACTIVATION);
|
||||
|
||||
//m_pPhysicsWorld->m_pDynamicsWorld->addRigidBody(m_pRigidBody);
|
||||
|
||||
// Ghost object that is synchronized with rigid body
|
||||
m_GhostObject = new btPairCachingGhostObject();
|
||||
m_GhostObject->setCollisionShape(m_CollisionShape);
|
||||
|
||||
// Specify filters manually, otherwise ghost doesn't collide with statics for some reason
|
||||
//m_pPhysicsWorld->m_pDynamicsWorld->addCollisionObject(m_pGhostObject, btBroadphaseProxy::KinematicFilter, btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter);
|
||||
}
|
||||
|
||||
void CharacterController::SetEntity(Entity& ent)
|
||||
{
|
||||
m_Rigidbody->setUserIndex(ent.GetHandle());
|
||||
m_GhostObject->setUserIndex(ent.GetHandle());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CharacterController::MoveAndSlide(glm::vec3 velocity)
|
||||
{
|
||||
m_Rigidbody->setGravity(btVector3(0, 0, 0));
|
||||
m_manualVelocity = velocity;
|
||||
// Sync ghost with actually object
|
||||
m_GhostObject->setWorldTransform(m_Rigidbody->getWorldTransform());
|
||||
|
||||
IsOnGround = false;
|
||||
ParseGhostContacts();
|
||||
UpdatePosition();
|
||||
UpdateVelocity();
|
||||
m_MotionState->getWorldTransform(m_motionTransform);
|
||||
}
|
||||
|
||||
void CharacterController::ParseGhostContacts()
|
||||
{
|
||||
btManifoldArray manifoldArray;
|
||||
btBroadphasePairArray& pairArray = m_GhostObject->getOverlappingPairCache()->getOverlappingPairArray();
|
||||
int numPairs = pairArray.size();
|
||||
|
||||
m_hittingWall = false;
|
||||
|
||||
for (int i = 0; i < numPairs; i++)
|
||||
CharacterController::CharacterController(float height, float radius, float mass, Vector3 position)
|
||||
{
|
||||
manifoldArray.clear();
|
||||
m_surfaceHitNormals = std::vector<glm::vec3>();
|
||||
|
||||
const btBroadphasePair& pair = pairArray[i];
|
||||
|
||||
btDiscreteDynamicsWorld* world = PhysicsManager::Get()->GetWorld()->GetDynamicWorld();
|
||||
btBroadphasePair* collisionPair = world->getPairCache()->findPair(pair.m_pProxy0, pair.m_pProxy1);
|
||||
m_bottomRoundedRegionYOffset = (height + radius) / 2.0f;
|
||||
m_bottomYOffset = height / 2.0f + radius;
|
||||
m_CollisionShape = new btCapsuleShape(radius, height);
|
||||
|
||||
if (collisionPair == NULL)
|
||||
continue;
|
||||
btQuaternion quat = btQuaternion(0, 0, 0);
|
||||
m_Transform = new btTransform();
|
||||
m_Transform->setOrigin(btVector3(position.x, position.y, position.z));
|
||||
m_Transform->setRotation(quat);
|
||||
m_MotionState = new btDefaultMotionState(*m_Transform);
|
||||
|
||||
if (collisionPair->m_algorithm != NULL)
|
||||
collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
|
||||
btVector3 inertia;
|
||||
//m_CollisionShape->calculateLocalInertia(mass, inertia);
|
||||
|
||||
for (int j = 0; j < manifoldArray.size(); j++)
|
||||
btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(mass, m_MotionState, m_CollisionShape, inertia);
|
||||
|
||||
rigidBodyCI.m_friction = 0.0f;
|
||||
//rigidBodyCI.m_additionalDamping = true;
|
||||
//rigidBodyCI.m_additionalLinearDampingThresholdSqr= 1.0f;
|
||||
//rigidBodyCI.m_additionalLinearDampingThresholdSqr = 0.5f;
|
||||
rigidBodyCI.m_restitution = 0.0f;
|
||||
|
||||
rigidBodyCI.m_linearDamping = 0.0f;
|
||||
m_Rigidbody = new btRigidBody(rigidBodyCI);
|
||||
m_Rigidbody->setGravity(btVector3(0, 0, 0));
|
||||
// Keep upright
|
||||
m_Rigidbody->setAngularFactor(0.0f);
|
||||
|
||||
// No sleeping (or else setLinearVelocity won't work)
|
||||
m_Rigidbody->setActivationState(DISABLE_DEACTIVATION);
|
||||
|
||||
//m_pPhysicsWorld->m_pDynamicsWorld->addRigidBody(m_pRigidBody);
|
||||
|
||||
// Ghost object that is synchronized with rigid body
|
||||
m_GhostObject = new btPairCachingGhostObject();
|
||||
m_GhostObject->setCollisionShape(m_CollisionShape);
|
||||
|
||||
// Specify filters manually, otherwise ghost doesn't collide with statics for some reason
|
||||
//m_pPhysicsWorld->m_pDynamicsWorld->addCollisionObject(m_pGhostObject, btBroadphaseProxy::KinematicFilter, btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter);
|
||||
}
|
||||
|
||||
void CharacterController::SetEntity(Entity& ent)
|
||||
{
|
||||
m_Rigidbody->setUserIndex(ent.GetHandle());
|
||||
m_GhostObject->setUserIndex(ent.GetHandle());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CharacterController::MoveAndSlide(glm::vec3 velocity)
|
||||
{
|
||||
m_Rigidbody->setGravity(btVector3(0, 0, 0));
|
||||
m_manualVelocity = velocity;
|
||||
// Sync ghost with actually object
|
||||
m_GhostObject->setWorldTransform(m_Rigidbody->getWorldTransform());
|
||||
|
||||
IsOnGround = false;
|
||||
ParseGhostContacts();
|
||||
UpdatePosition();
|
||||
UpdateVelocity();
|
||||
m_MotionState->getWorldTransform(m_motionTransform);
|
||||
}
|
||||
|
||||
void CharacterController::ParseGhostContacts()
|
||||
{
|
||||
btManifoldArray manifoldArray;
|
||||
btBroadphasePairArray& pairArray = m_GhostObject->getOverlappingPairCache()->getOverlappingPairArray();
|
||||
int numPairs = pairArray.size();
|
||||
|
||||
m_hittingWall = false;
|
||||
|
||||
for (int i = 0; i < numPairs; i++)
|
||||
{
|
||||
btPersistentManifold* pManifold = manifoldArray[j];
|
||||
manifoldArray.clear();
|
||||
|
||||
// Skip the rigid body the ghost monitors
|
||||
if (pManifold->getBody0() == m_Rigidbody)
|
||||
const btBroadphasePair& pair = pairArray[i];
|
||||
|
||||
btDiscreteDynamicsWorld* world = PhysicsManager::Get()->GetWorld()->GetDynamicWorld();
|
||||
btBroadphasePair* collisionPair = world->getPairCache()->findPair(pair.m_pProxy0, pair.m_pProxy1);
|
||||
|
||||
if (collisionPair == NULL)
|
||||
continue;
|
||||
|
||||
for (int p = 0; p < pManifold->getNumContacts(); p++)
|
||||
if (collisionPair->m_algorithm != NULL)
|
||||
collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
|
||||
|
||||
for (int j = 0; j < manifoldArray.size(); j++)
|
||||
{
|
||||
const btManifoldPoint& point = pManifold->getContactPoint(p);
|
||||
btPersistentManifold* pManifold = manifoldArray[j];
|
||||
|
||||
if (point.getDistance() < 0.0f)
|
||||
// Skip the rigid body the ghost monitors
|
||||
if (pManifold->getBody0() == m_Rigidbody)
|
||||
continue;
|
||||
|
||||
for (int p = 0; p < pManifold->getNumContacts(); p++)
|
||||
{
|
||||
//const btVector3 &ptA = point.getPositionWorldOnA();
|
||||
const btVector3& ptB = point.getPositionWorldOnB();
|
||||
const btManifoldPoint& point = pManifold->getContactPoint(p);
|
||||
|
||||
//const btVector3 &normalOnB = point.m_normalWorldOnB;
|
||||
|
||||
// If point is in rounded bottom region of capsule shape, it is on the ground
|
||||
if (ptB.getY() < m_motionTransform.getOrigin().getY() - m_bottomRoundedRegionYOffset)
|
||||
IsOnGround = true;
|
||||
else
|
||||
if (point.getDistance() < 0.0f)
|
||||
{
|
||||
m_hittingWall = true;
|
||||
//const btVector3 &ptA = point.getPositionWorldOnA();
|
||||
const btVector3& ptB = point.getPositionWorldOnB();
|
||||
|
||||
m_surfaceHitNormals.push_back(glm::vec3(point.m_normalWorldOnB.x(), point.m_normalWorldOnB.y(), point.m_normalWorldOnB.z()));
|
||||
//const btVector3 &normalOnB = point.m_normalWorldOnB;
|
||||
|
||||
// If point is in rounded bottom region of capsule shape, it is on the ground
|
||||
if (ptB.getY() < m_motionTransform.getOrigin().getY() - m_bottomRoundedRegionYOffset)
|
||||
IsOnGround = true;
|
||||
else
|
||||
{
|
||||
m_hittingWall = true;
|
||||
|
||||
m_surfaceHitNormals.push_back(glm::vec3(point.m_normalWorldOnB.x(), point.m_normalWorldOnB.y(), point.m_normalWorldOnB.z()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CharacterController::UpdatePosition()
|
||||
{
|
||||
// Ray cast, ignore rigid body
|
||||
IgnoreBodyAndGhostCast rayCallBack_bottom(m_Rigidbody, m_GhostObject);
|
||||
|
||||
btVector3 from = m_Rigidbody->getWorldTransform().getOrigin();
|
||||
btVector3 toBt = m_Rigidbody->getWorldTransform().getOrigin() - btVector3(0.0f, m_bottomYOffset + m_stepHeight , 0.0f);
|
||||
PhysicsManager::Get()->GetWorld()->GetDynamicWorld()->rayTest(from, toBt, rayCallBack_bottom);
|
||||
|
||||
// Bump up if hit
|
||||
if (rayCallBack_bottom.hasHit())
|
||||
void CharacterController::UpdatePosition()
|
||||
{
|
||||
float previousY = m_Rigidbody->getWorldTransform().getOrigin().getY();
|
||||
// Ray cast, ignore rigid body
|
||||
IgnoreBodyAndGhostCast rayCallBack_bottom(m_Rigidbody, m_GhostObject);
|
||||
|
||||
btVector3 from = m_Rigidbody->getWorldTransform().getOrigin();
|
||||
btVector3 toBt = m_Rigidbody->getWorldTransform().getOrigin() - btVector3(0.0f, m_bottomYOffset + m_stepHeight, 0.0f);
|
||||
PhysicsManager::Get()->GetWorld()->GetDynamicWorld()->rayTest(from, toBt, rayCallBack_bottom);
|
||||
|
||||
float t = rayCallBack_bottom.m_closestHitFraction ;
|
||||
|
||||
float clamped = (1.0 - rayCallBack_bottom.m_closestHitFraction);
|
||||
btVector3 vel(m_Rigidbody->getLinearVelocity());
|
||||
|
||||
if(vel.getY() < 0) // -magic number is to fix bouncing down a slope.
|
||||
m_Rigidbody->getWorldTransform().getOrigin().setY(previousY - 0.14f + (m_bottomYOffset + m_stepHeight) * (clamped));
|
||||
|
||||
vel.setY(0.0f);
|
||||
|
||||
m_Rigidbody->setLinearVelocity(vel);
|
||||
|
||||
IsOnGround = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
float testOffset = 0.07f;
|
||||
|
||||
// Ray cast, ignore rigid body
|
||||
IgnoreBodyAndGhostCast rayCallBack_top(m_Rigidbody, m_GhostObject);
|
||||
|
||||
PhysicsManager::Get()->GetWorld()->GetDynamicWorld()->rayTest(m_Rigidbody->getWorldTransform().getOrigin(), m_Rigidbody->getWorldTransform().getOrigin() + btVector3(0.0f, m_bottomYOffset + testOffset, 0.0f), rayCallBack_top);
|
||||
|
||||
// Bump up if hit
|
||||
if (rayCallBack_top.hasHit())
|
||||
{
|
||||
m_Rigidbody->getWorldTransform().setOrigin(m_previousPosition);
|
||||
|
||||
btVector3 vel(m_Rigidbody->getLinearVelocity());
|
||||
|
||||
vel.setY(0.0f);
|
||||
|
||||
m_Rigidbody->setLinearVelocity(vel);
|
||||
}
|
||||
|
||||
m_previousPosition = m_Rigidbody->getWorldTransform().getOrigin();
|
||||
}
|
||||
|
||||
void CharacterController::UpdateVelocity()
|
||||
{
|
||||
//m_manualVelocity.y = m_Rigidbody->getLinearVelocity().getY();
|
||||
btVector3 grav = m_Rigidbody->getGravity();
|
||||
btVector3 finalVel = btVector3(m_manualVelocity.x, m_manualVelocity.y, m_manualVelocity.z);
|
||||
m_Rigidbody->setLinearVelocity(finalVel);
|
||||
|
||||
// Decelerate
|
||||
//m_manualVelocity -= m_manualVelocity * m_deceleration * m_pPhysicsWorld->GetScene()->m_frameTimer.GetTimeMultiplier();
|
||||
|
||||
if (m_hittingWall)
|
||||
{
|
||||
for (unsigned int i = 0, size = m_surfaceHitNormals.size(); i < size; i++)
|
||||
// Bump up if hit
|
||||
if (rayCallBack_bottom.hasHit())
|
||||
{
|
||||
// Cancel velocity across normal
|
||||
glm::vec3 velInNormalDir(glm::reflect(m_manualVelocity, m_surfaceHitNormals[i]));
|
||||
float previousY = m_Rigidbody->getWorldTransform().getOrigin().getY();
|
||||
|
||||
|
||||
float t = rayCallBack_bottom.m_closestHitFraction;
|
||||
|
||||
float clamped = (1.0 - rayCallBack_bottom.m_closestHitFraction);
|
||||
btVector3 vel(m_Rigidbody->getLinearVelocity());
|
||||
|
||||
if (vel.getY() < 0) // -magic number is to fix bouncing down a slope.
|
||||
m_Rigidbody->getWorldTransform().getOrigin().setY(previousY - 0.14f + (m_bottomYOffset + m_stepHeight) * (clamped));
|
||||
|
||||
vel.setY(0.0f);
|
||||
|
||||
m_Rigidbody->setLinearVelocity(vel);
|
||||
|
||||
IsOnGround = true;
|
||||
|
||||
// Apply correction
|
||||
m_manualVelocity -= velInNormalDir * 1.05f;
|
||||
}
|
||||
|
||||
// Do not adjust rigid body velocity manually (so bodies can still be pushed by character)
|
||||
return;
|
||||
|
||||
|
||||
float testOffset = 0.07f;
|
||||
|
||||
// Ray cast, ignore rigid body
|
||||
IgnoreBodyAndGhostCast rayCallBack_top(m_Rigidbody, m_GhostObject);
|
||||
|
||||
PhysicsManager::Get()->GetWorld()->GetDynamicWorld()->rayTest(m_Rigidbody->getWorldTransform().getOrigin(), m_Rigidbody->getWorldTransform().getOrigin() + btVector3(0.0f, m_bottomYOffset + testOffset, 0.0f), rayCallBack_top);
|
||||
|
||||
// Bump up if hit
|
||||
if (rayCallBack_top.hasHit())
|
||||
{
|
||||
m_Rigidbody->getWorldTransform().setOrigin(m_previousPosition);
|
||||
|
||||
btVector3 vel(m_Rigidbody->getLinearVelocity());
|
||||
|
||||
vel.setY(0.0f);
|
||||
|
||||
m_Rigidbody->setLinearVelocity(vel);
|
||||
}
|
||||
|
||||
m_previousPosition = m_Rigidbody->getWorldTransform().getOrigin();
|
||||
}
|
||||
|
||||
void CharacterController::UpdateVelocity()
|
||||
{
|
||||
//m_manualVelocity.y = m_Rigidbody->getLinearVelocity().getY();
|
||||
btVector3 grav = m_Rigidbody->getGravity();
|
||||
btVector3 finalVel = btVector3(m_manualVelocity.x, m_manualVelocity.y, m_manualVelocity.z);
|
||||
m_Rigidbody->setLinearVelocity(finalVel);
|
||||
|
||||
// Decelerate
|
||||
//m_manualVelocity -= m_manualVelocity * m_deceleration * m_pPhysicsWorld->GetScene()->m_frameTimer.GetTimeMultiplier();
|
||||
|
||||
if (m_hittingWall)
|
||||
{
|
||||
for (unsigned int i = 0, size = m_surfaceHitNormals.size(); i < size; i++)
|
||||
{
|
||||
// Cancel velocity across normal
|
||||
glm::vec3 velInNormalDir(glm::reflect(m_manualVelocity, m_surfaceHitNormals[i]));
|
||||
|
||||
// Apply correction
|
||||
m_manualVelocity -= velInNormalDir * 1.05f;
|
||||
}
|
||||
|
||||
// Do not adjust rigid body velocity manually (so bodies can still be pushed by character)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,56 +1,57 @@
|
||||
#pragma once
|
||||
#include <glm/ext/vector_float3.hpp>
|
||||
#include "../Core/Core.h"
|
||||
#include "src/Core/Core.h"
|
||||
#include "src/Core/Maths.h"
|
||||
|
||||
#include <btBulletDynamicsCommon.h>
|
||||
|
||||
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
|
||||
#include <vector>
|
||||
#include "../Core/Maths.h"
|
||||
|
||||
|
||||
class Entity;
|
||||
namespace Physics
|
||||
namespace Nuake
|
||||
{
|
||||
class CharacterController
|
||||
class Entity;
|
||||
|
||||
namespace Physics
|
||||
{
|
||||
public:
|
||||
bool IsOnGround = false;
|
||||
bool m_hittingWall;
|
||||
float m_stepHeight = 0.35f;
|
||||
float m_MaxSlopeAngle = 45.0f;
|
||||
|
||||
btTransform* m_Transform;
|
||||
btCollisionShape* m_CollisionShape;
|
||||
btRigidBody* m_Rigidbody;
|
||||
btPairCachingGhostObject* m_GhostObject;
|
||||
btMotionState* m_MotionState;
|
||||
|
||||
//bool m_onJumpableGround; // A bit lower contact than just onGround
|
||||
|
||||
float m_bottomYOffset;
|
||||
float m_bottomRoundedRegionYOffset ;
|
||||
|
||||
btTransform m_motionTransform;
|
||||
|
||||
glm::vec3 m_manualVelocity;
|
||||
std::vector<glm::vec3> m_surfaceHitNormals;
|
||||
|
||||
btVector3 m_previousPosition;
|
||||
|
||||
float m_jumpRechargeTimer;
|
||||
CharacterController(float height, float radius, float mass, Vector3 position);
|
||||
|
||||
void SetEntity(Entity& ent);
|
||||
void MoveAndSlide(glm::vec3 velocity);
|
||||
|
||||
bool IsOnFloor()
|
||||
class CharacterController
|
||||
{
|
||||
return IsOnGround;
|
||||
}
|
||||
public:
|
||||
bool IsOnGround = false;
|
||||
bool m_hittingWall;
|
||||
float m_stepHeight = 0.35f;
|
||||
float m_MaxSlopeAngle = 45.0f;
|
||||
|
||||
private:
|
||||
void ParseGhostContacts();
|
||||
void UpdatePosition();
|
||||
void UpdateVelocity();
|
||||
};
|
||||
}
|
||||
btTransform* m_Transform;
|
||||
btCollisionShape* m_CollisionShape;
|
||||
btRigidBody* m_Rigidbody;
|
||||
btPairCachingGhostObject* m_GhostObject;
|
||||
btMotionState* m_MotionState;
|
||||
|
||||
//bool m_onJumpableGround; // A bit lower contact than just onGround
|
||||
|
||||
float m_bottomYOffset;
|
||||
float m_bottomRoundedRegionYOffset;
|
||||
|
||||
btTransform m_motionTransform;
|
||||
|
||||
glm::vec3 m_manualVelocity;
|
||||
std::vector<glm::vec3> m_surfaceHitNormals;
|
||||
|
||||
btVector3 m_previousPosition;
|
||||
|
||||
float m_jumpRechargeTimer;
|
||||
CharacterController(float height, float radius, float mass, Vector3 position);
|
||||
|
||||
void SetEntity(Entity& ent);
|
||||
void MoveAndSlide(glm::vec3 velocity);
|
||||
|
||||
bool IsOnFloor()
|
||||
{
|
||||
return IsOnGround;
|
||||
}
|
||||
|
||||
private:
|
||||
void ParseGhostContacts();
|
||||
void UpdatePosition();
|
||||
void UpdateVelocity();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,128 +5,131 @@
|
||||
#include <src/Vendors/glm/ext/quaternion_common.hpp>
|
||||
#include <src/Core/Logger.h>
|
||||
|
||||
namespace Physics
|
||||
namespace Nuake
|
||||
{
|
||||
|
||||
DynamicWorld::DynamicWorld() {
|
||||
///collision configuration contains default setup for memory, collision setup. Advanced users can create their own configuration.
|
||||
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
|
||||
|
||||
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
|
||||
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
|
||||
|
||||
///btDbvtBroadphase is a good general purpose broadphase. You can also try out btAxis3Sweep.
|
||||
btBroadphaseInterface* overlappingPairCache = new btDbvtBroadphase();
|
||||
|
||||
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
|
||||
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
|
||||
|
||||
dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration);
|
||||
dynamicsWorld->setDebugDrawer(new BulletDebugDrawer());
|
||||
|
||||
m_Bodies = std::map<btRigidBody*, Ref<RigidBody>>();
|
||||
|
||||
SetGravity(Vector3(0, -10000, 0));
|
||||
}
|
||||
|
||||
|
||||
void DynamicWorld::DrawDebug()
|
||||
namespace Physics
|
||||
{
|
||||
dynamicsWorld->debugDrawWorld();
|
||||
}
|
||||
DynamicWorld::DynamicWorld() {
|
||||
///collision configuration contains default setup for memory, collision setup. Advanced users can create their own configuration.
|
||||
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
|
||||
|
||||
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
|
||||
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
|
||||
|
||||
void DynamicWorld::SetGravity(glm::vec3 g)
|
||||
{
|
||||
dynamicsWorld->setGravity(btVector3(g.x, g.y, g.z));
|
||||
}
|
||||
///btDbvtBroadphase is a good general purpose broadphase. You can also try out btAxis3Sweep.
|
||||
btBroadphaseInterface* overlappingPairCache = new btDbvtBroadphase();
|
||||
|
||||
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
|
||||
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
|
||||
|
||||
void DynamicWorld::AddRigidbody(Ref<RigidBody> rb)
|
||||
{
|
||||
btRigidBody* bt = rb->GetBulletRigidbody();
|
||||
m_Bodies.emplace(std::pair<btRigidBody*, Ref<RigidBody>>(bt, rb));
|
||||
dynamicsWorld->addRigidBody(rb->GetBulletRigidbody());
|
||||
}
|
||||
dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration);
|
||||
dynamicsWorld->setDebugDrawer(new BulletDebugDrawer());
|
||||
|
||||
void DynamicWorld::AddGhostbody(Ref<GhostObject> gb)
|
||||
{
|
||||
dynamicsWorld->addCollisionObject(gb->GetBulletObject(), btBroadphaseProxy::SensorTrigger, btBroadphaseProxy::KinematicFilter);
|
||||
}
|
||||
m_Bodies = std::map<btRigidBody*, Ref<RigidBody>>();
|
||||
|
||||
void DynamicWorld::AddCharacterController(Ref<CharacterController> cc)
|
||||
{
|
||||
dynamicsWorld->addRigidBody(cc->m_Rigidbody);
|
||||
|
||||
// Specify filters manually, otherwise ghost doesn't collide with statics for some reason
|
||||
dynamicsWorld->addCollisionObject(cc->m_GhostObject, btBroadphaseProxy::KinematicFilter, btBroadphaseProxy::SensorTrigger | btBroadphaseProxy::StaticFilter );
|
||||
}
|
||||
|
||||
|
||||
RaycastResult DynamicWorld::Raycast(glm::vec3 from, glm::vec3 to)
|
||||
{
|
||||
btVector3 btFrom(from.x, from.y, from.z);
|
||||
btVector3 btTo(to.x, to.y, to.z);
|
||||
ClosestRayResultCallback res(btFrom, btTo);
|
||||
|
||||
dynamicsWorld->rayTest(btFrom, btTo, res);
|
||||
btVector3 localNormal;
|
||||
if(res.m_collisionObject)
|
||||
{
|
||||
// TODO: Fix the godammn fucked up normal
|
||||
localNormal = res.m_hitNormalWorld;
|
||||
SetGravity(Vector3(0, -10000, 0));
|
||||
}
|
||||
|
||||
|
||||
Vector3 localNorm = glm::vec3(localNormal.x(), localNormal.y(), localNormal.z());
|
||||
|
||||
//Logger::Log("normal: x:" + std::to_string(localNorm.x) + " y:" + std::to_string(localNorm.y )+ "z: " + std::to_string(localNorm.z));
|
||||
res.m_closestHitFraction;
|
||||
// Map bullet result to dto.
|
||||
RaycastResult result{
|
||||
glm::vec3(res.m_hitPointWorld.x(), res.m_hitPointWorld.y(), res.m_hitPointWorld.z()),
|
||||
glm::vec3(res.m_hitPointWorld.x(), res.m_hitPointWorld.y(), res.m_hitPointWorld.z()),
|
||||
localNorm
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void DynamicWorld::StepSimulation(Timestep ts)
|
||||
{
|
||||
dynamicsWorld->stepSimulation(ts, 10);
|
||||
for (int j = dynamicsWorld->getNumCollisionObjects() - 1; j >= 0; j--)
|
||||
void DynamicWorld::DrawDebug()
|
||||
{
|
||||
btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[j];
|
||||
btRigidBody* body = btRigidBody::upcast(obj);
|
||||
btTransform trans;
|
||||
if (body && body->getMotionState())
|
||||
{
|
||||
|
||||
body->getMotionState()->getWorldTransform(trans);
|
||||
if(m_Bodies.find(body) != m_Bodies.end())
|
||||
m_Bodies[body]->UpdateTransform(trans);
|
||||
}
|
||||
else
|
||||
{
|
||||
trans = obj->getWorldTransform();
|
||||
if (m_Bodies.find(body) != m_Bodies.end())
|
||||
m_Bodies[body]->UpdateTransform(trans);
|
||||
}
|
||||
//printf("world pos object %d = %f,%f,%f\n", j, float(trans.getOrigin().getX()), float(trans.getOrigin().getY()), float(trans.getOrigin().getZ()));
|
||||
dynamicsWorld->debugDrawWorld();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DynamicWorld::Clear()
|
||||
{
|
||||
for (int j = dynamicsWorld->getNumCollisionObjects() - 1; j >= 0; j--)
|
||||
void DynamicWorld::SetGravity(glm::vec3 g)
|
||||
{
|
||||
btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[j];
|
||||
dynamicsWorld->removeCollisionObject(obj);
|
||||
dynamicsWorld->setGravity(btVector3(g.x, g.y, g.z));
|
||||
}
|
||||
|
||||
m_Bodies.clear();
|
||||
|
||||
void DynamicWorld::AddRigidbody(Ref<RigidBody> rb)
|
||||
{
|
||||
btRigidBody* bt = rb->GetBulletRigidbody();
|
||||
m_Bodies.emplace(std::pair<btRigidBody*, Ref<RigidBody>>(bt, rb));
|
||||
dynamicsWorld->addRigidBody(rb->GetBulletRigidbody());
|
||||
}
|
||||
|
||||
void DynamicWorld::AddGhostbody(Ref<GhostObject> gb)
|
||||
{
|
||||
dynamicsWorld->addCollisionObject(gb->GetBulletObject(), btBroadphaseProxy::SensorTrigger, btBroadphaseProxy::KinematicFilter);
|
||||
}
|
||||
|
||||
void DynamicWorld::AddCharacterController(Ref<CharacterController> cc)
|
||||
{
|
||||
dynamicsWorld->addRigidBody(cc->m_Rigidbody);
|
||||
|
||||
// Specify filters manually, otherwise ghost doesn't collide with statics for some reason
|
||||
dynamicsWorld->addCollisionObject(cc->m_GhostObject, btBroadphaseProxy::KinematicFilter, btBroadphaseProxy::SensorTrigger | btBroadphaseProxy::StaticFilter);
|
||||
}
|
||||
|
||||
|
||||
RaycastResult DynamicWorld::Raycast(glm::vec3 from, glm::vec3 to)
|
||||
{
|
||||
btVector3 btFrom(from.x, from.y, from.z);
|
||||
btVector3 btTo(to.x, to.y, to.z);
|
||||
ClosestRayResultCallback res(btFrom, btTo);
|
||||
|
||||
dynamicsWorld->rayTest(btFrom, btTo, res);
|
||||
btVector3 localNormal;
|
||||
if (res.m_collisionObject)
|
||||
{
|
||||
// TODO: Fix the godammn fucked up normal
|
||||
localNormal = res.m_hitNormalWorld;
|
||||
}
|
||||
|
||||
|
||||
Vector3 localNorm = glm::vec3(localNormal.x(), localNormal.y(), localNormal.z());
|
||||
|
||||
//Logger::Log("normal: x:" + std::to_string(localNorm.x) + " y:" + std::to_string(localNorm.y )+ "z: " + std::to_string(localNorm.z));
|
||||
res.m_closestHitFraction;
|
||||
// Map bullet result to dto.
|
||||
RaycastResult result{
|
||||
glm::vec3(res.m_hitPointWorld.x(), res.m_hitPointWorld.y(), res.m_hitPointWorld.z()),
|
||||
glm::vec3(res.m_hitPointWorld.x(), res.m_hitPointWorld.y(), res.m_hitPointWorld.z()),
|
||||
localNorm
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void DynamicWorld::StepSimulation(Timestep ts)
|
||||
{
|
||||
dynamicsWorld->stepSimulation(ts, 10);
|
||||
for (int j = dynamicsWorld->getNumCollisionObjects() - 1; j >= 0; j--)
|
||||
{
|
||||
btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[j];
|
||||
btRigidBody* body = btRigidBody::upcast(obj);
|
||||
btTransform trans;
|
||||
if (body && body->getMotionState())
|
||||
{
|
||||
|
||||
body->getMotionState()->getWorldTransform(trans);
|
||||
if (m_Bodies.find(body) != m_Bodies.end())
|
||||
m_Bodies[body]->UpdateTransform(trans);
|
||||
}
|
||||
else
|
||||
{
|
||||
trans = obj->getWorldTransform();
|
||||
if (m_Bodies.find(body) != m_Bodies.end())
|
||||
m_Bodies[body]->UpdateTransform(trans);
|
||||
}
|
||||
//printf("world pos object %d = %f,%f,%f\n", j, float(trans.getOrigin().getX()), float(trans.getOrigin().getY()), float(trans.getOrigin().getZ()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DynamicWorld::Clear()
|
||||
{
|
||||
for (int j = dynamicsWorld->getNumCollisionObjects() - 1; j >= 0; j--)
|
||||
{
|
||||
btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[j];
|
||||
dynamicsWorld->removeCollisionObject(obj);
|
||||
}
|
||||
|
||||
m_Bodies.clear();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,34 +2,39 @@
|
||||
#include <btBulletDynamicsCommon.h>
|
||||
#include <glm/ext/vector_float3.hpp>
|
||||
#include "Rigibody.h"
|
||||
#include "../Timestep.h"
|
||||
#include "../Core/Core.h"
|
||||
#include "src/Core/Timestep.h"
|
||||
#include "src/Core/Core.h"
|
||||
#include <map>
|
||||
#include "RaycastResult.h"
|
||||
|
||||
#include <src/Core/Physics/GhostObject.h>
|
||||
#include "CharacterController.h"
|
||||
namespace Physics {
|
||||
class DynamicWorld {
|
||||
private:
|
||||
btDiscreteDynamicsWorld* dynamicsWorld;
|
||||
std::map<btRigidBody*, Ref<RigidBody>> m_Bodies;
|
||||
public:
|
||||
DynamicWorld();
|
||||
|
||||
void DrawDebug();
|
||||
namespace Nuake
|
||||
{
|
||||
namespace Physics {
|
||||
class DynamicWorld {
|
||||
private:
|
||||
btDiscreteDynamicsWorld* dynamicsWorld;
|
||||
std::map<btRigidBody*, Ref<RigidBody>> m_Bodies;
|
||||
public:
|
||||
DynamicWorld();
|
||||
|
||||
void SetGravity(glm::vec3 g);
|
||||
void AddRigidbody(Ref<RigidBody> rb);
|
||||
void DrawDebug();
|
||||
|
||||
void AddGhostbody(Ref<GhostObject> gb);
|
||||
void SetGravity(glm::vec3 g);
|
||||
void AddRigidbody(Ref<RigidBody> rb);
|
||||
|
||||
void AddCharacterController(Ref < CharacterController> cc);
|
||||
void AddGhostbody(Ref<GhostObject> gb);
|
||||
|
||||
RaycastResult Raycast(glm::vec3 from, glm::vec3 to);
|
||||
void StepSimulation(Timestep ts);
|
||||
void Clear();
|
||||
void AddCharacterController(Ref < CharacterController> cc);
|
||||
|
||||
btDiscreteDynamicsWorld* GetDynamicWorld() { return dynamicsWorld; }
|
||||
};
|
||||
RaycastResult Raycast(glm::vec3 from, glm::vec3 to);
|
||||
void StepSimulation(Timestep ts);
|
||||
void Clear();
|
||||
|
||||
btDiscreteDynamicsWorld* GetDynamicWorld() { return dynamicsWorld; }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,57 +4,59 @@
|
||||
#include <dependencies/bullet3/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h>
|
||||
#include <src/Core/Physics/PhysicsManager.h>
|
||||
|
||||
|
||||
GhostObject::GhostObject(Vector3 position, Ref<Physics::PhysicShape> shape)
|
||||
namespace Nuake
|
||||
{
|
||||
m_OverlappingEntities = std::vector<Entity>();
|
||||
m_BulletObject = new btGhostObject();
|
||||
|
||||
btTransform transform = btTransform();
|
||||
transform.setIdentity();
|
||||
transform.setOrigin(btVector3(position.x, position.y, position.z));
|
||||
|
||||
m_BulletObject->setWorldTransform(transform);
|
||||
m_BulletObject->setCollisionShape(shape->GetBulletShape());
|
||||
}
|
||||
|
||||
int GhostObject::OverlappingCount()
|
||||
{
|
||||
return m_BulletObject->getNumOverlappingObjects();
|
||||
}
|
||||
|
||||
void GhostObject::ClearOverlappingList()
|
||||
{
|
||||
m_OverlappingEntities.clear();
|
||||
}
|
||||
|
||||
void GhostObject::SetEntityID(Entity ent)
|
||||
{
|
||||
m_BulletObject->setUserIndex(ent.GetHandle());
|
||||
}
|
||||
|
||||
void GhostObject::ScanOverlap()
|
||||
{
|
||||
ClearOverlappingList();
|
||||
|
||||
for (int i = 0; i < OverlappingCount(); i++)
|
||||
GhostObject::GhostObject(Vector3 position, Ref<Physics::PhysicShape> shape)
|
||||
{
|
||||
int index = m_BulletObject->getOverlappingObject(i)->getUserIndex();
|
||||
if (index == -1)
|
||||
continue;
|
||||
m_OverlappingEntities = std::vector<Entity>();
|
||||
m_BulletObject = new btGhostObject();
|
||||
|
||||
Entity handle = Engine::GetCurrentScene()->GetEntity(index);
|
||||
m_OverlappingEntities.push_back(handle);
|
||||
btTransform transform = btTransform();
|
||||
transform.setIdentity();
|
||||
transform.setOrigin(btVector3(position.x, position.y, position.z));
|
||||
|
||||
m_BulletObject->setWorldTransform(transform);
|
||||
m_BulletObject->setCollisionShape(shape->GetBulletShape());
|
||||
}
|
||||
|
||||
int GhostObject::OverlappingCount()
|
||||
{
|
||||
return m_BulletObject->getNumOverlappingObjects();
|
||||
}
|
||||
|
||||
void GhostObject::ClearOverlappingList()
|
||||
{
|
||||
m_OverlappingEntities.clear();
|
||||
}
|
||||
|
||||
void GhostObject::SetEntityID(Entity ent)
|
||||
{
|
||||
m_BulletObject->setUserIndex(ent.GetHandle());
|
||||
}
|
||||
|
||||
void GhostObject::ScanOverlap()
|
||||
{
|
||||
ClearOverlappingList();
|
||||
|
||||
for (int i = 0; i < OverlappingCount(); i++)
|
||||
{
|
||||
int index = m_BulletObject->getOverlappingObject(i)->getUserIndex();
|
||||
if (index == -1)
|
||||
continue;
|
||||
|
||||
Entity handle = Engine::GetCurrentScene()->GetEntity(index);
|
||||
m_OverlappingEntities.push_back(handle);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Entity> GhostObject::GetOverlappingEntities()
|
||||
{
|
||||
return m_OverlappingEntities;
|
||||
}
|
||||
|
||||
// Internal use only.
|
||||
btGhostObject* GhostObject::GetBulletObject()
|
||||
{
|
||||
return m_BulletObject;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Entity> GhostObject::GetOverlappingEntities()
|
||||
{
|
||||
return m_OverlappingEntities;
|
||||
}
|
||||
|
||||
// Internal use only.
|
||||
btGhostObject* GhostObject::GetBulletObject()
|
||||
{
|
||||
return m_BulletObject;
|
||||
}
|
||||
@@ -1,27 +1,33 @@
|
||||
#pragma once
|
||||
#include "src/Core/Core.h"
|
||||
#include "src/Core/Maths.h"
|
||||
#include "PhysicsShapes.h"
|
||||
|
||||
#include <vector>
|
||||
#include <Engine.h>
|
||||
|
||||
|
||||
class btGhostObject;
|
||||
class GhostObject {
|
||||
private:
|
||||
btGhostObject* m_BulletObject;
|
||||
std::vector<Entity> m_OverlappingEntities;
|
||||
|
||||
public:
|
||||
GhostObject(Vector3 position, Ref<Physics::PhysicShape> shape);
|
||||
namespace Nuake
|
||||
{
|
||||
class GhostObject {
|
||||
private:
|
||||
btGhostObject* m_BulletObject;
|
||||
std::vector<Entity> m_OverlappingEntities;
|
||||
|
||||
int OverlappingCount();
|
||||
void ClearOverlappingList();
|
||||
void ScanOverlap();
|
||||
public:
|
||||
GhostObject(Vector3 position, Ref<Physics::PhysicShape> shape);
|
||||
|
||||
void SetEntityID(Entity ent);
|
||||
int OverlappingCount();
|
||||
void ClearOverlappingList();
|
||||
void ScanOverlap();
|
||||
|
||||
std::vector<Entity> GetOverlappingEntities();
|
||||
void SetEntityID(Entity ent);
|
||||
|
||||
// Internal use only.
|
||||
btGhostObject* GetBulletObject();
|
||||
};
|
||||
std::vector<Entity> GetOverlappingEntities();
|
||||
|
||||
// Internal use only.
|
||||
btGhostObject* GetBulletObject();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,54 +2,58 @@
|
||||
#include "PhysicsShapes.h"
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "../Core/Core.h"
|
||||
PhysicsManager* PhysicsManager::m_Instance;
|
||||
|
||||
void PhysicsManager::RegisterBody(Ref<Physics::RigidBody> rb) {
|
||||
m_World->AddRigidbody(rb);
|
||||
}
|
||||
|
||||
void PhysicsManager::RegisterGhostBody(Ref<GhostObject> rb)
|
||||
namespace Nuake
|
||||
{
|
||||
m_World->AddGhostbody(rb);
|
||||
|
||||
PhysicsManager* PhysicsManager::m_Instance;
|
||||
|
||||
void PhysicsManager::RegisterBody(Ref<Physics::RigidBody> rb) {
|
||||
m_World->AddRigidbody(rb);
|
||||
}
|
||||
|
||||
void PhysicsManager::RegisterGhostBody(Ref<GhostObject> rb)
|
||||
{
|
||||
m_World->AddGhostbody(rb);
|
||||
|
||||
}
|
||||
|
||||
void PhysicsManager::RegisterCharacterController(Ref<Physics::CharacterController> cc) {
|
||||
m_World->AddCharacterController(cc);
|
||||
}
|
||||
|
||||
void PhysicsManager::Step(Timestep ts)
|
||||
{
|
||||
m_World->StepSimulation(ts);
|
||||
}
|
||||
|
||||
void PhysicsManager::Reset()
|
||||
{
|
||||
m_World->Clear();
|
||||
}
|
||||
|
||||
RaycastResult PhysicsManager::Raycast(glm::vec3 from, glm::vec3 to)
|
||||
{
|
||||
btVector3 btFrom(from.x, from.y, from.z);
|
||||
btVector3 btTo(to.x, to.y, to.z);
|
||||
btCollisionWorld::ClosestRayResultCallback res(btFrom, btTo);
|
||||
|
||||
return m_World->Raycast(from, to);
|
||||
|
||||
}
|
||||
|
||||
void PhysicsManager::DrawDebug()
|
||||
{
|
||||
if (m_DrawDebug)
|
||||
m_World->DrawDebug();
|
||||
}
|
||||
|
||||
void PhysicsManager::Init() {
|
||||
|
||||
m_World = new Physics::DynamicWorld();
|
||||
m_World->SetGravity(glm::vec3(0, -3, 0));
|
||||
|
||||
m_World->GetDynamicWorld()->getBroadphase()->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
|
||||
|
||||
m_IsRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsManager::RegisterCharacterController(Ref<Physics::CharacterController> cc) {
|
||||
m_World->AddCharacterController(cc);
|
||||
}
|
||||
|
||||
void PhysicsManager::Step(Timestep ts)
|
||||
{
|
||||
m_World->StepSimulation(ts);
|
||||
}
|
||||
|
||||
void PhysicsManager::Reset()
|
||||
{
|
||||
m_World->Clear();
|
||||
}
|
||||
|
||||
RaycastResult PhysicsManager::Raycast(glm::vec3 from, glm::vec3 to)
|
||||
{
|
||||
btVector3 btFrom(from.x, from.y, from.z);
|
||||
btVector3 btTo(to.x, to.y, to.z);
|
||||
btCollisionWorld::ClosestRayResultCallback res(btFrom, btTo);
|
||||
|
||||
return m_World->Raycast(from, to);
|
||||
|
||||
}
|
||||
|
||||
void PhysicsManager::DrawDebug()
|
||||
{
|
||||
if(m_DrawDebug)
|
||||
m_World->DrawDebug();
|
||||
}
|
||||
|
||||
void PhysicsManager::Init() {
|
||||
|
||||
m_World = new Physics::DynamicWorld();
|
||||
m_World->SetGravity(glm::vec3(0, -3, 0));
|
||||
|
||||
m_World->GetDynamicWorld()->getBroadphase()->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
|
||||
|
||||
m_IsRunning = false;
|
||||
}
|
||||
@@ -5,48 +5,52 @@
|
||||
#include "Rigibody.h"
|
||||
|
||||
#include "RaycastResult.h"
|
||||
class PhysicsManager
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
private:
|
||||
Physics::DynamicWorld* m_World;
|
||||
bool m_IsRunning = false;
|
||||
btAlignedObjectArray<btCollisionShape*> collisionShapes;
|
||||
|
||||
bool m_DrawDebug = false;
|
||||
static PhysicsManager* m_Instance;
|
||||
public:
|
||||
static PhysicsManager* Get()
|
||||
class PhysicsManager
|
||||
{
|
||||
if (!m_Instance)
|
||||
m_Instance = new PhysicsManager();
|
||||
return m_Instance;
|
||||
}
|
||||
private:
|
||||
Physics::DynamicWorld* m_World;
|
||||
bool m_IsRunning = false;
|
||||
btAlignedObjectArray<btCollisionShape*> collisionShapes;
|
||||
|
||||
Physics::DynamicWorld* GetWorld() { return m_World; }
|
||||
bool m_DrawDebug = false;
|
||||
static PhysicsManager* m_Instance;
|
||||
public:
|
||||
static PhysicsManager* Get()
|
||||
{
|
||||
if (!m_Instance)
|
||||
m_Instance = new PhysicsManager();
|
||||
return m_Instance;
|
||||
}
|
||||
|
||||
PhysicsManager() { if (!m_Instance) m_Instance = this; }
|
||||
Physics::DynamicWorld* GetWorld() { return m_World; }
|
||||
|
||||
void SetDrawDebug(bool value) {
|
||||
m_DrawDebug = value;
|
||||
}
|
||||
PhysicsManager() { if (!m_Instance) m_Instance = this; }
|
||||
|
||||
bool GetDrawDebug() {
|
||||
return m_DrawDebug;
|
||||
}
|
||||
void SetDrawDebug(bool value) {
|
||||
m_DrawDebug = value;
|
||||
}
|
||||
|
||||
void Init();
|
||||
bool GetDrawDebug() {
|
||||
return m_DrawDebug;
|
||||
}
|
||||
|
||||
void Start() { m_IsRunning = true; }
|
||||
void Stop() { m_IsRunning = false; }
|
||||
void DrawDebug();
|
||||
bool IsRunning() { return m_IsRunning; }
|
||||
void Step(Timestep ts);
|
||||
void Init();
|
||||
|
||||
void Reset();
|
||||
void Start() { m_IsRunning = true; }
|
||||
void Stop() { m_IsRunning = false; }
|
||||
void DrawDebug();
|
||||
bool IsRunning() { return m_IsRunning; }
|
||||
void Step(Timestep ts);
|
||||
|
||||
RaycastResult Raycast(glm::vec3 from, glm::vec3 to);
|
||||
void Reset();
|
||||
|
||||
void RegisterBody(Ref<Physics::RigidBody> rb);
|
||||
void RegisterGhostBody(Ref<GhostObject> rb);
|
||||
void RegisterCharacterController(Ref<Physics::CharacterController> c);
|
||||
};
|
||||
RaycastResult Raycast(glm::vec3 from, glm::vec3 to);
|
||||
|
||||
void RegisterBody(Ref<Physics::RigidBody> rb);
|
||||
void RegisterGhostBody(Ref<GhostObject> rb);
|
||||
void RegisterCharacterController(Ref<Physics::CharacterController> c);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,60 +1,67 @@
|
||||
#include "PhysicsShapes.h"
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
Physics::Box::Box()
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
Size = glm::vec3(1);
|
||||
bShape = new btBoxShape(btVector3(Size.x, Size.y, Size.z));
|
||||
m_Type = BOX;
|
||||
}
|
||||
// Sphere
|
||||
Physics::Box::Box(glm::vec3 size) {
|
||||
Size = size;
|
||||
bShape = new btBoxShape(btVector3(size.x, size.y, size.z));
|
||||
m_Type = BOX;
|
||||
}
|
||||
|
||||
Physics::Box::Box(float x, float y, float z) {
|
||||
Size = glm::vec3(x, y, z);
|
||||
bShape = new btBoxShape(btVector3(x, y, z));
|
||||
m_Type = BOX;
|
||||
}
|
||||
|
||||
btCollisionShape* Physics::Box::GetBulletShape()
|
||||
{
|
||||
return bShape;
|
||||
}
|
||||
|
||||
// Sphere
|
||||
Physics::Sphere::Sphere(float radius) {
|
||||
Radius = radius;
|
||||
bShape = new btSphereShape(Radius);
|
||||
|
||||
m_Type = SPHERE;
|
||||
}
|
||||
|
||||
void Physics::Sphere::SetRadius(float radius) {
|
||||
((btSphereShape*)bShape)->setUnscaledRadius(radius);
|
||||
Radius = radius;
|
||||
}
|
||||
|
||||
btCollisionShape* Physics::Sphere::GetBulletShape()
|
||||
{
|
||||
return bShape;
|
||||
}
|
||||
|
||||
Physics::MeshShape::MeshShape(Ref<Mesh> mesh)
|
||||
{
|
||||
m_Mesh = mesh;
|
||||
btConvexHullShape* trimesh = new btConvexHullShape();
|
||||
|
||||
for (Vertex i : mesh->m_Vertices)
|
||||
namespace Physics
|
||||
{
|
||||
trimesh->addPoint(btVector3(i.position.x, i.position.y, i.position.z));
|
||||
}
|
||||
bShape = trimesh;
|
||||
}
|
||||
Box::Box()
|
||||
{
|
||||
Size = glm::vec3(1);
|
||||
bShape = new btBoxShape(btVector3(Size.x, Size.y, Size.z));
|
||||
m_Type = BOX;
|
||||
}
|
||||
// Sphere
|
||||
Box::Box(glm::vec3 size) {
|
||||
Size = size;
|
||||
bShape = new btBoxShape(btVector3(size.x, size.y, size.z));
|
||||
m_Type = BOX;
|
||||
}
|
||||
|
||||
btCollisionShape* Physics::MeshShape::GetBulletShape()
|
||||
{
|
||||
return bShape;
|
||||
}
|
||||
Box::Box(float x, float y, float z) {
|
||||
Size = glm::vec3(x, y, z);
|
||||
bShape = new btBoxShape(btVector3(x, y, z));
|
||||
m_Type = BOX;
|
||||
}
|
||||
|
||||
btCollisionShape* Box::GetBulletShape()
|
||||
{
|
||||
return bShape;
|
||||
}
|
||||
|
||||
// Sphere
|
||||
Sphere::Sphere(float radius) {
|
||||
Radius = radius;
|
||||
bShape = new btSphereShape(Radius);
|
||||
|
||||
m_Type = SPHERE;
|
||||
}
|
||||
|
||||
void Sphere::SetRadius(float radius) {
|
||||
((btSphereShape*)bShape)->setUnscaledRadius(radius);
|
||||
Radius = radius;
|
||||
}
|
||||
|
||||
btCollisionShape* Sphere::GetBulletShape()
|
||||
{
|
||||
return bShape;
|
||||
}
|
||||
|
||||
MeshShape::MeshShape(Ref<Mesh> mesh)
|
||||
{
|
||||
m_Mesh = mesh;
|
||||
btConvexHullShape* trimesh = new btConvexHullShape();
|
||||
|
||||
for (Vertex i : mesh->m_Vertices)
|
||||
{
|
||||
trimesh->addPoint(btVector3(i.position.x, i.position.y, i.position.z));
|
||||
}
|
||||
bShape = trimesh;
|
||||
}
|
||||
|
||||
btCollisionShape* MeshShape::GetBulletShape()
|
||||
{
|
||||
return bShape;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,58 +1,70 @@
|
||||
#pragma once
|
||||
#include "src/Core/Maths.h"
|
||||
#include "src/Rendering/Mesh/Mesh.h"
|
||||
|
||||
#include <glm/ext/vector_float3.hpp>
|
||||
#include "../../Rendering/Mesh/Mesh.h"
|
||||
class btCollisionShape;
|
||||
namespace Physics {
|
||||
enum RigidbodyShapes {
|
||||
BOX, SPHERE, CAPSULE, MESH
|
||||
};
|
||||
class PhysicShape {
|
||||
protected:
|
||||
btCollisionShape* bShape;
|
||||
RigidbodyShapes m_Type;
|
||||
public:
|
||||
virtual btCollisionShape* GetBulletShape() = 0;
|
||||
RigidbodyShapes GetType() const { return m_Type; }
|
||||
|
||||
};
|
||||
|
||||
class Box : public PhysicShape {
|
||||
private:
|
||||
glm::vec3 Size;
|
||||
btCollisionShape* bShape;
|
||||
public:
|
||||
Box();
|
||||
Box(glm::vec3 size);
|
||||
Box(float x, float y, float z);
|
||||
namespace Nuake
|
||||
{
|
||||
namespace Physics
|
||||
{
|
||||
enum RigidbodyShapes
|
||||
{
|
||||
BOX, SPHERE, CAPSULE, MESH
|
||||
};
|
||||
|
||||
glm::vec3 GetSize() const { return Size; }
|
||||
btCollisionShape* GetBulletShape() override;
|
||||
};
|
||||
class PhysicShape
|
||||
{
|
||||
protected:
|
||||
btCollisionShape* bShape;
|
||||
RigidbodyShapes m_Type;
|
||||
public:
|
||||
virtual btCollisionShape* GetBulletShape() = 0;
|
||||
RigidbodyShapes GetType() const { return m_Type; }
|
||||
|
||||
class Sphere : public PhysicShape {
|
||||
private:
|
||||
float Radius;
|
||||
btCollisionShape* bShape;
|
||||
public:
|
||||
Sphere(float radius);
|
||||
};
|
||||
|
||||
float GetRadius() const { return Radius; }
|
||||
void SetRadius(float radius);
|
||||
class Box : public PhysicShape
|
||||
{
|
||||
private:
|
||||
glm::vec3 Size;
|
||||
btCollisionShape* bShape;
|
||||
public:
|
||||
Box();
|
||||
Box(glm::vec3 size);
|
||||
Box(float x, float y, float z);
|
||||
|
||||
btCollisionShape* GetBulletShape() override;
|
||||
};
|
||||
glm::vec3 GetSize() const { return Size; }
|
||||
btCollisionShape* GetBulletShape() override;
|
||||
};
|
||||
|
||||
class MeshShape : public PhysicShape {
|
||||
private:
|
||||
Ref<Mesh> m_Mesh;
|
||||
btCollisionShape* bShape;
|
||||
public:
|
||||
MeshShape(Ref<Mesh> mesh);
|
||||
class Sphere : public PhysicShape
|
||||
{
|
||||
private:
|
||||
float Radius;
|
||||
btCollisionShape* bShape;
|
||||
public:
|
||||
Sphere(float radius);
|
||||
|
||||
void SetMesh(Mesh* mesh);
|
||||
Mesh* GetMesh();
|
||||
float GetRadius() const { return Radius; }
|
||||
void SetRadius(float radius);
|
||||
|
||||
btCollisionShape* GetBulletShape() override;
|
||||
};
|
||||
|
||||
class MeshShape : public PhysicShape
|
||||
{
|
||||
private:
|
||||
Ref<Mesh> m_Mesh;
|
||||
btCollisionShape* bShape;
|
||||
public:
|
||||
MeshShape(Ref<Mesh> mesh);
|
||||
|
||||
void SetMesh(Mesh* mesh);
|
||||
Mesh* GetMesh();
|
||||
|
||||
btCollisionShape* GetBulletShape() override;
|
||||
};
|
||||
}
|
||||
|
||||
btCollisionShape* GetBulletShape() override;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,66 +3,70 @@
|
||||
#include "CharacterController.h"
|
||||
|
||||
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
|
||||
namespace Physics
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
struct ClosestRayResultCallback : public btCollisionWorld::RayResultCallback
|
||||
namespace Physics
|
||||
{
|
||||
ClosestRayResultCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld)
|
||||
: m_rayFromWorld(rayFromWorld),
|
||||
m_rayToWorld(rayToWorld)
|
||||
struct ClosestRayResultCallback : public btCollisionWorld::RayResultCallback
|
||||
{
|
||||
}
|
||||
ClosestRayResultCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld)
|
||||
: m_rayFromWorld(rayFromWorld),
|
||||
m_rayToWorld(rayToWorld)
|
||||
{
|
||||
}
|
||||
|
||||
btVector3 m_rayFromWorld; //used to calculate hitPointWorld from hitFraction
|
||||
btVector3 m_rayToWorld;
|
||||
btVector3 m_rayFromWorld; //used to calculate hitPointWorld from hitFraction
|
||||
btVector3 m_rayToWorld;
|
||||
|
||||
btVector3 m_hitNormalWorld;
|
||||
btVector3 m_hitPointWorld;
|
||||
btVector3 m_hitNormalWorld;
|
||||
btVector3 m_hitPointWorld;
|
||||
|
||||
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace)
|
||||
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace)
|
||||
{
|
||||
//caller already does the filter on the m_closestHitFraction
|
||||
btAssert(rayResult.m_hitFraction <= m_closestHitFraction);
|
||||
|
||||
m_closestHitFraction = rayResult.m_hitFraction;
|
||||
m_collisionObject = rayResult.m_collisionObject;
|
||||
|
||||
m_hitNormalWorld = rayResult.m_hitNormalLocal;
|
||||
|
||||
|
||||
m_hitPointWorld.setInterpolate3(m_rayFromWorld, m_rayToWorld, rayResult.m_hitFraction);
|
||||
return rayResult.m_hitFraction;
|
||||
}
|
||||
};
|
||||
|
||||
class IgnoreBodyAndGhostCast :
|
||||
public Physics::ClosestRayResultCallback
|
||||
{
|
||||
//caller already does the filter on the m_closestHitFraction
|
||||
btAssert(rayResult.m_hitFraction <= m_closestHitFraction);
|
||||
private:
|
||||
btRigidBody* m_pBody;
|
||||
btPairCachingGhostObject* m_pGhostObject;
|
||||
|
||||
m_closestHitFraction = rayResult.m_hitFraction;
|
||||
m_collisionObject = rayResult.m_collisionObject;
|
||||
public:
|
||||
IgnoreBodyAndGhostCast(btRigidBody* pBody, btPairCachingGhostObject* pGhostObject)
|
||||
: ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)),
|
||||
m_pBody(pBody), m_pGhostObject(pGhostObject)
|
||||
{
|
||||
}
|
||||
|
||||
m_hitNormalWorld = rayResult.m_hitNormalLocal;
|
||||
btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace)
|
||||
{
|
||||
if (rayResult.m_collisionObject == m_pBody || rayResult.m_collisionObject == m_pGhostObject)
|
||||
return 1.0f;
|
||||
|
||||
return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
m_hitPointWorld.setInterpolate3(m_rayFromWorld, m_rayToWorld, rayResult.m_hitFraction);
|
||||
return rayResult.m_hitFraction;
|
||||
}
|
||||
};
|
||||
|
||||
class IgnoreBodyAndGhostCast :
|
||||
public Physics::ClosestRayResultCallback
|
||||
{
|
||||
private:
|
||||
btRigidBody* m_pBody;
|
||||
btPairCachingGhostObject* m_pGhostObject;
|
||||
|
||||
public:
|
||||
IgnoreBodyAndGhostCast(btRigidBody* pBody, btPairCachingGhostObject* pGhostObject)
|
||||
: ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)),
|
||||
m_pBody(pBody), m_pGhostObject(pGhostObject)
|
||||
{
|
||||
}
|
||||
|
||||
btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace)
|
||||
{
|
||||
if (rayResult.m_collisionObject == m_pBody || rayResult.m_collisionObject == m_pGhostObject)
|
||||
return 1.0f;
|
||||
|
||||
return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace);
|
||||
}
|
||||
// result object from raycast.
|
||||
struct RaycastResult {
|
||||
glm::vec3 WorldPoint;
|
||||
glm::vec3 LocalPoint;
|
||||
glm::vec3 Normal;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// result object from raycast.
|
||||
struct RaycastResult {
|
||||
glm::vec3 WorldPoint;
|
||||
glm::vec3 LocalPoint;
|
||||
glm::vec3 Normal;
|
||||
};
|
||||
@@ -5,44 +5,48 @@
|
||||
struct btTransform;
|
||||
struct btRigidBody;
|
||||
struct btVector3;
|
||||
class Entity;
|
||||
namespace Physics {
|
||||
class RigidBody {
|
||||
private:
|
||||
bool m_IsDynamic = false;
|
||||
bool m_IsKinematic = false;
|
||||
glm::vec3 m_InitialVel;
|
||||
|
||||
|
||||
btRigidBody* m_Rigidbody;
|
||||
namespace Nuake
|
||||
{
|
||||
class Entity;
|
||||
namespace Physics {
|
||||
class RigidBody {
|
||||
private:
|
||||
bool m_IsDynamic = false;
|
||||
bool m_IsKinematic = false;
|
||||
glm::vec3 m_InitialVel;
|
||||
|
||||
Ref<PhysicShape> m_CollisionShape;
|
||||
public:
|
||||
btTransform* m_Transform;
|
||||
float m_Mass;
|
||||
btRigidBody* m_Rigidbody;
|
||||
|
||||
RigidBody();
|
||||
RigidBody(glm::vec3 position, Entity handle);
|
||||
RigidBody(float mass, glm::vec3 position, Ref<PhysicShape> shape, glm::vec3 initialVel = glm::vec3(0, 0, 0));
|
||||
Ref<PhysicShape> m_CollisionShape;
|
||||
public:
|
||||
btTransform* m_Transform;
|
||||
float m_Mass;
|
||||
|
||||
btRigidBody* GetBulletRigidbody() const { return m_Rigidbody; }
|
||||
|
||||
void UpdateTransform(btTransform t);
|
||||
glm::vec3 GetPosition() const;
|
||||
glm::vec3 GetRotation() const;
|
||||
RigidBody();
|
||||
RigidBody(glm::vec3 position, Entity handle);
|
||||
RigidBody(float mass, glm::vec3 position, Ref<PhysicShape> shape, glm::vec3 initialVel = glm::vec3(0, 0, 0));
|
||||
|
||||
void SetEntityID(Entity ent);
|
||||
btRigidBody* GetBulletRigidbody() const { return m_Rigidbody; }
|
||||
|
||||
void SetKinematic(bool value);
|
||||
bool IsKinematic() const { return m_IsKinematic; }
|
||||
void UpdateTransform(btTransform t);
|
||||
glm::vec3 GetPosition() const;
|
||||
glm::vec3 GetRotation() const;
|
||||
|
||||
bool HasShape() { return m_CollisionShape != nullptr; }
|
||||
void SetShape(Ref<PhysicShape> shape);
|
||||
Ref<PhysicShape> GetShape() const { return m_CollisionShape; }
|
||||
void SetEntityID(Entity ent);
|
||||
|
||||
float GetMass() const { return m_Mass; }
|
||||
void SetMass(float m);
|
||||
void SetKinematic(bool value);
|
||||
bool IsKinematic() const { return m_IsKinematic; }
|
||||
|
||||
bool HasShape() { return m_CollisionShape != nullptr; }
|
||||
void SetShape(Ref<PhysicShape> shape);
|
||||
Ref<PhysicShape> GetShape() const { return m_CollisionShape; }
|
||||
|
||||
float GetMass() const { return m_Mass; }
|
||||
void SetMass(float m);
|
||||
|
||||
void MoveAndSlide(glm::vec3 velocity);
|
||||
};
|
||||
}
|
||||
|
||||
void MoveAndSlide(glm::vec3 velocity);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,116 +4,120 @@
|
||||
#include "../Core.h"
|
||||
#include <glm/trigonometric.hpp>
|
||||
#include <src/Scene/Entities/Entity.h>
|
||||
namespace Physics
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
RigidBody::RigidBody()
|
||||
namespace Physics
|
||||
{
|
||||
m_Transform = new btTransform();
|
||||
m_Transform->setIdentity();
|
||||
//m_Transform->setOrigin(btVector3(position.x, position.y, position.z));
|
||||
}
|
||||
|
||||
RigidBody::RigidBody(glm::vec3 position, Entity handle)
|
||||
{
|
||||
Ref<Box> shape = CreateRef<Box>();
|
||||
m_CollisionShape = shape;
|
||||
|
||||
m_Transform = new btTransform();
|
||||
m_Transform->setIdentity();
|
||||
m_Transform->setOrigin(btVector3(position.x, position.y, position.z));
|
||||
|
||||
m_Mass = 0.0f;
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
m_IsDynamic = (m_Mass != 0.0f);
|
||||
|
||||
btVector3 localInertia(0, 0, 0);
|
||||
if (m_IsDynamic)
|
||||
m_CollisionShape->GetBulletShape()->calculateLocalInertia(m_Mass, localInertia);
|
||||
|
||||
m_InitialVel = glm::vec3(0, 0, 0);
|
||||
|
||||
//using motionstate is optional, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(*m_Transform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(m_Mass, myMotionState, m_CollisionShape->GetBulletShape(), localInertia);
|
||||
|
||||
m_Rigidbody = new btRigidBody(rbInfo);
|
||||
m_Rigidbody->setUserIndex(handle.GetHandle());
|
||||
}
|
||||
|
||||
RigidBody::RigidBody(float mass, glm::vec3 position, Ref<PhysicShape> shape, glm::vec3 initialVel)
|
||||
{
|
||||
m_CollisionShape = shape;
|
||||
|
||||
m_Transform = new btTransform();
|
||||
m_Transform->setIdentity();
|
||||
m_Transform->setOrigin(btVector3(position.x, position.y, position.z));
|
||||
|
||||
m_Mass = mass;
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
m_IsDynamic = (m_Mass != 0.0f);
|
||||
|
||||
btVector3 localInertia(initialVel.x, initialVel.y, initialVel.z);
|
||||
m_InitialVel = initialVel;
|
||||
if (m_IsDynamic)
|
||||
m_CollisionShape->GetBulletShape()->calculateLocalInertia(m_Mass, localInertia);
|
||||
|
||||
//using motionstate is optional, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(*m_Transform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(m_Mass, myMotionState, m_CollisionShape->GetBulletShape(), localInertia);
|
||||
|
||||
m_Rigidbody = new btRigidBody(rbInfo);
|
||||
}
|
||||
|
||||
void RigidBody::SetShape(Ref<PhysicShape> shape)
|
||||
{
|
||||
m_Rigidbody->setCollisionShape(shape->GetBulletShape());
|
||||
m_CollisionShape = shape;
|
||||
}
|
||||
|
||||
void RigidBody::UpdateTransform(btTransform t)
|
||||
{
|
||||
m_Transform->setOrigin(t.getOrigin());
|
||||
m_Transform->setRotation(t.getRotation());
|
||||
m_Rigidbody->setWorldTransform(t);
|
||||
}
|
||||
|
||||
glm::vec3 RigidBody::GetRotation() const {
|
||||
auto q = m_Transform->getRotation();
|
||||
btScalar x = 0, y = 0, z = 0;
|
||||
q.getEulerZYX(z, y, x);
|
||||
return glm::vec3(glm::degrees(x), glm::degrees(y), glm::degrees(z));
|
||||
}
|
||||
|
||||
void RigidBody::SetEntityID(Entity ent)
|
||||
{
|
||||
m_Rigidbody->setUserIndex(ent.GetHandle());
|
||||
}
|
||||
|
||||
void RigidBody::SetKinematic(bool value)
|
||||
{
|
||||
if (value) // Kinematic bodies dont deactivate.
|
||||
RigidBody::RigidBody()
|
||||
{
|
||||
m_Rigidbody->setCollisionFlags(m_Rigidbody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
|
||||
m_Rigidbody->setActivationState(DISABLE_DEACTIVATION);
|
||||
m_Transform = new btTransform();
|
||||
m_Transform->setIdentity();
|
||||
//m_Transform->setOrigin(btVector3(position.x, position.y, position.z));
|
||||
}
|
||||
else // Reenable deactivation.
|
||||
|
||||
RigidBody::RigidBody(glm::vec3 position, Entity handle)
|
||||
{
|
||||
m_Rigidbody->setCollisionFlags(m_Rigidbody->getCollisionFlags() ^ ~btCollisionObject::CF_KINEMATIC_OBJECT);
|
||||
m_Rigidbody->setActivationState(WANTS_DEACTIVATION);
|
||||
Ref<Box> shape = CreateRef<Box>();
|
||||
m_CollisionShape = shape;
|
||||
|
||||
m_Transform = new btTransform();
|
||||
m_Transform->setIdentity();
|
||||
m_Transform->setOrigin(btVector3(position.x, position.y, position.z));
|
||||
|
||||
m_Mass = 0.0f;
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
m_IsDynamic = (m_Mass != 0.0f);
|
||||
|
||||
btVector3 localInertia(0, 0, 0);
|
||||
if (m_IsDynamic)
|
||||
m_CollisionShape->GetBulletShape()->calculateLocalInertia(m_Mass, localInertia);
|
||||
|
||||
m_InitialVel = glm::vec3(0, 0, 0);
|
||||
|
||||
//using motionstate is optional, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(*m_Transform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(m_Mass, myMotionState, m_CollisionShape->GetBulletShape(), localInertia);
|
||||
|
||||
m_Rigidbody = new btRigidBody(rbInfo);
|
||||
m_Rigidbody->setUserIndex(handle.GetHandle());
|
||||
}
|
||||
|
||||
RigidBody::RigidBody(float mass, glm::vec3 position, Ref<PhysicShape> shape, glm::vec3 initialVel)
|
||||
{
|
||||
m_CollisionShape = shape;
|
||||
|
||||
m_Transform = new btTransform();
|
||||
m_Transform->setIdentity();
|
||||
m_Transform->setOrigin(btVector3(position.x, position.y, position.z));
|
||||
|
||||
m_Mass = mass;
|
||||
|
||||
//rigidbody is dynamic if and only if mass is non zero, otherwise static
|
||||
m_IsDynamic = (m_Mass != 0.0f);
|
||||
|
||||
btVector3 localInertia(initialVel.x, initialVel.y, initialVel.z);
|
||||
m_InitialVel = initialVel;
|
||||
if (m_IsDynamic)
|
||||
m_CollisionShape->GetBulletShape()->calculateLocalInertia(m_Mass, localInertia);
|
||||
|
||||
//using motionstate is optional, it provides interpolation capabilities, and only synchronizes 'active' objects
|
||||
btDefaultMotionState* myMotionState = new btDefaultMotionState(*m_Transform);
|
||||
btRigidBody::btRigidBodyConstructionInfo rbInfo(m_Mass, myMotionState, m_CollisionShape->GetBulletShape(), localInertia);
|
||||
|
||||
m_Rigidbody = new btRigidBody(rbInfo);
|
||||
}
|
||||
|
||||
void RigidBody::SetShape(Ref<PhysicShape> shape)
|
||||
{
|
||||
m_Rigidbody->setCollisionShape(shape->GetBulletShape());
|
||||
m_CollisionShape = shape;
|
||||
}
|
||||
|
||||
void RigidBody::UpdateTransform(btTransform t)
|
||||
{
|
||||
m_Transform->setOrigin(t.getOrigin());
|
||||
m_Transform->setRotation(t.getRotation());
|
||||
m_Rigidbody->setWorldTransform(t);
|
||||
}
|
||||
|
||||
glm::vec3 RigidBody::GetRotation() const {
|
||||
auto q = m_Transform->getRotation();
|
||||
btScalar x = 0, y = 0, z = 0;
|
||||
q.getEulerZYX(z, y, x);
|
||||
return glm::vec3(glm::degrees(x), glm::degrees(y), glm::degrees(z));
|
||||
}
|
||||
|
||||
void RigidBody::SetEntityID(Entity ent)
|
||||
{
|
||||
m_Rigidbody->setUserIndex(ent.GetHandle());
|
||||
}
|
||||
|
||||
void RigidBody::SetKinematic(bool value)
|
||||
{
|
||||
if (value) // Kinematic bodies dont deactivate.
|
||||
{
|
||||
m_Rigidbody->setCollisionFlags(m_Rigidbody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
|
||||
m_Rigidbody->setActivationState(DISABLE_DEACTIVATION);
|
||||
}
|
||||
else // Reenable deactivation.
|
||||
{
|
||||
m_Rigidbody->setCollisionFlags(m_Rigidbody->getCollisionFlags() ^ ~btCollisionObject::CF_KINEMATIC_OBJECT);
|
||||
m_Rigidbody->setActivationState(WANTS_DEACTIVATION);
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 RigidBody::GetPosition() const {
|
||||
btVector3 btPos = m_Transform->getOrigin();
|
||||
|
||||
return glm::vec3(btPos.x(), btPos.y(), btPos.z());
|
||||
}
|
||||
|
||||
void RigidBody::SetMass(float m) { m_Rigidbody->setMassProps(m, btVector3(m_InitialVel.x, m_InitialVel.y, m_InitialVel.y)); m_Mass = m; }
|
||||
void RigidBody::MoveAndSlide(glm::vec3 velocity)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 RigidBody::GetPosition() const {
|
||||
btVector3 btPos = m_Transform->getOrigin();
|
||||
|
||||
return glm::vec3(btPos.x(), btPos.y(), btPos.z());
|
||||
}
|
||||
|
||||
void RigidBody::SetMass(float m) { m_Rigidbody->setMassProps(m, btVector3(m_InitialVel.x, m_InitialVel.y, m_InitialVel.y)); m_Mass = m; }
|
||||
void RigidBody::MoveAndSlide(glm::vec3 velocity)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,29 @@
|
||||
#include "TextureManager.h"
|
||||
#include "../Rendering/Textures/Texture.h"
|
||||
#include "src/Rendering/Textures/Texture.h"
|
||||
|
||||
std::map<std::string, Ref<Texture>> TextureManager::m_Registry;
|
||||
|
||||
TextureManager* TextureManager::s_Instance = nullptr;
|
||||
|
||||
bool TextureManager::IsTextureLoaded(const std::string path)
|
||||
namespace Nuake
|
||||
{
|
||||
return m_Registry.find(path) != m_Registry.end();
|
||||
}
|
||||
|
||||
Ref<Texture> TextureManager::GetTexture(const std::string path)
|
||||
{
|
||||
if (!IsTextureLoaded(path))
|
||||
m_Registry.emplace(path, new Texture(path));
|
||||
|
||||
return m_Registry.at(path);
|
||||
}
|
||||
|
||||
TextureManager* TextureManager::Get() { return s_Instance; }
|
||||
|
||||
TextureManager::TextureManager()
|
||||
{
|
||||
s_Instance = this;
|
||||
std::map<std::string, Ref<Texture>> TextureManager::m_Registry;
|
||||
|
||||
TextureManager* TextureManager::s_Instance = nullptr;
|
||||
|
||||
bool TextureManager::IsTextureLoaded(const std::string path)
|
||||
{
|
||||
return m_Registry.find(path) != m_Registry.end();
|
||||
}
|
||||
|
||||
Ref<Texture> TextureManager::GetTexture(const std::string path)
|
||||
{
|
||||
if (!IsTextureLoaded(path))
|
||||
m_Registry.emplace(path, new Texture(path));
|
||||
|
||||
return m_Registry.at(path);
|
||||
}
|
||||
|
||||
TextureManager* TextureManager::Get() { return s_Instance; }
|
||||
|
||||
TextureManager::TextureManager()
|
||||
{
|
||||
s_Instance = this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
#pragma once
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "../Core/Core.h"
|
||||
class Texture;
|
||||
#include "src/Core/Core.h"
|
||||
|
||||
// Todo: SHOULD probably be static too.
|
||||
class TextureManager
|
||||
namespace Nuake
|
||||
{
|
||||
private:
|
||||
static TextureManager* s_Instance;
|
||||
class Texture;
|
||||
|
||||
static std::map<std::string, Ref<Texture>> m_Registry;
|
||||
bool IsTextureLoaded(const std::string path);
|
||||
// Todo: SHOULD probably be static too.
|
||||
class TextureManager
|
||||
{
|
||||
private:
|
||||
static TextureManager* s_Instance;
|
||||
|
||||
public:
|
||||
static TextureManager* Get();
|
||||
static std::map<std::string, Ref<Texture>> m_Registry;
|
||||
bool IsTextureLoaded(const std::string path);
|
||||
|
||||
TextureManager();
|
||||
public:
|
||||
static TextureManager* Get();
|
||||
|
||||
Ref<Texture> GetTexture(const std::string path);
|
||||
};
|
||||
TextureManager();
|
||||
|
||||
Ref<Texture> GetTexture(const std::string path);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
class Timestep {
|
||||
private:
|
||||
float m_Time;
|
||||
namespace Nuake
|
||||
{
|
||||
class Timestep {
|
||||
private:
|
||||
float m_Time;
|
||||
|
||||
public:
|
||||
operator float() const { return m_Time; }
|
||||
public:
|
||||
operator float() const { return m_Time; }
|
||||
|
||||
Timestep(float time = 0.0f) : m_Time(time) { }
|
||||
Timestep(float time = 0.0f) : m_Time(time) { }
|
||||
|
||||
float GetSeconds()
|
||||
{
|
||||
return m_Time;
|
||||
}
|
||||
float GetSeconds()
|
||||
{
|
||||
return m_Time;
|
||||
}
|
||||
|
||||
float GetMilliseconds() const
|
||||
{
|
||||
return m_Time * 1000.0f;
|
||||
}
|
||||
};
|
||||
float GetMilliseconds() const
|
||||
{
|
||||
return m_Time * 1000.0f;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
128
Nuake/src/Rendering/Buffers/Framebuffer.cpp
Normal file
128
Nuake/src/Rendering/Buffers/Framebuffer.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
#include "Framebuffer.h"
|
||||
#include <GL\glew.h>
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
FrameBuffer::FrameBuffer(bool hasRenderBuffer, Vector2 size)
|
||||
{
|
||||
m_Textures = std::map<int, Ref<Texture>>();
|
||||
m_Size = size;
|
||||
|
||||
glGenFramebuffers(1, &m_FramebufferID);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FramebufferID);
|
||||
|
||||
// Create render buffer and attach to frame buffer.
|
||||
if (hasRenderBuffer)
|
||||
{
|
||||
glGenRenderbuffers(1, &m_RenderBuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, m_RenderBuffer);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_Size.x, m_Size.y);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_RenderBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RenderBuffer = -1;
|
||||
}
|
||||
|
||||
// Unbind
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void FrameBuffer::SetTexture(Ref<Texture> texture, GLenum attachment)
|
||||
{
|
||||
m_Textures[attachment] = texture;
|
||||
// Attach texture to the framebuffer.
|
||||
Bind();
|
||||
texture->AttachToFramebuffer(attachment);
|
||||
|
||||
// Set draw buffer with dynamic amount of render target.
|
||||
// Surely, this can be optimized.
|
||||
int size = 0;
|
||||
std::vector<unsigned int> keys = std::vector<unsigned int>();
|
||||
for (auto s : m_Textures)
|
||||
{
|
||||
if (s.first != GL_DEPTH_ATTACHMENT)
|
||||
{
|
||||
keys.push_back(s.first);
|
||||
size += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (size > 0)
|
||||
glDrawBuffers(size, &keys[0]);
|
||||
|
||||
Unbind();
|
||||
}
|
||||
|
||||
|
||||
void FrameBuffer::Clear()
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void FrameBuffer::Bind()
|
||||
{
|
||||
if (ResizeQueued)
|
||||
UpdateSize(m_Size);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_FramebufferID);
|
||||
|
||||
glViewport(0, 0, m_Size.x, m_Size.y);
|
||||
}
|
||||
|
||||
void FrameBuffer::Unbind()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void FrameBuffer::QueueResize(Vector2 size)
|
||||
{
|
||||
ResizeQueued = true;
|
||||
m_Size = size;
|
||||
}
|
||||
|
||||
void FrameBuffer::UpdateSize(Vector2 size)
|
||||
{
|
||||
m_Size = size;
|
||||
ResizeQueued = false;
|
||||
|
||||
// Delete frame buffer and render buffer.
|
||||
glDeleteFramebuffers(1, &m_FramebufferID);
|
||||
glDeleteRenderbuffers(1, &m_RenderBuffer);
|
||||
|
||||
// Recreate resized texture.
|
||||
for (auto t : m_Textures)
|
||||
t.second->Resize(size);
|
||||
|
||||
// New FBO and RBO.
|
||||
glGenFramebuffers(1, &m_FramebufferID);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FramebufferID);
|
||||
|
||||
// Recreate resized texture.
|
||||
for (auto t : m_Textures)
|
||||
t.second->AttachToFramebuffer(t.first);
|
||||
|
||||
// Recreate render buffer
|
||||
glGenRenderbuffers(1, &m_RenderBuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, m_RenderBuffer);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_Size.x, m_Size.y);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_RenderBuffer);
|
||||
|
||||
// Unbind.
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void FrameBuffer::SetDrawBuffer(GLenum draw)
|
||||
{
|
||||
Bind();
|
||||
//glReadBuffer(draw);
|
||||
Unbind();
|
||||
}
|
||||
|
||||
void FrameBuffer::SetReadBuffer(GLenum read)
|
||||
{
|
||||
Bind();
|
||||
//glReadBuffer(read);
|
||||
Unbind();
|
||||
}
|
||||
}
|
||||
42
Nuake/src/Rendering/Buffers/Framebuffer.h
Normal file
42
Nuake/src/Rendering/Buffers/Framebuffer.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
#include "../Core/Maths.h"
|
||||
|
||||
#include <vector>
|
||||
#include "../Core/Core.h"
|
||||
#include <map>
|
||||
#include <src/Rendering/Textures/Texture.h>
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
class FrameBuffer
|
||||
{
|
||||
private:
|
||||
unsigned int m_FramebufferID;
|
||||
unsigned int m_RenderBuffer;
|
||||
|
||||
Vector2 m_Size;
|
||||
bool ResizeQueued = false;
|
||||
|
||||
std::map<int, Ref<Texture>> m_Textures;
|
||||
Ref<Texture> m_Texture;
|
||||
|
||||
public:
|
||||
FrameBuffer(bool hasRenderBuffer, Vector2 size);
|
||||
~FrameBuffer() { }
|
||||
|
||||
// 0x8CE0 = color attachment 0.
|
||||
// TODO: Remove blackbox crap
|
||||
Ref<Texture> GetTexture(GLenum attachment = 0x8CE0) { return m_Textures[(int)attachment]; }
|
||||
void SetTexture(Ref<Texture> texture, GLenum attachment = 0x8CE0);
|
||||
|
||||
void Clear();
|
||||
void Bind();
|
||||
void Unbind();
|
||||
void QueueResize(Vector2 size);
|
||||
Vector2 GetSize() const { return m_Size; }
|
||||
void UpdateSize(Vector2 size);
|
||||
|
||||
void SetDrawBuffer(GLenum draw);
|
||||
void SetReadBuffer(GLenum read);
|
||||
};
|
||||
}
|
||||
124
Nuake/src/Rendering/Buffers/MSAAFramebuffer.cpp
Normal file
124
Nuake/src/Rendering/Buffers/MSAAFramebuffer.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
#include "MSAAFramebuffer.h"
|
||||
#include <GL\glew.h>
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
MSAAFrameBuffer::MSAAFrameBuffer(bool hasRenderBuffer, Vector2 size)
|
||||
{
|
||||
m_Textures = std::map<int, Ref<MultiSampledTexture>>();
|
||||
m_Size = size;
|
||||
|
||||
glGenFramebuffers(1, &m_FramebufferID);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FramebufferID);
|
||||
|
||||
// Create render buffer and attach to frame buffer.
|
||||
if (hasRenderBuffer)
|
||||
{
|
||||
glGenRenderbuffers(1, &m_RenderBuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, m_RenderBuffer);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, m_Size.x, m_Size.y);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_RenderBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RenderBuffer = -1;
|
||||
}
|
||||
|
||||
// Unbind
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void MSAAFrameBuffer::SetTexture(Ref<MultiSampledTexture> texture, GLenum attachment)
|
||||
{
|
||||
m_Textures[attachment] = texture;
|
||||
// Attach texture to the framebuffer.
|
||||
Bind();
|
||||
texture->AttachToFramebuffer(attachment);
|
||||
|
||||
// Set draw buffer with dynamic amount of render target.
|
||||
// Surely, this can be optimized.
|
||||
int size = 0;
|
||||
std::vector<unsigned int> keys = std::vector<unsigned int>();
|
||||
for (auto s : m_Textures)
|
||||
{
|
||||
if (s.first != GL_DEPTH_ATTACHMENT)
|
||||
{
|
||||
keys.push_back(s.first);
|
||||
size += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (size > 0)
|
||||
glDrawBuffers(size, &keys[0]);
|
||||
|
||||
Unbind();
|
||||
}
|
||||
|
||||
|
||||
void MSAAFrameBuffer::Bind()
|
||||
{
|
||||
if (ResizeQueued)
|
||||
UpdateSize(m_Size);
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_FramebufferID);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
glBlitFramebuffer(0, 0, m_Size.x, m_Size.y, 0, 0, m_Size.x, m_Size.y, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glViewport(0, 0, m_Size.x, m_Size.y);
|
||||
}
|
||||
|
||||
void MSAAFrameBuffer::Unbind()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void MSAAFrameBuffer::QueueResize(Vector2 size)
|
||||
{
|
||||
ResizeQueued = true;
|
||||
m_Size = size;
|
||||
}
|
||||
|
||||
void MSAAFrameBuffer::UpdateSize(Vector2 size)
|
||||
{
|
||||
m_Size = size;
|
||||
|
||||
// Delete frame buffer and render buffer.
|
||||
glDeleteFramebuffers(1, &m_FramebufferID);
|
||||
glDeleteRenderbuffers(1, &m_RenderBuffer);
|
||||
|
||||
// Recreate resized texture.
|
||||
for (auto t : m_Textures)
|
||||
t.second->Resize(size);
|
||||
|
||||
// New FBO and RBO.
|
||||
glGenFramebuffers(1, &m_FramebufferID);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FramebufferID);
|
||||
|
||||
// Recreate resized texture.
|
||||
for (auto t : m_Textures)
|
||||
t.second->AttachToFramebuffer(t.first);
|
||||
|
||||
// Recreate render buffer
|
||||
glGenRenderbuffers(1, &m_RenderBuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, m_RenderBuffer);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_Size.x, m_Size.y);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_RenderBuffer);
|
||||
|
||||
// Unbind.
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void MSAAFrameBuffer::SetDrawBuffer(GLenum draw)
|
||||
{
|
||||
Bind();
|
||||
//glReadBuffer(draw);
|
||||
Unbind();
|
||||
}
|
||||
|
||||
void MSAAFrameBuffer::SetReadBuffer(GLenum read)
|
||||
{
|
||||
Bind();
|
||||
//glReadBuffer(read);
|
||||
Unbind();
|
||||
}
|
||||
}
|
||||
42
Nuake/src/Rendering/Buffers/MSAAFramebuffer.h
Normal file
42
Nuake/src/Rendering/Buffers/MSAAFramebuffer.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
#include "src/Core/Maths.h"
|
||||
#include <vector>
|
||||
#include "src/Core/Core.h"
|
||||
|
||||
#include <src/Rendering/Textures/MultiSampledTexture.h>
|
||||
#include <map>
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
class MSAAFrameBuffer
|
||||
{
|
||||
private:
|
||||
unsigned int m_FramebufferID;
|
||||
unsigned int m_RenderBuffer;
|
||||
|
||||
Vector2 m_Size;
|
||||
bool ResizeQueued = false;
|
||||
|
||||
std::map<int, Ref<MultiSampledTexture>> m_Textures;
|
||||
Ref<MultiSampledTexture> m_Texture;
|
||||
|
||||
public:
|
||||
MSAAFrameBuffer(bool hasRenderBuffer, Vector2 size);
|
||||
~MSAAFrameBuffer() { }
|
||||
|
||||
// 0x8CE0 = color attachment 0.
|
||||
// TODO: Remove blackbox crap
|
||||
Ref<MultiSampledTexture> GetTexture(GLenum attachment = 0x8CE0) { return m_Textures[(int)attachment]; }
|
||||
void SetTexture(Ref<MultiSampledTexture> texture, GLenum attachment = 0x8CE0);
|
||||
|
||||
|
||||
void Bind();
|
||||
void Unbind();
|
||||
void QueueResize(Vector2 size);
|
||||
Vector2 GetSize() const { return m_Size; }
|
||||
void UpdateSize(Vector2 size);
|
||||
|
||||
void SetDrawBuffer(GLenum draw);
|
||||
void SetReadBuffer(GLenum read);
|
||||
};
|
||||
}
|
||||
@@ -5,12 +5,8 @@ class UniformBuffer {
|
||||
private:
|
||||
unsigned int RendererID;
|
||||
public:
|
||||
|
||||
UniformBuffer();
|
||||
|
||||
|
||||
|
||||
void Bind();
|
||||
void Unbind();
|
||||
|
||||
};
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
#include "Camera.h"
|
||||
#include "../Core/Input.h"
|
||||
#include <glm\ext\vector_float3.hpp>
|
||||
@@ -7,98 +6,100 @@
|
||||
#include <glm\ext\matrix_transform.hpp>
|
||||
#include <GLFW\glfw3.h>
|
||||
|
||||
Camera::Camera(CAMERA_TYPE type, glm::vec3 position) {
|
||||
m_Type = PERSPECTIVE;
|
||||
Translation = position;
|
||||
cameraDirection = glm::vec3(0, 0, 1);
|
||||
up = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
cameraRight = glm::normalize(glm::cross(up, cameraDirection));
|
||||
cameraUp = glm::cross(cameraDirection, cameraRight);
|
||||
cameraFront = cameraDirection;
|
||||
}
|
||||
|
||||
Camera::Camera() {
|
||||
m_Type = PERSPECTIVE;
|
||||
Translation = glm::vec3(0, 0, 0);
|
||||
cameraDirection = glm::vec3(0, 0, 1);
|
||||
up = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
cameraRight = glm::normalize(glm::cross(up, cameraDirection));
|
||||
cameraUp = glm::cross(cameraDirection, cameraRight);
|
||||
}
|
||||
|
||||
void Camera::SetType(CAMERA_TYPE type)
|
||||
namespace Nuake
|
||||
{
|
||||
m_Type = type;
|
||||
Camera::Camera(CAMERA_TYPE type, glm::vec3 position)
|
||||
{
|
||||
m_Type = PERSPECTIVE;
|
||||
Translation = position;
|
||||
cameraDirection = glm::vec3(0, 0, 1);
|
||||
up = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
cameraRight = glm::normalize(glm::cross(up, cameraDirection));
|
||||
cameraUp = glm::cross(cameraDirection, cameraRight);
|
||||
cameraFront = cameraDirection;
|
||||
}
|
||||
|
||||
Camera::Camera()
|
||||
{
|
||||
m_Type = PERSPECTIVE;
|
||||
Translation = glm::vec3(0, 0, 0);
|
||||
cameraDirection = glm::vec3(0, 0, 1);
|
||||
up = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
cameraRight = glm::normalize(glm::cross(up, cameraDirection));
|
||||
cameraUp = glm::cross(cameraDirection, cameraRight);
|
||||
}
|
||||
|
||||
void Camera::SetType(CAMERA_TYPE type)
|
||||
{
|
||||
m_Type = type;
|
||||
}
|
||||
|
||||
void Camera::OnWindowResize(int x, int y)
|
||||
{
|
||||
AspectRatio = (float)x / (float)y;
|
||||
float width = y * (16 * 9);
|
||||
float height = y;
|
||||
}
|
||||
|
||||
void Camera::SetDirection(Vector3 direction)
|
||||
{
|
||||
//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));
|
||||
cameraDirection = glm::normalize(direction);
|
||||
cameraFront = cameraDirection;
|
||||
cameraRight = glm::normalize(glm::cross(up, cameraFront));
|
||||
}
|
||||
|
||||
glm::vec3 Camera::GetTranslation() {
|
||||
return Translation;
|
||||
}
|
||||
|
||||
glm::vec3 Camera::GetDirection() {
|
||||
return cameraDirection;
|
||||
}
|
||||
|
||||
glm::mat4 Camera::GetPerspective()
|
||||
{
|
||||
//TODO: Add perspective options
|
||||
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;
|
||||
}
|
||||
|
||||
glm::mat4 Camera::GetTransform()
|
||||
{
|
||||
glm::mat4 tr = lookAt(Translation, Translation + cameraFront, cameraUp);
|
||||
return tr;
|
||||
}
|
||||
|
||||
glm::mat4 Camera::GetTransformRotation()
|
||||
{
|
||||
return lookAt(glm::vec3(), cameraFront, cameraUp);
|
||||
}
|
||||
|
||||
json Camera::Serialize()
|
||||
{
|
||||
BEGIN_SERIALIZE();
|
||||
SERIALIZE_VAL(m_Type);
|
||||
SERIALIZE_VAL(AspectRatio);
|
||||
SERIALIZE_VAL(Fov);
|
||||
SERIALIZE_VAL(Exposure);
|
||||
SERIALIZE_VAL(Speed);
|
||||
END_SERIALIZE();
|
||||
}
|
||||
|
||||
bool Camera::Deserialize(const std::string& str)
|
||||
{
|
||||
BEGIN_DESERIALIZE();
|
||||
j = j["CameraInstance"];
|
||||
this->m_Type = (CAMERA_TYPE)j["m_Type"];
|
||||
this->AspectRatio = j["AspectRatio"];
|
||||
this->Fov = j["Fov"];
|
||||
this->Exposure = j["Exposure"];
|
||||
this->Speed = j["Speed"];
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Camera::OnWindowResize(int x, int y)
|
||||
{
|
||||
AspectRatio = (float)x / (float)y;
|
||||
float width = y * (16 * 9);
|
||||
float height = y;
|
||||
}
|
||||
|
||||
void Camera::SetDirection(Vector3 direction)
|
||||
{
|
||||
//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));
|
||||
cameraDirection = glm::normalize(direction);
|
||||
cameraFront = cameraDirection;
|
||||
cameraRight = glm::normalize(glm::cross(up, cameraFront));
|
||||
}
|
||||
|
||||
glm::vec3 Camera::GetTranslation() {
|
||||
return Translation;
|
||||
}
|
||||
|
||||
glm::vec3 Camera::GetDirection() {
|
||||
return cameraDirection;
|
||||
}
|
||||
|
||||
glm::mat4 Camera::GetPerspective()
|
||||
{
|
||||
//TODO: Add perspective options
|
||||
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;
|
||||
}
|
||||
|
||||
glm::mat4 Camera::GetTransform()
|
||||
{
|
||||
glm::mat4 tr = lookAt(Translation, Translation + cameraFront, cameraUp);
|
||||
return tr;
|
||||
}
|
||||
|
||||
glm::mat4 Camera::GetTransformRotation()
|
||||
{
|
||||
return lookAt(glm::vec3(), cameraFront, cameraUp);
|
||||
}
|
||||
|
||||
json Camera::Serialize()
|
||||
{
|
||||
BEGIN_SERIALIZE();
|
||||
SERIALIZE_VAL(m_Type);
|
||||
SERIALIZE_VAL(AspectRatio);
|
||||
SERIALIZE_VAL(Fov);
|
||||
SERIALIZE_VAL(Exposure);
|
||||
SERIALIZE_VAL(Speed);
|
||||
END_SERIALIZE();
|
||||
}
|
||||
|
||||
bool Camera::Deserialize(const std::string& str)
|
||||
{
|
||||
BEGIN_DESERIALIZE();
|
||||
j = j["CameraInstance"];
|
||||
this->m_Type = (CAMERA_TYPE)j["m_Type"];
|
||||
this->AspectRatio = j["AspectRatio"];
|
||||
this->Fov = j["Fov"];
|
||||
this->Exposure = j["Exposure"];
|
||||
this->Speed = j["Speed"];
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,58 +1,63 @@
|
||||
#pragma once
|
||||
#include "../Core/Timestep.h"
|
||||
#include "../Core/Maths.h"
|
||||
#include "../Resource/Serializable.h"
|
||||
#include "src/Core/Timestep.h"
|
||||
#include "src/Core/Maths.h"
|
||||
#include "src/Resource/Serializable.h"
|
||||
|
||||
enum CAMERA_TYPE {
|
||||
ORTHO,
|
||||
PERSPECTIVE
|
||||
};
|
||||
|
||||
class EditorCamera;
|
||||
|
||||
// TODO: Remove logic from here.
|
||||
class Camera : public ISerializable
|
||||
namespace Nuake
|
||||
{
|
||||
private:
|
||||
CAMERA_TYPE m_Type;
|
||||
enum CAMERA_TYPE
|
||||
{
|
||||
ORTHO,
|
||||
PERSPECTIVE
|
||||
};
|
||||
|
||||
|
||||
Vector3 Rotation = { 0.0f, 0.0f, 0.0f };
|
||||
Vector3 Scale = { 1.0f, 1.0f, 1.0f };
|
||||
Matrix4 m_Perspective;
|
||||
class EditorCamera;
|
||||
|
||||
public:
|
||||
float AspectRatio = 16.0f / 9.0f;
|
||||
// TODO: remove duplicate direction and have a proper api.
|
||||
Vector3 up = Vector3(0.0f, 1.0f, 0.0f);
|
||||
Vector3 cameraFront = Vector3(0.0f, 0.0f, 1.0f);
|
||||
// TODO: Remove logic from here.
|
||||
class Camera : public ISerializable
|
||||
{
|
||||
private:
|
||||
CAMERA_TYPE m_Type;
|
||||
|
||||
Vector3 cameraTarget;
|
||||
Vector3 cameraDirection;
|
||||
|
||||
Vector3 Translation = { 0.0f, 0.0f, 0.0f };
|
||||
Vector3 cameraRight;
|
||||
Vector3 cameraUp;
|
||||
float Fov = 88.0f;
|
||||
float Exposure = 1.0f;
|
||||
float Speed = 1.0f;
|
||||
Vector3 Rotation = { 0.0f, 0.0f, 0.0f };
|
||||
Vector3 Scale = { 1.0f, 1.0f, 1.0f };
|
||||
Matrix4 m_Perspective;
|
||||
|
||||
Camera();
|
||||
Camera(CAMERA_TYPE type, Vector3 position);
|
||||
public:
|
||||
float AspectRatio = 16.0f / 9.0f;
|
||||
// TODO: remove duplicate direction and have a proper api.
|
||||
Vector3 up = Vector3(0.0f, 1.0f, 0.0f);
|
||||
Vector3 cameraFront = Vector3(0.0f, 0.0f, 1.0f);
|
||||
|
||||
void SetType(CAMERA_TYPE type);
|
||||
void OnWindowResize(int x, int y);
|
||||
Vector3 cameraTarget;
|
||||
Vector3 cameraDirection;
|
||||
|
||||
void SetDirection(Vector3 direction);
|
||||
Vector3 Translation = { 0.0f, 0.0f, 0.0f };
|
||||
Vector3 cameraRight;
|
||||
Vector3 cameraUp;
|
||||
float Fov = 88.0f;
|
||||
float Exposure = 1.0f;
|
||||
float Speed = 1.0f;
|
||||
|
||||
Vector3 GetTranslation();
|
||||
Vector3 GetDirection();
|
||||
Matrix4 GetPerspective();
|
||||
Matrix4 GetTransform();
|
||||
Matrix4 GetTransformRotation();
|
||||
Camera();
|
||||
Camera(CAMERA_TYPE type, Vector3 position);
|
||||
|
||||
json Serialize() override;
|
||||
bool Deserialize(const std::string& str) override;
|
||||
void SetType(CAMERA_TYPE type);
|
||||
void OnWindowResize(int x, int y);
|
||||
|
||||
void SetDirection(Vector3 direction);
|
||||
|
||||
Vector3 GetTranslation();
|
||||
Vector3 GetDirection();
|
||||
Matrix4 GetPerspective();
|
||||
Matrix4 GetTransform();
|
||||
Matrix4 GetTransformRotation();
|
||||
|
||||
json Serialize() override;
|
||||
bool Deserialize(const std::string& str) override;
|
||||
|
||||
friend EditorCamera;
|
||||
};
|
||||
}
|
||||
|
||||
friend EditorCamera;
|
||||
};
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
#include "Framebuffer.h"
|
||||
#include <GL\glew.h>
|
||||
FrameBuffer::FrameBuffer(bool hasRenderBuffer, Vector2 size)
|
||||
{
|
||||
m_Textures = std::map<int, Ref<Texture>>();
|
||||
m_Size = size;
|
||||
|
||||
glGenFramebuffers(1, &m_FramebufferID);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FramebufferID);
|
||||
|
||||
// Create render buffer and attach to frame buffer.
|
||||
if (hasRenderBuffer)
|
||||
{
|
||||
glGenRenderbuffers(1, &m_RenderBuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, m_RenderBuffer);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_Size.x, m_Size.y);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_RenderBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RenderBuffer = -1;
|
||||
}
|
||||
|
||||
// Unbind
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void FrameBuffer::SetTexture(Ref<Texture> texture, GLenum attachment)
|
||||
{
|
||||
m_Textures[attachment] = texture;
|
||||
// Attach texture to the framebuffer.
|
||||
Bind();
|
||||
texture->AttachToFramebuffer(attachment);
|
||||
|
||||
// Set draw buffer with dynamic amount of render target.
|
||||
// Surely, this can be optimized.
|
||||
int size = 0;
|
||||
std::vector<unsigned int> keys = std::vector<unsigned int>();
|
||||
for (auto s : m_Textures)
|
||||
{
|
||||
if (s.first != GL_DEPTH_ATTACHMENT)
|
||||
{
|
||||
keys.push_back(s.first);
|
||||
size += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(size > 0)
|
||||
glDrawBuffers(size, &keys[0]);
|
||||
|
||||
Unbind();
|
||||
}
|
||||
|
||||
|
||||
void FrameBuffer::Clear()
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void FrameBuffer::Bind()
|
||||
{
|
||||
if (ResizeQueued)
|
||||
UpdateSize(m_Size);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_FramebufferID);
|
||||
|
||||
glViewport(0, 0, m_Size.x, m_Size.y);
|
||||
}
|
||||
|
||||
void FrameBuffer::Unbind()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void FrameBuffer::QueueResize(Vector2 size)
|
||||
{
|
||||
ResizeQueued = true;
|
||||
m_Size = size;
|
||||
}
|
||||
|
||||
void FrameBuffer::UpdateSize(Vector2 size)
|
||||
{
|
||||
m_Size = size;
|
||||
ResizeQueued = false;
|
||||
|
||||
// Delete frame buffer and render buffer.
|
||||
glDeleteFramebuffers(1, &m_FramebufferID);
|
||||
glDeleteRenderbuffers(1, &m_RenderBuffer);
|
||||
|
||||
// Recreate resized texture.
|
||||
for (auto t : m_Textures)
|
||||
t.second->Resize(size);
|
||||
|
||||
// New FBO and RBO.
|
||||
glGenFramebuffers(1, &m_FramebufferID);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FramebufferID);
|
||||
|
||||
// Recreate resized texture.
|
||||
for (auto t : m_Textures)
|
||||
t.second->AttachToFramebuffer(t.first);
|
||||
|
||||
// Recreate render buffer
|
||||
glGenRenderbuffers(1, &m_RenderBuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, m_RenderBuffer);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_Size.x, m_Size.y);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_RenderBuffer);
|
||||
|
||||
// Unbind.
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void FrameBuffer::SetDrawBuffer(GLenum draw)
|
||||
{
|
||||
Bind();
|
||||
//glReadBuffer(draw);
|
||||
Unbind();
|
||||
}
|
||||
|
||||
void FrameBuffer::SetReadBuffer(GLenum read)
|
||||
{
|
||||
Bind();
|
||||
//glReadBuffer(read);
|
||||
Unbind();
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
#include "../Core/Maths.h"
|
||||
#include "Textures/Texture.h"
|
||||
#include <vector>
|
||||
#include "../Core/Core.h"
|
||||
#include <map>
|
||||
class FrameBuffer
|
||||
{
|
||||
private:
|
||||
unsigned int m_FramebufferID;
|
||||
unsigned int m_RenderBuffer;
|
||||
|
||||
Vector2 m_Size;
|
||||
bool ResizeQueued = false;
|
||||
|
||||
std::map<int, Ref<Texture>> m_Textures;
|
||||
Ref<Texture> m_Texture;
|
||||
|
||||
public:
|
||||
FrameBuffer(bool hasRenderBuffer, Vector2 size);
|
||||
~FrameBuffer() { }
|
||||
|
||||
// 0x8CE0 = color attachment 0.
|
||||
// TODO: Remove blackbox crap
|
||||
Ref<Texture> GetTexture(GLenum attachment = 0x8CE0) { return m_Textures[(int)attachment]; }
|
||||
void SetTexture(Ref<Texture> texture, GLenum attachment = 0x8CE0);
|
||||
|
||||
void Clear();
|
||||
void Bind();
|
||||
void Unbind();
|
||||
void QueueResize(Vector2 size);
|
||||
Vector2 GetSize() const { return m_Size; }
|
||||
void UpdateSize(Vector2 size);
|
||||
|
||||
void SetDrawBuffer(GLenum draw);
|
||||
void SetReadBuffer(GLenum read);
|
||||
};
|
||||
@@ -1,120 +0,0 @@
|
||||
#include "MSAAFramebuffer.h"
|
||||
#include <GL\glew.h>
|
||||
MSAAFrameBuffer::MSAAFrameBuffer(bool hasRenderBuffer, Vector2 size)
|
||||
{
|
||||
m_Textures = std::map<int, Ref<MultiSampledTexture>>();
|
||||
m_Size = size;
|
||||
|
||||
glGenFramebuffers(1, &m_FramebufferID);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FramebufferID);
|
||||
|
||||
// Create render buffer and attach to frame buffer.
|
||||
if (hasRenderBuffer)
|
||||
{
|
||||
glGenRenderbuffers(1, &m_RenderBuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, m_RenderBuffer);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, m_Size.x, m_Size.y);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_RenderBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RenderBuffer = -1;
|
||||
}
|
||||
|
||||
// Unbind
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void MSAAFrameBuffer::SetTexture(Ref<MultiSampledTexture> texture, GLenum attachment)
|
||||
{
|
||||
m_Textures[attachment] = texture;
|
||||
// Attach texture to the framebuffer.
|
||||
Bind();
|
||||
texture->AttachToFramebuffer(attachment);
|
||||
|
||||
// Set draw buffer with dynamic amount of render target.
|
||||
// Surely, this can be optimized.
|
||||
int size = 0;
|
||||
std::vector<unsigned int> keys = std::vector<unsigned int>();
|
||||
for (auto s : m_Textures)
|
||||
{
|
||||
if (s.first != GL_DEPTH_ATTACHMENT)
|
||||
{
|
||||
keys.push_back(s.first);
|
||||
size += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (size > 0)
|
||||
glDrawBuffers(size, &keys[0]);
|
||||
|
||||
Unbind();
|
||||
}
|
||||
|
||||
|
||||
void MSAAFrameBuffer::Bind()
|
||||
{
|
||||
if (ResizeQueued)
|
||||
UpdateSize(m_Size);
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_FramebufferID);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
glBlitFramebuffer(0, 0, m_Size.x, m_Size.y, 0, 0, m_Size.x, m_Size.y, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glViewport(0, 0, m_Size.x, m_Size.y);
|
||||
}
|
||||
|
||||
void MSAAFrameBuffer::Unbind()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void MSAAFrameBuffer::QueueResize(Vector2 size)
|
||||
{
|
||||
ResizeQueued = true;
|
||||
m_Size = size;
|
||||
}
|
||||
|
||||
void MSAAFrameBuffer::UpdateSize(Vector2 size)
|
||||
{
|
||||
m_Size = size;
|
||||
|
||||
// Delete frame buffer and render buffer.
|
||||
glDeleteFramebuffers(1, &m_FramebufferID);
|
||||
glDeleteRenderbuffers(1, &m_RenderBuffer);
|
||||
|
||||
// Recreate resized texture.
|
||||
for (auto t : m_Textures)
|
||||
t.second->Resize(size);
|
||||
|
||||
// New FBO and RBO.
|
||||
glGenFramebuffers(1, &m_FramebufferID);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FramebufferID);
|
||||
|
||||
// Recreate resized texture.
|
||||
for (auto t : m_Textures)
|
||||
t.second->AttachToFramebuffer(t.first);
|
||||
|
||||
// Recreate render buffer
|
||||
glGenRenderbuffers(1, &m_RenderBuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, m_RenderBuffer);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_Size.x, m_Size.y);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_RenderBuffer);
|
||||
|
||||
// Unbind.
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void MSAAFrameBuffer::SetDrawBuffer(GLenum draw)
|
||||
{
|
||||
Bind();
|
||||
//glReadBuffer(draw);
|
||||
Unbind();
|
||||
}
|
||||
|
||||
void MSAAFrameBuffer::SetReadBuffer(GLenum read)
|
||||
{
|
||||
Bind();
|
||||
//glReadBuffer(read);
|
||||
Unbind();
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
#pragma once
|
||||
#include "../Core/Maths.h"
|
||||
#include <vector>
|
||||
#include "../Core/Core.h"
|
||||
|
||||
#include <src/Rendering/Textures/MultiSampledTexture.h>
|
||||
#include <map>
|
||||
class MSAAFrameBuffer
|
||||
{
|
||||
private:
|
||||
unsigned int m_FramebufferID;
|
||||
unsigned int m_RenderBuffer;
|
||||
|
||||
Vector2 m_Size;
|
||||
bool ResizeQueued = false;
|
||||
|
||||
std::map<int, Ref<MultiSampledTexture>> m_Textures;
|
||||
Ref<MultiSampledTexture> m_Texture;
|
||||
|
||||
public:
|
||||
MSAAFrameBuffer(bool hasRenderBuffer, Vector2 size);
|
||||
~MSAAFrameBuffer() { }
|
||||
|
||||
// 0x8CE0 = color attachment 0.
|
||||
// TODO: Remove blackbox crap
|
||||
Ref<MultiSampledTexture> GetTexture(GLenum attachment = 0x8CE0) { return m_Textures[(int)attachment]; }
|
||||
void SetTexture(Ref<MultiSampledTexture> texture, GLenum attachment = 0x8CE0);
|
||||
|
||||
|
||||
void Bind();
|
||||
void Unbind();
|
||||
void QueueResize(Vector2 size);
|
||||
Vector2 GetSize() const { return m_Size; }
|
||||
void UpdateSize(Vector2 size);
|
||||
|
||||
void SetDrawBuffer(GLenum draw);
|
||||
void SetReadBuffer(GLenum read);
|
||||
};
|
||||
@@ -1,76 +1,79 @@
|
||||
#include "Mesh.h"
|
||||
#include <GL\glew.h>
|
||||
#include "../Renderer.h"
|
||||
#include "../../Core/MaterialManager.h"
|
||||
|
||||
Mesh::Mesh(std::vector<Vertex> vertices, std::vector<unsigned int> indices, Ref<Material> material)
|
||||
#include "src/Rendering/Renderer.h"
|
||||
#include "src/Core/MaterialManager.h"
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
this->m_Vertices = vertices;
|
||||
this->m_Indices = indices;
|
||||
this->m_Material = material;
|
||||
Mesh::Mesh(std::vector<Vertex> vertices, std::vector<unsigned int> indices, Ref<Material> material)
|
||||
{
|
||||
this->m_Vertices = vertices;
|
||||
this->m_Indices = indices;
|
||||
this->m_Material = material;
|
||||
|
||||
MaterialManager::Get()->RegisterMaterial(material);
|
||||
MaterialManager::Get()->RegisterMaterial(material);
|
||||
|
||||
setupMesh();
|
||||
setupMesh();
|
||||
}
|
||||
|
||||
void Mesh::setupMesh()
|
||||
{
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
glGenBuffers(1, &EBO);
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, m_Vertices.size() * sizeof(Vertex), &m_Vertices[0], GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_Indices.size() * sizeof(unsigned int), &m_Indices[0], GL_STATIC_DRAW);
|
||||
|
||||
// vertex positions
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
// UV
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 3));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
// Normal
|
||||
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 5));
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
// Tangent
|
||||
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 8));
|
||||
glEnableVertexAttribArray(3);
|
||||
|
||||
// Bi tangent
|
||||
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 11));
|
||||
glEnableVertexAttribArray(4);
|
||||
|
||||
// Texture
|
||||
glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 14));
|
||||
glEnableVertexAttribArray(5);
|
||||
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void Mesh::Draw(bool drawMaterial)
|
||||
{
|
||||
if (drawMaterial)
|
||||
m_Material->Bind();
|
||||
// draw mesh
|
||||
glBindVertexArray(VAO);
|
||||
glDrawElements(GL_TRIANGLES, m_Indices.size(), GL_UNSIGNED_INT, 0);
|
||||
//glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void Mesh::DebugDraw()
|
||||
{
|
||||
Renderer::m_DebugShader->Bind();
|
||||
Renderer::m_DebugShader->SetUniform4f("u_Color", 1.0f, 0.0f, 0.0f, 1.f);
|
||||
glBindVertexArray(VAO);
|
||||
glDrawElements(GL_TRIANGLES, m_Indices.size(), GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Mesh::setupMesh()
|
||||
{
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
glGenBuffers(1, &EBO);
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, m_Vertices.size() * sizeof(Vertex), &m_Vertices[0], GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_Indices.size() * sizeof(unsigned int), &m_Indices[0], GL_STATIC_DRAW);
|
||||
|
||||
// vertex positions
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
// UV
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 3));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
// Normal
|
||||
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 5));
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
// Tangent
|
||||
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 8));
|
||||
glEnableVertexAttribArray(3);
|
||||
|
||||
// Bi tangent
|
||||
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 11));
|
||||
glEnableVertexAttribArray(4);
|
||||
|
||||
// Texture
|
||||
glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 14));
|
||||
glEnableVertexAttribArray(5);
|
||||
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void Mesh::Draw(bool drawMaterial)
|
||||
{
|
||||
if(drawMaterial)
|
||||
m_Material->Bind();
|
||||
// draw mesh
|
||||
glBindVertexArray(VAO);
|
||||
glDrawElements(GL_TRIANGLES, m_Indices.size(), GL_UNSIGNED_INT, 0);
|
||||
//glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void Mesh::DebugDraw()
|
||||
{
|
||||
Renderer::m_DebugShader->Bind();
|
||||
Renderer::m_DebugShader->SetUniform4f("u_Color", 1.0f, 0.0f, 0.0f, 1.f);
|
||||
glBindVertexArray(VAO);
|
||||
glDrawElements(GL_TRIANGLES, m_Indices.size(), GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +1,27 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include "../Textures/Texture.h"
|
||||
#include "../Vertex.h"
|
||||
#include "src/Rendering/Textures/Texture.h"
|
||||
#include "src/Rendering/Vertex.h"
|
||||
#include <glm\ext\matrix_float4x4.hpp>
|
||||
#include "../Textures/Material.h"
|
||||
#include "../Core/Core.h"
|
||||
struct MeshVertex
|
||||
#include "src/Rendering/Textures/Material.h"
|
||||
#include "src/Core/Core.h"
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
class Mesh
|
||||
{
|
||||
public:
|
||||
std::vector<unsigned int> m_Indices;
|
||||
std::vector<Vertex> m_Vertices;
|
||||
Ref<Material> m_Material;
|
||||
|
||||
};
|
||||
Mesh(std::vector<Vertex> vertices, std::vector<unsigned int> indices, Ref<Material> material);
|
||||
|
||||
void Draw(bool bindMaterial = true);
|
||||
void DebugDraw();
|
||||
|
||||
class Mesh
|
||||
{
|
||||
public:
|
||||
std::vector<unsigned int> m_Indices;
|
||||
std::vector<Vertex> m_Vertices;
|
||||
Ref<Material> m_Material;
|
||||
|
||||
Mesh(std::vector<Vertex> vertices, std::vector<unsigned int> indices, Ref<Material> material);
|
||||
|
||||
void Draw(bool bindMaterial = true);
|
||||
void DebugDraw();
|
||||
private:
|
||||
unsigned int VAO, VBO, EBO;
|
||||
void setupMesh();
|
||||
};
|
||||
private:
|
||||
unsigned int VAO, VBO, EBO;
|
||||
void setupMesh();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
#include "ProceduralSky.h"
|
||||
#include "Renderer.h"
|
||||
#include "Shaders/Shader.h"
|
||||
#include "Camera.h"
|
||||
#include <GL/glew.h>
|
||||
// TODO: move this to primitive
|
||||
ProceduralSky::ProceduralSky() {
|
||||
float quadVertices[] = {
|
||||
// positions // texture Coords
|
||||
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
|
||||
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
|
||||
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
|
||||
|
||||
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
||||
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
|
||||
1.0f, 1.0f, 0.0f, 1.0f, 1.0f
|
||||
};
|
||||
// setup plane VAO
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
glBindVertexArray(VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||
}
|
||||
|
||||
void ProceduralSky::Draw(Ref<Camera> cam) {
|
||||
|
||||
glm::vec3 CameraDirection = cam->GetDirection();
|
||||
|
||||
Renderer::m_ProceduralSkyShader->Bind();
|
||||
Renderer::m_ProceduralSkyShader->SetUniform1f("SurfaceRadius", SurfaceRadius);
|
||||
Renderer::m_ProceduralSkyShader->SetUniform1f("AtmosphereRadius", AtmosphereRadius);
|
||||
Renderer::m_ProceduralSkyShader->SetUniform1f("SunIntensity", SunIntensity);
|
||||
|
||||
Renderer::m_ProceduralSkyShader->SetUniform3f("RayleighScattering",
|
||||
RayleighScattering.r,
|
||||
RayleighScattering.g,
|
||||
RayleighScattering.b);
|
||||
|
||||
Renderer::m_ProceduralSkyShader->SetUniform3f("MieScattering",
|
||||
MieScattering.r,
|
||||
MieScattering.g,
|
||||
MieScattering.b);
|
||||
|
||||
Renderer::m_ProceduralSkyShader->SetUniform3f("CenterPoint",
|
||||
CenterPoint.x,
|
||||
CenterPoint.y,
|
||||
CenterPoint.z);
|
||||
|
||||
Renderer::m_ProceduralSkyShader->SetUniform3f("SunDirection",
|
||||
SunDirection.x,
|
||||
SunDirection.y,
|
||||
SunDirection.z);
|
||||
|
||||
Renderer::m_ProceduralSkyShader->SetUniform1f("u_Exposure", cam->Exposure);
|
||||
|
||||
//Renderer::m_ProceduralSkyShader->SetUniform3f("CamDirection",
|
||||
// CameraDirection.x,
|
||||
// CameraDirection.y,
|
||||
// CameraDirection.z);
|
||||
|
||||
|
||||
Renderer::m_ProceduralSkyShader->SetUniformMat4f("InvProjection", cam->GetPerspective());
|
||||
Renderer::m_ProceduralSkyShader->SetUniformMat4f("InvView", cam->GetTransformRotation());
|
||||
//glm::vec3 CamRight = cam->cameraRight;
|
||||
//Renderer::m_ProceduralSkyShader->SetUniform3f("CamRight",
|
||||
// CamRight.x,
|
||||
// CamRight.y,
|
||||
// CamRight.z);
|
||||
//
|
||||
//glm::vec3 CamUp = cam->cameraUp;//glm::normalize(glm::cross(CameraDirection, CamRight));
|
||||
|
||||
//Renderer::m_ProceduralSkyShader->SetUniform3f("CamUp",
|
||||
// CamUp.x,
|
||||
// CamUp.y,
|
||||
// CamUp.z);
|
||||
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
||||
glm::vec3 ProceduralSky::GetSunDirection() {
|
||||
return SunDirection;
|
||||
}
|
||||
|
||||
json ProceduralSky::Serialize()
|
||||
{
|
||||
BEGIN_SERIALIZE()
|
||||
SERIALIZE_VAL(SurfaceRadius);
|
||||
SERIALIZE_VAL(AtmosphereRadius);
|
||||
SERIALIZE_VEC3(RayleighScattering);
|
||||
SERIALIZE_VEC3(MieScattering);
|
||||
SERIALIZE_VAL(SunIntensity);
|
||||
SERIALIZE_VEC3(SunDirection);
|
||||
END_SERIALIZE();
|
||||
}
|
||||
|
||||
bool ProceduralSky::Deserialize(const std::string& str)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
#include <glm/ext/vector_float3.hpp>
|
||||
#include "Vertex.h"
|
||||
#include "../Core/Core.h"
|
||||
#include "../Resource/Serializable.h"
|
||||
|
||||
class Camera;
|
||||
class ProceduralSky : ISerializable {
|
||||
public:
|
||||
float SurfaceRadius = 6360e3f;
|
||||
float AtmosphereRadius = 6380e3f;
|
||||
glm::vec3 RayleighScattering = glm::vec3(58e-7f, 135e-7f, 331e-7f);
|
||||
glm::vec3 MieScattering = glm::vec3(2e-5f);
|
||||
float SunIntensity = 100.0;
|
||||
|
||||
glm::vec3 CenterPoint = glm::vec3(0.f, -SurfaceRadius, 0.f);
|
||||
glm::vec3 SunDirection = glm::vec3(0.20000f, 0.95917f, 0.20000f);
|
||||
unsigned int VAO;
|
||||
unsigned int VBO;
|
||||
ProceduralSky();
|
||||
void Draw(Ref<Camera> cam);
|
||||
|
||||
glm::vec3 GetSunDirection();
|
||||
|
||||
json Serialize() override;
|
||||
bool Deserialize(const std::string& str) override;
|
||||
};
|
||||
@@ -6,19 +6,27 @@
|
||||
#include "src/Rendering/Textures/Material.h"
|
||||
#include "src/Rendering/Mesh/Mesh.h"
|
||||
|
||||
class RenderList
|
||||
namespace Nuake
|
||||
{
|
||||
private:
|
||||
std::map<Ref<Material>, std::vector<Ref<Mesh>>> m_RenderList;
|
||||
|
||||
public:
|
||||
|
||||
RenderList() {
|
||||
this->m_RenderList = std::map<Ref<Material>, std::vector<Ref<Mesh>>>();
|
||||
}
|
||||
|
||||
void AddToRenderList(Ref<Mesh> mesh)
|
||||
struct RenderMesh
|
||||
{
|
||||
Ref<Mesh> Mesh;
|
||||
};
|
||||
|
||||
}
|
||||
};
|
||||
class RenderList
|
||||
{
|
||||
public:
|
||||
RenderList()
|
||||
{
|
||||
this->m_RenderList = std::map<Ref<Material>, std::vector<Ref<Mesh>>>();
|
||||
}
|
||||
|
||||
void AddToRenderList(Ref<Mesh> mesh)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<Ref<Material>, std::vector<Ref<Mesh>>> m_RenderList;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,221 +6,225 @@
|
||||
#include "../../Engine.h"
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
unsigned int depthTexture;
|
||||
unsigned int depthFBO;
|
||||
|
||||
Shader* Renderer::m_Shader;
|
||||
Shader* Renderer::m_SkyboxShader;
|
||||
Shader* Renderer::m_BRDShader;
|
||||
Shader* Renderer::m_GBufferShader;
|
||||
Shader* Renderer::m_DeferredShader;
|
||||
Shader* Renderer::m_ProceduralSkyShader;
|
||||
Shader* Renderer::m_DebugShader;
|
||||
|
||||
unsigned int CubeVAO;
|
||||
unsigned int CubeVBO;
|
||||
unsigned int QuadVAO;
|
||||
unsigned int QuadVBO;
|
||||
|
||||
|
||||
glm::vec3 CubeVertices[36]{
|
||||
glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(0.5f, 0.5f, -0.5f),
|
||||
glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(-0.5f, -0.5f, -0.5f),
|
||||
glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.5f, 0.5f, 0.5f),
|
||||
glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, -0.5f, 0.5f),
|
||||
glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(-0.5f, -0.5f, -0.5f),
|
||||
glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, 0.5f),
|
||||
glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(0.5f, -0.5f, -0.5f),
|
||||
glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.5f, 0.5f, 0.5f),
|
||||
glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(0.5f, -0.5f, 0.5f),
|
||||
glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(-0.5f, -0.5f, -0.5f),
|
||||
glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(0.5f, 0.5f, 0.5f),
|
||||
glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, -0.5f)
|
||||
};
|
||||
|
||||
float QuadVertices[] = {
|
||||
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
|
||||
0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
|
||||
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
|
||||
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
|
||||
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
|
||||
0.5f, 0.5f, 0.0f, 1.0f, 1.0f
|
||||
};
|
||||
|
||||
|
||||
void Renderer::Init()
|
||||
namespace Nuake
|
||||
{
|
||||
// TODO: Make shader storage somewhere.
|
||||
m_ShadowmapShader = new Shader("resources/Shaders/shadowMap.shader");
|
||||
m_SkyboxShader = new Shader("resources/Shaders/skybox.shader");
|
||||
m_BRDShader = new Shader("resources/Shaders/BRD.shader");
|
||||
m_GBufferShader = new Shader("resources/Shaders/gbuffer.shader");
|
||||
m_DeferredShader = new Shader("resources/Shaders/deferred.shader");
|
||||
m_ProceduralSkyShader = new Shader("resources/Shaders/atmospheric_sky.shader");
|
||||
m_DebugShader = new Shader("resources/Shaders/debug.shader");
|
||||
m_Shader = new Shader("resources/Shaders/basic.shader");
|
||||
m_Shader->Bind();
|
||||
unsigned int depthTexture;
|
||||
unsigned int depthFBO;
|
||||
|
||||
// TODO: Use buffer abstraction.
|
||||
// Setup buffers
|
||||
glGenVertexArrays(1, &CubeVAO);
|
||||
glBindVertexArray(CubeVAO);
|
||||
Shader* Renderer::m_Shader;
|
||||
Shader* Renderer::m_SkyboxShader;
|
||||
Shader* Renderer::m_BRDShader;
|
||||
Shader* Renderer::m_GBufferShader;
|
||||
Shader* Renderer::m_DeferredShader;
|
||||
Shader* Renderer::m_ProceduralSkyShader;
|
||||
Shader* Renderer::m_DebugShader;
|
||||
|
||||
glGenBuffers(1, &CubeVBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, CubeVBO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, CubeVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(CubeVertices), CubeVertices, GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
// Quad
|
||||
glGenVertexArrays(1, &QuadVAO);
|
||||
glBindVertexArray(QuadVAO);
|
||||
|
||||
glGenBuffers(1, &QuadVBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, QuadVBO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, QuadVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(QuadVertices), QuadVertices, GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||
|
||||
}
|
||||
|
||||
// TODO: Move to shader storage
|
||||
Shader* Renderer::m_ShadowmapShader;
|
||||
|
||||
void Renderer::BeginDraw(Ref<Camera> camera)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
m_Shader->SetUniformMat4f("u_Projection", camera->GetPerspective());
|
||||
m_Shader->SetUniformMat4f("u_View", camera->GetTransform());
|
||||
m_Shader->SetUniform3f("u_EyePosition", camera->GetTranslation().x, camera->GetTranslation().y, camera->GetTranslation().z);
|
||||
m_Shader->Bind();
|
||||
}
|
||||
|
||||
void Renderer::EndDraw()
|
||||
{
|
||||
m_Lights.clear(); // Clean up lights.
|
||||
}
|
||||
unsigned int CubeVAO;
|
||||
unsigned int CubeVBO;
|
||||
unsigned int QuadVAO;
|
||||
unsigned int QuadVBO;
|
||||
|
||||
|
||||
// List of all lights queued to be used for rendering this frame.
|
||||
std::vector<Light> Renderer::m_Lights;
|
||||
glm::vec3 CubeVertices[36]{
|
||||
glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(0.5f, 0.5f, -0.5f),
|
||||
glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(-0.5f, -0.5f, -0.5f),
|
||||
glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.5f, 0.5f, 0.5f),
|
||||
glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, -0.5f, 0.5f),
|
||||
glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(-0.5f, -0.5f, -0.5f),
|
||||
glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, 0.5f),
|
||||
glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(0.5f, -0.5f, -0.5f),
|
||||
glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.5f, 0.5f, 0.5f),
|
||||
glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(0.5f, -0.5f, 0.5f),
|
||||
glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(-0.5f, -0.5f, -0.5f),
|
||||
glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(0.5f, 0.5f, 0.5f),
|
||||
glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, -0.5f)
|
||||
};
|
||||
|
||||
void Renderer::RegisterLight(TransformComponent transform, LightComponent light, Ref<Camera> cam)
|
||||
{
|
||||
if (m_Lights.size() == 20)
|
||||
return;
|
||||
m_Lights.push_back({ transform , light });
|
||||
float QuadVertices[] = {
|
||||
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
|
||||
0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
|
||||
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
|
||||
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
|
||||
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
|
||||
0.5f, 0.5f, 0.0f, 1.0f, 1.0f
|
||||
};
|
||||
|
||||
// What light idx is this?
|
||||
int idx = m_Lights.size();
|
||||
|
||||
glm::vec3 direction = light.GetDirection();
|
||||
glm::vec3 pos = transform.GlobalTranslation;
|
||||
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);
|
||||
|
||||
if (light.CastShadows)
|
||||
void Renderer::Init()
|
||||
{
|
||||
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);
|
||||
// TODO: Make shader storage somewhere.
|
||||
m_ShadowmapShader = new Shader("resources/Shaders/shadowMap.shader");
|
||||
m_SkyboxShader = new Shader("resources/Shaders/skybox.shader");
|
||||
m_BRDShader = new Shader("resources/Shaders/BRD.shader");
|
||||
m_GBufferShader = new Shader("resources/Shaders/gbuffer.shader");
|
||||
m_DeferredShader = new Shader("resources/Shaders/deferred.shader");
|
||||
m_ProceduralSkyShader = new Shader("resources/Shaders/atmospheric_sky.shader");
|
||||
m_DebugShader = new Shader("resources/Shaders/debug.shader");
|
||||
m_Shader = new Shader("resources/Shaders/basic.shader");
|
||||
m_Shader->Bind();
|
||||
|
||||
// TODO: Use buffer abstraction.
|
||||
// Setup buffers
|
||||
glGenVertexArrays(1, &CubeVAO);
|
||||
glBindVertexArray(CubeVAO);
|
||||
|
||||
glGenBuffers(1, &CubeVBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, CubeVBO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, CubeVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(CubeVertices), CubeVertices, GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
// Quad
|
||||
glGenVertexArrays(1, &QuadVAO);
|
||||
glBindVertexArray(QuadVAO);
|
||||
|
||||
glGenBuffers(1, &QuadVBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, QuadVBO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, QuadVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(QuadVertices), QuadVertices, GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||
|
||||
}
|
||||
|
||||
// TODO: Move to shader storage
|
||||
Shader* Renderer::m_ShadowmapShader;
|
||||
|
||||
void Renderer::BeginDraw(Ref<Camera> camera)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
m_Shader->SetUniformMat4f("u_Projection", camera->GetPerspective());
|
||||
m_Shader->SetUniformMat4f("u_View", camera->GetTransform());
|
||||
m_Shader->SetUniform3f("u_EyePosition", camera->GetTranslation().x, camera->GetTranslation().y, camera->GetTranslation().z);
|
||||
m_Shader->Bind();
|
||||
}
|
||||
|
||||
void Renderer::EndDraw()
|
||||
{
|
||||
m_Lights.clear(); // Clean up lights.
|
||||
}
|
||||
|
||||
|
||||
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) + "].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.GlobalTranslation.x, transform.GlobalTranslation.y, transform.GlobalTranslation.z);
|
||||
m_Shader->SetUniform3f ("Lights[" + std::to_string(idx - 1) + "].Direction" , direction.x, direction.y, direction.z);
|
||||
m_Shader->SetUniform3f ("Lights[" + std::to_string(idx - 1) + "].Color" , light.Color.r * light.Strength, light.Color.g * light.Strength, light.Color.b * light.Strength);
|
||||
m_Shader->SetUniform1i ("Lights[" + std::to_string(idx - 1) + "].Volumetric", light.IsVolumetric);
|
||||
}
|
||||
|
||||
void Renderer::RegisterDeferredLight(TransformComponent transform, LightComponent light, Camera* cam)
|
||||
{
|
||||
m_Lights.push_back({ transform , light });
|
||||
|
||||
// What light idx is this?
|
||||
int idx = m_Lights.size();
|
||||
|
||||
glm::vec3 direction = light.GetDirection();
|
||||
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()->Bind(11);
|
||||
|
||||
m_DeferredShader->SetUniform1i("LightCount", idx);
|
||||
m_DeferredShader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].Type", light.Type);
|
||||
m_DeferredShader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].ShadowMap", 11);
|
||||
m_DeferredShader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransform", light.GetProjection() * lightView);
|
||||
m_DeferredShader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Position", transform.Translation.x, transform.Translation.y, transform.Translation.z);
|
||||
m_DeferredShader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Direction", direction.x, direction.y, direction.z);
|
||||
m_DeferredShader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Color", light.Color.r * light.Strength, light.Color.g * light.Strength, light.Color.b * light.Strength);
|
||||
}
|
||||
|
||||
void Renderer::DrawDebugLine(glm::vec3 start, glm::vec3 end, glm::vec4 color) {
|
||||
//m_DebugShader->Bind();
|
||||
//m_DebugShader->SetUniform4f("u_Color", color.r, color.g, color.b, color.a);
|
||||
}
|
||||
|
||||
// TODO: Maybe have a debug primitive draw list
|
||||
void Renderer::DrawCube(TransformComponent transform, glm::vec4 color)
|
||||
{
|
||||
//glDisable(GL_DEPTH_TEST);
|
||||
Ref<Window> window = Engine::GetCurrentWindow();
|
||||
Ref<FrameBuffer> fb = window->GetFrameBuffer();
|
||||
|
||||
|
||||
m_DebugShader->SetUniformMat4f("u_Model", transform.GetTransform());
|
||||
m_DebugShader->SetUniform4f("u_Color", color.r, color.g, color.b, color.a);
|
||||
glBindVertexArray(CubeVAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
|
||||
m_DebugShader->SetUniform4f("u_Color", color.r, color.g, color.b, 1.0f);
|
||||
|
||||
glPolygonMode(GL_FRONT, GL_LINE);
|
||||
glPolygonMode(GL_BACK, GL_LINE);
|
||||
glLineWidth(4);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
|
||||
// Turn off wireframe mode
|
||||
glPolygonMode(GL_FRONT, GL_FILL);
|
||||
glPolygonMode(GL_BACK, GL_FILL);
|
||||
//glEnable(GL_DEPTH_TEST);
|
||||
|
||||
}
|
||||
|
||||
// TODO: See above
|
||||
void Renderer::DrawSphere(TransformComponent transform, glm::vec4 color)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Renderer::DrawQuad(Matrix4 transform)
|
||||
{
|
||||
glBindVertexArray(QuadVAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
// List of all lights queued to be used for rendering this frame.
|
||||
std::vector<Light> Renderer::m_Lights;
|
||||
|
||||
void Renderer::RegisterLight(TransformComponent transform, LightComponent light, Ref<Camera> cam)
|
||||
{
|
||||
if (m_Lights.size() == 20)
|
||||
return;
|
||||
m_Lights.push_back({ transform , light });
|
||||
|
||||
// What light idx is this?
|
||||
int idx = m_Lights.size();
|
||||
|
||||
glm::vec3 direction = light.GetDirection();
|
||||
glm::vec3 pos = transform.GlobalTranslation;
|
||||
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);
|
||||
|
||||
if (light.CastShadows)
|
||||
{
|
||||
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) + "].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.GlobalTranslation.x, transform.GlobalTranslation.y, transform.GlobalTranslation.z);
|
||||
m_Shader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Direction", direction.x, direction.y, direction.z);
|
||||
m_Shader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Color", light.Color.r * light.Strength, light.Color.g * light.Strength, light.Color.b * light.Strength);
|
||||
m_Shader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].Volumetric", light.IsVolumetric);
|
||||
}
|
||||
|
||||
void Renderer::RegisterDeferredLight(TransformComponent transform, LightComponent light, Camera* cam)
|
||||
{
|
||||
m_Lights.push_back({ transform , light });
|
||||
|
||||
// What light idx is this?
|
||||
int idx = m_Lights.size();
|
||||
|
||||
glm::vec3 direction = light.GetDirection();
|
||||
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()->Bind(11);
|
||||
|
||||
m_DeferredShader->SetUniform1i("LightCount", idx);
|
||||
m_DeferredShader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].Type", light.Type);
|
||||
m_DeferredShader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].ShadowMap", 11);
|
||||
m_DeferredShader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransform", light.GetProjection() * lightView);
|
||||
m_DeferredShader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Position", transform.Translation.x, transform.Translation.y, transform.Translation.z);
|
||||
m_DeferredShader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Direction", direction.x, direction.y, direction.z);
|
||||
m_DeferredShader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Color", light.Color.r * light.Strength, light.Color.g * light.Strength, light.Color.b * light.Strength);
|
||||
}
|
||||
|
||||
void Renderer::DrawDebugLine(glm::vec3 start, glm::vec3 end, glm::vec4 color)
|
||||
{
|
||||
//m_DebugShader->Bind();
|
||||
//m_DebugShader->SetUniform4f("u_Color", color.r, color.g, color.b, color.a);
|
||||
}
|
||||
|
||||
// TODO: Maybe have a debug primitive draw list
|
||||
void Renderer::DrawCube(TransformComponent transform, glm::vec4 color)
|
||||
{
|
||||
//glDisable(GL_DEPTH_TEST);
|
||||
Ref<Window> window = Engine::GetCurrentWindow();
|
||||
Ref<FrameBuffer> fb = window->GetFrameBuffer();
|
||||
|
||||
|
||||
m_DebugShader->SetUniformMat4f("u_Model", transform.GetTransform());
|
||||
m_DebugShader->SetUniform4f("u_Color", color.r, color.g, color.b, color.a);
|
||||
glBindVertexArray(CubeVAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
|
||||
m_DebugShader->SetUniform4f("u_Color", color.r, color.g, color.b, 1.0f);
|
||||
|
||||
glPolygonMode(GL_FRONT, GL_LINE);
|
||||
glPolygonMode(GL_BACK, GL_LINE);
|
||||
glLineWidth(4);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
|
||||
// Turn off wireframe mode
|
||||
glPolygonMode(GL_FRONT, GL_FILL);
|
||||
glPolygonMode(GL_BACK, GL_FILL);
|
||||
//glEnable(GL_DEPTH_TEST);
|
||||
|
||||
}
|
||||
|
||||
// TODO: See above
|
||||
void Renderer::DrawSphere(TransformComponent transform, glm::vec4 color)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Renderer::DrawQuad(Matrix4 transform)
|
||||
{
|
||||
glBindVertexArray(QuadVAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,36 +3,44 @@
|
||||
#include "../Scene/Components/Components.h"
|
||||
#include "../Core/Core.h"
|
||||
|
||||
struct Light {
|
||||
TransformComponent transform;
|
||||
LightComponent light;
|
||||
};
|
||||
namespace Nuake
|
||||
{
|
||||
struct Light
|
||||
{
|
||||
TransformComponent transform;
|
||||
LightComponent light;
|
||||
};
|
||||
|
||||
class Renderer {
|
||||
public:
|
||||
static Shader* m_Shader;
|
||||
static Shader* m_ShadowmapShader;
|
||||
static Shader* m_SkyboxShader;
|
||||
static Shader* m_BRDShader;
|
||||
static Shader* m_GBufferShader;
|
||||
static Shader* m_DeferredShader;
|
||||
static Shader* m_ProceduralSkyShader;
|
||||
static Shader* m_DebugShader;
|
||||
class Renderer
|
||||
{
|
||||
public:
|
||||
static Shader* m_Shader;
|
||||
static Shader* m_ShadowmapShader;
|
||||
static Shader* m_SkyboxShader;
|
||||
static Shader* m_BRDShader;
|
||||
static Shader* m_GBufferShader;
|
||||
static Shader* m_DeferredShader;
|
||||
static Shader* m_ProceduralSkyShader;
|
||||
static Shader* m_DebugShader;
|
||||
|
||||
static void Init();
|
||||
static void Init();
|
||||
|
||||
// Drawing states
|
||||
static void BeginDraw(Ref<Camera> camera);
|
||||
static void EndDraw();
|
||||
// Drawing states
|
||||
static void BeginDraw(Ref<Camera> camera);
|
||||
static void EndDraw();
|
||||
|
||||
// Lights
|
||||
static std::vector<Light> m_Lights;
|
||||
static void RegisterLight(TransformComponent transform, LightComponent light, Ref<Camera> cam);
|
||||
static void RegisterDeferredLight(TransformComponent transform, LightComponent light, Camera* cam);
|
||||
// Lights
|
||||
static std::vector<Light> m_Lights;
|
||||
static void RegisterLight(TransformComponent transform, LightComponent light, Ref<Camera> cam);
|
||||
static void RegisterDeferredLight(TransformComponent transform, LightComponent light, Camera* cam);
|
||||
|
||||
// Debug
|
||||
static void DrawDebugLine(glm::vec3 start, glm::vec3 end, glm::vec4 color);
|
||||
static void DrawCube(TransformComponent transform, glm::vec4 color);
|
||||
static void DrawSphere(TransformComponent transform, glm::vec4 color);
|
||||
static void DrawQuad(Matrix4 transform);
|
||||
};
|
||||
|
||||
static void SubmitMesh(Ref<Mesh> mesh);
|
||||
|
||||
// Debug
|
||||
static void DrawDebugLine(glm::vec3 start, glm::vec3 end, glm::vec4 color);
|
||||
static void DrawCube(TransformComponent transform, glm::vec4 color);
|
||||
static void DrawSphere(TransformComponent transform, glm::vec4 color);
|
||||
static void DrawQuad(Matrix4 transform);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,137 +1,140 @@
|
||||
#include "Renderer2D.h"
|
||||
#include "GL/glew.h"
|
||||
#include "../Core/Maths.h"
|
||||
#include <Engine.h>
|
||||
#include "src/UI/Nodes/TextNode.h"
|
||||
|
||||
#include "../UI/Nodes/TextNode.h"
|
||||
Ref<Shader> Renderer2D::UIShader;
|
||||
Ref<Shader> Renderer2D::TextShader;
|
||||
|
||||
unsigned int Renderer2D::VAO;
|
||||
unsigned int Renderer2D::VBO;
|
||||
|
||||
Matrix4 Renderer2D::Projection;
|
||||
|
||||
void Renderer2D::Init()
|
||||
namespace Nuake
|
||||
{
|
||||
UIShader = CreateRef<Shader>("resources/Shaders/ui.shader");
|
||||
TextShader = CreateRef<Shader>("resources/Shaders/sdf_text.shader");
|
||||
Ref<Shader> Renderer2D::UIShader;
|
||||
Ref<Shader> Renderer2D::TextShader;
|
||||
|
||||
float quad_Vertices[] = {
|
||||
// positions // texture Coords
|
||||
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
|
||||
0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
|
||||
1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f, 1.0f
|
||||
};
|
||||
// setup plane VAO
|
||||
glGenVertexArrays(1, &Renderer2D::VAO);
|
||||
glGenBuffers(1, &Renderer2D::VBO);
|
||||
glBindVertexArray(Renderer2D::VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, Renderer2D::VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(quad_Vertices), &quad_Vertices, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||
}
|
||||
unsigned int Renderer2D::VAO;
|
||||
unsigned int Renderer2D::VBO;
|
||||
|
||||
void Renderer2D::BeginDraw(Vector2 size)
|
||||
{
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
Projection = glm::ortho(0.f, size.x, size.y, 0.f, -0.5f, 1000.0f);
|
||||
UIShader->Bind();
|
||||
UIShader->SetUniformMat4f("projection", Projection);
|
||||
}
|
||||
Matrix4 Renderer2D::Projection;
|
||||
|
||||
void Renderer2D::DrawRect()
|
||||
{
|
||||
glBindVertexArray(Renderer2D::VAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
void Renderer2D::Init()
|
||||
{
|
||||
UIShader = CreateRef<Shader>("resources/Shaders/ui.shader");
|
||||
TextShader = CreateRef<Shader>("resources/Shaders/sdf_text.shader");
|
||||
|
||||
Vector2 Renderer2D::CalculateStringSize(const std::string& str, Ref<Font> font, Vector2 position, float fontSize)
|
||||
{
|
||||
float advance = 0.0f;
|
||||
float Y = 0.0f;
|
||||
for (char const& c : str) {
|
||||
Char& letter = font->GetChar((int)c);
|
||||
advance += letter.Advance * fontSize;
|
||||
if(letter.PlaneBounds.top - letter.PlaneBounds.bottom > Y)
|
||||
Y = letter.PlaneBounds.top - letter.PlaneBounds.bottom;
|
||||
}
|
||||
return Vector2(advance, Y);
|
||||
}
|
||||
|
||||
void Renderer2D::DrawString(const std::string& str, TextStyle style, Matrix4 model)
|
||||
{
|
||||
|
||||
TextShader->Bind();
|
||||
TextShader->SetUniformMat4f("projection", Projection);
|
||||
float advance = 0.0f;
|
||||
style.font->FontAtlas->Bind(5);
|
||||
TextShader->SetUniform1i("msdf", 5);
|
||||
|
||||
|
||||
float lineHeight = 0.0f;
|
||||
for (char const& c : str) {
|
||||
Char& letter = style.font->GetChar((int)c);
|
||||
|
||||
if (letter.PlaneBounds.top - letter.PlaneBounds.bottom > lineHeight)
|
||||
lineHeight = letter.PlaneBounds.top - letter.PlaneBounds.bottom ;
|
||||
float quad_Vertices[] = {
|
||||
// positions // texture Coords
|
||||
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
|
||||
0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
|
||||
1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f, 1.0f
|
||||
};
|
||||
// setup plane VAO
|
||||
glGenVertexArrays(1, &Renderer2D::VAO);
|
||||
glGenBuffers(1, &Renderer2D::VBO);
|
||||
glBindVertexArray(Renderer2D::VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, Renderer2D::VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(quad_Vertices), &quad_Vertices, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||
}
|
||||
|
||||
lineHeight *= style.fontSize;
|
||||
void Renderer2D::BeginDraw(Vector2 size)
|
||||
{
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
Projection = glm::ortho(0.f, size.x, size.y, 0.f, -0.5f, 1000.0f);
|
||||
UIShader->Bind();
|
||||
UIShader->SetUniformMat4f("projection", Projection);
|
||||
}
|
||||
|
||||
for (char const& c : str) {
|
||||
Char& letter = style.font->GetChar((int)c);
|
||||
Matrix4 mat = glm::translate(model, Vector3(advance, -(letter.PlaneBounds.top) + (lineHeight), 0.f));
|
||||
float scaleX = letter.PlaneBounds.right - letter.PlaneBounds.left;
|
||||
float scaleY = letter.PlaneBounds.top - letter.PlaneBounds.bottom;
|
||||
mat = glm::scale(mat, Vector3(scaleX, scaleY, 0.f));
|
||||
void Renderer2D::DrawRect()
|
||||
{
|
||||
glBindVertexArray(Renderer2D::VAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
||||
Vector2 Renderer2D::CalculateStringSize(const std::string& str, Ref<Font> font, Vector2 position, float fontSize)
|
||||
{
|
||||
float advance = 0.0f;
|
||||
float Y = 0.0f;
|
||||
for (char const& c : str) {
|
||||
Char& letter = font->GetChar((int)c);
|
||||
advance += letter.Advance * fontSize;
|
||||
if (letter.PlaneBounds.top - letter.PlaneBounds.bottom > Y)
|
||||
Y = letter.PlaneBounds.top - letter.PlaneBounds.bottom;
|
||||
}
|
||||
return Vector2(advance, Y);
|
||||
}
|
||||
|
||||
void Renderer2D::DrawString(const std::string& str, TextStyle style, Matrix4 model)
|
||||
{
|
||||
|
||||
TextShader->Bind();
|
||||
TextShader->SetUniformMat4f("projection", Projection);
|
||||
float advance = 0.0f;
|
||||
style.font->FontAtlas->Bind(5);
|
||||
TextShader->SetUniform1i("msdf", 5);
|
||||
|
||||
|
||||
float lineHeight = 0.0f;
|
||||
for (char const& c : str) {
|
||||
Char& letter = style.font->GetChar((int)c);
|
||||
|
||||
if (letter.PlaneBounds.top - letter.PlaneBounds.bottom > lineHeight)
|
||||
lineHeight = letter.PlaneBounds.top - letter.PlaneBounds.bottom;
|
||||
}
|
||||
|
||||
lineHeight *= style.fontSize;
|
||||
|
||||
for (char const& c : str) {
|
||||
Char& letter = style.font->GetChar((int)c);
|
||||
Matrix4 mat = glm::translate(model, Vector3(advance, -(letter.PlaneBounds.top) + (lineHeight), 0.f));
|
||||
float scaleX = letter.PlaneBounds.right - letter.PlaneBounds.left;
|
||||
float scaleY = letter.PlaneBounds.top - letter.PlaneBounds.bottom;
|
||||
mat = glm::scale(mat, Vector3(scaleX, scaleY, 0.f));
|
||||
TextShader->SetUniform2f("texPos", letter.AtlasBounds.Pos.x, letter.AtlasBounds.Pos.y);
|
||||
TextShader->SetUniform2f("texScale", letter.AtlasBounds.Size.x, letter.AtlasBounds.Size.y);
|
||||
TextShader->SetUniformMat4f("model", mat);
|
||||
//TextShader->SetUniform4f("bgColor", 0, 0, 1, 1);
|
||||
TextShader->SetUniform4f("bgColor", 1.f, 0.f, 0.f, 0.f);
|
||||
TextShader->SetUniform4f("fgColor", 1.f, 1.f, 1.f, 1.f);
|
||||
//TextShader->SetUniform1f("pxRange", 32);
|
||||
glBindVertexArray(VAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
advance += letter.Advance;
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer2D::DrawChar(Char& letter, Ref<Font> font, Vector2 position, Vector2 size)
|
||||
{
|
||||
TextShader->Bind();
|
||||
TextShader->SetUniformMat4f("projection", Projection);
|
||||
|
||||
Matrix4 mat = Matrix4(1.0f);
|
||||
mat = glm::translate(mat, Vector3(position.x, position.y, 0.f));
|
||||
mat = glm::scale(mat, Vector3(letter.AtlasBounds.Size.x, letter.AtlasBounds.Size.y, 0.f));
|
||||
|
||||
//TextShader->SetUniform1f("u_border_radius", 8.1f);
|
||||
//TextShader->SetUniform2f("u_size", 100.f, 100.f);
|
||||
|
||||
font->FontAtlas->Bind(5);
|
||||
//
|
||||
TextShader->SetUniform1i("msdf", 5);
|
||||
TextShader->SetUniform2f("texPos", letter.AtlasBounds.Pos.x, letter.AtlasBounds.Pos.y);
|
||||
TextShader->SetUniform2f("texScale", letter.AtlasBounds.Size.x, letter.AtlasBounds.Size.y);
|
||||
TextShader->SetUniformMat4f("model", mat);
|
||||
//TextShader->SetUniform4f("bgColor", 0, 0, 1, 1);
|
||||
TextShader->SetUniform4f("bgColor", 1.f, 0.f, 0.f, 0.f);
|
||||
TextShader->SetUniform4f("bgColor", 0.f, 0.f, 0.f, 0.f);
|
||||
TextShader->SetUniform4f("fgColor", 1.f, 1.f, 1.f, 1.f);
|
||||
//TextShader->SetUniform1f("pxRange", 32);
|
||||
glBindVertexArray(VAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
advance += letter.Advance;
|
||||
}
|
||||
|
||||
|
||||
void Renderer2D::EndDraw()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer2D::DrawChar(Char& letter, Ref<Font> font, Vector2 position, Vector2 size)
|
||||
{
|
||||
TextShader->Bind();
|
||||
TextShader->SetUniformMat4f("projection", Projection);
|
||||
|
||||
Matrix4 mat = Matrix4(1.0f);
|
||||
mat = glm::translate(mat, Vector3(position.x, position.y, 0.f));
|
||||
mat = glm::scale(mat, Vector3(letter.AtlasBounds.Size.x, letter.AtlasBounds.Size.y, 0.f));
|
||||
|
||||
//TextShader->SetUniform1f("u_border_radius", 8.1f);
|
||||
//TextShader->SetUniform2f("u_size", 100.f, 100.f);
|
||||
|
||||
font->FontAtlas->Bind(5);
|
||||
//
|
||||
TextShader->SetUniform1i("msdf", 5);
|
||||
TextShader->SetUniform2f("texPos", letter.AtlasBounds.Pos.x, letter.AtlasBounds.Pos.y);
|
||||
TextShader->SetUniform2f("texScale", letter.AtlasBounds.Size.x, letter.AtlasBounds.Size.y);
|
||||
TextShader->SetUniformMat4f("model", mat);
|
||||
//TextShader->SetUniform4f("bgColor", 0, 0, 1, 1);
|
||||
TextShader->SetUniform4f("bgColor", 0.f, 0.f, 0.f, 0.f);
|
||||
TextShader->SetUniform4f("fgColor", 1.f, 1.f, 1.f, 1.f);
|
||||
//TextShader->SetUniform1f("pxRange", 32);
|
||||
glBindVertexArray(VAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
||||
|
||||
void Renderer2D::EndDraw()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,24 +1,28 @@
|
||||
#pragma once
|
||||
#include <src/Rendering/Shaders/Shader.h>
|
||||
#include <src/Core/Core.h>
|
||||
#include <src/Core/Maths.h>
|
||||
#include "src/Rendering/Shaders/Shader.h"
|
||||
#include "src/Core/Core.h"
|
||||
#include "src/Core/Maths.h"
|
||||
#include "src/UI/Font/Font.h"
|
||||
class TextStyle;
|
||||
class Renderer2D
|
||||
{
|
||||
private:
|
||||
static unsigned int VAO;
|
||||
static unsigned int VBO;
|
||||
public:
|
||||
static Ref<Shader> UIShader;
|
||||
static Ref<Shader> TextShader;
|
||||
static Matrix4 Projection;
|
||||
|
||||
static void Init();
|
||||
static void BeginDraw(Vector2 size);
|
||||
static void DrawRect();
|
||||
static Vector2 CalculateStringSize(const std::string& str, Ref<Font> font, Vector2 position, float fontSize);
|
||||
static void DrawString(const std::string& str, TextStyle style, Matrix4 model);
|
||||
static void DrawChar(Char& letter, Ref<Font> font, Vector2 position, Vector2 size);
|
||||
static void EndDraw();
|
||||
};
|
||||
namespace Nuake
|
||||
{
|
||||
class TextStyle;
|
||||
class Renderer2D
|
||||
{
|
||||
private:
|
||||
static unsigned int VAO;
|
||||
static unsigned int VBO;
|
||||
public:
|
||||
static Ref<Shader> UIShader;
|
||||
static Ref<Shader> TextShader;
|
||||
static Matrix4 Projection;
|
||||
|
||||
static void Init();
|
||||
static void BeginDraw(Vector2 size);
|
||||
static void DrawRect();
|
||||
static Vector2 CalculateStringSize(const std::string& str, Ref<Font> font, Vector2 position, float fontSize);
|
||||
static void DrawString(const std::string& str, TextStyle style, Matrix4 model);
|
||||
static void DrawChar(Char& letter, Ref<Font> font, Vector2 position, Vector2 size);
|
||||
static void EndDraw();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,186 +5,200 @@
|
||||
|
||||
#define ASSERT(x) if (!(x)) assert(false)
|
||||
|
||||
// TODO: Register all uniform when creating shader.
|
||||
Shader::Shader(const std::string& filePath) {
|
||||
Source = ParseShader(filePath);
|
||||
|
||||
ProgramId = CreateProgram();
|
||||
}
|
||||
|
||||
// Bind the shader
|
||||
void Shader::Bind() const {
|
||||
glUseProgram(ProgramId);
|
||||
}
|
||||
|
||||
// unbind the shader
|
||||
void Shader::Unbind() const {
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
// Prase the shader file and create string source.
|
||||
ShaderSource Shader::ParseShader(const std::string& filePath) {
|
||||
std::ifstream stream(filePath);
|
||||
|
||||
enum class ShaderType {
|
||||
NONE = -1, VERTEX = 0, FRAGMENT = 1
|
||||
};
|
||||
|
||||
ShaderType type = ShaderType::NONE;
|
||||
|
||||
std::string line;
|
||||
std::stringstream ss[2];
|
||||
|
||||
while (getline(stream, line))
|
||||
namespace Nuake
|
||||
{
|
||||
// TODO: Register all uniform when creating shader.
|
||||
Shader::Shader(const std::string& filePath)
|
||||
{
|
||||
// If the current lines contains #shader
|
||||
if (line.find("#shader") != std::string::npos)
|
||||
Source = ParseShader(filePath);
|
||||
|
||||
ProgramId = CreateProgram();
|
||||
}
|
||||
|
||||
// Bind the shader
|
||||
void Shader::Bind() const
|
||||
{
|
||||
glUseProgram(ProgramId);
|
||||
}
|
||||
|
||||
// unbind the shader
|
||||
void Shader::Unbind() const
|
||||
{
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
// Prase the shader file and create string source.
|
||||
ShaderSource Shader::ParseShader(const std::string& filePath)
|
||||
{
|
||||
std::ifstream stream(filePath);
|
||||
|
||||
enum class ShaderType
|
||||
{
|
||||
// If the current line containes vertex
|
||||
if (line.find("vertex") != std::string::npos) {
|
||||
// set mode to vertex
|
||||
type = ShaderType::VERTEX;
|
||||
NONE = -1, VERTEX = 0, FRAGMENT = 1
|
||||
};
|
||||
|
||||
ShaderType type = ShaderType::NONE;
|
||||
|
||||
std::string line;
|
||||
std::stringstream ss[2];
|
||||
|
||||
while (getline(stream, line))
|
||||
{
|
||||
// If the current lines contains #shader
|
||||
if (line.find("#shader") != std::string::npos)
|
||||
{
|
||||
// If the current line containes vertex
|
||||
if (line.find("vertex") != std::string::npos)
|
||||
{
|
||||
// set mode to vertex
|
||||
type = ShaderType::VERTEX;
|
||||
}
|
||||
else if (line.find("fragment") != std::string::npos)
|
||||
{
|
||||
// set mode to fragment
|
||||
type = ShaderType::FRAGMENT;
|
||||
}
|
||||
}
|
||||
else if (line.find("fragment") != std::string::npos) {
|
||||
// set mode to fragment
|
||||
type = ShaderType::FRAGMENT;
|
||||
else
|
||||
{
|
||||
ss[(int)type] << line << "\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ss[(int)type] << line << "\n";
|
||||
}
|
||||
|
||||
return { ss[0].str(), ss[1].str() };
|
||||
}
|
||||
|
||||
return { ss[0].str(), ss[1].str() };
|
||||
}
|
||||
|
||||
// Parse both source and creates a shader program.
|
||||
// This returns the program id.
|
||||
unsigned int Shader::CreateProgram() {
|
||||
unsigned int program = glCreateProgram();
|
||||
unsigned int vs = Compile(GL_VERTEX_SHADER);
|
||||
unsigned int fs = Compile(GL_FRAGMENT_SHADER);
|
||||
|
||||
glAttachShader(program, vs);
|
||||
glAttachShader(program, fs);
|
||||
glLinkProgram(program);
|
||||
glValidateProgram(program);
|
||||
|
||||
glDeleteShader(vs);
|
||||
glDeleteShader(fs);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
// Compile a single shader and checks for error.
|
||||
unsigned int Shader::Compile(unsigned int type)
|
||||
{
|
||||
unsigned int id = glCreateShader(type);
|
||||
|
||||
const char* src;
|
||||
if (type == GL_FRAGMENT_SHADER) src = Source.FragmentShader.c_str();
|
||||
if (type == GL_VERTEX_SHADER) src = Source.VertexShader.c_str();
|
||||
|
||||
glShaderSource(id, 1, &src, nullptr);
|
||||
glCompileShader(id);
|
||||
|
||||
//TODO: Error handling
|
||||
int result;
|
||||
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
|
||||
|
||||
// Shader error.
|
||||
if (result == GL_FALSE)
|
||||
// Parse both source and creates a shader program.
|
||||
// This returns the program id.
|
||||
unsigned int Shader::CreateProgram()
|
||||
{
|
||||
int length;
|
||||
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
|
||||
unsigned int program = glCreateProgram();
|
||||
unsigned int vs = Compile(GL_VERTEX_SHADER);
|
||||
unsigned int fs = Compile(GL_FRAGMENT_SHADER);
|
||||
|
||||
// We allocate the size of the array using
|
||||
// m alloc. casted as a pointer.
|
||||
char* message = (char*)malloc(length * sizeof(char));
|
||||
glAttachShader(program, vs);
|
||||
glAttachShader(program, fs);
|
||||
glLinkProgram(program);
|
||||
glValidateProgram(program);
|
||||
|
||||
//glGetShaderInfoLog(id, length, &length, message);
|
||||
glDeleteShader(vs);
|
||||
glDeleteShader(fs);
|
||||
|
||||
std::cout << "Failed to compile " <<
|
||||
(type == GL_VERTEX_SHADER ? "vertex" : "Fragment") << " shader!" << std::endl;
|
||||
std::cout << message << std::endl;
|
||||
|
||||
// Delete invalid shader
|
||||
glDeleteShader(id);
|
||||
return 0;
|
||||
return program;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
// Compile a single shader and checks for error.
|
||||
unsigned int Shader::Compile(unsigned int type)
|
||||
{
|
||||
unsigned int id = glCreateShader(type);
|
||||
|
||||
// Retrieve uniform address and registers it if not already registered.
|
||||
int Shader::FindUniformLocation(std::string uniform) {
|
||||
if (UniformCache.count(uniform) == 0) {
|
||||
int addr = glGetUniformLocation(ProgramId, uniform.c_str());
|
||||
const char* src;
|
||||
if (type == GL_FRAGMENT_SHADER) src = Source.FragmentShader.c_str();
|
||||
if (type == GL_VERTEX_SHADER) src = Source.VertexShader.c_str();
|
||||
|
||||
if (addr == -1)
|
||||
std::cout << "Warning: uniform '" << uniform << "' doesn't exists!" << std::endl;
|
||||
else {
|
||||
//std::cout << "Info: uniform '" << uniform << "' registered." << std::endl;
|
||||
UniformCache[uniform] = addr;
|
||||
glShaderSource(id, 1, &src, nullptr);
|
||||
glCompileShader(id);
|
||||
|
||||
//TODO: Error handling
|
||||
int result;
|
||||
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
|
||||
|
||||
// Shader error.
|
||||
if (result == GL_FALSE)
|
||||
{
|
||||
int length;
|
||||
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
|
||||
|
||||
// We allocate the size of the array using
|
||||
// m alloc. casted as a pointer.
|
||||
char* message = (char*)malloc(length * sizeof(char));
|
||||
|
||||
//glGetShaderInfoLog(id, length, &length, message);
|
||||
|
||||
std::cout << "Failed to compile " <<
|
||||
(type == GL_VERTEX_SHADER ? "vertex" : "Fragment") << " shader!" << std::endl;
|
||||
std::cout << message << std::endl;
|
||||
|
||||
// Delete invalid shader
|
||||
glDeleteShader(id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
return addr;
|
||||
return id;
|
||||
}
|
||||
|
||||
return UniformCache[uniform];
|
||||
}
|
||||
// Retrieve uniform address and registers it if not already registered.
|
||||
int Shader::FindUniformLocation(std::string uniform)
|
||||
{
|
||||
if (UniformCache.count(uniform) != 0)
|
||||
{
|
||||
int addr = glGetUniformLocation(ProgramId, uniform.c_str());
|
||||
|
||||
// Uniforms
|
||||
void Shader::SetUniform4f(const std::string& name, float v0, float v1, float v2, float v3) {
|
||||
int addr = FindUniformLocation(name);
|
||||
ASSERT(addr != -1);
|
||||
glUniform4f(addr, v0, v1, v2, v3);
|
||||
}
|
||||
if (addr == -1)
|
||||
std::cout << "Warning: uniform '" << uniform << "' doesn't exists!" << std::endl;
|
||||
else
|
||||
UniformCache[uniform] = addr;
|
||||
|
||||
void Shader::SetUniform3f(const std::string& name, float v0, float v1, float v2) {
|
||||
int addr = FindUniformLocation(name);
|
||||
ASSERT(addr != -1);
|
||||
glUniform3f(addr, v0, v1, v2);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
void Shader::SetUniform2f(const std::string& name, float v0, float v1) {
|
||||
int addr = FindUniformLocation(name);
|
||||
ASSERT(addr != -1);
|
||||
glUniform2f(addr, v0, v1);
|
||||
}
|
||||
return UniformCache[uniform];
|
||||
}
|
||||
|
||||
void Shader::SetUniform1i(const std::string& name, int v0) {
|
||||
int addr = FindUniformLocation(name);
|
||||
ASSERT(addr != -1);
|
||||
glUniform1i(addr, v0);
|
||||
}
|
||||
// Uniforms
|
||||
void Shader::SetUniform4f(const std::string& name, float v0, float v1, float v2, float v3)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
ASSERT(addr != -1);
|
||||
glUniform4f(addr, v0, v1, v2, v3);
|
||||
}
|
||||
|
||||
void Shader::SetUniform1iv(const std::string& name, int size, int* value)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
ASSERT(addr != -1);
|
||||
glUniform1iv(addr, size, value);
|
||||
}
|
||||
void Shader::SetUniform3f(const std::string& name, float v0, float v1, float v2)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
ASSERT(addr != -1);
|
||||
glUniform3f(addr, v0, v1, v2);
|
||||
}
|
||||
|
||||
void Shader::SetUniformMat3f(const std::string& name, glm::mat3 mat)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
ASSERT(addr != -1);
|
||||
glUniformMatrix3fv(addr, 1, GL_FALSE, &mat[0][0]);
|
||||
}
|
||||
void Shader::SetUniform2f(const std::string& name, float v0, float v1)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
ASSERT(addr != -1);
|
||||
glUniform2f(addr, v0, v1);
|
||||
}
|
||||
|
||||
void Shader::SetUniformMat4f(const std::string& name, glm::mat4 mat)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
ASSERT(addr != -1);
|
||||
glUniformMatrix4fv(addr, 1, GL_FALSE, &mat[0][0]);
|
||||
}
|
||||
void Shader::SetUniform1i(const std::string& name, int v0)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
ASSERT(addr != -1);
|
||||
glUniform1i(addr, v0);
|
||||
}
|
||||
|
||||
void Shader::SetUniform1f(const std::string& name, float v0) {
|
||||
int addr = FindUniformLocation(name);
|
||||
ASSERT(addr != -1);
|
||||
glUniform1f(addr, v0);
|
||||
}
|
||||
void Shader::SetUniform1iv(const std::string& name, int size, int* value)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
ASSERT(addr != -1);
|
||||
glUniform1iv(addr, size, value);
|
||||
}
|
||||
|
||||
void Shader::SetUniformMat3f(const std::string& name, glm::mat3 mat)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
ASSERT(addr != -1);
|
||||
glUniformMatrix3fv(addr, 1, GL_FALSE, &mat[0][0]);
|
||||
}
|
||||
|
||||
void Shader::SetUniformMat4f(const std::string& name, glm::mat4 mat)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
ASSERT(addr != -1);
|
||||
glUniformMatrix4fv(addr, 1, GL_FALSE, &mat[0][0]);
|
||||
}
|
||||
|
||||
void Shader::SetUniform1f(const std::string& name, float v0)
|
||||
{
|
||||
int addr = FindUniformLocation(name);
|
||||
ASSERT(addr != -1);
|
||||
glUniform1f(addr, v0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,40 +5,43 @@
|
||||
#include <unordered_map>
|
||||
#include "glm/gtc/matrix_transform.hpp"
|
||||
|
||||
struct ShaderSource {
|
||||
std::string VertexShader;
|
||||
std::string FragmentShader;
|
||||
};
|
||||
namespace Nuake
|
||||
{
|
||||
struct ShaderSource
|
||||
{
|
||||
std::string VertexShader;
|
||||
std::string FragmentShader;
|
||||
};
|
||||
|
||||
class Shader {
|
||||
public:
|
||||
ShaderSource Source;
|
||||
unsigned int ProgramId;
|
||||
class Shader
|
||||
{
|
||||
public:
|
||||
ShaderSource Source;
|
||||
unsigned int ProgramId;
|
||||
|
||||
std::unordered_map<std::string, int> UniformCache;
|
||||
std::unordered_map<std::string, int> UniformCache;
|
||||
|
||||
Shader(const std::string& filePath);
|
||||
Shader(const std::string& filePath);
|
||||
|
||||
void Bind() const;
|
||||
void Unbind() const;
|
||||
void Bind() const;
|
||||
void Unbind() const;
|
||||
|
||||
|
||||
// Todo: Other uniform types.
|
||||
void SetUniform4f(const std::string& name, float v0, float v1, float v2, float v3);
|
||||
void SetUniform3f(const std::string& name, float v0, float v1, float v2);
|
||||
void SetUniform2f(const std::string& name, float v0, float v1);
|
||||
void SetUniform1f(const std::string& name, float v0);
|
||||
void SetUniform1i(const std::string& name, int v0);
|
||||
|
||||
void SetUniform1iv(const std::string& name, int size, int* value);
|
||||
void SetUniformMat3f(const std::string& name, glm::mat3 mat);
|
||||
void SetUniformMat4f(const std::string& name, glm::mat4 mat);
|
||||
|
||||
private:
|
||||
ShaderSource ParseShader(const std::string& filePath);
|
||||
unsigned int CreateProgram();
|
||||
unsigned int Compile(unsigned int type);
|
||||
int FindUniformLocation(std::string uniform);
|
||||
};
|
||||
// Todo: Other uniform types.
|
||||
void SetUniform4f(const std::string& name, float v0, float v1, float v2, float v3);
|
||||
void SetUniform3f(const std::string& name, float v0, float v1, float v2);
|
||||
void SetUniform2f(const std::string& name, float v0, float v1);
|
||||
void SetUniform1f(const std::string& name, float v0);
|
||||
void SetUniform1i(const std::string& name, int v0);
|
||||
|
||||
void SetUniform1iv(const std::string& name, int size, int* value);
|
||||
void SetUniformMat3f(const std::string& name, glm::mat3 mat);
|
||||
void SetUniformMat4f(const std::string& name, glm::mat4 mat);
|
||||
|
||||
private:
|
||||
ShaderSource ParseShader(const std::string& filePath);
|
||||
unsigned int CreateProgram();
|
||||
unsigned int Compile(unsigned int type);
|
||||
int FindUniformLocation(std::string uniform);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
#pragma once
|
||||
#include "ShaderManager.h"
|
||||
|
||||
std::map<std::string, Ref<Shader>> ShaderManager::m_Shaders = std::map<std::string, Ref<Shader>>();
|
||||
|
||||
Ref<Shader> ShaderManager::GetShader(const std::string& path)
|
||||
namespace Nuake
|
||||
{
|
||||
if (m_Shaders.find(path) == m_Shaders.end())
|
||||
{
|
||||
m_Shaders[path] = CreateRef<Shader>(path);
|
||||
}
|
||||
std::map<std::string, Ref<Shader>> ShaderManager::m_Shaders = std::map<std::string, Ref<Shader>>();
|
||||
|
||||
return m_Shaders[path];
|
||||
}
|
||||
Ref<Shader> ShaderManager::GetShader(const std::string& path)
|
||||
{
|
||||
if (m_Shaders.find(path) == m_Shaders.end())
|
||||
{
|
||||
m_Shaders[path] = CreateRef<Shader>(path);
|
||||
}
|
||||
|
||||
return m_Shaders[path];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,13 @@
|
||||
#include "src/Core/Core.h"
|
||||
#include "Shader.h"
|
||||
|
||||
class ShaderManager {
|
||||
private:
|
||||
static std::map<std::string, Ref<Shader>> m_Shaders;
|
||||
namespace Nuake
|
||||
{
|
||||
class ShaderManager {
|
||||
private:
|
||||
static std::map<std::string, Ref<Shader>> m_Shaders;
|
||||
|
||||
public:
|
||||
static Ref<Shader> GetShader(const std::string& path);
|
||||
};
|
||||
public:
|
||||
static Ref<Shader> GetShader(const std::string& path);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,158 +0,0 @@
|
||||
#include "Skybox.h"
|
||||
#include <GL\glew.h>
|
||||
#include "Renderer.h"
|
||||
#include "Textures/Cubemap.h"
|
||||
glm::vec3 Skybox::vertices[36] {
|
||||
glm::vec3(-0.5f, -0.5f, -0.5f),
|
||||
glm::vec3(0.5f, -0.5f, -0.5f),
|
||||
glm::vec3(0.5f, 0.5f, -0.5f),
|
||||
glm::vec3(0.5f, 0.5f, -0.5f),
|
||||
glm::vec3(-0.5f, 0.5f, -0.5f),
|
||||
glm::vec3(-0.5f, -0.5f, -0.5f),
|
||||
|
||||
glm::vec3(-0.5f, -0.5f, 0.5f),
|
||||
glm::vec3(0.5f, -0.5f, 0.5f),
|
||||
glm::vec3(0.5f, 0.5f, 0.5f),
|
||||
glm::vec3(0.5f, 0.5f, 0.5f),
|
||||
glm::vec3(-0.5f, 0.5f, 0.5f),
|
||||
glm::vec3(-0.5f, -0.5f, 0.5f),
|
||||
|
||||
glm::vec3(-0.5f, 0.5f, 0.5f),
|
||||
glm::vec3(-0.5f, 0.5f, -0.5f),
|
||||
glm::vec3(-0.5f, -0.5f, -0.5f),
|
||||
glm::vec3(-0.5f, -0.5f, -0.5f),
|
||||
glm::vec3(-0.5f, -0.5f, 0.5f),
|
||||
glm::vec3(-0.5f, 0.5f, 0.5f),
|
||||
|
||||
glm::vec3(0.5f, 0.5f, 0.5f),
|
||||
glm::vec3(0.5f, 0.5f, -0.5f),
|
||||
glm::vec3(0.5f, -0.5f, -0.5f),
|
||||
glm::vec3(0.5f, -0.5f, -0.5f),
|
||||
glm::vec3(0.5f, -0.5f, 0.5f),
|
||||
glm::vec3(0.5f, 0.5f, 0.5f),
|
||||
|
||||
glm::vec3(-0.5f, -0.5f, -0.5f),
|
||||
glm::vec3(0.5f, -0.5f, -0.5f),
|
||||
glm::vec3(0.5f, -0.5f, 0.5f),
|
||||
glm::vec3(0.5f, -0.5f, 0.5f),
|
||||
glm::vec3(-0.5f, -0.5f, 0.5f),
|
||||
glm::vec3(-0.5f, -0.5f, -0.5f),
|
||||
|
||||
glm::vec3(-0.5f, 0.5f, -0.5f) ,
|
||||
glm::vec3(0.5f, 0.5f, -0.5f) ,
|
||||
glm::vec3(0.5f, 0.5f, 0.5f) ,
|
||||
glm::vec3(0.5f, 0.5f, 0.5f) ,
|
||||
glm::vec3(-0.5f, 0.5f, 0.5f) ,
|
||||
glm::vec3(-0.5f, 0.5f, -0.5f)
|
||||
};
|
||||
|
||||
Skybox::Skybox(){
|
||||
// Setup buffers
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
glGenBuffers(1, &VBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
// TODO: mem leak.
|
||||
m_Texture = new CubemapTexture("Res/Textures/Skyboxes/1/japan");
|
||||
m_Hdr = new HDRTexture("Res/Textures/Skyboxes/HDR/OldIndustrialHall.jpg");
|
||||
}
|
||||
|
||||
void Skybox::Draw(glm::mat4 projection, glm::mat4 view) {
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
m_Texture->Bind(3);
|
||||
m_Hdr->Bind(4);
|
||||
Renderer::m_SkyboxShader->Bind();
|
||||
m_Hdr->BindCubemap(5);
|
||||
Renderer::m_SkyboxShader->SetUniformMat4f("projection", projection);
|
||||
Renderer::m_SkyboxShader->SetUniformMat4f("view", view);
|
||||
|
||||
Renderer::m_SkyboxShader->SetUniform1i("isHDR", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("equirectangularMap", 4);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("skybox", 5);
|
||||
|
||||
// ... set view and projection matrix
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
glDepthMask(GL_TRUE);
|
||||
//Renderer::m_Shader->SetUniform4f("u_AmbientColor", 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
|
||||
void Skybox::Push() {
|
||||
m_Hdr->BindCubemap(5);
|
||||
Renderer::m_Shader->SetUniform1i("u_IrradianceMap", 5);
|
||||
}
|
||||
|
||||
|
||||
void Skybox::CreateHDRCubemap() {
|
||||
unsigned int captureFBO, captureRBO;
|
||||
glGenFramebuffers(1, &captureFBO);
|
||||
glGenRenderbuffers(1, &captureRBO);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, captureRBO);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 512, 512);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, captureRBO);
|
||||
|
||||
unsigned int envCubemap;
|
||||
glGenTextures(1, &envCubemap);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, envCubemap);
|
||||
for (unsigned int i = 0; i < 6; ++i)
|
||||
{
|
||||
// note that we store each face with 16 bit floating point values
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F,
|
||||
512, 512, 0, GL_RGB, GL_FLOAT, nullptr);
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glm::mat4 captureProjection = glm::perspective(glm::radians(90.0f), 1.0f, 0.1f, 10.0f);
|
||||
glm::mat4 captureViews[] =
|
||||
{
|
||||
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
|
||||
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
|
||||
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)),
|
||||
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)),
|
||||
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
|
||||
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f))
|
||||
};
|
||||
m_Hdr->Bind(5);
|
||||
|
||||
// convert HDR equirectangular environment map to cubemap equivalent
|
||||
Renderer::m_SkyboxShader->Bind();
|
||||
Renderer::m_SkyboxShader->SetUniformMat4f("projection", captureProjection);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("convulate", 0);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("isHDR", 1);
|
||||
Renderer::m_SkyboxShader->SetUniform1i("equirectangularMap", 5);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glViewport(0, 0, 512, 512); // don't forget to configure the viewport to the capture dimensions.
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
|
||||
for (unsigned int i = 0; i < 6; ++i)
|
||||
{
|
||||
Renderer::m_SkyboxShader->SetUniformMat4f("view", captureViews[i]);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, envCubemap, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
}
|
||||
|
||||
m_Hdr->SetCubemapId(envCubemap);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
#include <glm\ext\vector_float3.hpp>
|
||||
#include <glm\mat4x4.hpp>
|
||||
#include "Textures/HDR.h"
|
||||
class CubemapTexture;
|
||||
|
||||
class Skybox {
|
||||
|
||||
static glm::vec3 vertices[];
|
||||
CubemapTexture* m_Texture;
|
||||
HDRTexture* m_Hdr;
|
||||
|
||||
|
||||
unsigned int VBO;
|
||||
unsigned int VAO;
|
||||
public:
|
||||
Skybox();
|
||||
void Draw(glm::mat4 projection, glm::mat4 view);
|
||||
|
||||
void Push();
|
||||
|
||||
void CreateHDRCubemap();
|
||||
|
||||
};
|
||||
@@ -3,76 +3,87 @@
|
||||
#include <iostream>
|
||||
#include "HDR.h"
|
||||
|
||||
bool hasEnding(std::string const& fullString, std::string const& ending) {
|
||||
if (fullString.length() >= ending.length()) {
|
||||
return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending));
|
||||
namespace Nuake
|
||||
{
|
||||
bool hasEnding(std::string const& fullString, std::string const& ending)
|
||||
{
|
||||
if (fullString.length() >= ending.length())
|
||||
return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending));
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
CubemapTexture::CubemapTexture(const std::string& path) {
|
||||
m_RendererId = 0;
|
||||
m_FilePath = path;
|
||||
m_LocalBuffer = nullptr;
|
||||
m_Width = 0;
|
||||
m_Height = 0;
|
||||
m_BPP = 0;
|
||||
CubemapTexture::CubemapTexture(const std::string& path)
|
||||
{
|
||||
m_RendererId = 0;
|
||||
m_FilePath = path;
|
||||
m_LocalBuffer = nullptr;
|
||||
m_Width = 0;
|
||||
m_Height = 0;
|
||||
m_BPP = 0;
|
||||
|
||||
if (hasEnding(path, ".hdr")) {
|
||||
CreateFromHDR();
|
||||
}
|
||||
else {
|
||||
stbi_set_flip_vertically_on_load(0);
|
||||
|
||||
GLvoid* texture_data[6];
|
||||
// Load file data.
|
||||
for (int face = 0; face < 6; face++)
|
||||
texture_data[face] = stbi_load((path + std::to_string(face) + ".jpg").c_str(), &m_Width, &m_Height, &m_BPP, 4);
|
||||
|
||||
// Create cube map.
|
||||
glGenTextures(1, &m_RendererId);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, m_RendererId);
|
||||
|
||||
// Set each face of the cube with image data.
|
||||
for (int face = 0; face < 6; face++) {
|
||||
|
||||
GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
|
||||
0, GL_RGBA, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_data[face]
|
||||
);
|
||||
|
||||
// Clear.
|
||||
if (texture_data[face])
|
||||
stbi_image_free(texture_data[face]);
|
||||
else
|
||||
std::cout << "Error: failed to load texture: " << path << std::endl;
|
||||
if (hasEnding(path, ".hdr"))
|
||||
{
|
||||
CreateFromHDR();
|
||||
}
|
||||
else
|
||||
{
|
||||
stbi_set_flip_vertically_on_load(0);
|
||||
|
||||
GLvoid* texture_data[6];
|
||||
// Load file data.
|
||||
for (int face = 0; face < 6; face++)
|
||||
texture_data[face] = stbi_load((path + std::to_string(face) + ".jpg").c_str(), &m_Width, &m_Height, &m_BPP, 4);
|
||||
|
||||
// Create cube map.
|
||||
glGenTextures(1, &m_RendererId);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, m_RendererId);
|
||||
|
||||
// Set each face of the cube with image data.
|
||||
for (int face = 0; face < 6; face++)
|
||||
{
|
||||
|
||||
GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
|
||||
0, GL_RGBA, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_data[face]
|
||||
);
|
||||
|
||||
// Clear.
|
||||
if (texture_data[face])
|
||||
stbi_image_free(texture_data[face]);
|
||||
else
|
||||
std::cout << "Error: failed to load texture: " << path << std::endl;
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CubemapTexture::CreateFromHDR()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CubemapTexture::~CubemapTexture()
|
||||
{
|
||||
glDeleteTextures(1, &m_RendererId);
|
||||
}
|
||||
|
||||
void CubemapTexture::Bind(unsigned int slot) const
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, m_RendererId);
|
||||
}
|
||||
|
||||
void CubemapTexture::Unbind() const
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CubemapTexture::CreateFromHDR() {
|
||||
|
||||
}
|
||||
|
||||
CubemapTexture::~CubemapTexture() {
|
||||
glDeleteTextures(1, &m_RendererId);
|
||||
}
|
||||
|
||||
void CubemapTexture::Bind(unsigned int slot) const {
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, m_RendererId);
|
||||
}
|
||||
|
||||
void CubemapTexture::Unbind() const {
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,28 +2,29 @@
|
||||
#include "stb_image/stb_image.h"
|
||||
#include <string>
|
||||
|
||||
|
||||
class CubemapTexture
|
||||
namespace Nuake
|
||||
{
|
||||
private:
|
||||
unsigned int m_RendererId;
|
||||
std::string m_FilePath;
|
||||
unsigned char* m_LocalBuffer;
|
||||
int m_Width;
|
||||
int m_Height;
|
||||
int m_BPP; // byte per pixel.
|
||||
class CubemapTexture
|
||||
{
|
||||
public:
|
||||
CubemapTexture(const std::string& path);
|
||||
void CreateFromHDR();
|
||||
~CubemapTexture();
|
||||
|
||||
public:
|
||||
CubemapTexture(const std::string& path);
|
||||
void CreateFromHDR();
|
||||
~CubemapTexture();
|
||||
void Bind(unsigned int slot = 0) const;
|
||||
void Unbind() const;
|
||||
|
||||
void Bind(unsigned int slot = 0) const;
|
||||
void Unbind() const;
|
||||
|
||||
inline int GetWidth() const { return m_Width; }
|
||||
inline int GetHeight() const { return m_Height; }
|
||||
};
|
||||
inline int GetWidth() const { return m_Width; }
|
||||
inline int GetHeight() const { return m_Height; }
|
||||
|
||||
private:
|
||||
std::string m_FilePath;
|
||||
|
||||
unsigned int m_RendererId;
|
||||
unsigned char* m_LocalBuffer;
|
||||
|
||||
int m_Width;
|
||||
int m_Height;
|
||||
int m_BPP; // byte per pixel.
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,55 +1,66 @@
|
||||
#include "HDR.h"
|
||||
#include <GL\glew.h>
|
||||
#include <iostream>
|
||||
#include "../Renderer.h"
|
||||
#include "src/Rendering/Renderer.h"
|
||||
|
||||
HDRTexture::HDRTexture(const std::string& path) {
|
||||
m_RendererId = 0;
|
||||
m_FilePath = path;
|
||||
m_LocalBuffer = nullptr;
|
||||
m_Width = 0;
|
||||
m_Height = 0;
|
||||
m_BPP = 0;
|
||||
|
||||
stbi_set_flip_vertically_on_load(1);
|
||||
float* data = stbi_loadf(path.c_str(), &m_Width, &m_Height, &m_BPP, 0);
|
||||
|
||||
if (data)
|
||||
namespace Nuake
|
||||
{
|
||||
HDRTexture::HDRTexture(const std::string& path)
|
||||
{
|
||||
glGenTextures(1, &m_RendererId);
|
||||
m_RendererId = 0;
|
||||
m_FilePath = path;
|
||||
m_LocalBuffer = nullptr;
|
||||
m_Width = 0;
|
||||
m_Height = 0;
|
||||
m_BPP = 0;
|
||||
|
||||
stbi_set_flip_vertically_on_load(1);
|
||||
float* data = stbi_loadf(path.c_str(), &m_Width, &m_Height, &m_BPP, 0);
|
||||
|
||||
if (data)
|
||||
{
|
||||
glGenTextures(1, &m_RendererId);
|
||||
glBindTexture(GL_TEXTURE_2D, m_RendererId);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, m_Width, m_Height, 0, GL_RGB, GL_FLOAT, data);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
stbi_image_free(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Failed to load HDR image." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
HDRTexture::~HDRTexture()
|
||||
{
|
||||
glDeleteTextures(1, &m_RendererId);
|
||||
}
|
||||
|
||||
void HDRTexture::Bind(unsigned int slot) const
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
glBindTexture(GL_TEXTURE_2D, m_RendererId);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, m_Width, m_Height, 0, GL_RGB, GL_FLOAT, data);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
stbi_image_free(data);
|
||||
}
|
||||
else
|
||||
|
||||
void HDRTexture::BindCubemap(unsigned int slot) const
|
||||
{
|
||||
std::cout << "Failed to load HDR image." << std::endl;
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubemapId);
|
||||
}
|
||||
|
||||
void HDRTexture::Unbind() const
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
void HDRTexture::GenerateCubeMap()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
HDRTexture::~HDRTexture() {
|
||||
glDeleteTextures(1, &m_RendererId);
|
||||
}
|
||||
|
||||
void HDRTexture::Bind(unsigned int slot) const {
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
glBindTexture(GL_TEXTURE_2D, m_RendererId);
|
||||
}
|
||||
void HDRTexture::BindCubemap(unsigned int slot) const {
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubemapId);
|
||||
}
|
||||
|
||||
void HDRTexture::Unbind() const {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
void HDRTexture::GenerateCubeMap() {
|
||||
|
||||
}
|
||||
|
||||
@@ -2,34 +2,33 @@
|
||||
#include "stb_image/stb_image.h"
|
||||
#include <string>
|
||||
|
||||
|
||||
class HDRTexture
|
||||
namespace Nuake
|
||||
{
|
||||
private:
|
||||
unsigned int m_RendererId;
|
||||
std::string m_FilePath;
|
||||
unsigned char* m_LocalBuffer;
|
||||
int m_Width;
|
||||
int m_Height;
|
||||
int m_BPP; // byte per pixel.
|
||||
unsigned int m_CubemapId;
|
||||
class HDRTexture
|
||||
{
|
||||
private:
|
||||
unsigned int m_RendererId;
|
||||
std::string m_FilePath;
|
||||
unsigned char* m_LocalBuffer;
|
||||
int m_Width;
|
||||
int m_Height;
|
||||
int m_BPP; // byte per pixel.
|
||||
unsigned int m_CubemapId;
|
||||
|
||||
public:
|
||||
HDRTexture(const std::string& path);
|
||||
~HDRTexture();
|
||||
public:
|
||||
HDRTexture(const std::string& path);
|
||||
~HDRTexture();
|
||||
|
||||
void Bind(unsigned int slot = 0) const;
|
||||
void BindCubemap(unsigned int slot = 0) const;
|
||||
void Unbind() const;
|
||||
|
||||
inline int GetWidth() const { return m_Width; }
|
||||
inline int GetHeight() const { return m_Height; }
|
||||
|
||||
void GenerateCubeMap();
|
||||
|
||||
void SetCubemapId(unsigned int id) { m_CubemapId = id; }
|
||||
unsigned int GetCubemapId() { return m_CubemapId; }
|
||||
};
|
||||
void Bind(unsigned int slot = 0) const;
|
||||
void BindCubemap(unsigned int slot = 0) const;
|
||||
void Unbind() const;
|
||||
|
||||
inline int GetWidth() const { return m_Width; }
|
||||
inline int GetHeight() const { return m_Height; }
|
||||
|
||||
void GenerateCubeMap();
|
||||
|
||||
void SetCubemapId(unsigned int id) { m_CubemapId = id; }
|
||||
unsigned int GetCubemapId() { return m_CubemapId; }
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,189 +1,181 @@
|
||||
|
||||
|
||||
#include "../Core/MaterialManager.h"
|
||||
#include "Material.h"
|
||||
#include <glm\ext\vector_float4.hpp>
|
||||
#include "../Renderer.h"
|
||||
|
||||
#include "src/Core/Maths.h"
|
||||
#include "src/Rendering/Renderer.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <dependencies/GLEW/include/GL/glew.h>
|
||||
Ref<Texture> Material::m_DefaultAlbedo;
|
||||
Ref<Texture> Material::m_DefaultAO;
|
||||
Ref<Texture> Material::m_DefaultNormal;
|
||||
Ref<Texture> Material::m_DefaultRoughness;
|
||||
Ref<Texture> Material::m_DefaultMetalness;
|
||||
Ref<Texture> Material::m_DefaultDisplacement;
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
Material::Material(const std::string albedo)
|
||||
namespace Nuake
|
||||
{
|
||||
glGenBuffers(1, &UBO);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, UBO);
|
||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(UBOStructure), NULL, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
Ref<Texture> Material::m_DefaultAlbedo;
|
||||
Ref<Texture> Material::m_DefaultAO;
|
||||
Ref<Texture> Material::m_DefaultNormal;
|
||||
Ref<Texture> Material::m_DefaultRoughness;
|
||||
Ref<Texture> Material::m_DefaultMetalness;
|
||||
Ref<Texture> Material::m_DefaultDisplacement;
|
||||
|
||||
m_Albedo = TextureManager::Get()->GetTexture(albedo);
|
||||
|
||||
data.u_HasAlbedo = 1;
|
||||
Material::Material(const std::string albedo)
|
||||
{
|
||||
glGenBuffers(1, &UBO);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, UBO);
|
||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(UBOStructure), NULL, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
|
||||
std::stringstream ss(albedo);
|
||||
std::string item;
|
||||
std::vector<std::string> elems;
|
||||
while (std::getline(ss, item, '/')) {
|
||||
elems.push_back(item);
|
||||
// elems.push_back(std::move(item)); // if C++11 (based on comment from @mchiasson)
|
||||
m_Albedo = TextureManager::Get()->GetTexture(albedo);
|
||||
|
||||
data.u_HasAlbedo = 1;
|
||||
|
||||
std::stringstream ss(albedo);
|
||||
std::string item;
|
||||
std::vector<std::string> elems;
|
||||
while (std::getline(ss, item, '/'))
|
||||
{
|
||||
elems.push_back(item);
|
||||
}
|
||||
|
||||
m_Name = albedo;
|
||||
|
||||
if (m_DefaultAO == nullptr)
|
||||
m_DefaultAO = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png");
|
||||
if (m_DefaultNormal == nullptr)
|
||||
m_DefaultNormal = TextureManager::Get()->GetTexture("resources/Textures/default/defaultNormal.png");
|
||||
if (m_DefaultDisplacement == nullptr)
|
||||
m_DefaultDisplacement = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png");
|
||||
if (m_DefaultRoughness == nullptr)
|
||||
m_DefaultRoughness = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png");
|
||||
if (m_DefaultMetalness == nullptr)
|
||||
m_DefaultMetalness = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png");
|
||||
}
|
||||
|
||||
m_Name = albedo;
|
||||
if (m_DefaultAO == nullptr)
|
||||
m_DefaultAO = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png");
|
||||
if (m_DefaultNormal == nullptr)
|
||||
m_DefaultNormal = TextureManager::Get()->GetTexture("resources/Textures/default/defaultNormal.png");
|
||||
if (m_DefaultDisplacement == nullptr)
|
||||
m_DefaultDisplacement = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png");
|
||||
if (m_DefaultRoughness == nullptr)
|
||||
m_DefaultRoughness = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png");
|
||||
if (m_DefaultMetalness == nullptr)
|
||||
m_DefaultMetalness = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png");
|
||||
Material::Material(const glm::vec3 albedoColor)
|
||||
{
|
||||
glGenBuffers(1, &UBO);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, UBO);
|
||||
glBufferData(GL_UNIFORM_BUFFER, 128, NULL, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
|
||||
data.m_AlbedoColor = Vector3{ albedoColor.r, albedoColor.g, albedoColor.b };
|
||||
|
||||
m_Name = "New material";
|
||||
|
||||
if (m_DefaultAlbedo == nullptr)
|
||||
m_DefaultAlbedo = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png");
|
||||
|
||||
m_Albedo = m_DefaultAlbedo;
|
||||
|
||||
if (m_DefaultAO == nullptr)
|
||||
m_DefaultAO = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png");
|
||||
if (m_DefaultNormal == nullptr)
|
||||
m_DefaultNormal = TextureManager::Get()->GetTexture("resources/Textures/default/defaultNormal.png");
|
||||
if (m_DefaultDisplacement == nullptr)
|
||||
m_DefaultDisplacement = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png");
|
||||
if (m_DefaultRoughness == nullptr)
|
||||
m_DefaultRoughness = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png");
|
||||
if (m_DefaultMetalness == nullptr)
|
||||
m_DefaultMetalness = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png");
|
||||
}
|
||||
|
||||
Material::~Material() {}
|
||||
|
||||
void Material::Bind()
|
||||
{
|
||||
if (MaterialManager::Get()->CurrentlyBoundedMaterial == m_Name)
|
||||
return;
|
||||
|
||||
MaterialManager::Get()->CurrentlyBoundedMaterial = m_Name;
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, UBO);
|
||||
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UBOStructure), &data);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, 32, UBO);
|
||||
|
||||
// Albedo
|
||||
if (m_Albedo != nullptr)
|
||||
m_Albedo->Bind(4);
|
||||
else
|
||||
m_DefaultAlbedo->Bind(4);
|
||||
Renderer::m_Shader->SetUniform1i("m_Albedo", 4);
|
||||
|
||||
// AO
|
||||
if (m_AO != nullptr)
|
||||
m_AO->Bind(5);
|
||||
else
|
||||
m_DefaultAO->Bind(5);
|
||||
Renderer::m_Shader->SetUniform1i("m_AO", 5);
|
||||
|
||||
// Metallic
|
||||
if (m_Metalness != nullptr)
|
||||
m_Metalness->Bind(6);
|
||||
else
|
||||
m_DefaultMetalness->Bind(6);
|
||||
Renderer::m_Shader->SetUniform1i("m_Metalness", 6);
|
||||
|
||||
// Roughness
|
||||
if (m_Roughness != nullptr)
|
||||
m_Roughness->Bind(7);
|
||||
else
|
||||
m_DefaultRoughness->Bind(7);
|
||||
Renderer::m_Shader->SetUniform1i("m_Roughness", 7);
|
||||
|
||||
// Normal
|
||||
if (m_Normal != nullptr)
|
||||
m_Normal->Bind(8);
|
||||
else
|
||||
m_DefaultNormal->Bind(8);
|
||||
Renderer::m_Shader->SetUniform1i("m_Normal", 8);
|
||||
|
||||
// Displacement
|
||||
if (m_Displacement != nullptr)
|
||||
m_Displacement->Bind(9);
|
||||
else
|
||||
m_DefaultDisplacement->Bind(9);
|
||||
//Renderer::m_Shader->SetUniform1i("m_Displacement", 9);
|
||||
//Renderer::m_Shader->SetUniform1i("m_Displacement", 9);
|
||||
}
|
||||
|
||||
void Material::SetupUniformBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
void Material::SetName(const std::string name)
|
||||
{
|
||||
m_Name = name;
|
||||
}
|
||||
|
||||
std::string Material::GetName() { return m_Name; }
|
||||
|
||||
|
||||
void Material::SetAO(const std::string ao)
|
||||
{
|
||||
m_AO = CreateRef<Texture>(ao);
|
||||
}
|
||||
|
||||
void Material::SetMetalness(const std::string metalness)
|
||||
{
|
||||
m_Metalness = CreateRef<Texture>(metalness);
|
||||
}
|
||||
|
||||
void Material::SetRoughness(const std::string roughness)
|
||||
{
|
||||
m_Roughness = CreateRef<Texture>(roughness);
|
||||
}
|
||||
|
||||
void Material::SetNormal(const std::string normal)
|
||||
{
|
||||
m_Normal = CreateRef<Texture>(normal);
|
||||
}
|
||||
|
||||
void Material::SetDisplacement(const std::string displacement)
|
||||
{
|
||||
m_Displacement = CreateRef<Texture>(displacement);
|
||||
}
|
||||
}
|
||||
|
||||
//Material::Material()
|
||||
//{
|
||||
//}
|
||||
|
||||
Material::Material(const glm::vec3 albedoColor)
|
||||
{
|
||||
glGenBuffers(1, &UBO);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, UBO);
|
||||
glBufferData(GL_UNIFORM_BUFFER, 128, NULL, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
|
||||
data.m_AlbedoColor = Vector3{ albedoColor.r, albedoColor.g, albedoColor.b};
|
||||
|
||||
m_Name = "New material";
|
||||
|
||||
if (m_DefaultAlbedo == nullptr)
|
||||
m_DefaultAlbedo = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png");
|
||||
|
||||
m_Albedo = m_DefaultAlbedo;
|
||||
|
||||
if (m_DefaultAO == nullptr)
|
||||
m_DefaultAO = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png");
|
||||
if (m_DefaultNormal == nullptr)
|
||||
m_DefaultNormal = TextureManager::Get()->GetTexture("resources/Textures/default/defaultNormal.png");
|
||||
if (m_DefaultDisplacement == nullptr)
|
||||
m_DefaultDisplacement = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png");
|
||||
if (m_DefaultRoughness == nullptr)
|
||||
m_DefaultRoughness = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png");
|
||||
if (m_DefaultMetalness == nullptr)
|
||||
m_DefaultMetalness = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png");
|
||||
}
|
||||
|
||||
Material::~Material() {}
|
||||
|
||||
void Material::Bind()
|
||||
{
|
||||
if (MaterialManager::Get()->CurrentlyBoundedMaterial == m_Name)
|
||||
return;
|
||||
|
||||
MaterialManager::Get()->CurrentlyBoundedMaterial = m_Name;
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, UBO);
|
||||
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UBOStructure), &data);
|
||||
//glBufferSubData(GL_UNIFORM_BUFFER, 0, 4, &data.u_HasAlbedo);
|
||||
//
|
||||
//glBufferSubData(GL_UNIFORM_BUFFER, 16, 12, &data.m_AlbedoColor);
|
||||
//
|
||||
//glBufferSubData(GL_UNIFORM_BUFFER, 28, 4, &data.u_HasMetalness);
|
||||
//glBufferSubData(GL_UNIFORM_BUFFER, 32, 4, &data.u_MetalnessValue);
|
||||
//glBufferSubData(GL_UNIFORM_BUFFER, 36, 4, &data.u_HasRoughness);
|
||||
//glBufferSubData(GL_UNIFORM_BUFFER, 40, 4, &data.u_RoughnessValue);
|
||||
//
|
||||
//glBufferSubData(GL_UNIFORM_BUFFER, 44, 4, &data.u_HasAO);
|
||||
//glBufferSubData(GL_UNIFORM_BUFFER, 48, 4, &data.u_AOValue);
|
||||
//glBufferSubData(GL_UNIFORM_BUFFER, 52, 4, &data.u_HasNormal);
|
||||
//glBufferSubData(GL_UNIFORM_BUFFER, 56, 4, &data.u_HasDisplacement);
|
||||
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, 32, UBO);
|
||||
|
||||
// Albedo
|
||||
if (m_Albedo != nullptr)
|
||||
m_Albedo->Bind(4);
|
||||
else
|
||||
m_DefaultAlbedo->Bind(4);
|
||||
Renderer::m_Shader->SetUniform1i("m_Albedo", 4);
|
||||
|
||||
// AO
|
||||
if (m_AO != nullptr)
|
||||
m_AO->Bind(5);
|
||||
else
|
||||
m_DefaultAO->Bind(5);
|
||||
Renderer::m_Shader->SetUniform1i("m_AO", 5);
|
||||
|
||||
// Metallic
|
||||
if (m_Metalness != nullptr)
|
||||
m_Metalness->Bind(6);
|
||||
else
|
||||
m_DefaultMetalness->Bind(6);
|
||||
Renderer::m_Shader->SetUniform1i("m_Metalness", 6);
|
||||
|
||||
// Roughness
|
||||
if (m_Roughness != nullptr)
|
||||
m_Roughness->Bind(7);
|
||||
else
|
||||
m_DefaultRoughness->Bind(7);
|
||||
Renderer::m_Shader->SetUniform1i("m_Roughness", 7);
|
||||
|
||||
// Normal
|
||||
if (m_Normal != nullptr)
|
||||
m_Normal->Bind(8);
|
||||
else
|
||||
m_DefaultNormal->Bind(8);
|
||||
Renderer::m_Shader->SetUniform1i("m_Normal", 8);
|
||||
|
||||
// Displacement
|
||||
if (m_Displacement != nullptr)
|
||||
m_Displacement->Bind(9);
|
||||
else
|
||||
m_DefaultDisplacement->Bind(9);
|
||||
//Renderer::m_Shader->SetUniform1i("m_Displacement", 9);
|
||||
//Renderer::m_Shader->SetUniform1i("m_Displacement", 9);
|
||||
}
|
||||
|
||||
void Material::SetupUniformBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
void Material::SetName(const std::string name)
|
||||
{
|
||||
m_Name = name;
|
||||
}
|
||||
|
||||
std::string Material::GetName() { return m_Name; }
|
||||
|
||||
|
||||
void Material::SetAO(const std::string ao)
|
||||
{
|
||||
m_AO = CreateRef<Texture>(ao);
|
||||
}
|
||||
void Material::SetMetalness(const std::string metalness)
|
||||
{
|
||||
m_Metalness = CreateRef<Texture>(metalness);
|
||||
}
|
||||
void Material::SetRoughness(const std::string roughness)
|
||||
{
|
||||
m_Roughness = CreateRef<Texture>(roughness);
|
||||
}
|
||||
void Material::SetNormal(const std::string normal)
|
||||
{
|
||||
m_Normal = CreateRef<Texture>(normal);
|
||||
}
|
||||
|
||||
void Material::SetDisplacement(const std::string displacement)
|
||||
{
|
||||
m_Displacement = CreateRef<Texture>(displacement);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,103 +1,100 @@
|
||||
#pragma once
|
||||
#include "../../Core/TextureManager.h"
|
||||
#include "src/Core/TextureManager.h"
|
||||
#include "Texture.h"
|
||||
#include <glm\ext\vector_float3.hpp>
|
||||
#include <glm\ext\vector_float4.hpp>
|
||||
#include "../Core/Core.h"
|
||||
|
||||
#include "src/Core/Core.h"
|
||||
#include "src/Core/Maths.h"
|
||||
|
||||
struct myVec3 {
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
};
|
||||
|
||||
struct UBOStructure {
|
||||
int u_HasAlbedo;
|
||||
float padding;
|
||||
float padding2;
|
||||
float padding3;
|
||||
glm::vec3 m_AlbedoColor;
|
||||
int u_HasMetalness;
|
||||
float u_MetalnessValue;
|
||||
int u_HasRoughness;
|
||||
float u_RoughnessValue;
|
||||
int u_HasAO;
|
||||
float u_AOValue;
|
||||
int u_HasNormal;
|
||||
int u_HasDisplacement;
|
||||
};
|
||||
|
||||
class Material
|
||||
namespace Nuake
|
||||
{
|
||||
private:
|
||||
std::string m_Name;
|
||||
unsigned int UBO;
|
||||
public:
|
||||
Ref<Texture> m_Albedo;
|
||||
Ref<Texture> m_AO;
|
||||
Ref<Texture> m_Metalness;
|
||||
Ref<Texture> m_Roughness;
|
||||
Ref<Texture> m_Normal;
|
||||
Ref<Texture> m_Displacement;
|
||||
|
||||
UBOStructure data{
|
||||
0, // has labedo
|
||||
0, // padding
|
||||
0, // padding
|
||||
0, // padding
|
||||
glm::vec3{0.f, 0.f, 0.f}, // m_AlbedoColor
|
||||
0, // u_HasMetalness
|
||||
0.5f, // u_MetalnessValue
|
||||
0, // u_HasRoughness
|
||||
0.5f, // u_RoughnessValue
|
||||
0, // u_HasAO
|
||||
0.5f, // u_AOValue
|
||||
0, // u_HasNormal
|
||||
0 // u_HasDisplacement
|
||||
struct UBOStructure {
|
||||
int u_HasAlbedo;
|
||||
float padding;
|
||||
float padding2;
|
||||
float padding3;
|
||||
Vector3 m_AlbedoColor;
|
||||
int u_HasMetalness;
|
||||
float u_MetalnessValue;
|
||||
int u_HasRoughness;
|
||||
float u_RoughnessValue;
|
||||
int u_HasAO;
|
||||
float u_AOValue;
|
||||
int u_HasNormal;
|
||||
int u_HasDisplacement;
|
||||
};
|
||||
|
||||
static Ref<Texture> m_DefaultAlbedo;
|
||||
static Ref<Texture> m_DefaultAO;
|
||||
static Ref<Texture> m_DefaultMetalness;
|
||||
static Ref<Texture> m_DefaultRoughness;
|
||||
static Ref<Texture> m_DefaultNormal;
|
||||
static Ref<Texture> m_DefaultDisplacement;
|
||||
class Material
|
||||
{
|
||||
private:
|
||||
std::string m_Name;
|
||||
unsigned int UBO;
|
||||
public:
|
||||
Ref<Texture> m_Albedo;
|
||||
Ref<Texture> m_AO;
|
||||
Ref<Texture> m_Metalness;
|
||||
Ref<Texture> m_Roughness;
|
||||
Ref<Texture> m_Normal;
|
||||
Ref<Texture> m_Displacement;
|
||||
|
||||
Material(const std::string albedo);
|
||||
Material(Ref<Texture> texture) { m_Albedo = texture; }
|
||||
Material(const glm::vec3 albedoColor);
|
||||
UBOStructure data
|
||||
{
|
||||
0, // Has albedo texture
|
||||
0, // Padding byte
|
||||
0, // Padding byte
|
||||
0, // Padding byte
|
||||
Vector3(0.f, 0.f, 0.f), // Albedo color
|
||||
0, // Has metalness
|
||||
0.5f, // Metalness value
|
||||
0, // u_HasRoughness
|
||||
0.5f, // u_RoughnessValue
|
||||
0, // u_HasAO
|
||||
0.5f, // u_AOValue
|
||||
0, // u_HasNormal
|
||||
0 // u_HasDisplacement
|
||||
};
|
||||
|
||||
~Material();
|
||||
static Ref<Texture> m_DefaultAlbedo;
|
||||
static Ref<Texture> m_DefaultAO;
|
||||
static Ref<Texture> m_DefaultMetalness;
|
||||
static Ref<Texture> m_DefaultRoughness;
|
||||
static Ref<Texture> m_DefaultNormal;
|
||||
static Ref<Texture> m_DefaultDisplacement;
|
||||
|
||||
void Bind();
|
||||
Material(const std::string albedo);
|
||||
Material(Ref<Texture> texture) { m_Albedo = texture; }
|
||||
Material(const glm::vec3 albedoColor);
|
||||
|
||||
void SetupUniformBuffer();
|
||||
~Material();
|
||||
|
||||
void SetName(const std::string name);
|
||||
std::string GetName();
|
||||
void Bind();
|
||||
|
||||
bool HasAlbedo() { return m_Albedo != nullptr; }
|
||||
void SetAlbedo(const std::string path) { m_Albedo = CreateRef<Texture>(path); }
|
||||
void SetAlbedo(Ref<Texture> texture) { m_Albedo = texture; }
|
||||
void SetupUniformBuffer();
|
||||
|
||||
bool HasAO() { return m_AO != nullptr; }
|
||||
void SetAO(const std::string albedo);
|
||||
void SetAO(Ref<Texture> texture) { m_AO = texture; }
|
||||
void SetName(const std::string name);
|
||||
std::string GetName();
|
||||
|
||||
bool HasMetalness() { return m_Metalness != nullptr; }
|
||||
void SetMetalness(const std::string albedo);
|
||||
void SetMetalness(Ref<Texture> texture) { m_Metalness = texture; }
|
||||
bool HasAlbedo() { return m_Albedo != nullptr; }
|
||||
void SetAlbedo(const std::string path) { m_Albedo = CreateRef<Texture>(path); }
|
||||
void SetAlbedo(Ref<Texture> texture) { m_Albedo = texture; }
|
||||
|
||||
bool HasRougness() { return m_Roughness != nullptr; }
|
||||
void SetRoughness(const std::string albedo);
|
||||
void SetRoughness(Ref<Texture> texture) { m_Roughness = texture; }
|
||||
bool HasAO() { return m_AO != nullptr; }
|
||||
void SetAO(const std::string albedo);
|
||||
void SetAO(Ref<Texture> texture) { m_AO = texture; }
|
||||
|
||||
bool HasNormal() { return m_Normal != nullptr; }
|
||||
void SetNormal(const std::string albedo);
|
||||
void SetNormal(Ref<Texture> texture) { m_Normal = texture; }
|
||||
bool HasMetalness() { return m_Metalness != nullptr; }
|
||||
void SetMetalness(const std::string albedo);
|
||||
void SetMetalness(Ref<Texture> texture) { m_Metalness = texture; }
|
||||
|
||||
bool HasDisplacement() { return m_Displacement != nullptr; }
|
||||
void SetDisplacement(const std::string displacement);
|
||||
void SetDisplacement(Ref<Texture> texture) { m_Displacement = texture; }
|
||||
};
|
||||
bool HasRougness() { return m_Roughness != nullptr; }
|
||||
void SetRoughness(const std::string albedo);
|
||||
void SetRoughness(Ref<Texture> texture) { m_Roughness = texture; }
|
||||
|
||||
bool HasNormal() { return m_Normal != nullptr; }
|
||||
void SetNormal(const std::string albedo);
|
||||
void SetNormal(Ref<Texture> texture) { m_Normal = texture; }
|
||||
|
||||
bool HasDisplacement() { return m_Displacement != nullptr; }
|
||||
void SetDisplacement(const std::string displacement);
|
||||
void SetDisplacement(Ref<Texture> texture) { m_Displacement = texture; }
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,100 +2,108 @@
|
||||
#include <GL\glew.h>
|
||||
#include <iostream>
|
||||
|
||||
MultiSampledTexture::MultiSampledTexture(const std::string& path) {
|
||||
m_RendererId = 0;
|
||||
m_FilePath = path;
|
||||
m_LocalBuffer = nullptr;
|
||||
m_Width = 0;
|
||||
m_Height = 0;
|
||||
m_BPP = 0;
|
||||
|
||||
stbi_set_flip_vertically_on_load(1);
|
||||
|
||||
m_LocalBuffer = stbi_load(path.c_str(), &m_Width, &m_Height, &m_BPP, 4);
|
||||
|
||||
glGenTextures(1, &m_RendererId);
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_RendererId);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -1.0f);
|
||||
//glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, format, size.x, size.y, GL_TRUE);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
if (m_LocalBuffer)
|
||||
stbi_image_free(m_LocalBuffer);
|
||||
else
|
||||
std::cout << "Error: failed to load texture: " << path << std::endl;
|
||||
}
|
||||
|
||||
// Empty texture not from file.
|
||||
MultiSampledTexture::MultiSampledTexture(glm::vec2 size, GLenum format)
|
||||
namespace Nuake
|
||||
{
|
||||
m_Format = format;
|
||||
MultiSampledTexture::MultiSampledTexture(const std::string& path)
|
||||
{
|
||||
m_RendererId = 0;
|
||||
m_FilePath = path;
|
||||
m_LocalBuffer = nullptr;
|
||||
m_Width = 0;
|
||||
m_Height = 0;
|
||||
m_BPP = 0;
|
||||
|
||||
m_Width = size.x;
|
||||
m_Height = size.y;
|
||||
stbi_set_flip_vertically_on_load(1);
|
||||
|
||||
glGenTextures(1, &m_RendererId);
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_RendererId);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, size.x, size.y, 0, format, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, format, size.x, size.y, GL_TRUE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
m_LocalBuffer = stbi_load(path.c_str(), &m_Width, &m_Height, &m_BPP, 4);
|
||||
|
||||
glGenTextures(1, &m_RendererId);
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_RendererId);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -1.0f);
|
||||
//glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, format, size.x, size.y, GL_TRUE);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
if (m_LocalBuffer)
|
||||
stbi_image_free(m_LocalBuffer);
|
||||
else
|
||||
std::cout << "Error: failed to load texture: " << path << std::endl;
|
||||
}
|
||||
|
||||
// Empty texture not from file.
|
||||
MultiSampledTexture::MultiSampledTexture(glm::vec2 size, GLenum format)
|
||||
{
|
||||
m_Format = format;
|
||||
|
||||
m_Width = size.x;
|
||||
m_Height = size.y;
|
||||
|
||||
glGenTextures(1, &m_RendererId);
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_RendererId);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, size.x, size.y, 0, format, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, format, size.x, size.y, GL_TRUE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
|
||||
MultiSampledTexture::MultiSampledTexture(glm::vec2 size, msdfgen::BitmapConstRef<unsigned char, 4>& bitmap, bool t)
|
||||
{
|
||||
m_Width = size.x;
|
||||
m_Height = size.y;
|
||||
|
||||
glGenTextures(1, &m_RendererId);
|
||||
glBindTexture(GL_TEXTURE_2D, m_RendererId);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
|
||||
auto pixel = bitmap(0, bitmap.height - 0 - 1);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char*)bitmap.pixels);
|
||||
}
|
||||
|
||||
void MultiSampledTexture::Resize(glm::vec2 size)
|
||||
{
|
||||
glDeleteTextures(1, &m_RendererId);
|
||||
m_Width = size.x;
|
||||
m_Height = size.y;
|
||||
glGenTextures(1, &m_RendererId);
|
||||
glBindTexture(GL_TEXTURE_2D, m_RendererId);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, m_Format, size.x, size.y, 0, m_Format, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
MultiSampledTexture::~MultiSampledTexture()
|
||||
{
|
||||
glDeleteTextures(1, &m_RendererId);
|
||||
}
|
||||
|
||||
void MultiSampledTexture::AttachToFramebuffer(GLenum attachment)
|
||||
{
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D_MULTISAMPLE, m_RendererId, 0);
|
||||
|
||||
//glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, m_RendererId, 0);
|
||||
}
|
||||
|
||||
|
||||
void MultiSampledTexture::Bind(unsigned int slot) const
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
glBindTexture(GL_TEXTURE_2D, m_RendererId);
|
||||
}
|
||||
|
||||
void MultiSampledTexture::Unbind() const
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MultiSampledTexture::MultiSampledTexture(glm::vec2 size, msdfgen::BitmapConstRef<unsigned char, 4>& bitmap, bool t)
|
||||
{
|
||||
m_Width = size.x;
|
||||
m_Height = size.y;
|
||||
|
||||
glGenTextures(1, &m_RendererId);
|
||||
glBindTexture(GL_TEXTURE_2D, m_RendererId);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
|
||||
auto pixel = bitmap(0, bitmap.height - 0 - 1);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char*)bitmap.pixels);
|
||||
}
|
||||
|
||||
void MultiSampledTexture::Resize(glm::vec2 size)
|
||||
{
|
||||
glDeleteTextures(1, &m_RendererId);
|
||||
m_Width = size.x;
|
||||
m_Height = size.y;
|
||||
glGenTextures(1, &m_RendererId);
|
||||
glBindTexture(GL_TEXTURE_2D, m_RendererId);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, m_Format, size.x, size.y, 0, m_Format, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
MultiSampledTexture::~MultiSampledTexture() {
|
||||
glDeleteTextures(1, &m_RendererId);
|
||||
}
|
||||
|
||||
void MultiSampledTexture::AttachToFramebuffer(GLenum attachment)
|
||||
{
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D_MULTISAMPLE, m_RendererId, 0);
|
||||
|
||||
//glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, m_RendererId, 0);
|
||||
}
|
||||
|
||||
|
||||
void MultiSampledTexture::Bind(unsigned int slot) const {
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
glBindTexture(GL_TEXTURE_2D, m_RendererId);
|
||||
}
|
||||
|
||||
void MultiSampledTexture::Unbind() const {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,38 +4,37 @@
|
||||
#include "glm/vec2.hpp"
|
||||
#include "msdfgen/core/BitmapRef.hpp"
|
||||
|
||||
|
||||
typedef unsigned int GLenum;
|
||||
class MultiSampledTexture
|
||||
namespace Nuake
|
||||
{
|
||||
private:
|
||||
unsigned int m_RendererId;
|
||||
std::string m_FilePath;
|
||||
unsigned char* m_LocalBuffer;
|
||||
GLenum m_Format;
|
||||
typedef unsigned int GLenum;
|
||||
class MultiSampledTexture
|
||||
{
|
||||
private:
|
||||
unsigned int m_RendererId;
|
||||
std::string m_FilePath;
|
||||
unsigned char* m_LocalBuffer;
|
||||
GLenum m_Format;
|
||||
|
||||
int m_Width;
|
||||
int m_Height;
|
||||
int m_BPP; // byte per pixel.
|
||||
int m_Width;
|
||||
int m_Height;
|
||||
int m_BPP; // byte per pixel.
|
||||
|
||||
public:
|
||||
MultiSampledTexture(const std::string& path);
|
||||
MultiSampledTexture(glm::vec2 size, msdfgen::BitmapConstRef<unsigned char, 4>& bitmap, bool t);
|
||||
MultiSampledTexture(glm::vec2 size, GLenum format);
|
||||
public:
|
||||
MultiSampledTexture(const std::string& path);
|
||||
MultiSampledTexture(glm::vec2 size, msdfgen::BitmapConstRef<unsigned char, 4>& bitmap, bool t);
|
||||
MultiSampledTexture(glm::vec2 size, GLenum format);
|
||||
|
||||
~MultiSampledTexture();
|
||||
~MultiSampledTexture();
|
||||
|
||||
void Resize(glm::vec2 size);
|
||||
void AttachToFramebuffer(GLenum attachment);
|
||||
|
||||
void Bind(unsigned int slot = 0) const;
|
||||
void Unbind() const;
|
||||
|
||||
unsigned int GetID() const { return m_RendererId; }
|
||||
|
||||
inline int GetWidth() const { return m_Width; }
|
||||
inline int GetHeight() const { return m_Height; }
|
||||
};
|
||||
void Resize(glm::vec2 size);
|
||||
void AttachToFramebuffer(GLenum attachment);
|
||||
|
||||
void Bind(unsigned int slot = 0) const;
|
||||
void Unbind() const;
|
||||
|
||||
unsigned int GetID() const { return m_RendererId; }
|
||||
|
||||
inline int GetWidth() const { return m_Width; }
|
||||
inline int GetHeight() const { return m_Height; }
|
||||
};
|
||||
}
|
||||
@@ -3,94 +3,100 @@
|
||||
#include <iostream>
|
||||
#include <src/Core/FileSystem.h>
|
||||
|
||||
Texture::Texture(const std::string& path) {
|
||||
m_RendererId = 0;
|
||||
m_FilePath = path;
|
||||
m_LocalBuffer = nullptr;
|
||||
m_Width = 0;
|
||||
m_Height = 0;
|
||||
m_BPP = 0;
|
||||
|
||||
stbi_set_flip_vertically_on_load(1);
|
||||
|
||||
m_LocalBuffer = stbi_load((path).c_str(), &m_Width, &m_Height, &m_BPP, 4);
|
||||
|
||||
glGenTextures(1, &m_RendererId);
|
||||
glBindTexture(GL_TEXTURE_2D, m_RendererId);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -1.0f);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_LocalBuffer);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
if (m_LocalBuffer)
|
||||
stbi_image_free(m_LocalBuffer);
|
||||
else
|
||||
std::cout << "Error: failed to load texture: " << path << std::endl;
|
||||
}
|
||||
|
||||
// Empty texture not from file.
|
||||
Texture::Texture(glm::vec2 size, GLenum format)
|
||||
namespace Nuake
|
||||
{
|
||||
m_Format = format;
|
||||
Texture::Texture(const std::string& path)
|
||||
{
|
||||
m_RendererId = 0;
|
||||
m_FilePath = path;
|
||||
m_LocalBuffer = nullptr;
|
||||
m_Width = 0;
|
||||
m_Height = 0;
|
||||
m_BPP = 0;
|
||||
|
||||
m_Width = size.x;
|
||||
m_Height = size.y;
|
||||
stbi_set_flip_vertically_on_load(1);
|
||||
|
||||
glGenTextures(1, &m_RendererId);
|
||||
glBindTexture(GL_TEXTURE_2D, m_RendererId);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, size.x, size.y, 0, format, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
//glGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
Texture::Texture(glm::vec2 size, msdfgen::BitmapConstRef<unsigned char, 4>& bitmap, bool t)
|
||||
{
|
||||
m_Width = size.x;
|
||||
m_Height = size.y;
|
||||
|
||||
glGenTextures(1, &m_RendererId);
|
||||
glBindTexture(GL_TEXTURE_2D, m_RendererId);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
|
||||
auto pixel = bitmap(0, bitmap.height - 0 - 1);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char*)bitmap.pixels);
|
||||
}
|
||||
|
||||
void Texture::Resize(glm::vec2 size)
|
||||
{
|
||||
glDeleteTextures(1, &m_RendererId);
|
||||
m_Width = size.x;
|
||||
m_Height = size.y;
|
||||
glGenTextures(1, &m_RendererId);
|
||||
glBindTexture(GL_TEXTURE_2D, m_RendererId);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, m_Format, size.x, size.y, 0, m_Format, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
Texture::~Texture() {
|
||||
glDeleteTextures(1, &m_RendererId);
|
||||
}
|
||||
|
||||
void Texture::AttachToFramebuffer(GLenum attachment)
|
||||
{
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, m_RendererId, 0);
|
||||
}
|
||||
|
||||
void Texture::Bind(unsigned int slot) const {
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
glBindTexture(GL_TEXTURE_2D, m_RendererId);
|
||||
}
|
||||
|
||||
void Texture::Unbind() const {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
m_LocalBuffer = stbi_load((path).c_str(), &m_Width, &m_Height, &m_BPP, 4);
|
||||
|
||||
glGenTextures(1, &m_RendererId);
|
||||
glBindTexture(GL_TEXTURE_2D, m_RendererId);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -1.0f);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_LocalBuffer);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
if (m_LocalBuffer)
|
||||
stbi_image_free(m_LocalBuffer);
|
||||
else
|
||||
std::cout << "Error: failed to load texture: " << path << std::endl;
|
||||
}
|
||||
|
||||
Texture::Texture(glm::vec2 size, GLenum format)
|
||||
{
|
||||
m_Format = format;
|
||||
|
||||
m_Width = size.x;
|
||||
m_Height = size.y;
|
||||
|
||||
glGenTextures(1, &m_RendererId);
|
||||
glBindTexture(GL_TEXTURE_2D, m_RendererId);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, size.x, size.y, 0, format, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
//glGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
Texture::Texture(glm::vec2 size, msdfgen::BitmapConstRef<unsigned char, 4>& bitmap, bool t)
|
||||
{
|
||||
m_Width = size.x;
|
||||
m_Height = size.y;
|
||||
|
||||
glGenTextures(1, &m_RendererId);
|
||||
glBindTexture(GL_TEXTURE_2D, m_RendererId);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
|
||||
auto pixel = bitmap(0, bitmap.height - 0 - 1);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char*)bitmap.pixels);
|
||||
}
|
||||
|
||||
void Texture::Resize(glm::vec2 size)
|
||||
{
|
||||
glDeleteTextures(1, &m_RendererId);
|
||||
m_Width = size.x;
|
||||
m_Height = size.y;
|
||||
glGenTextures(1, &m_RendererId);
|
||||
glBindTexture(GL_TEXTURE_2D, m_RendererId);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, m_Format, size.x, size.y, 0, m_Format, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
Texture::~Texture()
|
||||
{
|
||||
glDeleteTextures(1, &m_RendererId);
|
||||
}
|
||||
|
||||
void Texture::AttachToFramebuffer(GLenum attachment)
|
||||
{
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, m_RendererId, 0);
|
||||
}
|
||||
|
||||
void Texture::Bind(unsigned int slot) const
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
glBindTexture(GL_TEXTURE_2D, m_RendererId);
|
||||
}
|
||||
|
||||
void Texture::Unbind() const
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,41 +1,41 @@
|
||||
#pragma once
|
||||
#include "stb_image/stb_image.h"
|
||||
#include <string>
|
||||
#include "glm/vec2.hpp"
|
||||
#include "src/Core/Maths.h"
|
||||
#include "msdfgen/core/BitmapRef.hpp"
|
||||
|
||||
|
||||
typedef unsigned int GLenum;
|
||||
class Texture
|
||||
namespace Nuake
|
||||
{
|
||||
private:
|
||||
unsigned int m_RendererId;
|
||||
std::string m_FilePath;
|
||||
unsigned char* m_LocalBuffer;
|
||||
GLenum m_Format;
|
||||
typedef unsigned int GLenum;
|
||||
|
||||
int m_Width;
|
||||
int m_Height;
|
||||
int m_BPP; // byte per pixel.
|
||||
class Texture
|
||||
{
|
||||
private:
|
||||
unsigned int m_RendererId;
|
||||
std::string m_FilePath;
|
||||
unsigned char* m_LocalBuffer;
|
||||
GLenum m_Format;
|
||||
|
||||
public:
|
||||
Texture(const std::string& path);
|
||||
Texture(glm::vec2 size, msdfgen::BitmapConstRef<unsigned char, 4>& bitmap, bool t);
|
||||
Texture(glm::vec2 size, GLenum format);
|
||||
int m_Width;
|
||||
int m_Height;
|
||||
int m_BPP; // byte per pixel.
|
||||
|
||||
~Texture();
|
||||
public:
|
||||
Texture(const std::string& path);
|
||||
Texture(glm::vec2 size, msdfgen::BitmapConstRef<unsigned char, 4>& bitmap, bool t);
|
||||
Texture(glm::vec2 size, GLenum format);
|
||||
|
||||
void Resize(glm::vec2 size);
|
||||
void AttachToFramebuffer(GLenum attachment);
|
||||
~Texture();
|
||||
|
||||
void Bind(unsigned int slot = 0) const;
|
||||
void Unbind() const;
|
||||
|
||||
unsigned int GetID() const { return m_RendererId; }
|
||||
|
||||
inline int GetWidth() const { return m_Width; }
|
||||
inline int GetHeight() const { return m_Height; }
|
||||
};
|
||||
void Resize(glm::vec2 size);
|
||||
void AttachToFramebuffer(GLenum attachment);
|
||||
|
||||
void Bind(unsigned int slot = 0) const;
|
||||
void Unbind() const;
|
||||
|
||||
unsigned int GetID() const { return m_RendererId; }
|
||||
|
||||
inline int GetWidth() const { return m_Width; }
|
||||
inline int GetHeight() const { return m_Height; }
|
||||
};
|
||||
}
|
||||
|
||||
12
Nuake/src/Rendering/Transform.h
Normal file
12
Nuake/src/Rendering/Transform.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include <src/Core/Maths.h>
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
struct Transform
|
||||
{
|
||||
Vector3 Translation;
|
||||
Vector3 Rotation;
|
||||
Vector3 Scale;
|
||||
};
|
||||
}
|
||||
@@ -1,13 +1,16 @@
|
||||
#pragma once
|
||||
#include <glm\ext\vector_float3.hpp>
|
||||
#include <glm\ext\vector_float2.hpp>
|
||||
#include "src/Core/Maths.h"
|
||||
|
||||
struct Vertex
|
||||
namespace Nuake
|
||||
{
|
||||
glm::vec3 position;
|
||||
glm::vec2 uv;
|
||||
glm::vec3 normal;
|
||||
glm::vec3 tangent;
|
||||
glm::vec3 bitangent;
|
||||
float texture;
|
||||
};
|
||||
struct Vertex
|
||||
{
|
||||
glm::vec3 position;
|
||||
glm::vec2 uv;
|
||||
glm::vec3 normal;
|
||||
glm::vec3 tangent;
|
||||
glm::vec3 bitangent;
|
||||
float texture;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#pragma once
|
||||
#include "BaseClass.h"
|
||||
#include "ClassProperty.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
#pragma once
|
||||
#include "FGDClass.h"
|
||||
#include <string>
|
||||
class FGDSerializer
|
||||
{
|
||||
public:
|
||||
static bool BeginFGDFile(const std::string path);
|
||||
|
||||
static bool SerializeClass(FGDClass fgdClass);
|
||||
static bool SerializeBrush(FGDBrushEntity fgdClass);
|
||||
static bool EndFGDFile();
|
||||
};
|
||||
namespace Nuake {
|
||||
class FGDSerializer
|
||||
{
|
||||
public:
|
||||
static bool BeginFGDFile(const std::string path);
|
||||
|
||||
static bool SerializeClass(FGDClass fgdClass);
|
||||
static bool SerializeBrush(FGDBrushEntity fgdClass);
|
||||
static bool EndFGDFile();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,26 +1,28 @@
|
||||
#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)
|
||||
namespace Nuake {
|
||||
FGDClass::FGDClass(FGDClassType type, const std::string& name, const std::string& desc)
|
||||
{
|
||||
if (p.name == name)
|
||||
Properties.erase(Properties.begin() + position);
|
||||
Type = type;
|
||||
Name = name;
|
||||
Description = desc;
|
||||
}
|
||||
|
||||
position++;
|
||||
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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,56 +4,56 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
class FGDBaseEntity
|
||||
{
|
||||
public:
|
||||
std::string Name;
|
||||
std::vector<ClassProperty> Properties;
|
||||
};
|
||||
|
||||
|
||||
class FGDBrushEntity : ISerializable
|
||||
{
|
||||
public:
|
||||
std::string Name;
|
||||
std::string Description;
|
||||
|
||||
bool Visible = false;
|
||||
bool Solid = false;
|
||||
bool IsTrigger = false;
|
||||
std::string Script = "";
|
||||
std::string Class = "";
|
||||
std::vector<ClassProperty> Properties;
|
||||
|
||||
FGDBrushEntity()
|
||||
namespace Nuake {
|
||||
class FGDBaseEntity
|
||||
{
|
||||
Name = "";
|
||||
Description = "";
|
||||
}
|
||||
public:
|
||||
std::string Name;
|
||||
std::vector<ClassProperty> Properties;
|
||||
};
|
||||
|
||||
FGDBrushEntity(const std::string& name)
|
||||
{
|
||||
Name = name;
|
||||
Description = "";
|
||||
}
|
||||
|
||||
json Serialize() override
|
||||
class FGDBrushEntity : ISerializable
|
||||
{
|
||||
BEGIN_SERIALIZE();
|
||||
public:
|
||||
std::string Name;
|
||||
std::string Description;
|
||||
|
||||
bool Visible = false;
|
||||
bool Solid = false;
|
||||
bool IsTrigger = false;
|
||||
std::string Script = "";
|
||||
std::string Class = "";
|
||||
std::vector<ClassProperty> Properties;
|
||||
|
||||
FGDBrushEntity()
|
||||
{
|
||||
Name = "";
|
||||
Description = "";
|
||||
}
|
||||
|
||||
FGDBrushEntity(const std::string& name)
|
||||
{
|
||||
Name = name;
|
||||
Description = "";
|
||||
}
|
||||
|
||||
json Serialize() override
|
||||
{
|
||||
BEGIN_SERIALIZE();
|
||||
SERIALIZE_VAL(Name);
|
||||
SERIALIZE_VAL(Description);
|
||||
SERIALIZE_VAL(Visible);
|
||||
SERIALIZE_VAL(Visible);
|
||||
SERIALIZE_VAL(Solid);
|
||||
SERIALIZE_VAL(IsTrigger);
|
||||
SERIALIZE_VAL(Script);
|
||||
SERIALIZE_VAL(Class);
|
||||
END_SERIALIZE();
|
||||
}
|
||||
END_SERIALIZE();
|
||||
}
|
||||
|
||||
bool Deserialize(const std::string& str) override
|
||||
{
|
||||
BEGIN_DESERIALIZE();
|
||||
bool Deserialize(const std::string& str) override
|
||||
{
|
||||
BEGIN_DESERIALIZE();
|
||||
Name = j["Name"];
|
||||
Description = j["Description"];
|
||||
Visible = j["Visible"];
|
||||
@@ -61,46 +61,47 @@ public:
|
||||
IsTrigger = j["IsTrigger"];
|
||||
Script = j["Script"];
|
||||
Class = j["Class"];
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
FGDBaseEntity BaseClass;
|
||||
};
|
||||
FGDBaseEntity BaseClass;
|
||||
};
|
||||
|
||||
|
||||
class FGDPointEntity : ISerializable
|
||||
{
|
||||
public:
|
||||
std::string Name;
|
||||
std::string Description;
|
||||
std::string Prefab;
|
||||
std::vector<ClassProperty> Properties;
|
||||
FGDBaseEntity BaseClass;
|
||||
|
||||
json Serialize() override
|
||||
class FGDPointEntity : ISerializable
|
||||
{
|
||||
BEGIN_SERIALIZE();
|
||||
public:
|
||||
std::string Name;
|
||||
std::string Description;
|
||||
std::string Prefab;
|
||||
std::vector<ClassProperty> Properties;
|
||||
FGDBaseEntity BaseClass;
|
||||
|
||||
json Serialize() override
|
||||
{
|
||||
BEGIN_SERIALIZE();
|
||||
SERIALIZE_VAL(Name);
|
||||
SERIALIZE_VAL(Description);
|
||||
SERIALIZE_VAL(Prefab);
|
||||
END_SERIALIZE();
|
||||
}
|
||||
END_SERIALIZE();
|
||||
}
|
||||
|
||||
bool Deserialize(const std::string& str) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
bool Deserialize(const std::string& str) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class FGDClass {
|
||||
public:
|
||||
FGDClassType Type;
|
||||
std::string Name;
|
||||
std::string Description;
|
||||
std::vector<ClassProperty> Properties;
|
||||
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);
|
||||
FGDClass(FGDClassType type, const std::string& name, const std::string& desc);
|
||||
|
||||
void AddProperty(ClassProperty prop);
|
||||
void RemoveProperty(const std::string name);
|
||||
};
|
||||
void AddProperty(ClassProperty prop);
|
||||
void RemoveProperty(const std::string name);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,96 +3,98 @@
|
||||
#include <src/Core/FileSystem.h>
|
||||
#include "Engine.h"
|
||||
|
||||
FGDFile::FGDFile(const std::string path)
|
||||
{
|
||||
this->Path = path;
|
||||
namespace Nuake {
|
||||
FGDFile::FGDFile(const std::string path)
|
||||
{
|
||||
this->Path = path;
|
||||
|
||||
this->BaseEntities = std::vector<FGDBaseEntity>();
|
||||
this->BrushEntities = std::vector<FGDBrushEntity>();
|
||||
this->PointEntities = std::vector<FGDPointEntity>();
|
||||
}
|
||||
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>();
|
||||
FGDFile::FGDFile()
|
||||
{
|
||||
this->Path = "";
|
||||
this->BaseEntities = std::vector<FGDBaseEntity>();
|
||||
this->BrushEntities = std::vector<FGDBrushEntity>();
|
||||
this->PointEntities = std::vector<FGDPointEntity>();
|
||||
|
||||
// TODO: Remove this, debugging stuff.
|
||||
FGDPointEntity newEnt;
|
||||
newEnt.Name = "Light";
|
||||
newEnt.Description = "A Nuake PBR light";
|
||||
|
||||
this->PointEntities.push_back(newEnt);
|
||||
}
|
||||
// TODO: Remove this, debugging stuff.
|
||||
FGDPointEntity newEnt;
|
||||
newEnt.Name = "Light";
|
||||
newEnt.Description = "A Nuake PBR light";
|
||||
|
||||
this->PointEntities.push_back(newEnt);
|
||||
}
|
||||
|
||||
|
||||
bool FGDFile::Save()
|
||||
{
|
||||
// Write to file.
|
||||
FileSystem::BeginWriteFile(FileSystem::Root + Path);
|
||||
bool FGDFile::Save()
|
||||
{
|
||||
// Write to file.
|
||||
FileSystem::BeginWriteFile(FileSystem::Root + Path);
|
||||
FileSystem::WriteLine(Serialize().dump(4));
|
||||
FileSystem::EndWriteFile();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FGDFile::SaveAs()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
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++;
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
// Exports the FGD data into an fgd file that Trenchbroom can read.
|
||||
// Should be exported in the Trenchbroom directory directly. /Games/project_name
|
||||
bool FGDFile::Export()
|
||||
{
|
||||
Ref<Project> project = Engine::GetProject();
|
||||
std::string path = project->TrenchbroomPath + "games/" + project->Name + "/" + project->Name + ".fgd";
|
||||
|
||||
|
||||
FGDSerializer::BeginFGDFile(path);
|
||||
|
||||
for (auto& b : BaseEntities)
|
||||
{
|
||||
FileSystem::EndWriteFile();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
for (auto& p : PointEntities)
|
||||
bool FGDFile::SaveAs()
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto& b : BrushEntities)
|
||||
|
||||
void FGDFile::AddClass(FGDClass fgdClass)
|
||||
{
|
||||
FGDSerializer::SerializeBrush(b);
|
||||
//this->Classes.push_back(fgdClass);
|
||||
}
|
||||
|
||||
//for(auto& c : Classes)
|
||||
// FGDSerializer::SerializeClass(c);
|
||||
|
||||
FGDSerializer::EndFGDFile();
|
||||
void FGDFile::RemoveClass(const std::string& name)
|
||||
{
|
||||
//int idx = 0;
|
||||
//for (auto& c : Classes)
|
||||
//{
|
||||
//if (c.Name == name)
|
||||
//Classes.erase(Classes.begin() + idx);
|
||||
|
||||
return true;
|
||||
}
|
||||
//idx++;
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
// Exports the FGD data into an fgd file that Trenchbroom can read.
|
||||
// Should be exported in the Trenchbroom directory directly. /Games/project_name
|
||||
bool FGDFile::Export()
|
||||
{
|
||||
Ref<Project> project = Engine::GetProject();
|
||||
std::string path = project->TrenchbroomPath + "games/" + project->Name + "/" + project->Name + ".fgd";
|
||||
|
||||
|
||||
FGDSerializer::BeginFGDFile(path);
|
||||
|
||||
for (auto& b : BaseEntities)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
for (auto& p : PointEntities)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
for (auto& b : BrushEntities)
|
||||
{
|
||||
FGDSerializer::SerializeBrush(b);
|
||||
}
|
||||
|
||||
//for(auto& c : Classes)
|
||||
// FGDSerializer::SerializeClass(c);
|
||||
|
||||
FGDSerializer::EndFGDFile();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,93 +4,95 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
enum class EntityType
|
||||
{
|
||||
Brush, Point, Base, None
|
||||
};
|
||||
|
||||
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 Export();
|
||||
bool Save();
|
||||
bool SaveAs();
|
||||
|
||||
void AddClass(FGDClass fgdClass);
|
||||
void RemoveClass(const std::string& name);
|
||||
|
||||
json Serialize() override
|
||||
namespace Nuake {
|
||||
enum class EntityType
|
||||
{
|
||||
BEGIN_SERIALIZE();
|
||||
int i = 0;
|
||||
for (auto& c : this->BrushEntities)
|
||||
{
|
||||
j["BrushEntities"][i] = c.Serialize();
|
||||
i++;
|
||||
}
|
||||
Brush, Point, Base, None
|
||||
};
|
||||
|
||||
i = 0;
|
||||
for (auto& c : this->PointEntities)
|
||||
{
|
||||
j["PointEntities"][i] = c.Serialize();
|
||||
i++;
|
||||
}
|
||||
END_SERIALIZE();
|
||||
}
|
||||
class FGDFile : ISerializable {
|
||||
public:
|
||||
std::string Path;
|
||||
|
||||
bool Deserialize(const std::string& str)
|
||||
{
|
||||
BEGIN_DESERIALIZE();
|
||||
std::vector<FGDPointEntity> PointEntities;
|
||||
std::vector<FGDBrushEntity> BrushEntities;
|
||||
std::vector<FGDBaseEntity> BaseEntities;
|
||||
|
||||
if (j.contains("BrushEntities"))
|
||||
FGDFile(const std::string path);
|
||||
FGDFile();
|
||||
|
||||
bool Export();
|
||||
bool Save();
|
||||
bool SaveAs();
|
||||
|
||||
void AddClass(FGDClass fgdClass);
|
||||
void RemoveClass(const std::string& name);
|
||||
|
||||
json Serialize() override
|
||||
{
|
||||
for (auto& brush : j["BrushEntities"])
|
||||
BEGIN_SERIALIZE();
|
||||
int i = 0;
|
||||
for (auto& c : this->BrushEntities)
|
||||
{
|
||||
FGDBrushEntity brushEntity = FGDBrushEntity();
|
||||
brushEntity.Deserialize(brush.dump());
|
||||
BrushEntities.push_back(brushEntity);
|
||||
j["BrushEntities"][i] = c.Serialize();
|
||||
i++;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for (auto& c : this->PointEntities)
|
||||
{
|
||||
j["PointEntities"][i] = c.Serialize();
|
||||
i++;
|
||||
}
|
||||
END_SERIALIZE();
|
||||
}
|
||||
|
||||
bool Deserialize(const std::string& str)
|
||||
{
|
||||
BEGIN_DESERIALIZE();
|
||||
|
||||
if (j.contains("BrushEntities"))
|
||||
{
|
||||
for (auto& brush : j["BrushEntities"])
|
||||
{
|
||||
FGDBrushEntity brushEntity = FGDBrushEntity();
|
||||
brushEntity.Deserialize(brush.dump());
|
||||
BrushEntities.push_back(brushEntity);
|
||||
}
|
||||
}
|
||||
|
||||
if (j.contains("PointEntities"))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FGDBrushEntity& GetBrushEntity(const std::string& name)
|
||||
{
|
||||
for (auto& b : BrushEntities)
|
||||
{
|
||||
if (b.Name == name)
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
if (j.contains("PointEntities"))
|
||||
EntityType GetTypeOfEntity(const std::string& className)
|
||||
{
|
||||
for (auto& b : BrushEntities)
|
||||
{
|
||||
if (b.Name == className)
|
||||
return EntityType::Brush;
|
||||
}
|
||||
|
||||
for (auto& p : PointEntities)
|
||||
{
|
||||
if (p.Name == className)
|
||||
return EntityType::Point;
|
||||
}
|
||||
|
||||
return EntityType::None;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FGDBrushEntity& GetBrushEntity(const std::string& name)
|
||||
{
|
||||
for (auto& b : BrushEntities)
|
||||
{
|
||||
if (b.Name == name)
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
EntityType GetTypeOfEntity(const std::string& className)
|
||||
{
|
||||
for (auto& b : BrushEntities)
|
||||
{
|
||||
if (b.Name == className)
|
||||
return EntityType::Brush;
|
||||
}
|
||||
|
||||
for (auto& p : PointEntities)
|
||||
{
|
||||
if (p.Name == className)
|
||||
return EntityType::Point;
|
||||
}
|
||||
|
||||
return EntityType::None;
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,96 +1,96 @@
|
||||
#include "FDGSerializer.h"
|
||||
#include <src\Core\FileSystem.h>
|
||||
|
||||
namespace Nuake {
|
||||
bool FGDSerializer::BeginFGDFile(const std::string path)
|
||||
{
|
||||
FileSystem::BeginWriteFile(path);
|
||||
return true;
|
||||
}
|
||||
|
||||
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 + "\"";
|
||||
|
||||
bool FGDSerializer::SerializeClass(FGDClass fgdClass)
|
||||
{
|
||||
std::string line = "@";
|
||||
// Exit early
|
||||
if (fgdClass.Properties.size() == 0)
|
||||
{
|
||||
line += " [] \n";
|
||||
FileSystem::WriteLine(line);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fgdClass.Type == FGDClassType::Point)
|
||||
line += "PointClass = ";
|
||||
else if (fgdClass.Type == FGDClassType::Brush)
|
||||
// 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::SerializeBrush(FGDBrushEntity fgdClass)
|
||||
{
|
||||
std::string line = "@";
|
||||
line += "SolidClass = ";
|
||||
else // error.
|
||||
return true;
|
||||
line += fgdClass.Name + " : \"" + fgdClass.Description + "\"";
|
||||
|
||||
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 += "]";
|
||||
|
||||
// Exit early
|
||||
if (fgdClass.Properties.size() == 0)
|
||||
{
|
||||
line += " [] \n";
|
||||
FileSystem::WriteLine(line);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Properties here.
|
||||
line += "\n [ \n";
|
||||
for (auto& p : fgdClass.Properties)
|
||||
bool FGDSerializer::EndFGDFile()
|
||||
{
|
||||
// E.g: myProp(integer) : "description"
|
||||
line += " "; // Tabulation
|
||||
line += p.name;
|
||||
line += "(";
|
||||
if (p.type == ClassPropertyType::Integer)
|
||||
line += "integer";
|
||||
line += ") : ";
|
||||
line += "\"" + p.description + "\"";
|
||||
line += "\n";
|
||||
|
||||
FileSystem::EndWriteFile();
|
||||
return false;
|
||||
}
|
||||
|
||||
line += "]";
|
||||
|
||||
FileSystem::WriteLine(line);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FGDSerializer::SerializeBrush(FGDBrushEntity fgdClass)
|
||||
{
|
||||
std::string line = "@";
|
||||
line += "SolidClass = ";
|
||||
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 false;
|
||||
}
|
||||
|
||||
bool FGDSerializer::EndFGDFile()
|
||||
{
|
||||
FileSystem::EndWriteFile();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -4,138 +4,143 @@
|
||||
#include <fstream>
|
||||
#include <streambuf>
|
||||
#include "../Core/Logger.h"
|
||||
Project::Project(const std::string Name, const std::string Description, const std::string& FullPath, const std::string& defaultScenePath )
|
||||
{
|
||||
this->Name = Name;
|
||||
this->Description = Description;
|
||||
this->FullPath = FullPath;
|
||||
this->TrenchbroomPath = "";
|
||||
|
||||
if (defaultScenePath != "")
|
||||
namespace Nuake
|
||||
{
|
||||
Project::Project(const std::string Name, const std::string Description, const std::string& FullPath, const std::string& defaultScenePath)
|
||||
{
|
||||
Ref<Scene> scene = CreateRef<Scene>();
|
||||
scene->Deserialize(defaultScenePath);
|
||||
this->Name = Name;
|
||||
this->Description = Description;
|
||||
this->FullPath = FullPath;
|
||||
this->TrenchbroomPath = "";
|
||||
|
||||
if (defaultScenePath != "")
|
||||
{
|
||||
Ref<Scene> scene = CreateRef<Scene>();
|
||||
scene->Deserialize(defaultScenePath);
|
||||
}
|
||||
|
||||
this->EntityDefinitionsFile = CreateRef<FGDFile>();
|
||||
|
||||
SaveAs(FullPath);
|
||||
}
|
||||
|
||||
this->EntityDefinitionsFile = CreateRef<FGDFile>();
|
||||
Project::Project()
|
||||
{
|
||||
this->Name = "";
|
||||
this->Description = "";
|
||||
this->FullPath = "";
|
||||
this->TrenchbroomPath = "";
|
||||
|
||||
SaveAs(FullPath);
|
||||
}
|
||||
this->EntityDefinitionsFile = CreateRef<FGDFile>();
|
||||
}
|
||||
|
||||
Project::Project()
|
||||
{
|
||||
this->Name = "";
|
||||
this->Description = "";
|
||||
this->FullPath = "";
|
||||
this->TrenchbroomPath = "";
|
||||
void Project::Save()
|
||||
{
|
||||
SaveAs(this->FullPath);
|
||||
}
|
||||
|
||||
this->EntityDefinitionsFile = CreateRef<FGDFile>();
|
||||
}
|
||||
void Project::SaveAs(const std::string FullPath)
|
||||
{
|
||||
json j = Serialize();
|
||||
std::string serialized_string = j.dump();
|
||||
|
||||
void Project::Save()
|
||||
{
|
||||
SaveAs(this->FullPath);
|
||||
}
|
||||
|
||||
void Project::SaveAs(const std::string FullPath)
|
||||
{
|
||||
json j = Serialize();
|
||||
std::string serialized_string = j.dump();
|
||||
|
||||
// TODO: Use file interface here...
|
||||
// Write to file.
|
||||
std::ofstream projectFile;
|
||||
// TODO: Use file interface here...
|
||||
// Write to file.
|
||||
std::ofstream projectFile;
|
||||
projectFile.open(FullPath);
|
||||
projectFile << serialized_string;
|
||||
projectFile.close();
|
||||
}
|
||||
projectFile.close();
|
||||
}
|
||||
|
||||
Ref<Project> Project::New(const std::string Name, const std::string Description, const std::string FullPath)
|
||||
{
|
||||
if (Name == "")
|
||||
return nullptr;
|
||||
Ref<Project> Project::New(const std::string Name, const std::string Description, const std::string FullPath)
|
||||
{
|
||||
if (Name == "")
|
||||
return nullptr;
|
||||
|
||||
return CreateRef<Project>(Name, Description, FullPath);
|
||||
}
|
||||
return CreateRef<Project>(Name, Description, FullPath);
|
||||
}
|
||||
|
||||
Ref<Project> Project::New()
|
||||
{
|
||||
return CreateRef<Project>();
|
||||
}
|
||||
Ref<Project> Project::New()
|
||||
{
|
||||
return CreateRef<Project>();
|
||||
}
|
||||
|
||||
Ref<Project> Project::Load(std::string path)
|
||||
{
|
||||
std::ifstream i(path);
|
||||
json j;
|
||||
i >> j;
|
||||
Ref<Project> Project::Load(std::string path)
|
||||
{
|
||||
std::ifstream i(path);
|
||||
json j;
|
||||
i >> j;
|
||||
|
||||
// validation
|
||||
std::string projectName = "";
|
||||
if(!j.contains("ProjectName"))
|
||||
return nullptr;
|
||||
// validation
|
||||
std::string projectName = "";
|
||||
if (!j.contains("ProjectName"))
|
||||
return nullptr;
|
||||
|
||||
projectName = j["ProjectName"];
|
||||
projectName = j["ProjectName"];
|
||||
|
||||
std::string description = "";
|
||||
if (j.contains("Description"))
|
||||
description = j["Description"];
|
||||
std::string description = "";
|
||||
if (j.contains("Description"))
|
||||
description = j["Description"];
|
||||
|
||||
return CreateRef<Project>(projectName, description, path);
|
||||
}
|
||||
return CreateRef<Project>(projectName, description, path);
|
||||
}
|
||||
|
||||
json Project::Serialize()
|
||||
{
|
||||
BEGIN_SERIALIZE();
|
||||
json Project::Serialize()
|
||||
{
|
||||
BEGIN_SERIALIZE();
|
||||
SERIALIZE_VAL(Name);
|
||||
SERIALIZE_VAL(Description);
|
||||
SERIALIZE_VAL_LBL("DefaultScene", DefaultScene->Path);
|
||||
SERIALIZE_VAL_LBL("EntityDefinition", EntityDefinitionsFile->Path);
|
||||
SERIALIZE_VAL(TrenchbroomPath);
|
||||
END_SERIALIZE();
|
||||
END_SERIALIZE();
|
||||
}
|
||||
|
||||
bool Project::Deserialize(const std::string& str)
|
||||
{
|
||||
BEGIN_DESERIALIZE();
|
||||
|
||||
if (!j.contains("Name") || !j.contains("Description"))
|
||||
return false;
|
||||
|
||||
Name = j["Name"];
|
||||
Description = j["Description"];
|
||||
|
||||
if (j.contains("EntityDefinition"))
|
||||
{
|
||||
std::string path = j["EntityDefinition"];
|
||||
EntityDefinitionsFile = CreateRef<FGDFile>(path);
|
||||
std::string content = FileSystem::ReadFile(path, false);
|
||||
EntityDefinitionsFile->Deserialize(content);
|
||||
}
|
||||
|
||||
if (j.contains("TrenchbroomPath"))
|
||||
{
|
||||
this->TrenchbroomPath = j["TrenchbroomPath"];
|
||||
}
|
||||
|
||||
DefaultScene = Scene::New();
|
||||
|
||||
// Load default scene, a project can have no default scene set.
|
||||
if (!j.contains("DefaultScene"))
|
||||
return true;
|
||||
|
||||
std::string scenePath = j["DefaultScene"];
|
||||
if (scenePath == "") // Not set correctly.
|
||||
return true;
|
||||
|
||||
std::string sceneContent = FileSystem::ReadFile(scenePath, false);
|
||||
if (!DefaultScene->Deserialize(sceneContent))
|
||||
{
|
||||
Logger::Log("Error loading scene: " + scenePath, CRITICAL);
|
||||
return false;
|
||||
}
|
||||
|
||||
DefaultScene->Path = scenePath;
|
||||
Logger::Log("Successfully loaded scene: " + scenePath);
|
||||
|
||||
return true; // Success
|
||||
}
|
||||
}
|
||||
|
||||
bool Project::Deserialize(const std::string& str)
|
||||
{
|
||||
BEGIN_DESERIALIZE();
|
||||
|
||||
if (!j.contains("Name") || !j.contains("Description"))
|
||||
return false;
|
||||
|
||||
Name = j["Name"];
|
||||
Description = j["Description"];
|
||||
|
||||
if (j.contains("EntityDefinition"))
|
||||
{
|
||||
std::string path = j["EntityDefinition"];
|
||||
EntityDefinitionsFile = CreateRef<FGDFile>(path);
|
||||
std::string content = FileSystem::ReadFile(path, false);
|
||||
EntityDefinitionsFile->Deserialize(content);
|
||||
}
|
||||
|
||||
if (j.contains("TrenchbroomPath"))
|
||||
{
|
||||
this->TrenchbroomPath = j["TrenchbroomPath"];
|
||||
}
|
||||
|
||||
DefaultScene = Scene::New();
|
||||
|
||||
// Load default scene, a project can have no default scene set.
|
||||
if (!j.contains("DefaultScene"))
|
||||
return true;
|
||||
|
||||
std::string scenePath = j["DefaultScene"];
|
||||
if (scenePath == "") // Not set correctly.
|
||||
return true;
|
||||
|
||||
std::string sceneContent = FileSystem::ReadFile(scenePath, false);
|
||||
if (!DefaultScene->Deserialize(sceneContent))
|
||||
{
|
||||
Logger::Log("Error loading scene: " + scenePath, CRITICAL);
|
||||
return false;
|
||||
}
|
||||
|
||||
DefaultScene->Path = scenePath;
|
||||
Logger::Log("Successfully loaded scene: " + scenePath);
|
||||
|
||||
return true; // Success
|
||||
}
|
||||
|
||||
@@ -6,29 +6,32 @@
|
||||
|
||||
#include "FGD/FGDFile.h"
|
||||
|
||||
class Project : public ISerializable
|
||||
namespace Nuake
|
||||
{
|
||||
public:
|
||||
std::string Name;
|
||||
std::string Description;
|
||||
std::string FullPath;
|
||||
class Project : public ISerializable
|
||||
{
|
||||
public:
|
||||
std::string Name;
|
||||
std::string Description;
|
||||
std::string FullPath;
|
||||
|
||||
// Path of the trenchbroom .exe folder
|
||||
std::string TrenchbroomPath = "";
|
||||
// Path of the trenchbroom .exe folder
|
||||
std::string TrenchbroomPath = "";
|
||||
|
||||
Ref<Scene> DefaultScene;
|
||||
Ref<FGDFile> EntityDefinitionsFile;
|
||||
Ref<Scene> DefaultScene;
|
||||
Ref<FGDFile> EntityDefinitionsFile;
|
||||
|
||||
Project(const std::string Name, const std::string Description, const std::string& FullPath, const std::string& defaultScenePath = "");
|
||||
Project();
|
||||
Project(const std::string Name, const std::string Description, const std::string& FullPath, const std::string& defaultScenePath = "");
|
||||
Project();
|
||||
|
||||
void Save();
|
||||
void SaveAs(const std::string FullPath);
|
||||
void Save();
|
||||
void SaveAs(const std::string FullPath);
|
||||
|
||||
static Ref<Project> New(const std::string Name, const std::string Description, const std::string FullPath);
|
||||
static Ref<Project> New();
|
||||
static Ref<Project> Load(std::string path);
|
||||
static Ref<Project> New(const std::string Name, const std::string Description, const std::string FullPath);
|
||||
static Ref<Project> New();
|
||||
static Ref<Project> Load(std::string path);
|
||||
|
||||
json Serialize() override;
|
||||
bool Deserialize(const std::string& str) override;
|
||||
};
|
||||
json Serialize() override;
|
||||
bool Deserialize(const std::string& str) override;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,23 +6,26 @@
|
||||
#include "../Rendering/Mesh/Mesh.h"
|
||||
#include <src/Core/Physics/Rigibody.h>
|
||||
|
||||
class BSPBrushComponent {
|
||||
public:
|
||||
std::vector<Ref<Mesh>> Meshes;
|
||||
std::vector< Ref<Material>> Materials;
|
||||
std::vector<Ref<Physics::RigidBody>> Rigidbody;
|
||||
namespace Nuake
|
||||
{
|
||||
class BSPBrushComponent {
|
||||
public:
|
||||
std::vector<Ref<Mesh>> Meshes;
|
||||
std::vector< Ref<Material>> Materials;
|
||||
std::vector<Ref<Physics::RigidBody>> Rigidbody;
|
||||
|
||||
std::string target = "";
|
||||
std::vector<Entity> Targets;
|
||||
std::string target = "";
|
||||
std::vector<Entity> Targets;
|
||||
|
||||
bool IsSolid = true;
|
||||
bool IsTrigger = false;
|
||||
bool IsTransparent = false;
|
||||
bool IsFunc = false;
|
||||
bool IsSolid = true;
|
||||
bool IsTrigger = false;
|
||||
bool IsTransparent = false;
|
||||
bool IsFunc = false;
|
||||
|
||||
BSPBrushComponent() {
|
||||
Meshes = std::vector<Ref<Mesh>>();
|
||||
Materials = std::vector<Ref<Material>>();
|
||||
Rigidbody = std::vector<Ref<Physics::RigidBody>>();
|
||||
}
|
||||
};
|
||||
BSPBrushComponent() {
|
||||
Meshes = std::vector<Ref<Mesh>>();
|
||||
Materials = std::vector<Ref<Material>>();
|
||||
Rigidbody = std::vector<Ref<Physics::RigidBody>>();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
#pragma once
|
||||
#include "../Core/Physics/PhysicsShapes.h"
|
||||
#include "../Core/Core.h"
|
||||
#include "src/Core/Physics/PhysicsShapes.h"
|
||||
#include "src/Core/Core.h"
|
||||
|
||||
class BoxColliderComponent
|
||||
{
|
||||
public:
|
||||
Ref<Physics::PhysicShape> Box;
|
||||
glm::vec3 Size = glm::vec3(0.5f, 0.5f, 0.5f);
|
||||
bool IsTrigger;
|
||||
};
|
||||
namespace Nuake {
|
||||
class BoxColliderComponent
|
||||
{
|
||||
public:
|
||||
Ref<Physics::PhysicShape> Box;
|
||||
glm::vec3 Size = glm::vec3(0.5f, 0.5f, 0.5f);
|
||||
bool IsTrigger;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
#pragma once
|
||||
#include "CameraComponent.h"
|
||||
#include <src/Rendering/Camera.h>
|
||||
#include "src/Rendering/Camera.h"
|
||||
#include "src/Scene/Entities/ImGuiHelper.h"
|
||||
|
||||
CameraComponent::CameraComponent()
|
||||
{
|
||||
CameraInstance = CreateRef<Camera>();
|
||||
}
|
||||
namespace Nuake {
|
||||
CameraComponent::CameraComponent()
|
||||
{
|
||||
CameraInstance = CreateRef<Camera>();
|
||||
}
|
||||
|
||||
void CameraComponent::DrawEditor() {
|
||||
ImGui::Text("Camera");
|
||||
ImGui::SliderFloat("Exposure", &CameraInstance->Exposure, 0.0f, 2.0f, "%.2f", 1.0f);
|
||||
ImGui::SliderFloat("FOV", &CameraInstance->Fov, 1.0f, 180.0f, "%.2f", 1.0f);
|
||||
ImGui::SliderFloat("Speed", &CameraInstance->Speed, 0.1f, 5.0f, "%.2f", 1.0f);
|
||||
}
|
||||
void CameraComponent::DrawEditor()
|
||||
{
|
||||
ImGui::Text("Camera");
|
||||
ImGui::SliderFloat("Exposure", &CameraInstance->Exposure, 0.0f, 2.0f, "%.2f", 1.0f);
|
||||
ImGui::SliderFloat("FOV", &CameraInstance->Fov, 1.0f, 180.0f, "%.2f", 1.0f);
|
||||
ImGui::SliderFloat("Speed", &CameraInstance->Speed, 0.1f, 5.0f, "%.2f", 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +1,33 @@
|
||||
#pragma once
|
||||
#include "TransformComponent.h"
|
||||
#include "../Core/Core.h"
|
||||
#include "../Resource/Serializable.h"
|
||||
#include "../Rendering/Camera.h"
|
||||
#include "src/Core/Core.h"
|
||||
#include "src/Resource/Serializable.h"
|
||||
#include "src/Rendering/Camera.h"
|
||||
|
||||
class CameraComponent {
|
||||
public:
|
||||
Ref<Camera> CameraInstance;
|
||||
TransformComponent* transformComponent;
|
||||
|
||||
CameraComponent();
|
||||
|
||||
void DrawEditor();
|
||||
|
||||
json Serialize()
|
||||
namespace Nuake
|
||||
{
|
||||
class CameraComponent
|
||||
{
|
||||
BEGIN_SERIALIZE();
|
||||
SERIALIZE_OBJECT(CameraInstance);
|
||||
END_SERIALIZE();
|
||||
}
|
||||
public:
|
||||
Ref<Camera> CameraInstance;
|
||||
TransformComponent* transformComponent;
|
||||
|
||||
bool Deserialize(std::string str)
|
||||
{
|
||||
CameraInstance = CreateRef<Camera>();
|
||||
CameraComponent();
|
||||
|
||||
return CameraInstance->Deserialize(str);
|
||||
}
|
||||
};
|
||||
void DrawEditor();
|
||||
|
||||
json Serialize()
|
||||
{
|
||||
BEGIN_SERIALIZE();
|
||||
SERIALIZE_OBJECT(CameraInstance);
|
||||
END_SERIALIZE();
|
||||
}
|
||||
|
||||
bool Deserialize(std::string str)
|
||||
{
|
||||
CameraInstance = CreateRef<Camera>();
|
||||
|
||||
return CameraInstance->Deserialize(str);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,40 +1,42 @@
|
||||
#pragma once
|
||||
#include "src/Core/Physics/CharacterController.h"
|
||||
|
||||
#include "../Core/Physics/CharacterController.h"
|
||||
class CharacterControllerComponent
|
||||
{
|
||||
public:
|
||||
Ref < Physics::CharacterController> CharacterController;
|
||||
|
||||
float Height = 1.0f;
|
||||
float Radius = 0.2f;
|
||||
float Mass = 25.0f;
|
||||
|
||||
CharacterControllerComponent()
|
||||
namespace Nuake {
|
||||
class CharacterControllerComponent
|
||||
{
|
||||
|
||||
}
|
||||
public:
|
||||
Ref < Physics::CharacterController> CharacterController;
|
||||
|
||||
json Serialize() {
|
||||
BEGIN_SERIALIZE();
|
||||
SERIALIZE_VAL(Height);
|
||||
SERIALIZE_VAL(Radius);
|
||||
SERIALIZE_VAL(Mass);
|
||||
END_SERIALIZE();
|
||||
}
|
||||
float Height = 1.0f;
|
||||
float Radius = 0.2f;
|
||||
float Mass = 25.0f;
|
||||
|
||||
bool Deserialize(const std::string str) {
|
||||
BEGIN_DESERIALIZE();
|
||||
Height = j["Height"];
|
||||
Radius = j["Radius"];
|
||||
Mass = j["Mass"];
|
||||
return true;
|
||||
}
|
||||
void SyncWithTransform(TransformComponent& tc)
|
||||
{
|
||||
btVector3 pos = CharacterController->m_motionTransform.getOrigin();
|
||||
glm::vec3 finalPos = glm::vec3(pos.x(), pos.y(), pos.z());
|
||||
CharacterControllerComponent()
|
||||
{
|
||||
|
||||
tc.Translation = finalPos;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
json Serialize() {
|
||||
BEGIN_SERIALIZE();
|
||||
SERIALIZE_VAL(Height);
|
||||
SERIALIZE_VAL(Radius);
|
||||
SERIALIZE_VAL(Mass);
|
||||
END_SERIALIZE();
|
||||
}
|
||||
|
||||
bool Deserialize(const std::string str) {
|
||||
BEGIN_DESERIALIZE();
|
||||
Height = j["Height"];
|
||||
Radius = j["Radius"];
|
||||
Mass = j["Mass"];
|
||||
return true;
|
||||
}
|
||||
void SyncWithTransform(TransformComponent& tc)
|
||||
{
|
||||
btVector3 pos = CharacterController->m_motionTransform.getOrigin();
|
||||
glm::vec3 finalPos = glm::vec3(pos.x(), pos.y(), pos.z());
|
||||
|
||||
tc.Translation = finalPos;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,141 +6,144 @@
|
||||
#include <GL\glew.h>
|
||||
#include "../Core/Core.h"
|
||||
#include <src/Scene/Entities/ImGuiHelper.h>
|
||||
LightComponent::LightComponent()
|
||||
{
|
||||
Color = glm::vec3(1, 1, 1);
|
||||
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.
|
||||
|
||||
//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);
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
void LightComponent::SetCastShadows(bool toggle)
|
||||
{
|
||||
CastShadows = toggle;
|
||||
if (CastShadows)
|
||||
namespace Nuake {
|
||||
LightComponent::LightComponent()
|
||||
{
|
||||
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);
|
||||
}
|
||||
Color = glm::vec3(1, 1, 1);
|
||||
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.
|
||||
|
||||
//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);
|
||||
//}
|
||||
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_Framebuffers[i] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glm::mat4 LightComponent::GetProjection()
|
||||
{
|
||||
return glm::ortho(-25.0f, 25.0f, -25.0f, 25.0f, -25.0f, 25.0f);
|
||||
}
|
||||
|
||||
void LightComponent::SetDirection(glm::vec3 dir)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
glm::vec3 LightComponent::GetDirection()
|
||||
{
|
||||
//glm::mat4 start = glm::mat4(1.0f);
|
||||
//glm::vec3 defaultDirection(0, 0, 1); // forward
|
||||
//
|
||||
//start = glm::rotate(start, glm::radians(Direction.x), glm::vec3(1, 0, 0));
|
||||
//start = glm::rotate(start, glm::radians(Direction.y), glm::vec3(0, 1, 0));
|
||||
//start = glm::rotate(start, glm::radians(Direction.z), glm::vec3(0, 0, 1));
|
||||
|
||||
//return glm::vec3(start * glm::vec4(defaultDirection, 1.0f));
|
||||
return Direction;
|
||||
}
|
||||
|
||||
|
||||
void LightComponent::BeginDrawShadow()
|
||||
{
|
||||
Renderer::m_ShadowmapShader->Bind();
|
||||
//m_Framebuffer->Bind();
|
||||
|
||||
// Render scene...
|
||||
|
||||
}
|
||||
|
||||
void LightComponent::EndDrawShadow()
|
||||
{
|
||||
//m_Framebuffer->Unbind();
|
||||
}
|
||||
|
||||
void LightComponent::DrawShadow()
|
||||
{
|
||||
if (Type != Directional)
|
||||
return;
|
||||
|
||||
Renderer::m_ShadowmapShader->Bind();
|
||||
}
|
||||
|
||||
void LightComponent::Draw(TransformComponent transformComponent, Ref<Camera> cam)
|
||||
{
|
||||
Renderer::RegisterLight(transformComponent, *this, cam);
|
||||
}
|
||||
|
||||
void LightComponent::DrawDeferred(TransformComponent transformComponent, Camera* cam)
|
||||
{
|
||||
Renderer::RegisterDeferredLight(transformComponent, *this, cam);
|
||||
}
|
||||
|
||||
void LightComponent::DrawEditor() {
|
||||
ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Light properties");
|
||||
ImGui::ColorEdit3("Light Color", &Color.r);
|
||||
ImGui::SliderFloat("Strength", &Strength, 0.0f, 50.0f);
|
||||
bool before = CastShadows;
|
||||
ImGui::Checkbox("Cast shadows", &CastShadows);
|
||||
|
||||
if (CastShadows && before == false)
|
||||
SetCastShadows(true);
|
||||
|
||||
const char* types[] = { "Directional", "Point", "Spot" };
|
||||
static const char* current_item = types[Type];
|
||||
|
||||
if (ImGui::BeginCombo("Type", current_item)) // The second parameter is the label previewed before opening the combo.
|
||||
void LightComponent::SetCastShadows(bool toggle)
|
||||
{
|
||||
for (int n = 0; n < IM_ARRAYSIZE(types); n++)
|
||||
CastShadows = toggle;
|
||||
if (CastShadows)
|
||||
{
|
||||
bool is_selected = (current_item == types[n]); // You can store your selection however you want, outside or inside your objects
|
||||
if (ImGui::Selectable(types[n], is_selected)) {
|
||||
current_item = types[n];
|
||||
Type = (LightType)n;
|
||||
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);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_Framebuffers[i] = nullptr;
|
||||
}
|
||||
if (is_selected)
|
||||
ImGui::SetItemDefaultFocus(); // You may set the initial focus when opening the combo (scrolling + for keyboard navigation support)
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if (Type == Directional) {
|
||||
ImGui::Checkbox("Sync with sky", &SyncDirectionWithSky);
|
||||
ImGui::Checkbox("Volumetric?", &IsVolumetric);
|
||||
ImGuiHelper::DrawVec3("Direction", &Direction);
|
||||
glm::mat4 LightComponent::GetProjection()
|
||||
{
|
||||
return glm::ortho(-25.0f, 25.0f, -25.0f, 25.0f, -25.0f, 25.0f);
|
||||
}
|
||||
|
||||
void LightComponent::SetDirection(glm::vec3 dir)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
glm::vec3 LightComponent::GetDirection()
|
||||
{
|
||||
//glm::mat4 start = glm::mat4(1.0f);
|
||||
//glm::vec3 defaultDirection(0, 0, 1); // forward
|
||||
//
|
||||
//start = glm::rotate(start, glm::radians(Direction.x), glm::vec3(1, 0, 0));
|
||||
//start = glm::rotate(start, glm::radians(Direction.y), glm::vec3(0, 1, 0));
|
||||
//start = glm::rotate(start, glm::radians(Direction.z), glm::vec3(0, 0, 1));
|
||||
|
||||
//return glm::vec3(start * glm::vec4(defaultDirection, 1.0f));
|
||||
return Direction;
|
||||
}
|
||||
|
||||
|
||||
void LightComponent::BeginDrawShadow()
|
||||
{
|
||||
Renderer::m_ShadowmapShader->Bind();
|
||||
//m_Framebuffer->Bind();
|
||||
|
||||
// Render scene...
|
||||
|
||||
}
|
||||
|
||||
void LightComponent::EndDrawShadow()
|
||||
{
|
||||
//m_Framebuffer->Unbind();
|
||||
}
|
||||
|
||||
void LightComponent::DrawShadow()
|
||||
{
|
||||
if (Type != Directional)
|
||||
return;
|
||||
|
||||
Renderer::m_ShadowmapShader->Bind();
|
||||
}
|
||||
|
||||
void LightComponent::Draw(TransformComponent transformComponent, Ref<Camera> cam)
|
||||
{
|
||||
Renderer::RegisterLight(transformComponent, *this, cam);
|
||||
}
|
||||
|
||||
void LightComponent::DrawDeferred(TransformComponent transformComponent, Camera* cam)
|
||||
{
|
||||
Renderer::RegisterDeferredLight(transformComponent, *this, cam);
|
||||
}
|
||||
|
||||
void LightComponent::DrawEditor() {
|
||||
ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Light properties");
|
||||
ImGui::ColorEdit3("Light Color", &Color.r);
|
||||
ImGui::SliderFloat("Strength", &Strength, 0.0f, 50.0f);
|
||||
bool before = CastShadows;
|
||||
ImGui::Checkbox("Cast shadows", &CastShadows);
|
||||
|
||||
if (CastShadows && before == false)
|
||||
SetCastShadows(true);
|
||||
|
||||
const char* types[] = { "Directional", "Point", "Spot" };
|
||||
static const char* current_item = types[Type];
|
||||
|
||||
if (ImGui::BeginCombo("Type", current_item)) // The second parameter is the label previewed before opening the combo.
|
||||
{
|
||||
for (int n = 0; n < IM_ARRAYSIZE(types); n++)
|
||||
{
|
||||
bool is_selected = (current_item == types[n]); // You can store your selection however you want, outside or inside your objects
|
||||
if (ImGui::Selectable(types[n], is_selected)) {
|
||||
current_item = types[n];
|
||||
Type = (LightType)n;
|
||||
}
|
||||
if (is_selected)
|
||||
ImGui::SetItemDefaultFocus(); // You may set the initial focus when opening the combo (scrolling + for keyboard navigation support)
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if (Type == Directional) {
|
||||
ImGui::Checkbox("Sync with sky", &SyncDirectionWithSky);
|
||||
ImGui::Checkbox("Volumetric?", &IsVolumetric);
|
||||
ImGuiHelper::DrawVec3("Direction", &Direction);
|
||||
}
|
||||
|
||||
//if (Type == 1) {
|
||||
// ImGui::SliderFloat("Attenuation", &Attenuation, 0.0f, 1.0f);
|
||||
// ImGui::SliderFloat("Linear attenuation", &LinearAttenuation, 0.0f, 1.0f);
|
||||
// ImGui::SliderFloat("Quadratic attenuation", &QuadraticAttenuation, 0.0f, 1.0f);
|
||||
//}
|
||||
|
||||
//Direction = glm::normalize(Direction);
|
||||
}
|
||||
|
||||
//if (Type == 1) {
|
||||
// ImGui::SliderFloat("Attenuation", &Attenuation, 0.0f, 1.0f);
|
||||
// ImGui::SliderFloat("Linear attenuation", &LinearAttenuation, 0.0f, 1.0f);
|
||||
// ImGui::SliderFloat("Quadratic attenuation", &QuadraticAttenuation, 0.0f, 1.0f);
|
||||
//}
|
||||
|
||||
//Direction = glm::normalize(Direction);
|
||||
}
|
||||
|
||||
@@ -3,204 +3,209 @@
|
||||
#include <glm\ext\vector_float2.hpp>
|
||||
#include "TransformComponent.h"
|
||||
#include "../Rendering/Camera.h"
|
||||
#include "../Rendering/Framebuffer.h"
|
||||
#include "src/Rendering/Buffers/Framebuffer.h"
|
||||
#include "BaseComponent.h"
|
||||
#include "../Resource/Serializable.h"
|
||||
|
||||
#include <glm\ext\matrix_clip_space.hpp>
|
||||
|
||||
enum LightType {
|
||||
Directional, Point, Spot
|
||||
};
|
||||
|
||||
class LightComponent {
|
||||
public:
|
||||
LightType Type = Point;
|
||||
glm::vec3 Direction = glm::vec3(0, -1, 0);
|
||||
glm::vec3 Color;
|
||||
bool IsVolumetric = false;
|
||||
float Strength;
|
||||
bool SyncDirectionWithSky = false;
|
||||
Ref<FrameBuffer> m_Framebuffer;
|
||||
|
||||
bool CastShadows = false;
|
||||
float Attenuation = 0.0f;
|
||||
float LinearAttenuation = 0.0f;
|
||||
float QuadraticAttenuation = 0.0f;
|
||||
|
||||
Ref<FrameBuffer> m_Framebuffers[4];
|
||||
glm::mat4 mViewProjections[4];
|
||||
float mCascadeSplitDepth[4];
|
||||
|
||||
LightComponent();
|
||||
|
||||
void SetCastShadows(bool toggle);
|
||||
|
||||
glm::mat4 GetProjection();
|
||||
|
||||
glm::mat4 GetLightTransform();
|
||||
void SetDirection(glm::vec3 dir);
|
||||
glm::vec3 GetDirection();
|
||||
|
||||
void BeginDrawShadow();
|
||||
|
||||
void EndDrawShadow();
|
||||
void DrawShadow();
|
||||
|
||||
void Draw(TransformComponent transformComponent, Ref<Camera> cam);
|
||||
void DrawDeferred(TransformComponent transformComponent, Camera* cam);
|
||||
void DrawEditor();
|
||||
|
||||
void SetType(LightType type);
|
||||
|
||||
float mCascadeSplits[4];
|
||||
|
||||
|
||||
void CalculateViewProjection(glm::mat4& view, const glm::mat4& projection)
|
||||
namespace Nuake
|
||||
{
|
||||
enum LightType
|
||||
{
|
||||
glm::mat4 viewProjection = projection * view;
|
||||
glm::mat4 inverseViewProjection = glm::inverse(viewProjection);
|
||||
Directional, Point, Spot
|
||||
};
|
||||
|
||||
// TODO: Automate this
|
||||
const float nearClip = 0.01f;
|
||||
const float farClip = 1000.0f;
|
||||
const float clipRange = farClip - nearClip;
|
||||
class LightComponent
|
||||
{
|
||||
public:
|
||||
LightType Type = Point;
|
||||
glm::vec3 Direction = glm::vec3(0, -1, 0);
|
||||
glm::vec3 Color;
|
||||
bool IsVolumetric = false;
|
||||
float Strength;
|
||||
bool SyncDirectionWithSky = false;
|
||||
Ref<FrameBuffer> m_Framebuffer;
|
||||
|
||||
const float mCascadeNearPlaneOffset = 0.0;
|
||||
const float mCascadeFarPlaneOffset = 0.0;
|
||||
bool CastShadows = false;
|
||||
float Attenuation = 0.0f;
|
||||
float LinearAttenuation = 0.0f;
|
||||
float QuadraticAttenuation = 0.0f;
|
||||
|
||||
// Calculate the optimal cascade distances
|
||||
const float minZ = nearClip;
|
||||
const float maxZ = nearClip + clipRange;
|
||||
const float range = maxZ - minZ;
|
||||
const float ratio = maxZ / minZ;
|
||||
for (int i = 0; i < 4; i++)
|
||||
Ref<FrameBuffer> m_Framebuffers[4];
|
||||
glm::mat4 mViewProjections[4];
|
||||
float mCascadeSplitDepth[4];
|
||||
|
||||
LightComponent();
|
||||
|
||||
void SetCastShadows(bool toggle);
|
||||
|
||||
glm::mat4 GetProjection();
|
||||
|
||||
glm::mat4 GetLightTransform();
|
||||
void SetDirection(glm::vec3 dir);
|
||||
glm::vec3 GetDirection();
|
||||
|
||||
void BeginDrawShadow();
|
||||
|
||||
void EndDrawShadow();
|
||||
void DrawShadow();
|
||||
|
||||
void Draw(TransformComponent transformComponent, Ref<Camera> cam);
|
||||
void DrawDeferred(TransformComponent transformComponent, Camera* cam);
|
||||
void DrawEditor();
|
||||
|
||||
void SetType(LightType type);
|
||||
|
||||
float mCascadeSplits[4];
|
||||
|
||||
|
||||
void CalculateViewProjection(glm::mat4& view, const glm::mat4& projection)
|
||||
{
|
||||
const float p = (i + 1) / static_cast<float>(4);
|
||||
const float log = minZ * glm::pow(ratio, p);
|
||||
const float uniform = minZ + range * p;
|
||||
const float d = 0.91f * (log - uniform) + uniform;
|
||||
mCascadeSplits[i] = (d - nearClip) / clipRange;
|
||||
}
|
||||
glm::mat4 viewProjection = projection * view;
|
||||
glm::mat4 inverseViewProjection = glm::inverse(viewProjection);
|
||||
|
||||
//mCascadeSplits[0] = 0.2f;
|
||||
//mCascadeSplits[1] = 0.45f;
|
||||
//mCascadeSplits[2] = 1.0f;
|
||||
// TODO: Automate this
|
||||
const float nearClip = 0.01f;
|
||||
const float farClip = 1000.0f;
|
||||
const float clipRange = farClip - nearClip;
|
||||
|
||||
float lastSplitDist = 0.0f;
|
||||
// Calculate Orthographic Projection matrix for each cascade
|
||||
for (int cascade = 0; cascade < 4; cascade++)
|
||||
{
|
||||
float splitDist = mCascadeSplits[cascade];
|
||||
glm::vec4 frustumCorners[8] =
|
||||
{
|
||||
//Near face
|
||||
{ 1.0f, 1.0f, -1.0f, 1.0f },
|
||||
{ -1.0f, 1.0f, -1.0f, 1.0f },
|
||||
{ 1.0f, -1.0f, -1.0f, 1.0f },
|
||||
{ -1.0f, -1.0f, -1.0f, 1.0f },
|
||||
const float mCascadeNearPlaneOffset = 0.0;
|
||||
const float mCascadeFarPlaneOffset = 0.0;
|
||||
|
||||
//Far face
|
||||
{ 1.0f, 1.0f, 1.0f, 1.0f },
|
||||
{ -1.0f, 1.0f, 1.0f, 1.0f },
|
||||
{ 1.0f, -1.0f, 1.0f, 1.0f },
|
||||
{ -1.0f, -1.0f, 1.0f, 1.0f },
|
||||
};
|
||||
|
||||
// Project frustum corners into world space from clip space
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
glm::vec4 invCorner = inverseViewProjection * frustumCorners[i];
|
||||
frustumCorners[i] = invCorner / invCorner.w;
|
||||
}
|
||||
// Calculate the optimal cascade distances
|
||||
const float minZ = nearClip;
|
||||
const float maxZ = nearClip + clipRange;
|
||||
const float range = maxZ - minZ;
|
||||
const float ratio = maxZ / minZ;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
glm::vec4 dist = frustumCorners[i + 4] - frustumCorners[i];
|
||||
frustumCorners[i + 4] = frustumCorners[i] + (dist * splitDist);
|
||||
frustumCorners[i] = frustumCorners[i] + (dist * lastSplitDist);
|
||||
const float p = (i + 1) / static_cast<float>(4);
|
||||
const float log = minZ * glm::pow(ratio, p);
|
||||
const float uniform = minZ + range * p;
|
||||
const float d = 0.91f * (log - uniform) + uniform;
|
||||
mCascadeSplits[i] = (d - nearClip) / clipRange;
|
||||
}
|
||||
|
||||
// Get frustum center
|
||||
glm::vec3 frustumCenter = glm::vec3(0.0f);
|
||||
for (int i = 0; i < 8; i++)
|
||||
frustumCenter += glm::vec3(frustumCorners[i]);
|
||||
frustumCenter /= 8.0f;
|
||||
//mCascadeSplits[0] = 0.2f;
|
||||
//mCascadeSplits[1] = 0.45f;
|
||||
//mCascadeSplits[2] = 1.0f;
|
||||
|
||||
// Get the minimum and maximum extents
|
||||
float radius = 0.0f;
|
||||
for (int i = 0; i < 8; i++)
|
||||
float lastSplitDist = 0.0f;
|
||||
// Calculate Orthographic Projection matrix for each cascade
|
||||
for (int cascade = 0; cascade < 4; cascade++)
|
||||
{
|
||||
float distance = glm::length(glm::vec3(frustumCorners[i]) - frustumCenter);
|
||||
radius = glm::max(radius, distance);
|
||||
float splitDist = mCascadeSplits[cascade];
|
||||
glm::vec4 frustumCorners[8] =
|
||||
{
|
||||
//Near face
|
||||
{ 1.0f, 1.0f, -1.0f, 1.0f },
|
||||
{ -1.0f, 1.0f, -1.0f, 1.0f },
|
||||
{ 1.0f, -1.0f, -1.0f, 1.0f },
|
||||
{ -1.0f, -1.0f, -1.0f, 1.0f },
|
||||
|
||||
//Far face
|
||||
{ 1.0f, 1.0f, 1.0f, 1.0f },
|
||||
{ -1.0f, 1.0f, 1.0f, 1.0f },
|
||||
{ 1.0f, -1.0f, 1.0f, 1.0f },
|
||||
{ -1.0f, -1.0f, 1.0f, 1.0f },
|
||||
};
|
||||
|
||||
// Project frustum corners into world space from clip space
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
glm::vec4 invCorner = inverseViewProjection * frustumCorners[i];
|
||||
frustumCorners[i] = invCorner / invCorner.w;
|
||||
}
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
glm::vec4 dist = frustumCorners[i + 4] - frustumCorners[i];
|
||||
frustumCorners[i + 4] = frustumCorners[i] + (dist * splitDist);
|
||||
frustumCorners[i] = frustumCorners[i] + (dist * lastSplitDist);
|
||||
}
|
||||
|
||||
// Get frustum center
|
||||
glm::vec3 frustumCenter = glm::vec3(0.0f);
|
||||
for (int i = 0; i < 8; i++)
|
||||
frustumCenter += glm::vec3(frustumCorners[i]);
|
||||
frustumCenter /= 8.0f;
|
||||
|
||||
// Get the minimum and maximum extents
|
||||
float radius = 0.0f;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
float distance = glm::length(glm::vec3(frustumCorners[i]) - frustumCenter);
|
||||
radius = glm::max(radius, distance);
|
||||
}
|
||||
radius = std::ceil(radius * 16.0f) / 16.0f;
|
||||
glm::vec3 maxExtents = glm::vec3(radius);
|
||||
glm::vec3 minExtents = -maxExtents;
|
||||
|
||||
// Calculate the view and projection matrix
|
||||
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);
|
||||
|
||||
// Offset to texel space to avoid shimmering ->(https://stackoverflow.com/questions/33499053/cascaded-shadow-map-shimmering)
|
||||
glm::mat4 shadowMatrix = lightProjectionMatrix * lightViewMatrix;
|
||||
const float ShadowMapResolution = 4096;
|
||||
glm::vec4 shadowOrigin = (shadowMatrix * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)) * ShadowMapResolution / 2.0f;
|
||||
glm::vec4 roundedOrigin = glm::round(shadowOrigin);
|
||||
glm::vec4 roundOffset = roundedOrigin - shadowOrigin;
|
||||
roundOffset = roundOffset * 2.0f / ShadowMapResolution;
|
||||
roundOffset.z = 0.0f;
|
||||
roundOffset.w = 0.0f;
|
||||
lightProjectionMatrix[3] += roundOffset;
|
||||
|
||||
// Store SplitDistance and ViewProjection-Matrix
|
||||
mCascadeSplitDepth[cascade] = (nearClip + splitDist * clipRange) * 1.0f;
|
||||
mViewProjections[cascade] = lightProjectionMatrix * lightViewMatrix;
|
||||
lastSplitDist = mCascadeSplits[cascade];
|
||||
|
||||
// -----------------------Debug only-----------------------
|
||||
// RendererDebug::BeginScene(viewProjection);
|
||||
// RendererDebug::SubmitCameraFrustum(frustumCorners, glm::mat4(1.0f), GetColor(cascade)); // Draws the divided camera frustums
|
||||
// RendererDebug::SubmitLine(glm::vec3(0.0f, 0.0f, 0.0f), frustumCenter, GetColor(cascade)); // Draws the center of the frustum (A line pointing from origin to the center)
|
||||
// RendererDebug::EndScene();
|
||||
}
|
||||
radius = std::ceil(radius * 16.0f) / 16.0f;
|
||||
glm::vec3 maxExtents = glm::vec3(radius);
|
||||
glm::vec3 minExtents = -maxExtents;
|
||||
|
||||
// Calculate the view and projection matrix
|
||||
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);
|
||||
|
||||
// Offset to texel space to avoid shimmering ->(https://stackoverflow.com/questions/33499053/cascaded-shadow-map-shimmering)
|
||||
glm::mat4 shadowMatrix = lightProjectionMatrix * lightViewMatrix;
|
||||
const float ShadowMapResolution = 4096;
|
||||
glm::vec4 shadowOrigin = (shadowMatrix * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)) * ShadowMapResolution / 2.0f;
|
||||
glm::vec4 roundedOrigin = glm::round(shadowOrigin);
|
||||
glm::vec4 roundOffset = roundedOrigin - shadowOrigin;
|
||||
roundOffset = roundOffset * 2.0f / ShadowMapResolution;
|
||||
roundOffset.z = 0.0f;
|
||||
roundOffset.w = 0.0f;
|
||||
lightProjectionMatrix[3] += roundOffset;
|
||||
|
||||
// Store SplitDistance and ViewProjection-Matrix
|
||||
mCascadeSplitDepth[cascade] = (nearClip + splitDist * clipRange) * 1.0f;
|
||||
mViewProjections[cascade] = lightProjectionMatrix * lightViewMatrix;
|
||||
lastSplitDist = mCascadeSplits[cascade];
|
||||
|
||||
// -----------------------Debug only-----------------------
|
||||
// RendererDebug::BeginScene(viewProjection);
|
||||
// RendererDebug::SubmitCameraFrustum(frustumCorners, glm::mat4(1.0f), GetColor(cascade)); // Draws the divided camera frustums
|
||||
// RendererDebug::SubmitLine(glm::vec3(0.0f, 0.0f, 0.0f), frustumCenter, GetColor(cascade)); // Draws the center of the frustum (A line pointing from origin to the center)
|
||||
// RendererDebug::EndScene();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
json Serialize()
|
||||
{
|
||||
BEGIN_SERIALIZE();
|
||||
SERIALIZE_VAL(Type);
|
||||
SERIALIZE_VEC3(Direction);
|
||||
SERIALIZE_VEC3(Color);
|
||||
SERIALIZE_VAL(IsVolumetric);
|
||||
SERIALIZE_VAL(Strength);
|
||||
SERIALIZE_VAL(SyncDirectionWithSky);
|
||||
SERIALIZE_VAL(CastShadows);
|
||||
END_SERIALIZE();
|
||||
}
|
||||
json Serialize()
|
||||
{
|
||||
BEGIN_SERIALIZE();
|
||||
SERIALIZE_VAL(Type);
|
||||
SERIALIZE_VEC3(Direction);
|
||||
SERIALIZE_VEC3(Color);
|
||||
SERIALIZE_VAL(IsVolumetric);
|
||||
SERIALIZE_VAL(Strength);
|
||||
SERIALIZE_VAL(SyncDirectionWithSky);
|
||||
SERIALIZE_VAL(CastShadows);
|
||||
END_SERIALIZE();
|
||||
}
|
||||
|
||||
bool Deserialize(std::string str)
|
||||
{
|
||||
BEGIN_DESERIALIZE();
|
||||
if (j.contains("Type"))
|
||||
Type = (LightType)j["Type"];
|
||||
if (j.contains("IsVolumetric"))
|
||||
IsVolumetric = j["IsVolumetric"];
|
||||
if (j.contains("Strength"))
|
||||
Strength = j["Strength"];
|
||||
if (j.contains("SyncDirectionWithSky"))
|
||||
SyncDirectionWithSky = j["SyncDirectionWithSky"];
|
||||
if (j.contains("CastShadows"))
|
||||
SetCastShadows(j["CastShadows"]);
|
||||
if (j.contains("Direction"))
|
||||
{
|
||||
float x = j["Direction"]["x"];
|
||||
float y = j["Direction"]["y"];
|
||||
float z = j["Direction"]["z"];
|
||||
this->Direction = Vector3(x, y, z);
|
||||
}
|
||||
bool Deserialize(std::string str)
|
||||
{
|
||||
BEGIN_DESERIALIZE();
|
||||
if (j.contains("Type"))
|
||||
Type = (LightType)j["Type"];
|
||||
if (j.contains("IsVolumetric"))
|
||||
IsVolumetric = j["IsVolumetric"];
|
||||
if (j.contains("Strength"))
|
||||
Strength = j["Strength"];
|
||||
if (j.contains("SyncDirectionWithSky"))
|
||||
SyncDirectionWithSky = j["SyncDirectionWithSky"];
|
||||
if (j.contains("CastShadows"))
|
||||
SetCastShadows(j["CastShadows"]);
|
||||
if (j.contains("Direction"))
|
||||
{
|
||||
float x = j["Direction"]["x"];
|
||||
float y = j["Direction"]["y"];
|
||||
float z = j["Direction"]["z"];
|
||||
this->Direction = Vector3(x, y, z);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
#pragma once
|
||||
#include "../Core/Physics/PhysicsShapes.h"
|
||||
#include "../Core/Core.h"
|
||||
#include "src/Core/Physics/PhysicsShapes.h"
|
||||
#include "src/Core/Core.h"
|
||||
|
||||
class MeshColliderComponent
|
||||
{
|
||||
public:
|
||||
Ref<Physics::MeshShape> MeshShape;
|
||||
Ref<Mesh> Mesh;
|
||||
bool IsTrigger;
|
||||
};
|
||||
namespace Nuake {
|
||||
class MeshColliderComponent
|
||||
{
|
||||
public:
|
||||
Ref<Physics::MeshShape> MeshShape;
|
||||
Ref<Mesh> Mesh;
|
||||
bool IsTrigger;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,278 +1,279 @@
|
||||
#include "MeshComponent.h"
|
||||
#include <GL\glew.h>
|
||||
#include "../../../Rendering/Renderer.h"
|
||||
#include "../../../Rendering/Vertex.h"
|
||||
#include "../../../Core/MaterialManager.h"
|
||||
#include "src/Rendering/Renderer.h"
|
||||
#include "src/Rendering/Vertex.h"
|
||||
#include "src/Core/MaterialManager.h"
|
||||
#include <imgui\imgui.h>
|
||||
|
||||
// TODO: This is a pile of crap.
|
||||
|
||||
// TODO: MOVE TO PRIMITIVE
|
||||
Vertex vertices[] = {
|
||||
Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, -0.5f, -0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, 0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, 0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f },
|
||||
namespace Nuake{
|
||||
|
||||
Vertex{ glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, -0.5f, 0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f },
|
||||
|
||||
Vertex{ glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
// TODO: MOVE TO PRIMITIVE
|
||||
Vertex vertices[] = {
|
||||
Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, -0.5f, -0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, 0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, 0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f },
|
||||
|
||||
Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, 0.5f, -0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, -0.5f, 0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, -0.5f, 0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f },
|
||||
|
||||
Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, -0.5f, -0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, -0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, -0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
|
||||
Vertex{ glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, 0.5f, -0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
};
|
||||
Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, 0.5f, -0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, -0.5f, 0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f },
|
||||
|
||||
void MeshComponent::LoadModel(const std::string path) {
|
||||
//Assimp::Importer import;
|
||||
//const aiScene* scene = import.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs);
|
||||
//
|
||||
//if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
|
||||
//{
|
||||
// printf("ERROR::ASSIMP::");
|
||||
// return;
|
||||
//}
|
||||
//
|
||||
//ProcessNode(scene->mRootNode, scene);
|
||||
}
|
||||
unsigned int sphereVAO = 0;
|
||||
unsigned int indexCount;
|
||||
void MeshComponent::RenderSphere() {
|
||||
Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, -0.5f, -0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, -0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, -0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
|
||||
if (sphereVAO == 0)
|
||||
{
|
||||
glGenVertexArrays(1, &sphereVAO);
|
||||
Vertex{ glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, 0.5f, -0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
Vertex{ glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f },
|
||||
};
|
||||
|
||||
unsigned int vbo, ebo;
|
||||
glGenBuffers(1, &vbo);
|
||||
glGenBuffers(1, &ebo);
|
||||
void MeshComponent::LoadModel(const std::string path) {
|
||||
//Assimp::Importer import;
|
||||
//const aiScene* scene = import.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs);
|
||||
//
|
||||
//if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
|
||||
//{
|
||||
// printf("ERROR::ASSIMP::");
|
||||
// return;
|
||||
//}
|
||||
//
|
||||
//ProcessNode(scene->mRootNode, scene);
|
||||
}
|
||||
unsigned int sphereVAO = 0;
|
||||
unsigned int indexCount;
|
||||
void MeshComponent::RenderSphere() {
|
||||
|
||||
std::vector<glm::vec3> positions;
|
||||
std::vector<glm::vec2> uv;
|
||||
std::vector<glm::vec3> normals;
|
||||
std::vector<unsigned int> indices;
|
||||
|
||||
const unsigned int X_SEGMENTS = 64;
|
||||
const unsigned int Y_SEGMENTS = 64;
|
||||
const float PI = 3.14159265359;
|
||||
for (unsigned int y = 0; y <= Y_SEGMENTS; ++y)
|
||||
if (sphereVAO == 0)
|
||||
{
|
||||
for (unsigned int x = 0; x <= X_SEGMENTS; ++x)
|
||||
{
|
||||
float xSegment = (float)x / (float)X_SEGMENTS;
|
||||
float ySegment = (float)y / (float)Y_SEGMENTS;
|
||||
float xPos = std::cos(xSegment * 2.0f * PI) * std::sin(ySegment * PI);
|
||||
float yPos = std::cos(ySegment * PI);
|
||||
float zPos = std::sin(xSegment * 2.0f * PI) * std::sin(ySegment * PI);
|
||||
glGenVertexArrays(1, &sphereVAO);
|
||||
|
||||
positions.push_back(glm::vec3(xPos, yPos, zPos));
|
||||
uv.push_back(glm::vec2(xSegment, ySegment));
|
||||
normals.push_back(glm::vec3(xPos, yPos, zPos));
|
||||
}
|
||||
}
|
||||
unsigned int vbo, ebo;
|
||||
glGenBuffers(1, &vbo);
|
||||
glGenBuffers(1, &ebo);
|
||||
|
||||
bool oddRow = false;
|
||||
for (unsigned int y = 0; y < Y_SEGMENTS; ++y)
|
||||
{
|
||||
if (!oddRow) // even rows: y == 0, y == 2; and so on
|
||||
std::vector<glm::vec3> positions;
|
||||
std::vector<glm::vec2> uv;
|
||||
std::vector<glm::vec3> normals;
|
||||
std::vector<unsigned int> indices;
|
||||
|
||||
const unsigned int X_SEGMENTS = 64;
|
||||
const unsigned int Y_SEGMENTS = 64;
|
||||
const float PI = 3.14159265359;
|
||||
for (unsigned int y = 0; y <= Y_SEGMENTS; ++y)
|
||||
{
|
||||
for (unsigned int x = 0; x <= X_SEGMENTS; ++x)
|
||||
{
|
||||
indices.push_back(y * (X_SEGMENTS + 1) + x);
|
||||
indices.push_back((y + 1) * (X_SEGMENTS + 1) + x);
|
||||
float xSegment = (float)x / (float)X_SEGMENTS;
|
||||
float ySegment = (float)y / (float)Y_SEGMENTS;
|
||||
float xPos = std::cos(xSegment * 2.0f * PI) * std::sin(ySegment * PI);
|
||||
float yPos = std::cos(ySegment * PI);
|
||||
float zPos = std::sin(xSegment * 2.0f * PI) * std::sin(ySegment * PI);
|
||||
|
||||
positions.push_back(glm::vec3(xPos, yPos, zPos));
|
||||
uv.push_back(glm::vec2(xSegment, ySegment));
|
||||
normals.push_back(glm::vec3(xPos, yPos, zPos));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
bool oddRow = false;
|
||||
for (unsigned int y = 0; y < Y_SEGMENTS; ++y)
|
||||
{
|
||||
for (int x = X_SEGMENTS; x >= 0; --x)
|
||||
if (!oddRow) // even rows: y == 0, y == 2; and so on
|
||||
{
|
||||
indices.push_back((y + 1) * (X_SEGMENTS + 1) + x);
|
||||
indices.push_back(y * (X_SEGMENTS + 1) + x);
|
||||
for (unsigned int x = 0; x <= X_SEGMENTS; ++x)
|
||||
{
|
||||
indices.push_back(y * (X_SEGMENTS + 1) + x);
|
||||
indices.push_back((y + 1) * (X_SEGMENTS + 1) + x);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int x = X_SEGMENTS; x >= 0; --x)
|
||||
{
|
||||
indices.push_back((y + 1) * (X_SEGMENTS + 1) + x);
|
||||
indices.push_back(y * (X_SEGMENTS + 1) + x);
|
||||
}
|
||||
}
|
||||
oddRow = !oddRow;
|
||||
}
|
||||
indexCount = indices.size();
|
||||
|
||||
std::vector<float> data;
|
||||
for (std::size_t i = 0; i < positions.size(); ++i)
|
||||
{
|
||||
data.push_back(positions[i].x);
|
||||
data.push_back(positions[i].y);
|
||||
data.push_back(positions[i].z);
|
||||
|
||||
if (uv.size() > 0)
|
||||
{
|
||||
data.push_back(uv[i].x);
|
||||
data.push_back(uv[i].y);
|
||||
}
|
||||
if (normals.size() > 0)
|
||||
{
|
||||
data.push_back(normals[i].x);
|
||||
data.push_back(normals[i].y);
|
||||
data.push_back(normals[i].z);
|
||||
}
|
||||
}
|
||||
oddRow = !oddRow;
|
||||
}
|
||||
indexCount = indices.size();
|
||||
glBindVertexArray(sphereVAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(float), &data[0], GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
|
||||
float stride = (3 + 2 + 3) * sizeof(float);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
std::vector<float> data;
|
||||
for (std::size_t i = 0; i < positions.size(); ++i)
|
||||
{
|
||||
data.push_back(positions[i].x);
|
||||
data.push_back(positions[i].y);
|
||||
data.push_back(positions[i].z);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 3));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
if (uv.size() > 0)
|
||||
{
|
||||
data.push_back(uv[i].x);
|
||||
data.push_back(uv[i].y);
|
||||
}
|
||||
if (normals.size() > 0)
|
||||
{
|
||||
data.push_back(normals[i].x);
|
||||
data.push_back(normals[i].y);
|
||||
data.push_back(normals[i].z);
|
||||
}
|
||||
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 5));
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 8));
|
||||
glEnableVertexAttribArray(3);
|
||||
}
|
||||
|
||||
glBindVertexArray(sphereVAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(float), &data[0], GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
|
||||
float stride = (3 + 2 + 3) * sizeof(float);
|
||||
glDrawElements(GL_TRIANGLE_STRIP, indexCount, GL_UNSIGNED_INT, 0);
|
||||
|
||||
}
|
||||
|
||||
//void MeshComponent::ProcessNode(aiNode * node, const aiScene* scene)
|
||||
//{
|
||||
/// process all the node's meshes (if any)
|
||||
//or (unsigned int i = 0; i < node->mNumMeshes; i++)
|
||||
//
|
||||
// aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
|
||||
// meshes.push_back(ProcessNode(mesh, scene));
|
||||
//
|
||||
/// then do the same for each of its children
|
||||
//or (unsigned int i = 0; i < node->mNumChildren; i++)
|
||||
//
|
||||
// ProcessNode(node->mChildren[i], scene);
|
||||
//
|
||||
//}
|
||||
|
||||
MeshComponent::MeshComponent() {
|
||||
//BuildTangents();
|
||||
|
||||
// Setup buffers
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
glGenBuffers(1, &VBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
|
||||
// Position
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
|
||||
// UV
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 3));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
// Normal
|
||||
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 5));
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 8));
|
||||
// Tangent
|
||||
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 8));
|
||||
glEnableVertexAttribArray(3);
|
||||
}
|
||||
|
||||
glBindVertexArray(sphereVAO);
|
||||
glDrawElements(GL_TRIANGLE_STRIP, indexCount, GL_UNSIGNED_INT, 0);
|
||||
// Bitangent
|
||||
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 11));
|
||||
glEnableVertexAttribArray(4);
|
||||
|
||||
}
|
||||
// Texture
|
||||
glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 14));
|
||||
glEnableVertexAttribArray(5);
|
||||
|
||||
//void MeshComponent::ProcessNode(aiNode * node, const aiScene* scene)
|
||||
//{
|
||||
/// process all the node's meshes (if any)
|
||||
//or (unsigned int i = 0; i < node->mNumMeshes; i++)
|
||||
//
|
||||
// aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
|
||||
// meshes.push_back(ProcessNode(mesh, scene));
|
||||
//
|
||||
/// then do the same for each of its children
|
||||
//or (unsigned int i = 0; i < node->mNumChildren; i++)
|
||||
//
|
||||
// ProcessNode(node->mChildren[i], scene);
|
||||
//
|
||||
//}
|
||||
//m_Material = MaterialManager::Get()->LoadMaterial("Planks");
|
||||
|
||||
MeshComponent::MeshComponent() {
|
||||
//BuildTangents();
|
||||
}
|
||||
|
||||
// Setup buffers
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glBindVertexArray(VAO);
|
||||
void MeshComponent::BuildTangents()
|
||||
{
|
||||
for (int i = 0; i < 36; i += 3) {
|
||||
glm::vec3 pos1 = vertices[i].position;
|
||||
glm::vec3 pos2 = vertices[i + 1].position;
|
||||
glm::vec3 pos3 = vertices[i + 2].position;
|
||||
|
||||
glGenBuffers(1, &VBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glm::vec2 uv1 = vertices[i].uv;
|
||||
glm::vec2 uv2 = vertices[i + 1].uv;
|
||||
glm::vec2 uv3 = vertices[i + 2].uv;
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
glm::vec3 edge1 = pos2 - pos1;
|
||||
glm::vec3 edge2 = pos3 - pos1;
|
||||
glm::vec2 deltaUV1 = uv2 - uv1;
|
||||
glm::vec2 deltaUV2 = uv3 - uv1;
|
||||
|
||||
// Position
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
// UV
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 3));
|
||||
glEnableVertexAttribArray(1);
|
||||
float f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y);
|
||||
|
||||
// Normal
|
||||
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 5));
|
||||
glEnableVertexAttribArray(2);
|
||||
for (int j = 0; i < 3; i++)
|
||||
{
|
||||
vertices[i + j].tangent.x = f * (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x);
|
||||
vertices[i + j].tangent.y = f * (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y);
|
||||
vertices[i + j].tangent.z = f * (deltaUV2.y * edge1.z - deltaUV1.y * edge2.z);
|
||||
|
||||
// Tangent
|
||||
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 8));
|
||||
glEnableVertexAttribArray(3);
|
||||
|
||||
// Bitangent
|
||||
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 11));
|
||||
glEnableVertexAttribArray(4);
|
||||
|
||||
// Texture
|
||||
glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 14));
|
||||
glEnableVertexAttribArray(5);
|
||||
|
||||
//m_Material = MaterialManager::Get()->LoadMaterial("Planks");
|
||||
|
||||
}
|
||||
|
||||
void MeshComponent::BuildTangents()
|
||||
{
|
||||
for (int i = 0; i < 36; i += 3) {
|
||||
glm::vec3 pos1 = vertices[i].position;
|
||||
glm::vec3 pos2 = vertices[i + 1].position;
|
||||
glm::vec3 pos3 = vertices[i + 2].position;
|
||||
|
||||
glm::vec2 uv1 = vertices[i].uv;
|
||||
glm::vec2 uv2 = vertices[i + 1].uv;
|
||||
glm::vec2 uv3 = vertices[i + 2].uv;
|
||||
|
||||
glm::vec3 edge1 = pos2 - pos1;
|
||||
glm::vec3 edge2 = pos3 - pos1;
|
||||
glm::vec2 deltaUV1 = uv2 - uv1;
|
||||
glm::vec2 deltaUV2 = uv3 - uv1;
|
||||
|
||||
float f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y);
|
||||
|
||||
for (int j = 0; i < 3; i++)
|
||||
{
|
||||
vertices[i + j].tangent.x = f * (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x);
|
||||
vertices[i + j].tangent.y = f * (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y);
|
||||
vertices[i + j].tangent.z = f * (deltaUV2.y * edge1.z - deltaUV1.y * edge2.z);
|
||||
|
||||
vertices[i + j].bitangent.x = f * (-deltaUV2.x * edge1.x + deltaUV1.x * edge2.x);
|
||||
vertices[i + j].bitangent.y = f * (-deltaUV2.x * edge1.y + deltaUV1.x * edge2.y);
|
||||
vertices[i + j].bitangent.z = f * (-deltaUV2.x * edge1.z + deltaUV1.x * edge2.z);
|
||||
vertices[i + j].bitangent.x = f * (-deltaUV2.x * edge1.x + deltaUV1.x * edge2.x);
|
||||
vertices[i + j].bitangent.y = f * (-deltaUV2.x * edge1.y + deltaUV1.x * edge2.y);
|
||||
vertices[i + j].bitangent.z = f * (-deltaUV2.x * edge1.z + deltaUV1.x * edge2.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MeshComponent::SetMaterial(const std::string materialName)
|
||||
{
|
||||
m_Material = MaterialManager::Get()->LoadMaterial(materialName);
|
||||
}
|
||||
|
||||
void MeshComponent::Draw(glm::mat4 projection, glm::mat4 view, glm::mat4 transform) {
|
||||
|
||||
Renderer::m_Shader->SetUniformMat4f("u_Model", transform);
|
||||
|
||||
m_Material->Bind();
|
||||
|
||||
//RenderSphere();
|
||||
glBindVertexArray(VAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
}
|
||||
|
||||
void MeshComponent::DrawEditor() {
|
||||
int choice = 0;
|
||||
ImGui::Combo("Material", (int*)&choice, "Marble\0Copper\0Gold\0Paving\0Planks\0Default Material");
|
||||
|
||||
|
||||
|
||||
void MeshComponent::SetMaterial(const std::string materialName)
|
||||
{
|
||||
m_Material = MaterialManager::Get()->LoadMaterial(materialName);
|
||||
}
|
||||
|
||||
void MeshComponent::Draw(glm::mat4 projection, glm::mat4 view, glm::mat4 transform) {
|
||||
|
||||
Renderer::m_Shader->SetUniformMat4f("u_Model", transform);
|
||||
|
||||
m_Material->Bind();
|
||||
|
||||
//RenderSphere();
|
||||
glBindVertexArray(VAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
}
|
||||
|
||||
void MeshComponent::DrawEditor() {
|
||||
int choice = 0;
|
||||
ImGui::Combo("Material", (int*)&choice, "Marble\0Copper\0Gold\0Paving\0Planks\0Default Material");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,22 +3,24 @@
|
||||
#include <glm\ext\matrix_float4x4.hpp>
|
||||
#include "BaseComponent.h"
|
||||
|
||||
class MeshComponent {
|
||||
namespace Nuake {
|
||||
class MeshComponent {
|
||||
|
||||
private:
|
||||
unsigned int VAO;
|
||||
unsigned int VBO;
|
||||
Ref<Material> m_Material;
|
||||
private:
|
||||
unsigned int VAO;
|
||||
unsigned int VBO;
|
||||
Ref<Material> m_Material;
|
||||
|
||||
void BuildTangents();
|
||||
public:
|
||||
void LoadModel(const std::string path);
|
||||
//void ProcessNode(aiNode* node, const aiScene* scene);
|
||||
MeshComponent();
|
||||
void BuildTangents();
|
||||
public:
|
||||
void LoadModel(const std::string path);
|
||||
//void ProcessNode(aiNode* node, const aiScene* scene);
|
||||
MeshComponent();
|
||||
|
||||
void SetMaterial(const std::string materialName);
|
||||
void Draw(glm::mat4 projection, glm::mat4 view, glm::mat4 transform);
|
||||
void DrawEditor();
|
||||
void SetMaterial(const std::string materialName);
|
||||
void Draw(glm::mat4 projection, glm::mat4 view, glm::mat4 transform);
|
||||
void DrawEditor();
|
||||
|
||||
void RenderSphere();
|
||||
};
|
||||
void RenderSphere();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,136 +1,139 @@
|
||||
#include "ModelComponent.h"
|
||||
#include "../../../Rendering/Textures/Material.h"
|
||||
#include "../../../Rendering/Renderer.h"
|
||||
#include "../../../Core/TextureManager.h"
|
||||
#include "src/Rendering/Textures/Material.h"
|
||||
#include "src/Rendering/Renderer.h"
|
||||
#include "src/Core/TextureManager.h"
|
||||
|
||||
void ModelComponent::Draw()
|
||||
{
|
||||
for (auto m : meshes) {
|
||||
m.Draw();
|
||||
}
|
||||
}
|
||||
|
||||
void ModelComponent::LoadModel()
|
||||
{
|
||||
this->meshes.clear();
|
||||
Assimp::Importer import;
|
||||
import.SetPropertyFloat("PP_GSN_MAX_SMOOTHING_ANGLE", 90);
|
||||
const aiScene* scene = import.ReadFile(FileSystem::Root + ModelPath, aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_CalcTangentSpace);
|
||||
|
||||
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
|
||||
namespace Nuake {
|
||||
void ModelComponent::Draw()
|
||||
{
|
||||
Logger::Log("ASSIMP! Failed to load model" + std::string(import.GetErrorString()), CRITICAL);
|
||||
return;
|
||||
}
|
||||
|
||||
ProcessNode(scene->mRootNode, scene);
|
||||
}
|
||||
|
||||
void ModelComponent::ProcessNode(aiNode* node, const aiScene* scene)
|
||||
{
|
||||
// process all the node's meshes (if any)
|
||||
for (unsigned int i = 0; i < node->mNumMeshes; i++)
|
||||
{
|
||||
aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
|
||||
meshes.push_back(ProcessMesh(mesh, scene));
|
||||
}
|
||||
// then do the same for each of its children
|
||||
for (unsigned int i = 0; i < node->mNumChildren; i++)
|
||||
{
|
||||
ProcessNode(node->mChildren[i], scene);
|
||||
}
|
||||
}
|
||||
|
||||
Mesh ModelComponent::ProcessMesh(aiMesh* mesh, const aiScene* scene)
|
||||
{
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<unsigned int> indices;
|
||||
std::vector<Texture> textures;
|
||||
|
||||
for (unsigned int i = 0; i < mesh->mNumVertices; i++)
|
||||
{
|
||||
Vertex vertex;
|
||||
vertex.texture = 1.0f;
|
||||
|
||||
glm::vec3 vector;
|
||||
vector.x = mesh->mVertices[i].x;
|
||||
vector.y = mesh->mVertices[i].y;
|
||||
vector.z = mesh->mVertices[i].z;
|
||||
vertex.position = vector;
|
||||
|
||||
vector.x = mesh->mNormals[i].x;
|
||||
vector.y = mesh->mNormals[i].y;
|
||||
vector.z = mesh->mNormals[i].z;
|
||||
vertex.normal = vector;
|
||||
|
||||
vector.x = mesh->mTangents[i].x;
|
||||
vector.y = mesh->mTangents[i].y;
|
||||
vector.z = mesh->mTangents[i].z;
|
||||
vertex.tangent = vector;
|
||||
|
||||
vector.x = mesh->mBitangents[i].x;
|
||||
vector.y = mesh->mBitangents[i].y;
|
||||
vector.z = mesh->mBitangents[i].z;
|
||||
vertex.bitangent = vector;
|
||||
|
||||
if (mesh->mTextureCoords[0]) // does the mesh contain texture coordinates?
|
||||
{
|
||||
glm::vec2 vec;
|
||||
vec.x = mesh->mTextureCoords[0][i].x;
|
||||
vec.y = mesh->mTextureCoords[0][i].y;
|
||||
vertex.uv = vec;
|
||||
for (auto m : meshes) {
|
||||
m.Draw();
|
||||
}
|
||||
else
|
||||
vertex.uv = glm::vec2(0.0f, 0.0f);
|
||||
|
||||
vertices.push_back(vertex);
|
||||
}
|
||||
// process indices
|
||||
for (unsigned int i = 0; i < mesh->mNumFaces; i++)
|
||||
|
||||
void ModelComponent::LoadModel()
|
||||
{
|
||||
aiFace face = mesh->mFaces[i];
|
||||
for (unsigned int j = 0; j < face.mNumIndices; j++)
|
||||
indices.push_back(face.mIndices[j]);
|
||||
this->meshes.clear();
|
||||
Assimp::Importer import;
|
||||
import.SetPropertyFloat("PP_GSN_MAX_SMOOTHING_ANGLE", 90);
|
||||
const aiScene* scene = import.ReadFile(FileSystem::Root + ModelPath, aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_CalcTangentSpace);
|
||||
|
||||
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
|
||||
{
|
||||
Logger::Log("ASSIMP! Failed to load model" + std::string(import.GetErrorString()), CRITICAL);
|
||||
return;
|
||||
}
|
||||
|
||||
ProcessNode(scene->mRootNode, scene);
|
||||
}
|
||||
// process material
|
||||
if (mesh->mMaterialIndex >= 0)
|
||||
|
||||
void ModelComponent::ProcessNode(aiNode* node, const aiScene* scene)
|
||||
{
|
||||
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
|
||||
aiString str;
|
||||
std::string directory = FileSystem::Root + this->ModelPath + "/../";
|
||||
material->GetTexture(aiTextureType_DIFFUSE, 0, &str);
|
||||
Ref<Material> newMaterial = CreateRef<Material>(TextureManager::Get()->GetTexture(directory + str.C_Str()));
|
||||
// process all the node's meshes (if any)
|
||||
for (unsigned int i = 0; i < node->mNumMeshes; i++)
|
||||
{
|
||||
aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
|
||||
meshes.push_back(ProcessMesh(mesh, scene));
|
||||
}
|
||||
// then do the same for each of its children
|
||||
for (unsigned int i = 0; i < node->mNumChildren; i++)
|
||||
{
|
||||
ProcessNode(node->mChildren[i], scene);
|
||||
}
|
||||
}
|
||||
|
||||
//material->GetTexture(aiTextureType_NORMALS, 0, &str);
|
||||
//newMaterial->SetNormal(TextureManager::Get()->GetTexture(directory + str.C_Str()));
|
||||
//
|
||||
//material->GetTexture(aiTextureType_METALNESS, 0, &str);
|
||||
//newMaterial->SetMetalness(TextureManager::Get()->GetTexture(directory + str.C_Str()));
|
||||
//
|
||||
//material->GetTexture(aiTextureType_DIFFUSE_ROUGHNESS, 0, &str);
|
||||
//newMaterial->SetRoughness(TextureManager::Get()->GetTexture(directory + str.C_Str()));
|
||||
Mesh ModelComponent::ProcessMesh(aiMesh* mesh, const aiScene* scene)
|
||||
{
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<unsigned int> indices;
|
||||
std::vector<Texture> textures;
|
||||
|
||||
//material->GetTexture(aiTextureType_DISPLACEMENT, 0, &str);
|
||||
//newMaterial->SetDisplacement(TextureManager::Get()->GetTexture(directory + str.C_Str()));
|
||||
for (unsigned int i = 0; i < mesh->mNumVertices; i++)
|
||||
{
|
||||
Vertex vertex;
|
||||
vertex.texture = 1.0f;
|
||||
|
||||
//material->GetTexture(aiTextureType_AMBIENT_OCCLUSION, 0, &str);
|
||||
//newMaterial->SetAO(TextureManager::Get()->GetTexture(directory + str.C_Str()));
|
||||
glm::vec3 vector;
|
||||
vector.x = mesh->mVertices[i].x;
|
||||
vector.y = mesh->mVertices[i].y;
|
||||
vector.z = mesh->mVertices[i].z;
|
||||
vertex.position = vector;
|
||||
|
||||
return Mesh(vertices, indices, newMaterial);
|
||||
vector.x = mesh->mNormals[i].x;
|
||||
vector.y = mesh->mNormals[i].y;
|
||||
vector.z = mesh->mNormals[i].z;
|
||||
vertex.normal = vector;
|
||||
|
||||
vector.x = mesh->mTangents[i].x;
|
||||
vector.y = mesh->mTangents[i].y;
|
||||
vector.z = mesh->mTangents[i].z;
|
||||
vertex.tangent = vector;
|
||||
|
||||
vector.x = mesh->mBitangents[i].x;
|
||||
vector.y = mesh->mBitangents[i].y;
|
||||
vector.z = mesh->mBitangents[i].z;
|
||||
vertex.bitangent = vector;
|
||||
|
||||
if (mesh->mTextureCoords[0]) // does the mesh contain texture coordinates?
|
||||
{
|
||||
glm::vec2 vec;
|
||||
vec.x = mesh->mTextureCoords[0][i].x;
|
||||
vec.y = mesh->mTextureCoords[0][i].y;
|
||||
vertex.uv = vec;
|
||||
}
|
||||
else
|
||||
vertex.uv = glm::vec2(0.0f, 0.0f);
|
||||
|
||||
vertices.push_back(vertex);
|
||||
}
|
||||
// process indices
|
||||
for (unsigned int i = 0; i < mesh->mNumFaces; i++)
|
||||
{
|
||||
aiFace face = mesh->mFaces[i];
|
||||
for (unsigned int j = 0; j < face.mNumIndices; j++)
|
||||
indices.push_back(face.mIndices[j]);
|
||||
}
|
||||
// process material
|
||||
if (mesh->mMaterialIndex >= 0)
|
||||
{
|
||||
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
|
||||
aiString str;
|
||||
std::string directory = FileSystem::Root + this->ModelPath + "/../";
|
||||
material->GetTexture(aiTextureType_DIFFUSE, 0, &str);
|
||||
Ref<Material> newMaterial = CreateRef<Material>(TextureManager::Get()->GetTexture(directory + str.C_Str()));
|
||||
|
||||
//material->GetTexture(aiTextureType_NORMALS, 0, &str);
|
||||
//newMaterial->SetNormal(TextureManager::Get()->GetTexture(directory + str.C_Str()));
|
||||
//
|
||||
//material->GetTexture(aiTextureType_METALNESS, 0, &str);
|
||||
//newMaterial->SetMetalness(TextureManager::Get()->GetTexture(directory + str.C_Str()));
|
||||
//
|
||||
//material->GetTexture(aiTextureType_DIFFUSE_ROUGHNESS, 0, &str);
|
||||
//newMaterial->SetRoughness(TextureManager::Get()->GetTexture(directory + str.C_Str()));
|
||||
|
||||
//material->GetTexture(aiTextureType_DISPLACEMENT, 0, &str);
|
||||
//newMaterial->SetDisplacement(TextureManager::Get()->GetTexture(directory + str.C_Str()));
|
||||
|
||||
//material->GetTexture(aiTextureType_AMBIENT_OCCLUSION, 0, &str);
|
||||
//newMaterial->SetAO(TextureManager::Get()->GetTexture(directory + str.C_Str()));
|
||||
|
||||
return Mesh(vertices, indices, newMaterial);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Texture*> ModelComponent::LoadMaterialTextures(aiMaterial* mat, aiTextureType type)
|
||||
{
|
||||
std::vector<Texture*> textures;
|
||||
for (unsigned int i = 0; i < mat->GetTextureCount(type); i++)
|
||||
{
|
||||
aiString str;
|
||||
mat->GetTexture(type, i, &str);
|
||||
std::string fixedStr = std::string(str.C_Str());
|
||||
|
||||
Texture* texture = new Texture(directory + fixedStr);
|
||||
textures.push_back(texture);
|
||||
}
|
||||
return textures;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Texture*> ModelComponent::LoadMaterialTextures(aiMaterial* mat, aiTextureType type)
|
||||
{
|
||||
std::vector<Texture*> textures;
|
||||
for (unsigned int i = 0; i < mat->GetTextureCount(type); i++)
|
||||
{
|
||||
aiString str;
|
||||
mat->GetTexture(type, i, &str);
|
||||
std::string fixedStr = std::string(str.C_Str());
|
||||
|
||||
Texture* texture = new Texture(directory + fixedStr);
|
||||
textures.push_back(texture);
|
||||
}
|
||||
return textures;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user