diff --git a/src/run_modes/editor/CMakeLists.txt b/src/run_modes/editor/CMakeLists.txt index ad08c6f..1af52f8 100644 --- a/src/run_modes/editor/CMakeLists.txt +++ b/src/run_modes/editor/CMakeLists.txt @@ -15,6 +15,7 @@ set(EDITOR_SRC "contents/editor_asset.cpp" "contents/world.cpp" "contents/script.cpp" +"contents/image.cpp" "contents/tile_map.cpp" "contents/tile_set.cpp" "tools/map_editor/map_editor.cpp" diff --git a/src/run_modes/editor/component_guis.cpp b/src/run_modes/editor/component_guis.cpp index e9aa6df..1d9b63f 100644 --- a/src/run_modes/editor/component_guis.cpp +++ b/src/run_modes/editor/component_guis.cpp @@ -8,13 +8,16 @@ #include "component_guis.h" #include -#include #include #include #include #include +#include #include +#include + +#include #include @@ -141,6 +144,96 @@ namespace lunarium { namespace editor } + bool CompGui::RenderSpriteRendererComp(SpriteRendererComponent& comp) + { + bool remove = false; + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(ImGui::GetStyle().ItemSpacing.x, ImGui::GetStyle().ItemSpacing.y + 10.0f)); + remove = DrawTitle("Sprite Renderer Component"); + ImGui::PopStyleVar(); + + ImGui::Text("Preview"); + Image* pImage = (editor::Image*) ContentManager::GetInstance().GetAsset(comp.ImageID); + if (pImage) + { + lunarium::Texture* pTex = pImage->GetImage(); + float x1 = comp.FramePos.x / pTex->GetWidth(); + float y1 = comp.FramePos.y / pTex->GetHeight(); + float x2 = (comp.FramePos.x + comp.FrameSize.x) / pTex->GetWidth(); + float y2 = (comp.FramePos.y + comp.FrameSize.y) / pTex->GetHeight(); + ImGui::Image((ImTextureID)pTex->GetGLID64(), ImVec2(comp.FrameSize.x, comp.FrameSize.y), ImVec2(x1, y1), + ImVec2(x2, y2), + ImVec4(comp.TintColor.R, comp.TintColor.G, comp.TintColor.B, comp.TintColor.A)); + } + else + { + ImGui::Text("NOT SET"); + } + + ImGui::Separator(); + + // The image asset + std::string preview = (pImage ? pImage->GetFileLocation().filename().string().c_str() : "NOT SET"); + if (ImGui::BeginCombo("Image", preview.c_str())) + { + char search_buf[256] = ""; + ImGui::InputText("Search ##IMAGE", search_buf, 256); + std::string ssearch = search_buf; + + std::vector assets; + ContentManager::GetInstance().GetAllAssetsByType(assets, AssetType::EATYPE_IMAGE); + + for (auto iter = assets.begin(); iter != assets.end(); iter++) + { + editor::Image* pImg = (editor::Image*)(*iter); + + if (ssearch.size() > 0) + { + // Filter items based on search term + if (pImg->GetFileLocation().string().find(ssearch) == std::string::npos) + { + continue; + } + } + + bool selected = false; + if (ImGui::Selectable(pImg->GetFileLocation().string().c_str(), &selected)) + { + comp.ImageID = pImg->GetID(); + } + } + + ImGui::EndCombo(); + } + + // Render Layer + ImGui::Text("Render Layer: "); + ImGui::SameLine(); + ImGui::InputInt("##Render Layer Image", &comp.RenderLayer, 1, 10); + + // Frame Size + glm::vec3 _size = {comp.FrameSize.x, comp.FrameSize.y, 0.0f }; + if (ImGuiExt::Vec2Control("Frame Size", _size, 1.0f, 85.0f)) + { + comp.FrameSize.x = _size.x; + comp.FrameSize.y = _size.y; + } + + // Frame Position + glm::vec3 _size2 = {comp.FramePos.x, comp.FramePos.y, 0.0f }; + if (ImGuiExt::Vec2Control("Frame Position", _size2, 1.0f, 85.0f)) + { + comp.FramePos.x = _size2.x; + comp.FramePos.y = _size2.y; + } + + // Tint Color + ImGui::Text("Tint Color: "); + ImGui::SameLine(); + ImGui::ColorEdit4("##Tint Color", comp.TintColor.arr, ImGuiColorEditFlags_DisplayRGB); + + return remove; + } + bool CompGui::RenderScriptComp(ScriptComponent& comp) { bool remove = false; diff --git a/src/run_modes/editor/component_guis.h b/src/run_modes/editor/component_guis.h index ca5583b..933c24f 100644 --- a/src/run_modes/editor/component_guis.h +++ b/src/run_modes/editor/component_guis.h @@ -21,6 +21,7 @@ namespace lunarium { namespace editor static bool RenderVelocityComp(VelocityComponent& comp); static bool RenderCameraComp(CameraComponent& comp); static bool RenderBlockOutComp(BlockOutComponent& comp); + static bool RenderSpriteRendererComp(SpriteRendererComponent& comp); static bool RenderScriptComp(ScriptComponent& comp); }; }} diff --git a/src/run_modes/editor/contents/content_manager.cpp b/src/run_modes/editor/contents/content_manager.cpp index 5b81c7a..59547b2 100644 --- a/src/run_modes/editor/contents/content_manager.cpp +++ b/src/run_modes/editor/contents/content_manager.cpp @@ -22,6 +22,7 @@ #include "tile_set.h" #include "world.h" #include "script.h" +#include "image.h" namespace lunarium { namespace editor { @@ -377,6 +378,7 @@ namespace lunarium { namespace editor switch (type) { case AssetType::EATYPE_TILE_SET: return new TileSet(); + case AssetType::EATYPE_IMAGE: return new Image(); case AssetType::EATYPE_WORLD: return new editor::World(); case AssetType::EATYPE_SCRIPT: return new editor::Script("", ""); // Dummy info will be overwritten diff --git a/src/run_modes/editor/contents/image.cpp b/src/run_modes/editor/contents/image.cpp new file mode 100644 index 0000000..d56814b --- /dev/null +++ b/src/run_modes/editor/contents/image.cpp @@ -0,0 +1,73 @@ +/****************************************************************************** +* File - image.cpp +* Author - Joey Pollack +* Date - 2022/11/28 (y/m/d) +* Mod Date - 2022/11/28 (y/m/d) +* Description - The editor warpper for an Image asset +******************************************************************************/ + +#include "image.h" +#include +#include +#include + +namespace lunarium { namespace editor { + + Image::Image() + : EditorAsset(AssetType::EATYPE_IMAGE), mpImage(nullptr) + { + + } + + + lunarium::Texture* Image::GetImage() const + { + return mpImage; + } + + + bool Image::DrawProperties() + { + + return false; + } + + ///////////////////////////////////////////////////////////////////// + // SERIALIZATION + ///////////////////////////////////////////////////////////////////// + OpRes Image::LoadRawFile() + { + mpImage = FileLoaders::LoadImage(mAssetDir / GetFileLocation()); + mpImage->FlipVertically(); + if (!mpImage) + { + return OpRes::Fail("Could not load image file: %s", GetFileLocation().string().c_str()); + } + + return OpRes::OK(); + } + + OpRes Image::Serialize(nlohmann::ordered_json& node) + { + + + return OpRes::OK(); + } + + OpRes Image::Deserialize(nlohmann::ordered_json& node) + { + LoadRawFile(); + return OpRes::OK(); + } + + bool Image::IsValidNode(nlohmann::ordered_json& node) + { + return true; + } + + nlohmann::ordered_json Image::AsJSON() + { + return nlohmann::ordered_json(); + } + +}} \ No newline at end of file diff --git a/src/run_modes/editor/contents/image.h b/src/run_modes/editor/contents/image.h new file mode 100644 index 0000000..65f95e0 --- /dev/null +++ b/src/run_modes/editor/contents/image.h @@ -0,0 +1,46 @@ +/****************************************************************************** +* File - image.h +* Author - Joey Pollack +* Date - 2022/11/28 (y/m/d) +* Mod Date - 2022/11/28 (y/m/d) +* Description - The editor warpper for an Image asset +******************************************************************************/ + +#ifndef LUNARIUM_EDITOR_TEXTURE_H_ +#define LUNARIUM_EDITOR_TEXTURE_H_ + + +#include "editor_asset.h" +#include + +namespace lunarium +{ + class Texture; +} + +namespace lunarium { namespace editor { + + class Image : public EditorAsset + { + public: + Image(); + ~Image(); + + [[nodiscard]] virtual OpRes LoadRawFile(); + [[nodiscard]] virtual OpRes Serialize(nlohmann::ordered_json& node); + [[nodiscard]] virtual OpRes Deserialize(nlohmann::ordered_json& node); + [[nodiscord]] virtual bool IsValidNode(nlohmann::ordered_json& node); + [[nodiscard]] virtual nlohmann::ordered_json AsJSON(); + + bool DrawProperties(); + + lunarium::Texture* GetImage() const; + + private: + lunarium::Texture* mpImage; + }; + +}} + + +#endif // LUNARIUM_EDITOR_TEXTURE_H_ \ No newline at end of file diff --git a/src/run_modes/editor/panels/asset_browser.cpp b/src/run_modes/editor/panels/asset_browser.cpp index e932dec..4399eb7 100644 --- a/src/run_modes/editor/panels/asset_browser.cpp +++ b/src/run_modes/editor/panels/asset_browser.cpp @@ -19,6 +19,7 @@ #include #include #include +#include namespace lunarium { @@ -267,7 +268,29 @@ namespace editor OpenPopup(PopUp::NEW_SCRIPT).LogIfFailed(Editor::LogCat); } ImGui::EndMenu(); - + } + + if (ImGui::BeginMenu("Import Asset")) + { + if (ImGui::MenuItem("Image")) + { + std::filesystem::path outPath; + + // prepare filters for the dialog + FileSystem::FilterItem filterItem[3] = {{"Image file", "png"}, {"Image File", "jpg"}, {"Image File", "jpeg"}}; + + // show the dialog + FileSystem::DialogResult result = FileSystem::OpenFileDialog(outPath, filterItem, 3); + if (result == FileSystem::DialogResult::OK) + { + Logger::Info(Editor::LogCat, "Importing asset: %s", outPath.string().c_str()); + + LUUID id = 0; + ContentManager::GetInstance().ImportFile(outPath, mSelectedDir / outPath.filename(), + AssetType::EATYPE_IMAGE, id).LogIfFailed(Editor::LogCat); + } + } + ImGui::EndMenu(); } // TODO: Buttons for creating/importing new assets @@ -375,6 +398,7 @@ namespace editor } return stay_open; }).LogIfFailed(Editor::LogCat); + } diff --git a/src/run_modes/editor/panels/asset_browser.h b/src/run_modes/editor/panels/asset_browser.h index bb811c1..af38f46 100644 --- a/src/run_modes/editor/panels/asset_browser.h +++ b/src/run_modes/editor/panels/asset_browser.h @@ -58,6 +58,7 @@ namespace editor NEW_FOLDER, NEW_WORLD, NEW_SCRIPT, + IMPORT_IMAGE, }; }; diff --git a/src/run_modes/editor/panels/properties_view.cpp b/src/run_modes/editor/panels/properties_view.cpp index ff962e4..e660679 100644 --- a/src/run_modes/editor/panels/properties_view.cpp +++ b/src/run_modes/editor/panels/properties_view.cpp @@ -68,6 +68,7 @@ namespace lunarium { namespace editor PRESENT_COMP_CHOICE("Velocity Component", VelocityComponent, pv) PRESENT_COMP_CHOICE("Camera Component", CameraComponent, pv) PRESENT_COMP_CHOICE("Block Out Component", BlockOutComponent, pv) + PRESENT_COMP_CHOICE("Sprite Renderer Component", SpriteRendererComponent, pv) PRESENT_COMP_CHOICE("Script Component", ScriptComponent, pv) @@ -188,6 +189,7 @@ namespace lunarium { namespace editor DRAW_COMP_GUI(VelocityComponent, RenderVelocityComp) DRAW_COMP_GUI(CameraComponent, RenderCameraComp) DRAW_COMP_GUI(BlockOutComponent, RenderBlockOutComp) + DRAW_COMP_GUI(SpriteRendererComponent, RenderSpriteRendererComp) DRAW_COMP_GUI(ScriptComponent, RenderScriptComp) // After all components rendered diff --git a/src/scripting/wren_state.cpp b/src/scripting/wren_state.cpp index 3c36e79..9b76ebe 100644 --- a/src/scripting/wren_state.cpp +++ b/src/scripting/wren_state.cpp @@ -25,7 +25,8 @@ namespace lunarium void WrenState::Shutdown() { - wrenFreeVM(mpVM); + if (mpVM) + wrenFreeVM(mpVM); mpVM = nullptr; } diff --git a/src/world/components.h b/src/world/components.h index 349b2ae..e3c3924 100644 --- a/src/world/components.h +++ b/src/world/components.h @@ -84,6 +84,18 @@ namespace lunarium BlockOutComponent(const BlockOutComponent&) = default; }; + struct SpriteRendererComponent + { + LUUID ImageID; + int RenderLayer; + glm::vec2 FrameSize; + glm::vec2 FramePos; + Color TintColor; + + SpriteRendererComponent() = default; + SpriteRendererComponent(const SpriteRendererComponent&) = default; + }; + struct ScriptComponent { LUUID ScriptID; diff --git a/src/world/entity.cpp b/src/world/entity.cpp index 8d47493..ff6f1e9 100644 --- a/src/world/entity.cpp +++ b/src/world/entity.cpp @@ -268,6 +268,33 @@ namespace lunarium components.emplace_back(blockout); } + if (HasComponent()) + { + nlohmann::ordered_json sprite; + SpriteRendererComponent& comp = GetComponent(); + sprite["type_name"] = "SpriteRendererComponent"; + + sprite["image_id"] = comp.ImageID; + + sprite["render_layer"] = comp.RenderLayer; + + auto& frame_size = sprite["frame_size"]; + frame_size["width"] = comp.FrameSize.x; + frame_size["height"] = comp.FrameSize.y; + + auto& frame_pos = sprite["frame_pos"]; + frame_pos["x"] = comp.FramePos.x; + frame_pos["y"] = comp.FramePos.y; + + auto& color = sprite["color"]; + color["r"] = comp.TintColor.R; + color["g"] = comp.TintColor.G; + color["b"] = comp.TintColor.B; + color["a"] = comp.TintColor.A; + + components.emplace_back(sprite); + } + if (HasComponent()) { @@ -422,6 +449,24 @@ namespace lunarium AddComponent(Color, Size, layer); } + if ("SpriteRendererComponent" == comp_type_name) + { + LUUID image = comp["image_id"]; + + int layer = comp["render_layer"].get(); + + auto& frame_size = comp["frame_size"]; + glm::vec2 FrameSize(frame_size["width"].get(), frame_size["height"].get()); + + auto& frame_pos = comp["frame_pos"]; + glm::vec2 FramePos(frame_pos["x"].get(), frame_pos["y"].get()); + + auto& color = comp["color"]; + Color c(color["r"].get(), color["g"].get(), color["b"].get(), color["a"].get()); + + AddComponent(image, layer, FrameSize, FramePos, c ); + } + if ("ScriptComponent" == comp_type_name) { LUUID id = comp["script_id"]; diff --git a/src/world/world.cpp b/src/world/world.cpp index eb71696..2e94e56 100644 --- a/src/world/world.cpp +++ b/src/world/world.cpp @@ -19,12 +19,14 @@ #include #include #include +#include #include "entity.h" //#define LOAD_ASSETS_FROM_EDITOR true #if !BUILD_NO_EDITOR #include #include + #include #endif namespace lunarium @@ -105,38 +107,8 @@ namespace lunarium void World::Render(lunarium::Renderer2D* pGraphics) { - - // First get the group we want - auto group = mECSRegistry.group<>(entt::get); - - // Next sort the group - group.sort([](const BlockOutComponent &lhs, const BlockOutComponent &rhs) - { - return lhs.RenderLayer < rhs.RenderLayer; - }); - - // Render the group - for(auto entity: group) - { - auto &transform = group.get(entity); - auto &blockout = group.get(entity); - - - Rectangle rect(transform.Position.x, transform.Position.y, blockout.Size.x, blockout.Size.y); - Color color(blockout.Color.x, blockout.Color.y, blockout.Color.z, blockout.Color.w); - - // Get and apply parent transforms - LUUID uuid = mECSRegistry.get(entity).UUID; - Entity* pEnt = GetEntity(uuid); - glm::mat4 parent_transform = glm::mat4(1.0f); - if (pEnt->HasComponent()) - { - - parent_transform = GetParentTransform(pEnt->GetComponent().Parent); - } - - pGraphics->DrawQuad(rect, color, nullptr, transform.Rotation.z, Rectangle(-1, -1, -1, -1), parent_transform); - } + RenderBlockouts(pGraphics); + RenderSprites(pGraphics); } @@ -217,6 +189,89 @@ namespace lunarium // RUN MODE HELPERS ///////////////////////////////////////////////////////////////////// + void World::RenderBlockouts(lunarium::Renderer2D* pGraphics) + { + // First get the group we want + auto group = mECSRegistry.group<>(entt::get); + + // Next sort the group + group.sort([](const BlockOutComponent &lhs, const BlockOutComponent &rhs) + { + return lhs.RenderLayer < rhs.RenderLayer; + }); + + // Render the group + for(auto entity: group) + { + auto &transform = group.get(entity); + auto &blockout = group.get(entity); + + + Rectangle rect(transform.Position.x, transform.Position.y, blockout.Size.x, blockout.Size.y); + Color color(blockout.Color.x, blockout.Color.y, blockout.Color.z, blockout.Color.w); + + // Get and apply parent transforms + LUUID uuid = mECSRegistry.get(entity).UUID; + Entity* pEnt = GetEntity(uuid); + glm::mat4 parent_transform = glm::mat4(1.0f); + if (pEnt->HasComponent()) + { + + parent_transform = GetParentTransform(pEnt->GetComponent().Parent); + } + + pGraphics->DrawQuad(rect, color, nullptr, transform.Rotation.z, Rectangle(-1, -1, -1, -1), parent_transform); + } + } + + void World::RenderSprites(lunarium::Renderer2D* pGraphics) + { + // First get the group we want + auto group = mECSRegistry.group<>(entt::get); + + // Next sort the group + group.sort([](const SpriteRendererComponent &lhs, const SpriteRendererComponent &rhs) + { + return lhs.RenderLayer < rhs.RenderLayer; + }); + + // Render the group + for(auto entity: group) + { + auto &transform = group.get(entity); + auto &sprite = group.get(entity); + + + Rectangle rect(transform.Position.x, transform.Position.y, sprite.FrameSize.x, sprite.FrameSize.y); + + // Get and apply parent transforms + LUUID uuid = mECSRegistry.get(entity).UUID; + Entity* pEnt = GetEntity(uuid); + glm::mat4 parent_transform = glm::mat4(1.0f); + if (pEnt->HasComponent()) + { + + parent_transform = GetParentTransform(pEnt->GetComponent().Parent); + } + + // If were attached to the editor we need to get the script from the editor's content manager +#if !BUILD_NO_EDITOR + editor::Image* i = (editor::Image*)editor::ContentManager::GetInstance().GetAsset(sprite.ImageID); + if (!i) + continue; + + Texture* t = i->GetImage(); + Rectangle sub_region = Rectangle::MakeFromTopLeft(sprite.FramePos.x, sprite.FramePos.y, sprite.FrameSize.s, sprite.FrameSize.y); + + + pGraphics->DrawSprite(t, glm::vec2(transform.Position), sub_region, + sprite.TintColor, transform.Rotation.z, parent_transform); +#endif + + // pGraphics->DrawQuad(rect, color, nullptr, transform.Rotation.z, Rectangle(-1, -1, -1, -1), parent_transform); + } + } + // void World::DrawHeirarchy(lunarium::Renderer2D* g, entt::entity& entity, TransformComponent& my_trans, BlockOutComponent& bo_comp, glm::mat4 current_transform) // { diff --git a/src/world/world.h b/src/world/world.h index 2e96021..11e54c7 100644 --- a/src/world/world.h +++ b/src/world/world.h @@ -134,6 +134,8 @@ namespace lunarium void InitScriptState(); void RenderEditor(lunarium::Renderer2D* pGraphics) const; glm::mat4 GetParentTransform(LUUID parent); + void RenderBlockouts(lunarium::Renderer2D* pGraphics); + void RenderSprites(lunarium::Renderer2D* pGraphics); //void DrawHeirarchy(lunarium::Renderer2D* g, entt::entity& entity, TransformComponent& my_trans, BlockOutComponent& bo_comp, glm::mat4 current_transform); }; }