diff --git a/editor/include/editor.hpp b/editor/include/editor.hpp index edf230b..0820057 100755 --- a/editor/include/editor.hpp +++ b/editor/include/editor.hpp @@ -1,9 +1,12 @@ #ifndef EDITOR_HPP #define EDITOR_HPP +#include #include +#include "open_engine/renderer/renderer3d.hpp" #include "open_engine/scene/components.hpp" +#include "open_engine/scene/scene_serializer.hpp" #include "panels/content_browser.hpp" #include "panels/scene_hierarchy.hpp" @@ -101,6 +104,14 @@ namespace OpenEngine { cube.AddComponent(mesh); + Entity quad = scene->CreateEntity("quad"); + quad.AddComponent(); + quad.GetComponents().translation = {0, 0, 0}; + + Ref quad_mesh = CreateQuad(quad, true); + + quad.AddComponent(quad_mesh); + Entity cube2 = scene->CreateEntity("cube2"); cube2.AddComponent(); cube2.GetComponents().translation = {2, 0, 0}; @@ -108,7 +119,6 @@ namespace OpenEngine { Ref mesh2 = CreateCube(cube2); cube2.AddComponent(mesh2); - OE_DEBUG("cubes is like {} {}", (uint32_t)cube, (uint32_t)cube2); /* auto view = scene->GetRegistry().view(); @@ -217,6 +227,8 @@ namespace OpenEngine { } framebuffer->Unbind(); + + scene->UpdateEntities(); } bool EditorKeyBinds(KeyPressedEvent& event) @@ -227,6 +239,29 @@ namespace OpenEngine { bool shift = Input::IsKeyPressed(Key::LeftShift) || Input::IsKeyPressed(Key::RightShift); switch(event.GetKeyCode()) { + case KeyCode::S: { + if (control) { + std::string file = FileDialogs::SaveFile("useless"); + OE_TRACE("saving to filename: {}", file); + SaveScene(file); + } + break; + } + case KeyCode::N: { + if (control) { + scene = CreateRef(); + scene->OnViewportResize((uint32_t)viewport_size.x, (uint32_t)viewport_size.y); + scene_hierarchy.Init(scene); + } + break; + } + case KeyCode::O: { + if (control) { + std::string file = FileDialogs::OpenFile("useless"); + OE_DEBUG("loading scene: {}", file); + OpenScene(file);} + break; + } case KeyCode::Q: { guizmo_operation = -1; break; @@ -243,6 +278,12 @@ namespace OpenEngine { guizmo_operation = ImGuizmo::OPERATION::SCALE; break; } + case KeyCode::Delete: { + scene->MarkEntityForDeletion(selected_entity); + scene_hierarchy.ClearSelection(); + selected_entity = {}; + break; + } default: break; } @@ -428,6 +469,14 @@ namespace OpenEngine { } } + void SaveScene(const std::string& file) + { + if (!file.empty()) { + SceneSerializer serializer(scene); + serializer.Serialize(file); + } + } + void DrawPlayBar() { ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, { 0, 2 }); @@ -478,10 +527,7 @@ namespace OpenEngine { if (ImGui::MenuItem("Save Scene As", "Ctrl+S")) { std::string file = FileDialogs::SaveFile("useless"); OE_TRACE("saving to filename: {}", file); - if (!file.empty()) { - SceneSerializer serializer(scene); - serializer.Serialize(file); - } + SaveScene(file); } if (ImGui::MenuItem("Open Scene", "Ctrl+O")) { std::string file = FileDialogs::OpenFile("useless"); @@ -560,24 +606,3 @@ class EditorApp : public OpenEngine::Application }; #endif // EDITOR_HPP - -/* -#include -#include - -std::string OpenFile() { - char buffer[1024]; - // This command opens a native GTK file picker and returns the path - FILE* pipe = popen("zenity --file-selection", "r"); - if (!pipe) return ""; - - if (fgets(buffer, sizeof(buffer), pipe) != NULL) { - std::string path = buffer; - path.erase(path.find_last_not_of("\n") + 1); // Clean newline - pclose(pipe); - return path; - } - pclose(pipe); - return ""; -} -*/ diff --git a/editor/include/panels/scene_hierarchy.hpp b/editor/include/panels/scene_hierarchy.hpp index de15b38..fbbe4db 100644 --- a/editor/include/panels/scene_hierarchy.hpp +++ b/editor/include/panels/scene_hierarchy.hpp @@ -27,6 +27,7 @@ namespace OpenEngine { Entity GetSelectedEntity() const { return selected_context; }; void SetSelectedEntity(Entity entity) { selected_context = entity; }; + void ClearSelection() { selected_context = {}; }; private: void DrawEntityNode(Entity& entity); diff --git a/editor/src/panels/scene_hierarchy.cpp b/editor/src/panels/scene_hierarchy.cpp index 9d734c0..f00d60e 100644 --- a/editor/src/panels/scene_hierarchy.cpp +++ b/editor/src/panels/scene_hierarchy.cpp @@ -133,7 +133,6 @@ namespace OpenEngine { { auto& tag = entity.GetComponents().tag; - bool entity_marked_deletion = false; if (renamed_entity == entity && selected_context == entity) { char buffer[255]; std::memset(buffer, 0, sizeof(buffer)); @@ -161,8 +160,10 @@ namespace OpenEngine { bool opened = ImGui::TreeNodeEx((void*)(uint64_t)(uint32_t)entity, flags, "%s", tag.c_str()); if (ImGui::BeginPopupContextItem()) { - if (ImGui::MenuItem("Delete entity")) - entity_marked_deletion = true; + if (ImGui::MenuItem("Delete entity")) { + scene->MarkEntityForDeletion(entity); + selected_context = {}; + } ImGui::EndPopup(); } @@ -189,12 +190,6 @@ namespace OpenEngine { if (opened) ImGui::TreePop(); } - - if (entity_marked_deletion) { - scene->DeleteEntity(entity); - if (selected_context == entity) - selected_context = {}; - } } void SceneHierarchy::DrawComponents(Entity& entity) diff --git a/open_engine/include/open_engine/renderer/renderer3d.hpp b/open_engine/include/open_engine/renderer/renderer3d.hpp index e4647d9..c79cd39 100644 --- a/open_engine/include/open_engine/renderer/renderer3d.hpp +++ b/open_engine/include/open_engine/renderer/renderer3d.hpp @@ -3,8 +3,8 @@ #include "open_engine/renderer/editor_camera.hpp" #include "open_engine/renderer/vertex_array.hpp" -#include "open_engine/renderer/camera.hpp" #include "open_engine/renderer/buffer.hpp" +#include "open_engine/scene/scene_camera.hpp" #include namespace OpenEngine { @@ -33,6 +33,7 @@ namespace OpenEngine { Ref CreateMesh(const std::vector& vertices, const std::vector& indices); Ref CreateCube(uint32_t id = -1); + Ref CreateQuad(uint32_t id = -1, bool back_face = false); // ================================================== class Renderer3D @@ -41,20 +42,11 @@ namespace OpenEngine { static void Init(); static void Shutdown(); - static void BeginScene(const Camera& camera, const glm::mat4& transform); + static void BeginScene(const SceneCamera& camera, const glm::mat4& transform); static void BeginScene(const EditorCamera& camera); static void EndScene(); static void DrawMesh(const Ref& mesh, const glm::mat4& transform); - - /* - static void DrawCube(const glm::mat4& transform, const glm::vec4& color, - int entity_id); - static void DrawCube(const glm::mat4& transform, Ref, - int entity_id); - static void DrawCube(const glm::mat4& transform, Ref, - const glm::vec4& color, int entity_id); - */ }; } diff --git a/open_engine/include/open_engine/scene/scene.hpp b/open_engine/include/open_engine/scene/scene.hpp index c10800f..cf299a8 100644 --- a/open_engine/include/open_engine/scene/scene.hpp +++ b/open_engine/include/open_engine/scene/scene.hpp @@ -3,6 +3,7 @@ #include "open_engine/renderer/editor_camera.hpp" +#include #include #include @@ -13,11 +14,14 @@ namespace OpenEngine { class Scene { public: - Scene() {}; + Scene() = default; ~Scene() = default; Entity CreateEntity(const std::string& name = std::string()); - void DeleteEntity(Entity entity); + void DeleteEntity(entt::entity entity); + void MarkEntityForDeletion(Entity entity); + + void UpdateEntities(); void OnUpdateRuntime(); void OnUpdateEditor(EditorCamera& camera); @@ -36,6 +40,8 @@ namespace OpenEngine { uint32_t viewport_width = 0, viewport_height = 0; + std::vector entities_to_be_deleted; + friend class SceneSerializer; friend class Entity; }; diff --git a/open_engine/src/open_engine/renderer/renderer3d.cpp b/open_engine/src/open_engine/renderer/renderer3d.cpp index 5b5e1a4..cc14723 100644 --- a/open_engine/src/open_engine/renderer/renderer3d.cpp +++ b/open_engine/src/open_engine/renderer/renderer3d.cpp @@ -1,4 +1,5 @@ #include "logging.hpp" +#include "scene/scene_camera.hpp" #include #include @@ -29,10 +30,9 @@ namespace OpenEngine { mesh->vertices = vertices; mesh->indices = indices; - mesh->index_buffer = IndexBuffer::Create(indices.data(), indices.size()); mesh->vertex_array = VertexArray::Create(); - mesh->vertex_buffer = VertexBuffer::Create(vertices.size() * sizeof(MeshVertex)); + mesh->vertex_buffer = VertexBuffer::Create(vertices.size() * sizeof(MeshVertex)); mesh->vertex_buffer->SetData(vertices.data(), vertices.size() * sizeof(MeshVertex)); BufferLayout layout = { @@ -42,61 +42,108 @@ namespace OpenEngine { { ShaderDataType::Float2, "a_TexCoord" }, { ShaderDataType::Int, "a_EntityID"} }; - mesh->vertex_buffer->SetLayout(layout); - mesh->vertex_array->AddVertexBuffer(mesh->vertex_buffer); + + mesh->index_buffer = IndexBuffer::Create(indices.data(), indices.size()); mesh->vertex_array->SetIndexBuffer(mesh->index_buffer); return mesh; } + Ref CreateQuad(uint32_t id, bool back_face) + { + OE_PROFILE_FUNCTION(); + OE_CORE_DEBUG("Creating quad with id {}.", id); + + std::vector vertices; + std::vector indices; + if (back_face) { + vertices = { + // Front face (normal 0, 0, 1) + {{-0.5f, -0.5f, 0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {0,0}, id}, + {{-0.5f, 0.5f, 0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {0,1}, id}, + {{ 0.5f, 0.5f, 0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {1,1}, id}, + {{ 0.5f, -0.5f, 0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {1,0}, id}, + + // Back face (normal 0, 0, -1) + {{-0.5f, -0.5f, -0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,-1}, {0,0}, id}, + {{-0.5f, 0.5f, -0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,-1}, {0,1}, id}, + {{ 0.5f, 0.5f, -0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,-1}, {1,1}, id}, + {{ 0.5f, -0.5f, -0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,-1}, {1,0}, id} + }; + + indices = { + // Front face (z=0.5) + 0, 2, 1, 0, 3, 2, + // Back face (z=-0.5) + 4, 5, 6, 4, 6, 7 + }; + } else { + vertices = { + // Front face (normal 0, 0, 1) + {{-0.5f, -0.5f, 0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {0,0}, id}, + {{-0.5f, 0.5f, 0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {0,1}, id}, + {{ 0.5f, 0.5f, 0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {1,1}, id}, + {{ 0.5f, -0.5f, 0.0f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {1,0}, id} + }; + + indices = { + // Front face (z=0.5) + 0, 2, 1, 0, 3, 2 + }; + } + + return CreateMesh(vertices, indices); + } + Ref CreateCube(uint32_t id) { + OE_PROFILE_FUNCTION(); OE_CORE_DEBUG("Creating cube with id {}.", id); std::vector vertices = { - // Back face (normal 0, 0, -1) - {{-0.5f, -0.5f, -0.5f}, {0.5f,0.5f,0.5f,1}, {0,0,-1}, {0,0}, id}, - {{-0.5f, 0.5f, -0.5f}, {0.5f,0.5f,0.5f,1}, {0,0,-1}, {0,1}, id}, - {{ 0.5f, 0.5f, -0.5f}, {0.5f,0.5f,0.5f,1}, {0,0,-1}, {1,1}, id}, - {{ 0.5f, -0.5f, -0.5f}, {0.5f,0.5f,0.5f,1}, {0,0,-1}, {1,0}, id}, - // Front face (normal 0, 0, 1) - {{-0.5f, -0.5f, 0.5f}, {0.5f,0.5f,0.5f,1}, {0,0,1}, {0,0}, id}, - {{-0.5f, 0.5f, 0.5f}, {0.5f,0.5f,0.5f,1}, {0,0,1}, {0,1}, id}, - {{ 0.5f, 0.5f, 0.5f}, {0.5f,0.5f,0.5f,1}, {0,0,1}, {1,1}, id}, - {{ 0.5f, -0.5f, 0.5f}, {0.5f,0.5f,0.5f,1}, {0,0,1}, {1,0}, id}, + {{-0.5f, -0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {0,0}, id}, + {{-0.5f, 0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {0,1}, id}, + {{ 0.5f, 0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {1,1}, id}, + {{ 0.5f, -0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,1}, {1,0}, id}, + + // Back face (normal 0, 0, -1) + {{-0.5f, -0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,-1}, {0,0}, id}, + {{-0.5f, 0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,-1}, {0,1}, id}, + {{ 0.5f, 0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,-1}, {1,1}, id}, + {{ 0.5f, -0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,0,-1}, {1,0}, id}, // Left face (normal -1, 0, 0) - {{-0.5f, -0.5f, -0.5f}, {0.5f,0.5f,0.5f,1}, {-1,0,0}, {0,0}, id}, - {{-0.5f, 0.5f, -0.5f}, {0.5f,0.5f,0.5f,1}, {-1,0,0}, {0,1}, id}, - {{-0.5f, 0.5f, 0.5f}, {0.5f,0.5f,0.5f,1}, {-1,0,0}, {1,1}, id}, - {{-0.5f, -0.5f, 0.5f}, {0.5f,0.5f,0.5f,1}, {-1,0,0}, {1,0}, id}, + {{-0.5f, -0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {-1,0,0}, {0,0}, id}, + {{-0.5f, 0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {-1,0,0}, {0,1}, id}, + {{-0.5f, 0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {-1,0,0}, {1,1}, id}, + {{-0.5f, -0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {-1,0,0}, {1,0}, id}, // Right face (normal 1, 0, 0) - {{ 0.5f, -0.5f, -0.5f}, {0.5f,0.5f,0.5f,1}, {1,0,0}, {0,0}, id}, - {{ 0.5f, 0.5f, -0.5f}, {0.5f,0.5f,0.5f,1}, {1,0,0}, {0,1}, id}, - {{ 0.5f, 0.5f, 0.5f}, {0.5f,0.5f,0.5f,1}, {1,0,0}, {1,1}, id}, - {{ 0.5f, -0.5f, 0.5f}, {0.5f,0.5f,0.5f,1}, {1,0,0}, {1,0}, id}, + {{ 0.5f, -0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {1,0,0}, {0,0}, id}, + {{ 0.5f, 0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {1,0,0}, {0,1}, id}, + {{ 0.5f, 0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {1,0,0}, {1,1}, id}, + {{ 0.5f, -0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {1,0,0}, {1,0}, id}, // Top face (normal 0, 1, 0) - {{-0.5f, 0.5f, -0.5f}, {0.5f,0.5f,0.5f,1}, {0,1,0}, {0,0}, id}, - {{-0.5f, 0.5f, 0.5f}, {0.5f,0.5f,0.5f,1}, {0,1,0}, {0,1}, id}, - {{ 0.5f, 0.5f, 0.5f}, {0.5f,0.5f,0.5f,1}, {0,1,0}, {1,1}, id}, - {{ 0.5f, 0.5f, -0.5f}, {0.5f,0.5f,0.5f,1}, {0,1,0}, {1,0}, id}, + {{-0.5f, 0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,1,0}, {0,0}, id}, + {{-0.5f, 0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,1,0}, {0,1}, id}, + {{ 0.5f, 0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,1,0}, {1,1}, id}, + {{ 0.5f, 0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,1,0}, {1,0}, id}, // Bottom face (normal 0, -1, 0) - {{-0.5f, -0.5f, -0.5f}, {0.5f,0.5f,0.5f,1}, {0,-1,0}, {0,0}, id}, - {{-0.5f, -0.5f, 0.5f}, {0.5f,0.5f,0.5f,1}, {0,-1,0}, {0,1}, id}, - {{ 0.5f, -0.5f, 0.5f}, {0.5f,0.5f,0.5f,1}, {0,-1,0}, {1,1}, id}, - {{ 0.5f, -0.5f, -0.5f}, {0.5f,0.5f,0.5f,1}, {0,-1,0}, {1,0}, id}, + {{-0.5f, -0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,-1,0}, {0,0}, id}, + {{-0.5f, -0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,-1,0}, {0,1}, id}, + {{ 0.5f, -0.5f, 0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,-1,0}, {1,1}, id}, + {{ 0.5f, -0.5f, -0.5f}, { 0.5f, 0.5f, 0.5f, 1 }, {0,-1,0}, {1,0}, id}, }; std::vector indices = { - // Back face (z=-0.5) - 0, 1, 2, 0, 2, 3, - // Front face (z=0.5) - 4, 6, 5, 4, 7, 6, + // Front face (z=-0.5) + 0, 2, 1, 0, 3, 2, + // Back face (z=0.5) + 4, 5, 6, 4, 6, 7, // Right face 12, 13, 14, 12, 14, 15, // Left face @@ -105,7 +152,6 @@ namespace OpenEngine { 18, 16, 17, 18, 19, 16, // Bottom face 20, 22, 21, 20, 23, 22 - // TODO: Missing backface }; return CreateMesh(vertices, indices); @@ -159,7 +205,7 @@ namespace OpenEngine { renderer_data.color_shader_3d.reset(); } - void Renderer3D::BeginScene(const Camera& camera, const glm::mat4& transform) + void Renderer3D::BeginScene(const SceneCamera& camera, const glm::mat4& transform) { OE_PROFILE_FUNCTION(); diff --git a/open_engine/src/open_engine/scene/scene.cpp b/open_engine/src/open_engine/scene/scene.cpp index 3300279..d6a114e 100644 --- a/open_engine/src/open_engine/scene/scene.cpp +++ b/open_engine/src/open_engine/scene/scene.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -18,11 +19,24 @@ namespace OpenEngine { return entity; } - void Scene::DeleteEntity(Entity entity) + void Scene::DeleteEntity(entt::entity entity) { registry.destroy(entity); } + void Scene::MarkEntityForDeletion(Entity entity) + { + entities_to_be_deleted.emplace_back(entity); + } + + void Scene::UpdateEntities() + { + for (auto& entity : entities_to_be_deleted) + DeleteEntity(entity); + + entities_to_be_deleted.clear(); + } + void Scene::OnUpdateRuntime() { { @@ -54,26 +68,27 @@ namespace OpenEngine { } } - /* if (main_camera) { - Renderer2D::BeginScene(main_camera->GetProjection(), main_transform); + Renderer3D::BeginScene(*main_camera, main_transform); - auto view = registry.view(); + auto view = registry.view(); for (const auto& entity : view) { - auto [transform, sprite] = view.get(entity); + auto [transform, mesh] = view.get(entity); + Renderer3D::DrawMesh(mesh.mesh, GetTransformFromComp(transform)); + /* if (sprite.texture) Renderer2D::DrawQuad(GetTransformFromComp(transform), sprite.texture, sprite.color, (int)entity, sprite.tiling_factor); else Renderer2D::DrawQuad(GetTransformFromComp(transform), sprite.color, (int)entity); + */ } - Renderer2D::EndScene(); + Renderer3D::EndScene(); } - */ } }