diff --git a/docs/core.todo b/docs/core.todo index ffb802a..f4764a4 100644 --- a/docs/core.todo +++ b/docs/core.todo @@ -24,6 +24,7 @@ Core: ✔ Test rotation of images @done (11/1/2021, 2:11:13 PM) ☐ Fix line rotation @low ✔ Add Roboto-Regular.ttf as an internal font @high @done (11/3/2021, 8:35:51 PM) + ☐ Allow an image size to be passed in for rendering to an image @high GUI: diff --git a/src/graphics/igraphics.h b/src/graphics/igraphics.h index 823b6d8..e101523 100644 --- a/src/graphics/igraphics.h +++ b/src/graphics/igraphics.h @@ -30,7 +30,7 @@ namespace lunarium protected: // Interface methods for use only by the engine friend Core; - IGraphics() : mbIsInit(false) {} + IGraphics() : mbIsInit(false), mpFBTexture(nullptr) {} virtual OpRes Initialize(Window* pWindow, bool enableDebugMessages = true) = 0; virtual void Shutdown() = 0; diff --git a/src/graphics/opengl/glGraphics.cpp b/src/graphics/opengl/glGraphics.cpp index 47ea5b5..b0a0fe5 100644 --- a/src/graphics/opengl/glGraphics.cpp +++ b/src/graphics/opengl/glGraphics.cpp @@ -149,15 +149,14 @@ namespace lunarium // Buffer width and height (in pixels) is the same as the screen size // Need to multiply these by the number bytes per pixel - //int bufferSize = mFBWidth * mFBHeight * 4; // NOTE: Assuming 4 channels for now - //unsigned char* buffer = new unsigned char[bufferSize]; - //glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, (void*)buffer); - - //FlipImageVertically(buffer, mFBWidth, mFBHeight, 1); - - //glSetTexImage() - - mpFBTexture->FreeRawData(); + int bufferSize = mFBWidth * mFBHeight * 4; // NOTE: Assuming 4 channels for now + // TODO: Preallocate the buffer so we don't call new every frame! + unsigned char* buffer = new unsigned char[bufferSize]; + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, (void*)buffer); + + // FlipImageVertically(buffer, mFBWidth, mFBHeight, 1); + // mpFBTexture->FreeRawData(); + mpFBTexture->SetData(buffer); mpFBTexture->SetWidth(mFBWidth); mpFBTexture->SetHeight(mFBHeight); mpFBTexture->SetFormat(ImageFormat::RGBA); @@ -595,7 +594,7 @@ namespace lunarium glGenTextures(1, &id); mpFBTexture->SetGLTextureID(id); glBindTexture(GL_TEXTURE_2D, mpFBTexture->GetGLTextureID()); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, mFBWidth, mFBHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mFBWidth, mFBHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); diff --git a/src/internal_libs/assets/types/image.cpp b/src/internal_libs/assets/types/image.cpp index 5e2429e..50a7c8c 100644 --- a/src/internal_libs/assets/types/image.cpp +++ b/src/internal_libs/assets/types/image.cpp @@ -66,6 +66,12 @@ namespace lunarium return *this; } + + void Image::SetData(unsigned char* data) + { + mRawData = data; + } + unsigned int Image::GetGLTextureID() const { return mGLTextureID; diff --git a/src/internal_libs/assets/types/image.h b/src/internal_libs/assets/types/image.h index 6f2839f..9f01cea 100644 --- a/src/internal_libs/assets/types/image.h +++ b/src/internal_libs/assets/types/image.h @@ -29,6 +29,7 @@ namespace lunarium ImageFormat GetFormat() const; const unsigned char* GetData() const; + void SetData(unsigned char* data); void SetGLTextureID(unsigned int id); void SetWidth(int width); void SetHeight(int height); diff --git a/src/run_modes/editor/CMakeLists.txt b/src/run_modes/editor/CMakeLists.txt index 8eab76d..16f628e 100644 --- a/src/run_modes/editor/CMakeLists.txt +++ b/src/run_modes/editor/CMakeLists.txt @@ -1,5 +1,19 @@ -add_library(editor editor.cpp project/project.cpp panels/iPanel.cpp panels/mainPanel.cpp panels/about.cpp - panels/assetBrowser.cpp panels/worldTree.cpp panels/worldView.cpp panels/propertiesView.cpp) + +# Source Files +set(EDITOR_SRC +"editor.cpp" +"project/project.cpp" +"panels/iPanel.cpp" +"panels/mainPanel.cpp" +"panels/about.cpp" +"panels/assetBrowser.cpp" +"panels/worldTree.cpp" +"panels/worldView.cpp" +"panels/propertiesView.cpp" +"tools/map_editor/map_editor.cpp" +) + +add_library(editor ${EDITOR_SRC}) target_include_directories(editor PUBLIC "${PROJECT_BINARY_DIR}" diff --git a/src/run_modes/editor/editor.cpp b/src/run_modes/editor/editor.cpp index 638262b..90542d9 100644 --- a/src/run_modes/editor/editor.cpp +++ b/src/run_modes/editor/editor.cpp @@ -21,6 +21,9 @@ #include "panels/worldView.h" #include "panels/propertiesView.h" +// Tools +#include "tools/map_editor/map_editor.h" + namespace lunarium { namespace editor @@ -28,7 +31,7 @@ namespace editor Editor::Editor() : mLogCat(-1), mpMainPanel(nullptr), mpFileBrowser(nullptr), mpPath(nullptr), mDoNewProject(false), mDoOpenProject(false), - mDoSaveProject(false), mDoSaveAs(false) + mDoSaveProject(false), mDoSaveAs(false), mpMapEditor(nullptr) { } @@ -67,7 +70,7 @@ namespace editor HandleMenuEvents(); } - void Editor::OnRender(IGraphics* g) + void Editor::OnRender(lunarium::IGraphics* g) { mpMainPanel->DoFrame(); @@ -94,6 +97,24 @@ namespace editor return mLogCat; } + + bool Editor::IsToolOpen(ToolType type) const + { + switch (type) + { + case ToolType::TT_MAP_EDITOR: + { + if (!mpMapEditor) + return false; + + return mpMapEditor->IsOpen(); + } + } + + Logger::Log(mLogCat, LogLevel::WARNING, "And unknown ToolType was passed into Editor::IsToolOpen: %n", type); + return false; + } + //////////////////////////////////////////////////////////// // HELPER METHODS //////////////////////////////////////////////////////////// @@ -110,6 +131,18 @@ namespace editor { delete mPanels[PanelType::PT_ABOUT]; delete mPanels[PanelType::PT_ASSET_BROWSER]; + delete mPanels[PanelType::PT_WORLD_TREE]; + delete mPanels[PanelType::PT_WORLD_VIEW]; + delete mPanels[PanelType::PT_PROPERTIES_VIEW]; + + mPanels.clear(); + } + + void Editor::DestroyTools() + { + mpMapEditor->Shutdown(); + delete mpMapEditor; + mpMapEditor = nullptr; } void Editor::HandleMenuEvents() @@ -256,5 +289,17 @@ namespace editor mPanels[PanelType::PT_ABOUT]->SetOpen(true); } + + void Editor::OpenMapEditor() + { + if (!mpMapEditor) + { + mpMapEditor = new MapEditor; + mpMapEditor->Initialize(this); + } + + mpMapEditor->Open(); + } + } } \ No newline at end of file diff --git a/src/run_modes/editor/editor.h b/src/run_modes/editor/editor.h index 4230be4..d3d9b13 100644 --- a/src/run_modes/editor/editor.h +++ b/src/run_modes/editor/editor.h @@ -24,7 +24,12 @@ namespace lunarium namespace editor { + enum ToolType + { + TT_MAP_EDITOR, + }; + class MapEditor; class MainPanel; class Editor : public iRunMode { @@ -33,10 +38,11 @@ namespace lunarium OpRes Initialize(); void Shutdown(); void OnTick(double delta); - void OnRender(IGraphics* g); + void OnRender(lunarium::IGraphics* g); uint32_t GetLogCat() const; + bool IsToolOpen(ToolType type) const; // Menu Bar Events void NewProject(); @@ -44,6 +50,7 @@ namespace lunarium void SaveProject(); void SaveAs(); void Exit(); + void OpenMapEditor(); void ShowAboutPanel(); @@ -58,6 +65,9 @@ namespace lunarium Project mProject; + // Tools + MapEditor* mpMapEditor; + FileBrowser* mpFileBrowser; const std::filesystem::path* mpPath; @@ -72,6 +82,7 @@ namespace lunarium private: // HELPERS void CreatePanels(); void DestoryPanels(); + void DestroyTools(); void HandleMenuEvents(); }; diff --git a/src/run_modes/editor/panels/mainPanel.cpp b/src/run_modes/editor/panels/mainPanel.cpp index 2b04a94..fe01342 100644 --- a/src/run_modes/editor/panels/mainPanel.cpp +++ b/src/run_modes/editor/panels/mainPanel.cpp @@ -138,10 +138,42 @@ namespace editor if (ImGui::BeginMenu("Windows")) { - + ImGui::EndMenu(); } + // Tools + if (ImGui::BeginMenu("Tools")) + { + if (ImGui::MenuItem("Map Editor")) + { + mpEditor->OpenMapEditor(); + } + ImGui::EndMenu(); + } + + // TODO: If map editor is open show it's menu + if (mpEditor->IsToolOpen(ToolType::TT_MAP_EDITOR)) + { + if (ImGui::BeginMenu("Map Editor")) + { + if (ImGui::BeginMenu("Windows")) + { + + ImGui::EndMenu(); + } + + if (ImGui::BeginMenu("Settings")) + { + + ImGui::EndMenu(); + } + + + ImGui::EndMenu(); + } + } + if (ImGui::BeginMenu("Help")) { if (ImGui::MenuItem("About")) diff --git a/src/run_modes/editor/tools/map_editor/map_editor.cpp b/src/run_modes/editor/tools/map_editor/map_editor.cpp new file mode 100644 index 0000000..d668574 --- /dev/null +++ b/src/run_modes/editor/tools/map_editor/map_editor.cpp @@ -0,0 +1,127 @@ +/****************************************************************************** +* File - map_editor.h +* Author - Joey Pollack +* Date - 2022/01/31 (y/m/d) +* Mod Date - 2022/01/31 (y/m/d) +* Description - The tile map editor tool. Controls subwindows/panels. +******************************************************************************/ + +#include "map_editor.h" + +#include +#include +#include + +namespace lunarium { namespace editor +{ + MapEditor::MapEditor() + : mpEditor(nullptr), mIsOpen(false), mMapLoaded(false) + { + + } + + + OpRes MapEditor::Initialize(Editor* editor) + { + if (mpEditor) + { + return OpRes::Fail("MapEditor is already initialized"); + } + + mpEditor = editor; + + Open(); + + return OpRes::OK(); + } + + void MapEditor::Shutdown() + { + mpEditor = nullptr; + } + + void MapEditor::OnTick(double delta) + { + for (int i = 0; i < mPanels.size(); i++) + { + mPanels[i]->Update(delta); + } + } + + bool MapEditor::OnRender(IGraphics* g) + { + if (!mIsOpen) + { + Close(); + return false; + } + + ImGui::SetNextWindowSize(ImVec2(800, 500), ImGuiCond_FirstUseEver); + if (!ImGui::Begin("Map Editor", &mIsOpen, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBringToFrontOnFocus)) + { + Close(); + ImGui::End(); + return false; + } + + for (int i = 0; i < mPanels.size(); i++) + { + mPanels[i]->DoFrame(); + } + + ImGui::End(); + return true; + } + + + void MapEditor::Open() + { + if (mIsOpen) + { + return; + } + + for (int i = 0; i < mPanels.size(); i++) + { + mPanels[i]->SetOpen(true); + } + + mIsOpen = true; + } + + void MapEditor::Close() + { + for (int i = 0; i < mPanels.size(); i++) + { + mPanels[i]->SetOpen(false); + } + + mIsOpen = false; + } + + bool MapEditor::IsOpen() const + { + return mIsOpen; + } + + + void MapEditor::NewMap() + { + + } + + OpRes MapEditor::LoadMap(std::string map) + { + return OpRes::Fail("MapEditor::LoadMap not implemented"); + } + + void MapEditor::SaveMap() + { + + } + + bool MapEditor::IsMapLoaded() const + { + return mMapLoaded; + } +}} diff --git a/src/run_modes/editor/tools/map_editor/map_editor.h b/src/run_modes/editor/tools/map_editor/map_editor.h new file mode 100644 index 0000000..2b0c020 --- /dev/null +++ b/src/run_modes/editor/tools/map_editor/map_editor.h @@ -0,0 +1,57 @@ +/****************************************************************************** +* File - map_editor.h +* Author - Joey Pollack +* Date - 2022/01/31 (y/m/d) +* Mod Date - 2022/01/31 (y/m/d) +* Description - The tile map editor tool. Controls subwindows/panels. +******************************************************************************/ + +#ifndef MAP_EDITOR_H_ +#define MAP_EDITOR_H_ + +#include +#include +#include + +namespace lunarium { namespace editor +{ + class Editor; + class IGraphics; + class Panel; + class MapEditor + { + public: + MapEditor(); + + OpRes Initialize(Editor* editor); + void Shutdown(); + void OnTick(double delta); + bool OnRender(IGraphics* g); + + void Open(); + void Close(); + bool IsOpen() const; + + void NewMap(); + OpRes LoadMap(std::string map); + void SaveMap(); + bool IsMapLoaded() const; + + + private: + bool mIsOpen; + bool mMapLoaded; + bool mIsDirty; + Editor* mpEditor; + std::vector mPanels; + + enum PanelTypes + { + MPPT_MAP_VIEW, + MPPT_TILE_PALLET, + MPPT_PROPERTIES + }; + }; +}} + +#endif // MAP_EDITOR_H_ \ No newline at end of file diff --git a/src/run_modes/tester/scenes/simpleRenderScene.cpp b/src/run_modes/tester/scenes/simpleRenderScene.cpp index eeaec35..d161857 100644 --- a/src/run_modes/tester/scenes/simpleRenderScene.cpp +++ b/src/run_modes/tester/scenes/simpleRenderScene.cpp @@ -13,6 +13,7 @@ #include #include #include +#include namespace lunarium { @@ -87,6 +88,33 @@ namespace lunarium angle -= 0.1f; } + if (Core::Input().IsKeyPressed(KeyCode::Q)) + { + // Test writing out a rendered image with transparency + IGraphics& g = Core::Graphics(); + Color prev = g.GetClearColor(); + g.SetClearColor(Color(0.0f, 0.0f, 0.0f, 0.0f)); + OpRes result = Core::GetInstance().BeginRenderToTexture(); + if (Failed(result)) + { + Logger::Log(mLogCat, LogLevel::WARNING, "Unable to render to texture: %s", result.Description.c_str()); + return; + } + + Logger::Log(mLogCat, LogLevel::INFO, "Running transparent image test"); + + g.DrawFilledBox(Rectangle(500, 400, 300, 300), Color(0.5f, 0.0f, 0.75f, 1.0f)); + g.DrawString("This is a test of rendering an image with transparency", + Rectangle::MakeFromTopLeft(50, 50, 600, 200), Color(0.0f, 1.0f, 0.2f, 1.0f), 0.5f); + + mpRenderedImage = Core::GetInstance().EndRenderToTexture(); + g.SetClearColor(prev); + + stbi_flip_vertically_on_write(1); + stbi_write_png("lunarium_test_image.png", mpRenderedImage->GetWidth(), mpRenderedImage->GetHeight(), 4, + mpRenderedImage->GetData(), mpRenderedImage->GetWidth() * 4); + } + mImageSize.Width = Math::ClampI(mImageSize.Width, 320, 1280); mImageSize.Height = Math::ClampI(mImageSize.Height, 180, 720); @@ -106,6 +134,8 @@ namespace lunarium mpRenderedImage = Core::GetInstance().EndRenderToTexture(); + + box_angle += 0.01f; } @@ -114,10 +144,10 @@ namespace lunarium g->DrawImage(*mpRenderedImage, Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mpRenderedImage->GetWidth(), (float)mpRenderedImage->GetHeight()), Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mImageSize.Width, (float)mImageSize.Height), Color(1.0f, 1.0f, 1.0f, 1.0f), angle); - g->DrawBox(Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mImageSize.Width, (float)mImageSize.Height), Color(0.0f, 0.0f, 0.0f, 1.0f), 1.0f, angle); + // g->DrawBox(Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mImageSize.Width, (float)mImageSize.Height), Color(0.0f, 0.0f, 0.0f, 1.0f), 1.0f, angle); - g->DrawBox(Rectangle(400, 400, 128.0f, 128.0f), Color(0.0f, 1.0f, 0.0f, 1.0f), 2.0f, box_angle); + // g->DrawBox(Rectangle(400, 400, 128.0f, 128.0f), Color(0.0f, 1.0f, 0.0f, 1.0f), 2.0f, box_angle); - g->DrawString((*mGrid[{-2, 0,}])->msg.c_str(), Rectangle::MakeFromTopLeft(200.0f, 500.0f, 500.0f, 200.0f), Color(0.5f, 0.0f, 0.75f, 1.0f)); + // g->DrawString((*mGrid[{-2, 0,}])->msg.c_str(), Rectangle::MakeFromTopLeft(200.0f, 500.0f, 500.0f, 200.0f), Color(0.5f, 0.0f, 0.75f, 1.0f)); } } \ No newline at end of file diff --git a/test_data/engine_state.xml b/test_data/engine_state.xml index 277eb02..5cf7851 100644 --- a/test_data/engine_state.xml +++ b/test_data/engine_state.xml @@ -1,6 +1,6 @@ data/ - +