Major cleanup.

Moved to namespace
Cleanup includes
This commit is contained in:
Antoine Pilote
2021-07-11 18:56:44 -04:00
parent f77bef6b28
commit 0c6ed48bbd
174 changed files with 11772 additions and 11296 deletions

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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();
};
}

View File

@@ -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();
}

View File

@@ -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();
};
}

View File

@@ -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();
}
}

View File

@@ -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();
};
}

View File

@@ -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;
}

View File

@@ -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();
};

View File

@@ -1,5 +1,8 @@
#pragma once
#include <memory>
#include <map>
#include <string>
#include <vector>
template<typename T>
using Scope = std::unique_ptr<T>;

View File

@@ -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;
}

View File

@@ -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();
};
}

View File

@@ -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;
}
}
}

View File

@@ -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;
};
}

View File

@@ -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;
}

View File

@@ -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.
};
}

View File

@@ -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();
}

View File

@@ -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;
}
};
}

View File

@@ -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;
}

View File

@@ -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();
}
};
}

View File

@@ -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();
}

View File

@@ -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;
};
}

View File

@@ -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;
}
}
}
}

View File

@@ -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();
};
}
}

View File

@@ -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();
}
}
}

View File

@@ -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; }
};
}
}

View File

@@ -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;
}

View File

@@ -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();
};
}

View File

@@ -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;
}

View File

@@ -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);
};
}

View File

@@ -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;
}
}
}

View File

@@ -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;
};
}

View File

@@ -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;
};

View File

@@ -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);
};
}

View File

@@ -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)
{
}
}
}

View File

@@ -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;
}
}

View File

@@ -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);
};
}

View File

@@ -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;
}
};
}

View 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();
}
}

View 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);
};
}

View 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();
}
}

View 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);
};
}

View File

@@ -5,12 +5,8 @@ class UniformBuffer {
private:
unsigned int RendererID;
public:
UniformBuffer();
void Bind();
void Unbind();
};

View File

@@ -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;
}

View File

@@ -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;
};

View File

@@ -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();
}

View File

@@ -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);
};

View File

@@ -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();
}

View File

@@ -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);
};

View File

@@ -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);
}

View File

@@ -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();
};
}

View File

@@ -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;
}

View File

@@ -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;
};

View File

@@ -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;
};
}

View File

@@ -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);
}
}

View File

@@ -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);
};
}

View File

@@ -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()
{
}

View File

@@ -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();
};
}

View File

@@ -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);
}
}

View File

@@ -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);
};
}

View File

@@ -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];
}
}

View File

@@ -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);
};
}

View File

@@ -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);
}

View File

@@ -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();
};

View File

@@ -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);
}

View File

@@ -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.
};
}

View File

@@ -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() {
}

View File

@@ -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; }
};
}

View File

@@ -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);
}

View File

@@ -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; }
};
}

View File

@@ -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);
}

View File

@@ -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; }
};
}

View File

@@ -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);
}
}

View File

@@ -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; }
};
}

View File

@@ -0,0 +1,12 @@
#pragma once
#include <src/Core/Maths.h>
namespace Nuake
{
struct Transform
{
Vector3 Translation;
Vector3 Rotation;
Vector3 Scale;
};
}

View File

@@ -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;
};
}

View File

@@ -1,5 +1,4 @@
#pragma once
#include "BaseClass.h"
#include "ClassProperty.h"
#include <string>
#include <vector>

View File

@@ -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();
};
}

View File

@@ -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++;
}
}
}

View File

@@ -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);
};
}

View File

@@ -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;
}
}

View File

@@ -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;
}
};
};
}

View File

@@ -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;
}

View File

@@ -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
}

View File

@@ -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;
};
}

View File

@@ -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>>();
}
};
}

View File

@@ -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;
};
}

View File

@@ -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);
}
}

View File

@@ -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);
}
};
}

View File

@@ -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;
}
};
}

View File

@@ -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);
}

View File

@@ -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;
}
};
}

View File

@@ -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;
};
}

View File

@@ -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");
}
}

View File

@@ -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();
};
}

View File

@@ -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