diff --git a/docs/Bugs.todo b/docs/Bugs.todo index 4181ad1..11d3611 100644 --- a/docs/Bugs.todo +++ b/docs/Bugs.todo @@ -1,3 +1,5 @@ High Importance: - ☐ The Map Editor does not get the tile maps when a project is opened @high \ No newline at end of file + ✔ The Map Editor does not get the tile maps when a project is opened @high @done (3/3/2022, 2:47:41 PM) + ✔ Tile Set IDs (as opposed to the Asset ID) is not saved or loaded yet @high @done (3/11/2022, 2:10:30 PM) + ✔ Had to flip the V component of the UVs for the sprite vertices. This fixes the partial image drawing but will need to be accounted for in other places in the editor. @done (3/14/2022, 1:46:48 PM) \ No newline at end of file diff --git a/docs/editor.todo b/docs/editor.todo index e796433..dee8d39 100644 --- a/docs/editor.todo +++ b/docs/editor.todo @@ -3,7 +3,7 @@ Editor: ✔ Come up with project directory structure @done (9/17/2021, 6:46:44 PM) ✔ Make the editor a separate module @high @done (11/1/2021, 2:24:35 PM) ✔ Implement Run Mode interface class @high @done (2/8/2022, 4:05:17 PM) - ☐ Reference raw asset files in a "content" folder@high + ✔ Reference raw asset files in a "content" folder@high @done (3/3/2022, 3:15:32 PM) ✔ Platform independant file browsing @done (2/8/2022, 4:05:29 PM) ☐ Scan script files to make sure they don't overwrite globals ☐ Figure out how to make game asset types integrate with editor asset types @critical @@ -14,22 +14,22 @@ Editor: Raw Asset Importers: - Need classes to import raw resource files for the editor ✔ Raw Resource importer interface class (EditorAsset) @done (2/24/2022, 3:14:04 PM) - ☐ Raw Image importer class - ☐ Raw Sound importer class - ☐ Raw font file importer class - ☐ Tile Set + ✔ Raw Image importer method @done (3/3/2022, 3:15:51 PM) + ☐ Raw Sound importer method + ☐ Raw font file importer method + ✔ Tile Set @done (3/3/2022, 3:16:08 PM) ☐ Tile Map Project (Class for loading and tracking project data): ✔ Generate new project at given location @done (11/9/2021, 3:26:03 PM) - ☐ Save project data + ✔ Save project data @done (3/3/2022, 3:16:16 PM) ✔ Open existing project @done (2/8/2022, 4:05:42 PM) Content Manager: ✔ Design interface @done (2/24/2022, 3:15:39 PM) ✔ Generate new content file @done (2/24/2022, 3:16:00 PM) - ☐ Load existing contents - ☐ Save/Update contents file + ✔ Load existing contents @done (3/3/2022, 3:16:21 PM) + ✔ Save/Update contents file @done (3/3/2022, 3:16:23 PM) GUI Panels: Project Overview (Tree view): @@ -43,7 +43,14 @@ Editor: Tools: Tile Map Editor: - ☐ Tile map canvas + ☐ Allow Tile Maps to be named + + Tile Map Canvas: + Implement drawing tiles: + ✔ Connect Selected Tile Set to the Canvas @done (3/11/2022, 6:11:07 PM) + ✔ Handle mouse clicking in update @done (3/11/2022, 6:11:09 PM) + ✔ Update current Map with current Tile on mouse click @done (3/11/2022, 6:11:12 PM) + ✔ Tile map pallete @done (2/24/2022, 3:15:26 PM) ☐ Hideable grid ☐ Stamp creater diff --git a/src/core/types.cpp b/src/core/types.cpp index 7c01bc4..e6bb60b 100644 --- a/src/core/types.cpp +++ b/src/core/types.cpp @@ -11,6 +11,7 @@ namespace lunarium { + //////////////////////////////////////////////////////////// // COLOR //////////////////////////////////////////////////////////// diff --git a/src/core/types.h b/src/core/types.h index 6a15978..285fc4f 100644 --- a/src/core/types.h +++ b/src/core/types.h @@ -13,6 +13,7 @@ #include #include + namespace lunarium { //////////////////////////////////////////////////////////// @@ -23,6 +24,9 @@ namespace lunarium { T X; T Y; + + bool operator==(const Vec2& rhs) const { return (this->X == rhs.X && this->Y == rhs.Y); } + bool operator!=(const Vec2& rhs) const { return !((*this) == rhs); } }; typedef Vec2 Vec2i; @@ -37,6 +41,9 @@ namespace lunarium { T Width; T Height; + + bool operator==(const Size& rhs) const { return (this->Width == rhs.Width && this->Height == rhs.Height); } + bool operator!=(const Size& rhs) const { return !((*this) == rhs); } }; typedef Size Sizei; diff --git a/src/graphics/opengl/defaultShaders.h b/src/graphics/opengl/defaultShaders.h index 9114a03..b57c652 100644 --- a/src/graphics/opengl/defaultShaders.h +++ b/src/graphics/opengl/defaultShaders.h @@ -50,7 +50,7 @@ namespace lunarium \ void main()\ {\ - TexCoords = vec2(vertex.z * uvManip.x + uvManip.y, vertex.w * uvManip.z + uvManip.w);\ + TexCoords = vec2(vertex.z * uvManip.x + uvManip.y, vertex.w * uvManip.z - uvManip.w);\ gl_Position = projection * model * vec4(vertex.xy, 0.0, 1.0);\ }"; diff --git a/src/graphics/opengl/glGraphics.cpp b/src/graphics/opengl/glGraphics.cpp index c97ad05..536fd3d 100644 --- a/src/graphics/opengl/glGraphics.cpp +++ b/src/graphics/opengl/glGraphics.cpp @@ -475,10 +475,12 @@ namespace lunarium { glm::mat4 id = glm::mat4(1.0f); glm::vec3 pos = glm::vec3(destination.X, destination.Y, 0.0f); + //glm::vec3 pos = glm::vec3(destination.left(), destination.top(), 0.0f); glm::mat4 trans = glm::translate(id, pos); trans = glm::rotate(trans, angle, glm::vec3(0.0f, 0.0f, 1.0f)); trans = glm::scale(trans, glm::vec3(destination.HalfWidth * 2, destination.HalfHeight * 2, 1.0f)); + mImageShader.MakeActive(); // float widthDiff = image.GetWidth() - source.Width; @@ -503,19 +505,18 @@ namespace lunarium // Logger::Log(LogCategory::GRAPHICS, LogLevel::INFO_VERBOSE, "uvManip Values: %f, %f, %f, %f", xScale, xOffset, yScale, yOffset); // * -1.0f on yScale will flip the image vertically - mImageShader.SetUniformf("uvManip", { xScale, xOffset, yScale /** -1.0f*/, yOffset}); + mImageShader.SetUniformf("uvManip", { xScale, xOffset, yScale * -1.0f, yOffset}); mImageShader.SetUniformMatrix("model", 1, glm::value_ptr(trans)); mImageShader.SetUniformMatrix("projection", 1, glm::value_ptr(mProjection)); - mImageShader.SetUniformf("spriteColor", { color.R, color.G, color.B, color.A }); + mImageShader.SetUniformf("spriteColor", { color.R, color.G, color.B, /*color.A */ 1.0f}); //} - + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, image.GetGLTextureID()); glBindVertexArray(mImageVAO); glDrawArrays(GL_TRIANGLES, 0, 6); glBindVertexArray(0); - } void OglGraphics::DrawString(const char* string, Rectangle boundingArea, Color color, float scale, int font) @@ -600,15 +601,26 @@ namespace lunarium // Setup geometry // https://learnopengl.com/In-Practice/2D-Game/Rendering-Sprites GLuint VBO; + // GLfloat vertices[] = { + // //Pos // Tex + // -0.5f, 0.5f, 0.0f, 0.0f, + // 0.5f, -0.5f, 1.0f, 1.0f, + // -0.5f, -0.5f, 0.0f, 1.0f, + + // -0.5f, 0.5f, 0.0f, 0.0f, + // 0.5f, 0.5f, 1.0f, 0.0f, + // 0.5f, -0.5f, 1.0f, 1.0f + // }; + GLfloat vertices[] = { - // Pos // Tex - -0.5f, 0.5f, 0.0f, 0.0f, - 0.5f, -0.5f, 1.0f, 1.0f, - -0.5f, -0.5f, 0.0f, 1.0f, - - -0.5f, 0.5f, 0.0f, 0.0f, - 0.5f, 0.5f, 1.0f, 0.0f, - 0.5f, -0.5f, 1.0f, 1.0f + //Pos // Tex + -0.5f, 0.5f, 0.0f, 1.0f, + 0.5f, -0.5f, 1.0f, 0.0f, + -0.5f, -0.5f, 0.0f, 0.0f, + + -0.5f, 0.5f, 0.0f, 1.0f, + 0.5f, 0.5f, 1.0f, 1.0f, + 0.5f, -0.5f, 1.0f, 0.0f }; // GLfloat vertices[] = { diff --git a/src/run_modes/editor/CMakeLists.txt b/src/run_modes/editor/CMakeLists.txt index 6bf8f35..ea67262 100644 --- a/src/run_modes/editor/CMakeLists.txt +++ b/src/run_modes/editor/CMakeLists.txt @@ -4,16 +4,16 @@ set(EDITOR_SRC "editor.cpp" "editor_helpers.cpp" "panel_manager.cpp" -"project/project.cpp" +"project.cpp" "panels/about.cpp" "panels/assetBrowser.cpp" "panels/worldTree.cpp" "panels/worldView.cpp" "panels/propertiesView.cpp" -"project/contents/content_manager.cpp" -"project/contents/editor_asset.cpp" -"project/contents/tile_map.cpp" -"project/contents/tile_set.cpp" +"contents/content_manager.cpp" +"contents/editor_asset.cpp" +"contents/tile_map.cpp" +"contents/tile_set.cpp" "tools/map_editor/map_editor.cpp" "tools/map_editor/panels/map_canvas.cpp" "tools/map_editor/panels/tile_set_view.cpp" diff --git a/src/run_modes/editor/project/contents/content_manager.cpp b/src/run_modes/editor/contents/content_manager.cpp similarity index 100% rename from src/run_modes/editor/project/contents/content_manager.cpp rename to src/run_modes/editor/contents/content_manager.cpp diff --git a/src/run_modes/editor/project/contents/content_manager.h b/src/run_modes/editor/contents/content_manager.h similarity index 100% rename from src/run_modes/editor/project/contents/content_manager.h rename to src/run_modes/editor/contents/content_manager.h diff --git a/src/run_modes/editor/project/contents/definitions.h b/src/run_modes/editor/contents/definitions.h similarity index 52% rename from src/run_modes/editor/project/contents/definitions.h rename to src/run_modes/editor/contents/definitions.h index db9341f..f31610c 100644 --- a/src/run_modes/editor/project/contents/definitions.h +++ b/src/run_modes/editor/contents/definitions.h @@ -9,8 +9,23 @@ #ifndef EDITOR_ASSETS_DEFINITIONS_H_ #define EDITOR_ASSETS_DEFINITIONS_H_ +#include + namespace lunarium { namespace editor { + // Allows tiles from multiple tilesets to be used in one map + // A tile ID of -1 will mean "no tile" and result in a transparent spot + // when rendered + struct TileRef + { + int TileSetID; + Vec2i TileIndex; + + bool operator==(const TileRef& rhs) const { return this->TileSetID == rhs.TileSetID && this->TileIndex == rhs.TileIndex; } + bool operator!=(const TileRef& rhs) const { return !((*this) == rhs); } + }; + + enum AssetType { EATYPE_IMAGE, diff --git a/src/run_modes/editor/project/contents/editor_asset.cpp b/src/run_modes/editor/contents/editor_asset.cpp similarity index 100% rename from src/run_modes/editor/project/contents/editor_asset.cpp rename to src/run_modes/editor/contents/editor_asset.cpp diff --git a/src/run_modes/editor/project/contents/editor_asset.h b/src/run_modes/editor/contents/editor_asset.h similarity index 100% rename from src/run_modes/editor/project/contents/editor_asset.h rename to src/run_modes/editor/contents/editor_asset.h diff --git a/src/run_modes/editor/contents/tile_map.cpp b/src/run_modes/editor/contents/tile_map.cpp new file mode 100644 index 0000000..4e7afb9 --- /dev/null +++ b/src/run_modes/editor/contents/tile_map.cpp @@ -0,0 +1,200 @@ +/****************************************************************************** +* File - tile_map.h +* Author - Joey Pollack +* Date - 2022/02/15 (y/m/d) +* Mod Date - 2022/02/15 (y/m/d) +* Description - Contains a single tile map +******************************************************************************/ + +#include "tile_map.h" +#include "tile_set.h" +#include +#include +#include +#include + +namespace lunarium { namespace editor +{ + + TileMap::TileMap(Sizei tile_size) + : mpMap(nullptr), mTileSize(tile_size), mIsDirty(false) + { + + } + + OpRes TileMap::AddTileSet(int id, TileSet* set) + { + if (mTileSets.find(id) != mTileSets.end()) + { + return OpRes::Fail("Cannot add tile set to Tile Map - Tile Set with id: %d already exists", id); + } + + if (set->GetTileSize() != mTileSize) + { + return OpRes::Fail("Cannot add tile set to Tile Map - Tile size does not match"); + } + + mTileSets[id] = set; + return OpRes::OK(); + } + + // NOTE: This could probably be replaced with code that marks it clean on save + // since this class will have to implement saving to a file (because it's an asset). + void TileMap::MarkClean() + { + mIsDirty = false; + } + + bool TileMap::IsDirty() const + { + return mIsDirty; + } + + void TileMap::ClearMap() + { + for(int i = 0; i < mSizeInTiles.Width; i++) + { + for (int j = 0; j < mSizeInTiles.Height; j++) + { + mpMap[i][j] = { -1, {-1, -1} }; + } + } + + mIsDirty = true; + } + + + void TileMap::SetTile(TileRef tile, Vec2i location) + { + if (location.X < 0 || location.X >= mSizeInTiles.Width || location.Y < 0 || location.Y >= mSizeInTiles.Height) + { + return; + } + + mpMap[location.X][location.Y] = tile; + mIsDirty = true; + } + + TileRef TileMap::GetTile(Vec2i location) + { + if (location.X < 0 || location.X >= mSizeInTiles.Width || location.Y < 0 || location.Y >= mSizeInTiles.Height) + { + return {-1, {-1, -1 }}; + } + + TileRef tile = mpMap[location.X][location.Y]; + + // Make sure the tileset exists + if (mTileSets.find(tile.TileSetID) == mTileSets.end()) + { + return {-1, {-1, -1 }}; + } + + return tile; + } + + Sizei TileMap::GetSizeInTiles() + { + return mSizeInTiles; + } + + Sizei TileMap::GetSizeInPixels() + { + if (!mpMap) + return { 0, 0 }; + + return { mTileSize.Width * mSizeInTiles.Width, mTileSize.Height * mSizeInTiles.Height }; + } + + Sizei TileMap::GetTileSize() + { + return mTileSize; + } + + void TileMap::ResizeMap(Sizei size) + { + TileRef** new_map = new TileRef*[size.Width]; + for(int i = 0; i < size.Width; i++) + { + new_map[i] = new TileRef[size.Height]; + } + + int smaller_width = mSizeInTiles.Width < size.Width ? mSizeInTiles.Width : size.Width; + int smaller_height = mSizeInTiles.Height < size.Height ? mSizeInTiles.Height : size.Height; + + for(int i = 0; i < smaller_width; i++) + { + for (int j = 0; j < smaller_height; j++) + { + new_map[i][j] = mpMap[i][j]; + } + } + + for(int i = 0; i < mSizeInTiles.Width; i++) + { + delete[] mpMap[i]; + } + + delete[] mpMap; + mSizeInTiles = size; + mpMap = new_map; + mIsDirty = true; + } + + + void TileMap::Render(lunarium::IGraphics* g) + { + if (!mpMap) + return; + + Sizei map_size_pixels = { mTileSize.Width * mSizeInTiles.Width, mTileSize.Height * mSizeInTiles.Height }; + + // Draw Map + for (int i = 0; i < mSizeInTiles.Width; i++) + { + for (int j = 0; j < mSizeInTiles.Height; j++) + { + // If there is no tile here skip this spot + if (mpMap[i][j].TileIndex.X == -1 || mpMap[i][j].TileIndex.Y == -1) + continue; + + int id = mpMap[i][j].TileSetID; + + // -1 means an intentionally empty tile + if (-1 == id) + { + continue; + } + + // Make sure the tileset exists + if (mTileSets.find(id) == mTileSets.end()) + { + Logger::Log(Editor::LogCat, LogLevel::WARNING, "Tile Map is missing tile set. No Tile Set with id: %d", id); + continue; + } + + TileSet* set = mTileSets[id]; + Rectangle dest = Rectangle::MakeFromTopLeft(i * mTileSize.Width, j * mTileSize.Height, mTileSize.Width, mTileSize.Height); + Rectangle src = set->GetTileRect(mpMap[i][j].TileIndex); + + g->DrawImage(*set->GetImage(), src, dest, Color::White()); + //g->DrawImage(*set->GetImage(), glm::vec2(dest.left(), dest.top()), Color::White()); + //g->DrawImage(*set->GetImage(), Rectangle::MakeFromTopLeft(0, 0, 1024, 1024), dest, Color::White()); + //g->DrawImage(*set->GetImage(), Rectangle::MakeFromTopLeft(16, 0, 16, 16), Rectangle::MakeFromTopLeft(0, 0, 500, 500), Color::White()); + } + } + + // Draw grid + for (int i = 0; i < mSizeInTiles.Width; i++) + { + g->DrawLine(glm::vec2(i * mTileSize.Width, 0), glm::vec2(i * mTileSize.Width, map_size_pixels.Height), Color::Black(), 1.0f); + } + g->DrawLine(glm::vec2(map_size_pixels.Width, 0), glm::vec2(map_size_pixels.Width, map_size_pixels.Height), Color::Black(), 1.0f); + + for (int j = 0; j < mSizeInTiles.Height; j++) + { + g->DrawLine(glm::vec2(0, j * mTileSize.Height), glm::vec2(map_size_pixels.Width, j * mTileSize.Height), Color::Black(), 1.0f); + } + g->DrawLine(glm::vec2(0, map_size_pixels.Height), glm::vec2(map_size_pixels.Width, map_size_pixels.Height), Color::Black(), 1.0f); + } +}} diff --git a/src/run_modes/editor/project/contents/tile_map.h b/src/run_modes/editor/contents/tile_map.h similarity index 71% rename from src/run_modes/editor/project/contents/tile_map.h rename to src/run_modes/editor/contents/tile_map.h index 9d1b81e..a33dc63 100644 --- a/src/run_modes/editor/project/contents/tile_map.h +++ b/src/run_modes/editor/contents/tile_map.h @@ -9,7 +9,9 @@ #ifndef TILE_MAP_H_ #define TILE_MAP_H_ +#include "definitions.h" #include +#include #include namespace lunarium { class IGraphics; } @@ -18,19 +20,15 @@ namespace lunarium { namespace editor { class TileSet; - // Allows tiles from multiple tilesets to be used in one map - // A tile ID of -1 will mean "no tile" and result in a transparent spot - // when rendered - struct TileRef - { - int TileSetID; - Vec2i TileIndex; - }; - class TileMap { public: - TileMap(std::map* tilesets); + TileMap(Sizei tile_size); + [[NoDiscard]] OpRes AddTileSet(int id, TileSet*); + + void MarkClean(); + bool IsDirty() const; + void SetTile(TileRef, Vec2i location); TileRef GetTile(Vec2i location); @@ -39,6 +37,7 @@ namespace lunarium { namespace editor Sizei GetSizeInTiles(); Sizei GetSizeInPixels(); + Sizei GetTileSize(); // Call during render to texture phase void Render(lunarium::IGraphics* g); @@ -46,7 +45,9 @@ namespace lunarium { namespace editor private: TileRef** mpMap; Sizei mSizeInTiles; - std::map* mpTileSets; + Sizei mTileSize; + std::map mTileSets; + bool mIsDirty; }; }} diff --git a/src/run_modes/editor/project/contents/tile_set.cpp b/src/run_modes/editor/contents/tile_set.cpp similarity index 90% rename from src/run_modes/editor/project/contents/tile_set.cpp rename to src/run_modes/editor/contents/tile_set.cpp index 6e8c0c2..0caa7a1 100644 --- a/src/run_modes/editor/project/contents/tile_set.cpp +++ b/src/run_modes/editor/contents/tile_set.cpp @@ -17,7 +17,7 @@ namespace lunarium { namespace editor { TileSet::TileSet() - : EditorAsset(AssetType::EATYPE_TILE_SET), mSetImage(nullptr), mTileSize({ 0, 0}) + : EditorAsset(AssetType::EATYPE_TILE_SET), mTileSetID(-1), mSetImage(nullptr), mTileSize({ 0, 0}) { } @@ -46,6 +46,7 @@ namespace lunarium { namespace editor return OpRes::Fail("Could not load image file: %s", GetFileLocation().string().c_str()); } + mTileSetID = node.attribute("TileSetID").as_int(); mTileSize.Width = node.attribute("TileSizeWidth").as_int(); mTileSize.Height = node.attribute("TileSizeHeight").as_int(); mNumTiles.Width = node.attribute("NumTilesCol").as_int(); @@ -56,6 +57,7 @@ namespace lunarium { namespace editor OpRes TileSet::SaveToXML(pugi::xml_node& node) { + node.append_attribute("TileSetID").set_value(mTileSetID); node.append_attribute("TileSizeWidth").set_value(mTileSize.Width); node.append_attribute("TileSizeHeight").set_value(mTileSize.Height); node.append_attribute("NumTilesCol").set_value(mNumTiles.Width); @@ -64,6 +66,16 @@ namespace lunarium { namespace editor return OpRes::OK(); } + void TileSet::SetTileSetID(int id) + { + mTileSetID = id; + } + + int TileSet::GetTileSetID() const + { + return mTileSetID; + } + void TileSet::SetImage(Image* image) { mSetImage = image; diff --git a/src/run_modes/editor/project/contents/tile_set.h b/src/run_modes/editor/contents/tile_set.h similarity index 90% rename from src/run_modes/editor/project/contents/tile_set.h rename to src/run_modes/editor/contents/tile_set.h index 4cdb718..dbb6fe0 100644 --- a/src/run_modes/editor/project/contents/tile_set.h +++ b/src/run_modes/editor/contents/tile_set.h @@ -26,6 +26,9 @@ namespace lunarium { namespace editor OpRes LoadRawFile(); OpRes LoadFromXML(pugi::xml_node& node); OpRes SaveToXML(pugi::xml_node& node); + + void SetTileSetID(int id); + int GetTileSetID() const; void SetImage(Image* image); void SetTileSize(Sizei size); @@ -40,6 +43,7 @@ namespace lunarium { namespace editor Image* mSetImage; Sizei mTileSize; // in pixels, must be a square power of 2 Sizei mNumTiles; + int mTileSetID; }; }} diff --git a/src/run_modes/editor/editor.h b/src/run_modes/editor/editor.h index e0b1c18..28d7137 100644 --- a/src/run_modes/editor/editor.h +++ b/src/run_modes/editor/editor.h @@ -12,7 +12,7 @@ #include #include -#include "project/project.h" +#include "project.h" #include "panel_manager.h" #include "panels/about.h" #include diff --git a/src/run_modes/editor/project/project.cpp b/src/run_modes/editor/project.cpp similarity index 100% rename from src/run_modes/editor/project/project.cpp rename to src/run_modes/editor/project.cpp diff --git a/src/run_modes/editor/project/project.h b/src/run_modes/editor/project.h similarity index 100% rename from src/run_modes/editor/project/project.h rename to src/run_modes/editor/project.h diff --git a/src/run_modes/editor/project/contents/tile_map.cpp b/src/run_modes/editor/project/contents/tile_map.cpp deleted file mode 100644 index ad3b515..0000000 --- a/src/run_modes/editor/project/contents/tile_map.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/****************************************************************************** -* File - tile_map.h -* Author - Joey Pollack -* Date - 2022/02/15 (y/m/d) -* Mod Date - 2022/02/15 (y/m/d) -* Description - Contains a single tile map -******************************************************************************/ - -#include "tile_map.h" -#include "tile_set.h" -#include -#include - -namespace lunarium { namespace editor -{ - - TileMap::TileMap(std::map* tilesets) - : mpTileSets(tilesets), mpMap(nullptr) - { - - } - - void TileMap::ClearMap() - { - for(int i = 0; i < mSizeInTiles.Width; i++) - { - for (int j = 0; j < mSizeInTiles.Height; j++) - { - mpMap[i][j] = { -1, {-1, -1} }; - } - } - } - - - Sizei TileMap::GetSizeInTiles() - { - return mSizeInTiles; - } - - Sizei TileMap::GetSizeInPixels() - { - if (!mpMap) - return { 0, 0 }; - - Sizei tile_size = (*mpTileSets)[mpMap[0][0].TileSetID]->GetTileSize(); - return { tile_size.Width * mSizeInTiles.Width, tile_size.Height * mSizeInTiles.Height }; - } - - void TileMap::ResizeMap(Sizei size) - { - TileRef** new_map = new TileRef*[size.Width]; - for(int i = 0; i < size.Width; i++) - { - new_map[i] = new TileRef[size.Height]; - } - - int smaller_width = mSizeInTiles.Width < size.Width ? mSizeInTiles.Width : size.Width; - int smaller_height = mSizeInTiles.Height < size.Height ? mSizeInTiles.Height : size.Height; - - for(int i = 0; i < smaller_width; i++) - { - for (int j = 0; j < smaller_height; j++) - { - new_map[i][j] = mpMap[i][j]; - } - } - - for(int i = 0; i < mSizeInTiles.Width; i++) - { - delete[] mpMap[i]; - } - - delete[] mpMap; - mSizeInTiles = size; - mpMap = new_map; - } - - - void TileMap::Render(lunarium::IGraphics* g) - { - if (!mpMap) - return; - - // Check the size of the tiles - each tileset should have the same sized tiles for the same map - Sizei tile_size = (*mpTileSets)[mpMap[0][0].TileSetID]->GetTileSize(); - Sizei map_size_pixels = { tile_size.Width * mSizeInTiles.Width, tile_size.Height * mSizeInTiles.Height }; - - // Draw Map - for (int i = 0; i < mSizeInTiles.Width; i++) - { - for (int j = 0; j < mSizeInTiles.Height; j++) - { - // If there is no tile here skip this spot - if (mpMap[i][j].TileIndex.X == -1 || mpMap[i][j].TileIndex.Y == -1) - continue; - - TileSet* set = (*mpTileSets)[mpMap[i][j].TileSetID]; - Rectangle dest = Rectangle::MakeFromTopLeft(i * tile_size.Width, j * tile_size.Height, tile_size.Width, tile_size.Height); - Rectangle src = set->GetTileRect(mpMap[i][j].TileIndex); - - g->DrawImage(*set->GetImage(), src, dest, Color::White()); - } - } - - // Draw grid - for (int i = 0; i < mSizeInTiles.Width; i++) - { - g->DrawLine(glm::vec2(i * tile_size.Width, 0), glm::vec2(i * tile_size.Width, map_size_pixels.Height), Color::Black(), 1.0f); - } - g->DrawLine(glm::vec2(map_size_pixels.Width, 0), glm::vec2(map_size_pixels.Width, map_size_pixels.Height), Color::Black(), 1.0f); - - for (int j = 0; j < mSizeInTiles.Height; j++) - { - g->DrawLine(glm::vec2(0, j * tile_size.Height), glm::vec2(map_size_pixels.Width, j * tile_size.Height), Color::Black(), 1.0f); - } - g->DrawLine(glm::vec2(0, map_size_pixels.Height), glm::vec2(map_size_pixels.Width, map_size_pixels.Height), Color::Black(), 1.0f); - } -}} diff --git a/src/run_modes/editor/tools/map_editor/map_editor.cpp b/src/run_modes/editor/tools/map_editor/map_editor.cpp index 919f3e0..a2570bb 100644 --- a/src/run_modes/editor/tools/map_editor/map_editor.cpp +++ b/src/run_modes/editor/tools/map_editor/map_editor.cpp @@ -10,13 +10,13 @@ #include #include -#include #include #include #include #include -#include -#include +#include +#include +#include // Panels #include "panels/map_canvas.h" @@ -28,7 +28,7 @@ namespace lunarium { namespace editor { MapEditor::MapEditor() - : mpEditor(nullptr), mIsOpen(false), mMapLoaded(false), mImportTileSet(false), mTileSetNextID(0) + : mpEditor(nullptr), mIsOpen(false), mMapLoaded(false), mImportTileSet(false), mTileSetNextID(0), mpMap(nullptr) { } @@ -52,6 +52,15 @@ namespace lunarium { namespace editor Open(); + std::vector tile_sets; + ContentManager::GetInstance().GetAllAssetsByType(tile_sets, AssetType::EATYPE_TILE_SET); + for (int i = 0; i < tile_sets.size(); i++) + { + TileSet* ts = (TileSet*) tile_sets[i]; + mTileSets[ts->GetTileSetID()] = ts; + //((TileSetView*)mPanelManager.GetPanel(gui::PanelType::PT_TILE_SET_VIEW))->SetTileSet((TileSet*)tile_sets[i]); + } + return OpRes::OK(); } @@ -116,7 +125,7 @@ namespace lunarium { namespace editor { return; } - + mIsOpen = true; } @@ -133,11 +142,50 @@ namespace lunarium { namespace editor void MapEditor::NewMap() { - + if (mpMap && mpMap->IsDirty()) + { + // TODO: Do last chance save + } + + delete mpMap; + // HACK: Hardcoding the tile size to 16, 16 + mpMap = new TileMap({16, 16}); + + // HACK: Map size hardcoded for testing + mpMap->ResizeMap({50, 50}); + mpMap->ClearMap(); + + // Add all tilesets that match the Map's tile size + ((TileSetView*)mPanelManager.GetPanel(gui::PanelType::PT_TILE_SET_VIEW))->ClearTileSets(); + for (auto iter = mTileSets.begin(); iter != mTileSets.end(); iter++) + { + if (iter->second->GetTileSize() == mpMap->GetTileSize()) + { + mpMap->AddTileSet(iter->second->GetTileSetID(), iter->second); + ((TileSetView*)mPanelManager.GetPanel(gui::PanelType::PT_TILE_SET_VIEW))->AddTileSet(iter->second); + } + } + + ((MapCanvas*)mPanelManager.GetPanel(gui::PanelType::PT_MAP_CANVAS))->SetTileMap(mpMap); } OpRes MapEditor::LoadMap(std::string map) { + { + // TODO: Do last chance save if needed + + // TODO: Clean up currrent map + } + + // TODO: Clear out the tileset view + + // TODO: Load the new map + + // TODO: Add all tilesets that match the Map's tile size + // to the Map and the TileSetView panel + + // TODO: Set the map for the MapCanvas panel + return OpRes::Fail("MapEditor::LoadMap not implemented"); } @@ -165,6 +213,12 @@ namespace lunarium { namespace editor if (ImGui::BeginMenu("File")) { + if (ImGui::MenuItem("New Map")) + { + NewMap(); + } + + ImGui::Separator(); if (ImGui::MenuItem("Import Tile Set")) { mImportTileSet = true; @@ -218,37 +272,18 @@ namespace lunarium { namespace editor uint64_t id = 0; ContentManager::GetInstance().ImportFile(*path, mpEditor->GetAssetBrowserLocation() / path->filename(), AssetType::EATYPE_TILE_SET, id).LogIfFailed(Editor::LogCat); - // For now just directly load the file and make a tileset out of it - // int w, h, n; - // stbi_set_flip_vertically_on_load(1); - // unsigned char* buffer = stbi_load(path->string().c_str(), &w, &h, &n, 0); - - // Image* i = new Image(); - // i->SetData(buffer); - // i->SetFormat(ImageFormat::RGBA); - - // if (n == 3) - // { - // i->SetFormat(ImageFormat::RGB); - // } - - // i->SetWidth(w); - // i->SetHeight(h); - - // Core::Graphics().RegisterImage(*i); - - // TileSet* ts = new TileSet(); - // // ts->SetFileLocation(*path); - // ts->SetImage(i); - TileSet* ts = (TileSet*)ContentManager::GetInstance().GetAsset(id); ts->SetTileSize({16, 16}); // NOTE: Hardcoding the tile size for testing - + ts->SetTileSetID(mTileSetNextID); mTileSets[mTileSetNextID] = ts; mTileSetNextID++; - // FOR TESTING - ((TileSetView*)mPanelManager.GetPanel(gui::PanelType::PT_TILE_SET_VIEW))->SetTileSet(ts); + // Check if the tile set can be used on the current map + if (mpMap && mpMap->GetTileSize() == ts->GetTileSize()) + { + mpMap->AddTileSet(ts->GetTileSetID(), ts); + ((TileSetView*)mPanelManager.GetPanel(gui::PanelType::PT_TILE_SET_VIEW))->AddTileSet(ts); + } mImportTileSet = false; } @@ -261,4 +296,10 @@ namespace lunarium { namespace editor } } + + + void MapEditor::ChangeSelectedTile(TileRef tile) + { + ((MapCanvas*)mPanelManager.GetPanel(gui::PanelType::PT_MAP_CANVAS))->SetSelectedTile(tile); + } }} diff --git a/src/run_modes/editor/tools/map_editor/map_editor.h b/src/run_modes/editor/tools/map_editor/map_editor.h index db2a26d..43feaea 100644 --- a/src/run_modes/editor/tools/map_editor/map_editor.h +++ b/src/run_modes/editor/tools/map_editor/map_editor.h @@ -15,6 +15,7 @@ #include #include "../../panel_manager.h" #include +#include namespace lunarium { class IGraphics; @@ -25,6 +26,7 @@ namespace lunarium { namespace editor { + class TileMap; class TileSet; class Editor; class MapEditor @@ -48,11 +50,13 @@ namespace editor const std::map* GetTileSets() const; + void ChangeSelectedTile(TileRef tile); + private: bool mIsOpen; bool mMapLoaded; - bool mIsDirty; + TileMap* mpMap; Editor* mpEditor; PanelManager mPanelManager; diff --git a/src/run_modes/editor/tools/map_editor/panels/map_canvas.cpp b/src/run_modes/editor/tools/map_editor/panels/map_canvas.cpp index fa6aede..59c4cb0 100644 --- a/src/run_modes/editor/tools/map_editor/panels/map_canvas.cpp +++ b/src/run_modes/editor/tools/map_editor/panels/map_canvas.cpp @@ -9,6 +9,7 @@ #include "map_canvas.h" #include "../map_editor.h" #include +#include #include #include #include @@ -27,7 +28,38 @@ namespace lunarium { namespace editor } void MapCanvas::Update(float delta) - { + { + // Check for input and update map + if (mMap && ImGui::GetIO().MouseDown[ImGuiMouseButton_Left] && mSelectedTile.TileSetID > -1 + && mSelectedTile.TileIndex.X > -1&& mSelectedTile.TileIndex.Y > -1) + { + // Get mouse coords + float x = ImGui::GetMousePos().x; + float y = ImGui::GetMousePos().y; + + // Adjust for window pos + x -= mWorkAreaPos.X; + y -= mWorkAreaPos.Y; + + // Check that mouse pos is within the window + bool is_in_window = x >= 0.0f && x < mWorkAreaSize.X && y >= 0.0f && y < mWorkAreaSize.Y; + + if (is_in_window) + { + // Convert to tile grid index + x /= mMap->GetTileSize().Width; + y /= mMap->GetTileSize().Height; + + // Don't update the map if the current tile is already set to the selected tile + if (mMap->GetTile({ (int)x, (int)y }) != mSelectedTile) + { + mMap->SetTile(mSelectedTile, { (int)x, (int)y }); + mpCanvasImage = nullptr; + } + } + } + + // Check if redraw is needed if (!mpCanvasImage) { if (mMap) @@ -74,8 +106,6 @@ namespace lunarium { namespace editor ImGuiIO& io = ImGui::GetIO(); float x = io.MousePos.x - pos.x; float y = io.MousePos.y - pos.y; - - std::ostringstream oss; oss << "Mouse Position on Panel: "; @@ -92,10 +122,19 @@ namespace lunarium { namespace editor oss <<"\nFrameHeightWithSpacing: " << ImGui::GetFrameHeightWithSpacing(); mMouseStatusInfo = oss.str(); + mWorkAreaPos = { ImGui::GetWindowPos().x, ImGui::GetWindowPos().y }; + mWorkAreaSize = { ImGui::GetWindowSize().x, ImGui::GetWindowSize().y }; + mScrollOffset = { ImGui::GetScrollX(), ImGui::GetScrollY() }; + + // Adjust pos and size to account for the title bar + mWorkAreaPos.Y += ImGui::GetFrameHeight(); + mWorkAreaSize.Y -= ImGui::GetFrameHeight(); + //ImGui::Text(mMouseStatusInfo.c_str()); if (mpCanvasImage) { - ImGui::Image((ImTextureID)mpCanvasImage->GetGLTextureID64(), ImVec2(mpCanvasImage->GetWidth(), mpCanvasImage->GetHeight())); + ImGui::Image((ImTextureID)mpCanvasImage->GetGLTextureID64(), + ImVec2(mpCanvasImage->GetWidth(), mpCanvasImage->GetHeight()), ImVec2(0, 1), ImVec2(1, 0)); } // TODO: If a tile on the map was changed this frame null out the canvas image so it will be redrawn @@ -106,7 +145,12 @@ namespace lunarium { namespace editor } void MapCanvas::SetTileMap(TileMap* pMap) - { + { + if (mMap && mMap->GetSizeInPixels() != pMap->GetSizeInPixels()) + { + mMapSizeChanged = true; + } + mMap = pMap; // Force the image to redraw diff --git a/src/run_modes/editor/tools/map_editor/panels/map_canvas.h b/src/run_modes/editor/tools/map_editor/panels/map_canvas.h index 2d924f7..2c940e1 100644 --- a/src/run_modes/editor/tools/map_editor/panels/map_canvas.h +++ b/src/run_modes/editor/tools/map_editor/panels/map_canvas.h @@ -10,8 +10,7 @@ #define MAP_CANVAS_H_ #include -#include -#include +#include #include namespace lunarium { class Image; class IGraphics; } @@ -19,6 +18,7 @@ namespace lunarium { class Image; class IGraphics; } namespace lunarium { namespace editor { class MapEditor; + class TileMap; class MapCanvas : public gui::Panel { @@ -38,6 +38,9 @@ namespace lunarium { namespace editor private: MapEditor* mpMapEditor; + Vec2f mWorkAreaPos; + Vec2f mWorkAreaSize; + Vec2f mScrollOffset; std::string mMouseStatusInfo; int mFrameBuffer; Image* mpCanvasImage; diff --git a/src/run_modes/editor/tools/map_editor/panels/tile_set_view.cpp b/src/run_modes/editor/tools/map_editor/panels/tile_set_view.cpp index dad9e1b..8087dea 100644 --- a/src/run_modes/editor/tools/map_editor/panels/tile_set_view.cpp +++ b/src/run_modes/editor/tools/map_editor/panels/tile_set_view.cpp @@ -8,7 +8,7 @@ #include "tile_set_view.h" #include "../map_editor.h" -#include +#include #include #include #include @@ -61,6 +61,9 @@ namespace lunarium { namespace editor //Logger::Log(Editor::LogCat, LogLevel::INFO_VERBOSE, "Updating Tile Selection: tile (%d, %d)", mSelectedTile.X, mSelectedTile.Y); + // Notify the editor that the selected tile has changed + mpEditor->ChangeSelectedTile({ mpSelectedTileSet->GetTileSetID(), mSelectedTile }); + Invalidate(); } } @@ -134,8 +137,7 @@ namespace lunarium { namespace editor } if (ImGui::BeginCombo("Tile Sets", name.c_str())) { - auto tile_sets = mpEditor->GetTileSets(); - for (auto iter = tile_sets->begin(); iter != tile_sets->end(); iter++) + for (auto iter = mTileSets.begin(); iter != mTileSets.end(); iter++) { bool selected = false; if (ImGui::Selectable(iter->second->GetFileLocation().filename().string().c_str(), &selected)) @@ -174,12 +176,25 @@ namespace lunarium { namespace editor return mIsOpen; } - void TileSetView::SetTileSet(TileSet* set) + void TileSetView::ClearTileSets() { - mpSelectedTileSet = set; + mTileSets.clear(); + mpSelectedTileSet = nullptr; + mSelectedTile = {-1, -1}; Invalidate(true); } + void TileSetView::AddTileSet(TileSet* set) + { + mTileSets[set->GetTileSetID()] = set; + + if (!mpSelectedTileSet) + { + mpSelectedTileSet = set; + Invalidate(true); + } + } + TileSet* TileSetView::GetTileSet() { return mpSelectedTileSet; diff --git a/src/run_modes/editor/tools/map_editor/panels/tile_set_view.h b/src/run_modes/editor/tools/map_editor/panels/tile_set_view.h index 01b4e03..b9184d2 100644 --- a/src/run_modes/editor/tools/map_editor/panels/tile_set_view.h +++ b/src/run_modes/editor/tools/map_editor/panels/tile_set_view.h @@ -12,6 +12,7 @@ #include #include #include +#include namespace lunarium { class Image; } @@ -27,7 +28,8 @@ namespace lunarium { namespace editor void Update(float delta); bool DoFrame(); - void SetTileSet(TileSet* set); + void ClearTileSets(); + void AddTileSet(TileSet* set); TileSet* GetTileSet(); Vec2i GetSelectedTile(); @@ -36,6 +38,7 @@ namespace lunarium { namespace editor private: MapEditor* mpEditor; + std::map mTileSets; TileSet* mpSelectedTileSet; int mFrameBuffer; bool mInvalidate; diff --git a/src/run_modes/tester/scenes/simpleRenderScene.cpp b/src/run_modes/tester/scenes/simpleRenderScene.cpp index 6c8f002..b9c155c 100644 --- a/src/run_modes/tester/scenes/simpleRenderScene.cpp +++ b/src/run_modes/tester/scenes/simpleRenderScene.cpp @@ -61,6 +61,9 @@ namespace lunarium mpTestImageLoad->SetWidth(w); mpTestImageLoad->SetHeight(h); + mSrcWidth = w; + mSrcHeight = h; + Core::Graphics().RegisterImage(*mpTestImageLoad); angle = 0.0f; @@ -88,6 +91,18 @@ namespace lunarium mTextBoxWidth += 10; } + if (Core::Input().IsKeyDown(KeyCode::R)) + { + mSrcWidth -= 10.0f; + mSrcHeight -= 10.0f; + } + + if (Core::Input().IsKeyDown(KeyCode::F)) + { + mSrcWidth += 10.0f; + mSrcHeight += 10.0f; + } + mTextBoxWidth = Math::ClampI(mTextBoxWidth, 20, 500); // Image Size adjustment @@ -159,8 +174,6 @@ namespace lunarium mpRenderedImage = Core::GetInstance().EndRenderToTexture(); - - box_angle += 0.01f; } @@ -176,7 +189,14 @@ namespace lunarium 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->DrawImage(*mpTestImageLoad, glm::vec2(0.0f, 0.0f), Color::White()); - // g->DrawImage(*mpTestImageLoad, Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mpTestImageLoad->GetWidth(), (float)mpTestImageLoad->GetHeight()), - // Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mpTestImageLoad->GetWidth(), (float)mpTestImageLoad->GetHeight()), Color::White()); + //Rectangle src = Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mpTestImageLoad->GetWidth(), (float)mpTestImageLoad->GetHeight()); + //Rectangle src = Rectangle::MakeFromTopLeft(0.0f, 0.0f, mSrcWidth, mSrcHeight); + Rectangle src = Rectangle::MakeFromTopLeft(0.0f, 0.0f, 16, 16); + Rectangle dest = Rectangle::MakeFromTopLeft(100.0f, 100.0f, 512.0f, 512.0f); + g->DrawImage(*mpTestImageLoad, src, + dest, Color(1.0f, 1.0f, 1.0f, 0.9f)); + + // g->DrawImage(*mpTestImageLoad, src, + // dest, Color(1.0f, 1.0f, 1.0f, 0.8f)); } } \ No newline at end of file diff --git a/src/run_modes/tester/scenes/simpleRenderScene.h b/src/run_modes/tester/scenes/simpleRenderScene.h index 3faed9a..3724424 100644 --- a/src/run_modes/tester/scenes/simpleRenderScene.h +++ b/src/run_modes/tester/scenes/simpleRenderScene.h @@ -37,6 +37,9 @@ namespace lunarium float angle; float box_angle; + float mSrcWidth; + float mSrcHeight; + struct GridTestObj { int X;