Tile maps can now be painted to correctly

Gui_Panel_Refactor
Joeyrp 4 years ago
parent 60bb47f25e
commit 8360eceabf

@ -1,3 +1,5 @@
High Importance:
☐ The Map Editor does not get the tile maps when a project is opened @high
✔ 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)

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

@ -11,6 +11,7 @@
namespace lunarium
{
////////////////////////////////////////////////////////////
// COLOR
////////////////////////////////////////////////////////////

@ -13,6 +13,7 @@
#include <glm/glm.hpp>
#include <box2d/box2d.h>
namespace lunarium
{
////////////////////////////////////////////////////////////
@ -23,6 +24,9 @@ namespace lunarium
{
T X;
T Y;
bool operator==(const Vec2<T>& rhs) const { return (this->X == rhs.X && this->Y == rhs.Y); }
bool operator!=(const Vec2<T>& rhs) const { return !((*this) == rhs); }
};
typedef Vec2<int> Vec2i;
@ -37,6 +41,9 @@ namespace lunarium
{
T Width;
T Height;
bool operator==(const Size<T>& rhs) const { return (this->Width == rhs.Width && this->Height == rhs.Height); }
bool operator!=(const Size<T>& rhs) const { return !((*this) == rhs); }
};
typedef Size<int> Sizei;

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

@ -479,35 +479,21 @@ namespace lunarium
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;
// if (source.Width == image.GetWidth() && source.Height == image.GetHeight())
// {
// mImageShader.SetUniformf("uvManip", { 1.0f, 0.0f, 1.0f, 0.0f }); // No uv Manipulation
// mImageShader.SetUniformMatrix("model", 1, glm::value_ptr(trans));
// mImageShader.SetUniformMatrix("projection", 1, glm::value_ptr(mProjection));
// mImageShader.SetUniformf("spriteColor", { color.Red, color.Green, color.Blue, color.Alpha });
// }
// else
// {
mImageShader.MakeActive();
// NOTE: Pretty sure these values will work out to be correct with out the if check
float xScale = (source.HalfWidth * 2) / image.GetWidth();
float xOffset = source.left() / image.GetWidth();
float yScale = (source.HalfHeight * 2) / image.GetHeight();
float yOffset = source.top() / image.GetHeight();
// 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 });
//}
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, image.GetGLTextureID());
@ -515,7 +501,6 @@ namespace lunarium
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 +585,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, 1.0f,
0.5f, -0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.0f, 0.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
-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[] = {

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

@ -9,8 +9,23 @@
#ifndef EDITOR_ASSETS_DEFINITIONS_H_
#define EDITOR_ASSETS_DEFINITIONS_H_
#include <core/types.h>
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,

@ -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 <core/core.h>
#include <graphics/graphics.h>
#include <editor/editor.h>
#include <utils/logger.h>
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);
}
}}

@ -9,7 +9,9 @@
#ifndef TILE_MAP_H_
#define TILE_MAP_H_
#include "definitions.h"
#include <core/types.h>
#include <utils/opRes.h>
#include <map>
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<int, TileSet*>* 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<int, TileSet*>* mpTileSets;
Sizei mTileSize;
std::map<int, TileSet*> mTileSets;
bool mIsDirty;
};
}}

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

@ -27,6 +27,9 @@ namespace lunarium { namespace editor
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;
};
}}

@ -12,7 +12,7 @@
#include <core/iRunMode.h>
#include <utils/opRes.h>
#include "project/project.h"
#include "project.h"
#include "panel_manager.h"
#include "panels/about.h"
#include <gui/file_browser.h>

@ -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 <core/core.h>
#include <graphics/graphics.h>
namespace lunarium { namespace editor
{
TileMap::TileMap(std::map<int, TileSet*>* 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);
}
}}

@ -10,13 +10,13 @@
#include <core/core.h>
#include <graphics/graphics.h>
#include <editor/project/contents/content_manager.h>
#include <assets/types/image.h>
#include <editor/editor.h>
#include <gui/panel.h>
#include <gui/dearimgui/imgui.h>
#include <editor/project/contents/tile_set.h>
#include <editor/project/contents/tile_map.h>
#include <editor/contents/content_manager.h>
#include <editor/contents/tile_set.h>
#include <editor/contents/tile_map.h>
// 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<EditorAsset*> 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();
}
@ -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);
}
}}

@ -15,6 +15,7 @@
#include <utils/opRes.h>
#include "../../panel_manager.h"
#include <gui/file_browser.h>
#include <editor/contents/definitions.h>
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<int, TileSet*>* GetTileSets() const;
void ChangeSelectedTile(TileRef tile);
private:
bool mIsOpen;
bool mMapLoaded;
bool mIsDirty;
TileMap* mpMap;
Editor* mpEditor;
PanelManager mPanelManager;

@ -9,6 +9,7 @@
#include "map_canvas.h"
#include "../map_editor.h"
#include <editor/editor.h>
#include <editor/contents/tile_map.h>
#include <gui/dearimgui/imgui.h>
#include <core/core.h>
#include <graphics/graphics.h>
@ -28,6 +29,37 @@ 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)
@ -75,8 +107,6 @@ namespace lunarium { namespace editor
float x = io.MousePos.x - pos.x;
float y = io.MousePos.y - pos.y;
std::ostringstream oss;
oss << "Mouse Position on Panel: ";
if (x < 0.0f || y < 0.0f || x > size.x || y > size.y)
@ -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
@ -107,6 +146,11 @@ namespace lunarium { namespace editor
void MapCanvas::SetTileMap(TileMap* pMap)
{
if (mMap && mMap->GetSizeInPixels() != pMap->GetSizeInPixels())
{
mMapSizeChanged = true;
}
mMap = pMap;
// Force the image to redraw

@ -10,8 +10,7 @@
#define MAP_CANVAS_H_
#include <gui/panel.h>
#include <editor/project/contents/tile_map.h>
#include <core/types.h>
#include <editor/contents/definitions.h>
#include <string>
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;

@ -8,7 +8,7 @@
#include "tile_set_view.h"
#include "../map_editor.h"
#include <editor/project/contents/tile_set.h>
#include <editor/contents/tile_set.h>
#include <assets/types/image.h>
#include <editor/editor.h>
#include <core/core.h>
@ -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,11 +176,24 @@ namespace lunarium { namespace editor
return mIsOpen;
}
void TileSetView::SetTileSet(TileSet* set)
void TileSetView::ClearTileSets()
{
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()
{

@ -12,6 +12,7 @@
#include <gui/panel.h>
#include <core/types.h>
#include <utils/highResTimer.h>
#include <map>
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<int, TileSet*> mTileSets;
TileSet* mpSelectedTileSet;
int mFrameBuffer;
bool mInvalidate;

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

@ -37,6 +37,9 @@ namespace lunarium
float angle;
float box_angle;
float mSrcWidth;
float mSrcHeight;
struct GridTestObj
{
int X;

Loading…
Cancel
Save