summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaG1924 <12997935+LaG1924@users.noreply.github.com>2018-08-05 15:21:42 +0200
committerLaG1924 <12997935+LaG1924@users.noreply.github.com>2018-08-05 15:21:42 +0200
commitf3e01e3a318fea8d7065468df09e32c1765bfef8 (patch)
tree8840f61192ba65b92912405940f948755305af2e
parentRemoved previous implementation of texture atlas (diff)
downloadAltCraft-f3e01e3a318fea8d7065468df09e32c1765bfef8.tar
AltCraft-f3e01e3a318fea8d7065468df09e32c1765bfef8.tar.gz
AltCraft-f3e01e3a318fea8d7065468df09e32c1765bfef8.tar.bz2
AltCraft-f3e01e3a318fea8d7065468df09e32c1765bfef8.tar.lz
AltCraft-f3e01e3a318fea8d7065468df09e32c1765bfef8.tar.xz
AltCraft-f3e01e3a318fea8d7065468df09e32c1765bfef8.tar.zst
AltCraft-f3e01e3a318fea8d7065468df09e32c1765bfef8.zip
-rw-r--r--src/AssetManager.cpp586
-rw-r--r--src/AssetManager.hpp51
-rw-r--r--src/Render.cpp6
-rw-r--r--src/RendererSectionData.cpp2
-rw-r--r--src/RendererWorld.cpp4
5 files changed, 325 insertions, 324 deletions
diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp
index 7f4bf7d..6a4b3a3 100644
--- a/src/AssetManager.cpp
+++ b/src/AssetManager.cpp
@@ -14,17 +14,35 @@
namespace fs = std::experimental::filesystem::v1;
const fs::path pathToAssets = "./assets/";
-//const fs::path pathToAssetsList = "./items.json";
-//const fs::path pathToTextureIndex = "./textures.json";
const std::string pathToAssetsList = "./items.json";
-const std::string pathToTextureIndex = "./textures.json";
-const fs::path pathToModels = "./assets/minecraft/models/";
+std::map<std::string, BlockId> assetIds;
+std::map<BlockId, std::string> blockIdToBlockName;
+std::unique_ptr<AssetTreeNode> assetTree;
+std::unique_ptr<TextureAtlas> atlas;
-AssetManager::AssetManager() {
+void LoadIds();
+void LoadAssets();
+void LoadTextures();
+
+void WalkDirEntry(const fs::directory_entry &dirEntry, AssetTreeNode *node);
+void ParseAsset(AssetTreeNode &node);
+void ParseAssetTexture(AssetTreeNode &node);
+void ParseAssetBlockModel(AssetTreeNode &node);
+
+void ParseBlockModels();
+
+void AssetManager::InitAssetManager()
+{
+ static bool Initialized = false;
+ if (Initialized) {
+ LOG(WARNING) << "Trying to init AssetManager twice";
+ }
+ Initialized = true;
+
LoadAssets();
- auto parseAssetRecur = [this](AssetTreeNode &node) {
+ auto parseAssetRecur = [](AssetTreeNode &node) {
ParseAsset(node);
};
@@ -32,79 +50,248 @@ AssetManager::AssetManager() {
LoadTextures();
- LoadIds();
- ParseBlockModels();
+ LoadIds();
+ ParseBlockModels();
}
-void AssetManager::LoadIds() {
- std::ifstream in(pathToAssetsList);
- nlohmann::json index;
- in >> index;
- for (auto &it:index) {
- unsigned short id = it["type"].get<int>();
- unsigned char state = it["meta"].get<int>();
- std::string blockName = it["text_type"].get<std::string>();
- assetIds[blockName] = BlockId{ id, state };
- }
- LOG(INFO) << "Loaded " << assetIds.size() << " ids";
+void LoadIds() {
+ std::ifstream in(pathToAssetsList);
+ nlohmann::json index;
+ in >> index;
+ for (auto &it : index) {
+ unsigned short id = it["type"].get<int>();
+ unsigned char state = it["meta"].get<int>();
+ std::string blockName = it["text_type"].get<std::string>();
+ assetIds[blockName] = BlockId{ id, state };
+ }
+ LOG(INFO) << "Loaded " << assetIds.size() << " ids";
}
-AssetManager::~AssetManager() {
+void LoadAssets() {
+ assetTree = std::make_unique<AssetTreeNode>();
+ assetTree->name = "/";
+ WalkDirEntry(fs::directory_entry(pathToAssets), assetTree.get());
}
-AssetManager &AssetManager::Instance() {
- static AssetManager assetManager;
- return assetManager;
+void LoadTextures() {
+ std::vector<TextureData> textureData;
+ size_t id = 0;
+ AssetManager::RecursiveWalkAsset("/minecraft/textures/", [&](AssetTreeNode &node) {
+ TextureData data;
+ AssetTexture *textureAsset = dynamic_cast<AssetTexture*>(node.asset.get());
+ if (!textureAsset)
+ return;
+ data.data = std::move(textureAsset->textureData);
+ data.width = textureAsset->realWidth;
+ data.height = textureAsset->realHeight;
+ textureData.push_back(data);
+ textureAsset->id = id++;
+ });
+ atlas = std::make_unique<TextureAtlas>(textureData);
}
-const BlockModel *AssetManager::GetBlockModelByBlockId(BlockId block) {
- block.state = 0;
- if (blockIdToBlockName.find(block) == blockIdToBlockName.end()) {
- std::string blockName = "";
- for (const auto& it : assetIds) {
- if (BlockId{ it.second.id,0 } == block) {
- blockName = it.first;
- break;
- }
- }
- if (blockName == "grass")
- blockName = "grass_normal";
- if (blockName == "torch")
- blockName = "normal_torch";
- if (blockName == "leaves")
- blockName = "oak_leaves";
- if (blockName == "tallgrass")
- blockName = "tall_grass";
- if (blockName == "log")
- blockName = "oak_bark";
- if (blockName == "snow_layer")
- blockName = "snow_height2";
+void WalkDirEntry(const fs::directory_entry &dirEntry, AssetTreeNode *node) {
+ for (auto &file : fs::directory_iterator(dirEntry)) {
+ node->childs.push_back(std::make_unique<AssetTreeNode>());
+ AssetTreeNode *fileNode = node->childs.back().get();
+ fileNode->parent = node;
+ fileNode->name = file.path().stem().string();
+ if (fs::is_directory(file)) {
+ WalkDirEntry(file, fileNode);
+ }
+ else {
+ size_t fileSize = fs::file_size(file);
+ fileNode->data.resize(fileSize);
+ FILE *f = fopen(file.path().string().c_str(), "rb");
+ fread(fileNode->data.data(), 1, fileSize, f);
+ fclose(f);
+ }
+ }
+}
- blockName = "block/" + blockName;
+void ParseAsset(AssetTreeNode &node) {
+ if (node.data.empty() || node.asset)
+ return;
- if (blockName == "")
- return nullptr;
+ if (node.parent->name == "block" && node.parent->parent->name == "models") {
+ ParseAssetBlockModel(node);
+ return;
+ }
- blockIdToBlockName[block] = blockName;
- }
+ if (node.data[0] == 0x89 && node.data[1] == 'P' && node.data[2] == 'N' && node.data[3] == 'G') {
+ ParseAssetTexture(node);
+ return;
+ }
+}
- std::string blockName = blockIdToBlockName[block];
+void ParseAssetTexture(AssetTreeNode &node) {
+ SDL_RWops *rw = SDL_RWFromMem(node.data.data(), node.data.size());
+ SDL_Surface *surface = IMG_LoadPNG_RW(rw);
- AssetBlockModel *model = GetAsset<AssetBlockModel>("/minecraft/models/" + blockName);
- return (model == nullptr) ? &GetAsset<AssetBlockModel>("/minecraft/models/block/diamond_block")->blockModel : &model->blockModel;
+ SDL_RWclose(rw);
+ if (!surface) {
+ return;
+ }
+
+ if (surface->format->format != SDL_PIXELFORMAT_RGBA8888) {
+ SDL_Surface *temp = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_RGBA8888, 0);
+ std::swap(temp, surface);
+ if (!temp) {
+ std::swap(temp, surface);
+ }
+ SDL_FreeSurface(temp);
+ }
+
+ SDL_LockSurface(surface);
+
+ node.asset = std::make_unique<AssetTexture>();
+ AssetTexture *asset = dynamic_cast<AssetTexture*>(node.asset.get());
+ size_t dataLen = surface->h * surface->pitch;
+ asset->textureData.resize(dataLen);
+ std::memcpy(asset->textureData.data(), surface->pixels, dataLen);
+ asset->realWidth = surface->w;
+ asset->realHeight = surface->h;
+
+ SDL_UnlockSurface(surface);
+ SDL_FreeSurface(surface);
+
+ node.data.swap(std::vector<unsigned char>());
}
-std::string AssetManager::GetAssetNameByBlockId(BlockId block) {
- for (auto& it : assetIds) {
- BlockId value = it.second;
- value.state = 0;
- if (value == block)
- return it.first;
- }
- return "#NF";
+void ParseAssetBlockModel(AssetTreeNode &node) {
+ nlohmann::json modelData = nlohmann::json::parse(node.data);
+ BlockModel model;
+
+ if (node.name == "button") {
+ int a = 15;
+ a++;
+ }
+
+ if (modelData.find("parent") != modelData.end()) {
+ std::string parentName = modelData["parent"].get<std::string>();
+ parentName = parentName.substr(parentName.find('/') + 1);
+ for (auto &it : node.parent->childs) {
+ if (it->name == parentName) {
+ ParseAsset(*it);
+ model = dynamic_cast<AssetBlockModel*>(it->asset.get())->blockModel;
+ unsigned char *b = reinterpret_cast<unsigned char*>(&model.IsBlock);
+ }
+ }
+ }
+
+ model.BlockName = node.name;
+
+ if (model.BlockName == "block")
+ model.IsBlock = true;
+
+ if (model.BlockName == "thin_block" || model.BlockName == "leaves")
+ model.IsBlock = false;
+
+ if (modelData.find("ambientocclusion") != modelData.end())
+ model.AmbientOcclusion = modelData["ambientocclusion"].get<bool>();
+
+ //models.Display
+
+ if (modelData.find("textures") != modelData.end()) {
+ for (nlohmann::json::iterator texture = modelData["textures"].begin(); texture != modelData["textures"].end(); ++texture) {
+ model.Textures[texture.key()] = texture.value().get<std::string>();
+ }
+ }
+
+ if (modelData.find("elements") != modelData.end()) {
+ model.Elements.clear();
+ for (auto& it : modelData["elements"]) {
+ BlockModel::ElementData element;
+
+ auto vec = it["from"];
+ Vector from(vec[0].get<int>(), vec[1].get<int>(), vec[2].get<int>());
+ vec = it["to"];
+ Vector to(vec[0].get<int>(), vec[1].get<int>(), vec[2].get<int>());
+
+ element.from = from;
+ element.to = to;
+
+ if (it.find("rotation") != it.end()) {
+ vec = it["rotation"]["origin"];
+ Vector rotOrig(vec[0].get<int>(), vec[1].get<int>(), vec[2].get<int>());
+
+ element.rotationOrigin = rotOrig;
+ element.rotationAxis = (it["rotation"]["axis"].get<std::string>() == "x") ? BlockModel::ElementData::Axis::x : ((it["rotation"]["axis"].get<std::string>() == "y") ? BlockModel::ElementData::Axis::y : BlockModel::ElementData::Axis::z);
+ if (it["rotation"].find("angle") != it["rotation"].end())
+ element.rotationAngle = it["rotation"]["angle"].get<int>();
+
+ if (it["rotation"].find("rescale") != it["rotation"].end())
+ element.rotationRescale = it["rotation"]["rescale"].get<bool>();
+ }
+
+ if (it.find("shade") != it.end())
+ element.shade = it["shade"].get<bool>();
+
+ for (nlohmann::json::iterator faceIt = it["faces"].begin(); faceIt != it["faces"].end(); ++faceIt) {
+ auto face = faceIt.value();
+ BlockModel::ElementData::FaceData faceData;
+
+ BlockModel::ElementData::FaceDirection faceDir;
+ if (faceIt.key() == "down")
+ faceDir = BlockModel::ElementData::FaceDirection::down;
+ else if (faceIt.key() == "up")
+ faceDir = BlockModel::ElementData::FaceDirection::up;
+ else if (faceIt.key() == "north")
+ faceDir = BlockModel::ElementData::FaceDirection::north;
+ else if (faceIt.key() == "south")
+ faceDir = BlockModel::ElementData::FaceDirection::south;
+ else if (faceIt.key() == "west")
+ faceDir = BlockModel::ElementData::FaceDirection::west;
+ else if (faceIt.key() == "east")
+ faceDir = BlockModel::ElementData::FaceDirection::east;
+
+ if (face.find("uv") != face.end()) {
+ BlockModel::ElementData::FaceData::Uv uv;
+ uv.x1 = face["uv"][0];
+ uv.y1 = face["uv"][1];
+ uv.x2 = face["uv"][2];
+ uv.y2 = face["uv"][3];
+ faceData.uv = uv;
+ }
+
+ BlockModel::ElementData::FaceDirection cullface = BlockModel::ElementData::FaceDirection::none;
+ if (face.find("cullface") != face.end()) {
+ if (face["cullface"] == "down")
+ cullface = BlockModel::ElementData::FaceDirection::down;
+ else if (face["cullface"] == "up")
+ cullface = BlockModel::ElementData::FaceDirection::up;
+ else if (face["cullface"] == "north")
+ cullface = BlockModel::ElementData::FaceDirection::north;
+ else if (face["cullface"] == "south")
+ cullface = BlockModel::ElementData::FaceDirection::south;
+ else if (face["cullface"] == "west")
+ cullface = BlockModel::ElementData::FaceDirection::west;
+ else if (face["cullface"] == "east")
+ cullface = BlockModel::ElementData::FaceDirection::east;
+ }
+ faceData.cullface = cullface;
+
+ faceData.texture = face["texture"].get<std::string>();
+
+ if (face.find("rotation") != face.end())
+ faceData.rotation = face["rotation"].get<int>();
+
+ if (face.find("tintindex") != face.end())
+ faceData.tintIndex = true;
+
+ element.faces[faceDir] = faceData;
+ }
+
+ model.Elements.push_back(element);
+ }
+ }
+
+ node.asset = std::make_unique<AssetBlockModel>();
+ dynamic_cast<AssetBlockModel*>(node.asset.get())->blockModel = model;
+ node.data.swap(std::vector<unsigned char>());
}
-void AssetManager::ParseBlockModels() {
+void ParseBlockModels() {
std::string textureName;
auto parseBlockModel = [&](AssetTreeNode &node) {
@@ -213,7 +400,7 @@ void AssetManager::ParseBlockModels() {
TextureCoord texture;
textureName = face.second.texture;
if (model.Textures.empty()) {
- texture = GetTexture("minecraft/texture/blocks/tnt_side");
+ texture = AssetManager::GetTexture("minecraft/texture/blocks/tnt_side");
}
else {
while (textureName[0] == '#') {
@@ -222,7 +409,7 @@ void AssetManager::ParseBlockModels() {
textureName = textureIt != model.Textures.end() ? textureIt->second : "minecraft/texture/blocks/tnt_side";
}
textureName.insert(0, "minecraft/textures/");
- texture = GetTexture(textureName);
+ texture = AssetManager::GetTexture(textureName);
if (!(face.second.uv == BlockModel::ElementData::FaceData::Uv{ 0,16,0,16 }) && !(face.second.uv == BlockModel::ElementData::FaceData::Uv{ 0,0,0,0 })
&& !(face.second.uv == BlockModel::ElementData::FaceData::Uv{ 0,0,16,16 })) {
@@ -257,164 +444,65 @@ void AssetManager::ParseBlockModels() {
}
};
- RecursiveWalkAsset("/minecraft/models/", parseBlockModel);
+ AssetManager::RecursiveWalkAsset("/minecraft/models/", parseBlockModel);
}
-void WalkDirEntry(const fs::directory_entry &dirEntry, AssetTreeNode *node) {
- for (auto &file : fs::directory_iterator(dirEntry)) {
- node->childs.push_back(std::make_unique<AssetTreeNode>());
- AssetTreeNode *fileNode = node->childs.back().get();
- fileNode->parent = node;
- fileNode->name = file.path().stem().string();
- if (fs::is_directory(file)) {
- WalkDirEntry(file, fileNode);
- } else {
- size_t fileSize = fs::file_size(file);
- fileNode->data.resize(fileSize);
- FILE *f = fopen(file.path().string().c_str(), "rb");
- fread(fileNode->data.data(), 1, fileSize, f);
- fclose(f);
- }
- }
-}
-
-void AssetManager::LoadAssets() {
- assetTree = std::make_unique<AssetTreeNode>();
- assetTree->name = "/";
- WalkDirEntry(fs::directory_entry(pathToAssets), assetTree.get());
-}
-
-void AssetManager::ParseAssetBlockModel(AssetTreeNode &node) {
- nlohmann::json modelData = nlohmann::json::parse(node.data);
- BlockModel model;
-
- if (node.name == "button") {
- int a = 15;
- a++;
- }
-
- if (modelData.find("parent") != modelData.end()) {
- std::string parentName = modelData["parent"].get<std::string>();
- parentName = parentName.substr(parentName.find('/') + 1);
- for (auto &it : node.parent->childs) {
- if (it->name == parentName) {
- ParseAsset(*it);
- model = dynamic_cast<AssetBlockModel*>(it->asset.get())->blockModel;
- unsigned char *b = reinterpret_cast<unsigned char*>(&model.IsBlock);
- }
- }
- }
-
- model.BlockName = node.name;
-
- if (model.BlockName == "block")
- model.IsBlock = true;
-
- if (model.BlockName == "thin_block" || model.BlockName == "leaves")
- model.IsBlock = false;
-
- if (modelData.find("ambientocclusion") != modelData.end())
- model.AmbientOcclusion = modelData["ambientocclusion"].get<bool>();
-
- //models.Display
-
- if (modelData.find("textures") != modelData.end()) {
- for (nlohmann::json::iterator texture = modelData["textures"].begin(); texture != modelData["textures"].end(); ++texture) {
- model.Textures[texture.key()] = texture.value().get<std::string>();
- }
- }
-
- if (modelData.find("elements") != modelData.end()) {
- model.Elements.clear();
- for (auto& it : modelData["elements"]) {
- BlockModel::ElementData element;
-
- auto vec = it["from"];
- Vector from(vec[0].get<int>(), vec[1].get<int>(), vec[2].get<int>());
- vec = it["to"];
- Vector to(vec[0].get<int>(), vec[1].get<int>(), vec[2].get<int>());
-
- element.from = from;
- element.to = to;
-
- if (it.find("rotation") != it.end()) {
- vec = it["rotation"]["origin"];
- Vector rotOrig(vec[0].get<int>(), vec[1].get<int>(), vec[2].get<int>());
-
- element.rotationOrigin = rotOrig;
- element.rotationAxis = (it["rotation"]["axis"].get<std::string>() == "x") ? BlockModel::ElementData::Axis::x : ((it["rotation"]["axis"].get<std::string>() == "y") ? BlockModel::ElementData::Axis::y : BlockModel::ElementData::Axis::z);
- if (it["rotation"].find("angle") != it["rotation"].end())
- element.rotationAngle = it["rotation"]["angle"].get<int>();
-
- if (it["rotation"].find("rescale") != it["rotation"].end())
- element.rotationRescale = it["rotation"]["rescale"].get<bool>();
- }
-
- if (it.find("shade") != it.end())
- element.shade = it["shade"].get<bool>();
-
- for (nlohmann::json::iterator faceIt = it["faces"].begin(); faceIt != it["faces"].end(); ++faceIt) {
- auto face = faceIt.value();
- BlockModel::ElementData::FaceData faceData;
-
- BlockModel::ElementData::FaceDirection faceDir;
- if (faceIt.key() == "down")
- faceDir = BlockModel::ElementData::FaceDirection::down;
- else if (faceIt.key() == "up")
- faceDir = BlockModel::ElementData::FaceDirection::up;
- else if (faceIt.key() == "north")
- faceDir = BlockModel::ElementData::FaceDirection::north;
- else if (faceIt.key() == "south")
- faceDir = BlockModel::ElementData::FaceDirection::south;
- else if (faceIt.key() == "west")
- faceDir = BlockModel::ElementData::FaceDirection::west;
- else if (faceIt.key() == "east")
- faceDir = BlockModel::ElementData::FaceDirection::east;
-
- if (face.find("uv") != face.end()) {
- BlockModel::ElementData::FaceData::Uv uv;
- uv.x1 = face["uv"][0];
- uv.y1 = face["uv"][1];
- uv.x2 = face["uv"][2];
- uv.y2 = face["uv"][3];
- faceData.uv = uv;
- }
+const BlockModel *AssetManager::GetBlockModelByBlockId(BlockId block) {
+ block.state = 0;
+ if (blockIdToBlockName.find(block) == blockIdToBlockName.end()) {
+ std::string blockName = "";
+ for (const auto& it : assetIds) {
+ if (BlockId{ it.second.id,0 } == block) {
+ blockName = it.first;
+ break;
+ }
+ }
+ if (blockName == "grass")
+ blockName = "grass_normal";
+ if (blockName == "torch")
+ blockName = "normal_torch";
+ if (blockName == "leaves")
+ blockName = "oak_leaves";
+ if (blockName == "tallgrass")
+ blockName = "tall_grass";
+ if (blockName == "log")
+ blockName = "oak_bark";
+ if (blockName == "snow_layer")
+ blockName = "snow_height2";
- BlockModel::ElementData::FaceDirection cullface = BlockModel::ElementData::FaceDirection::none;
- if (face.find("cullface") != face.end()) {
- if (face["cullface"] == "down")
- cullface = BlockModel::ElementData::FaceDirection::down;
- else if (face["cullface"] == "up")
- cullface = BlockModel::ElementData::FaceDirection::up;
- else if (face["cullface"] == "north")
- cullface = BlockModel::ElementData::FaceDirection::north;
- else if (face["cullface"] == "south")
- cullface = BlockModel::ElementData::FaceDirection::south;
- else if (face["cullface"] == "west")
- cullface = BlockModel::ElementData::FaceDirection::west;
- else if (face["cullface"] == "east")
- cullface = BlockModel::ElementData::FaceDirection::east;
- }
- faceData.cullface = cullface;
+ blockName = "block/" + blockName;
- faceData.texture = face["texture"].get<std::string>();
+ if (blockName == "")
+ return nullptr;
- if (face.find("rotation") != face.end())
- faceData.rotation = face["rotation"].get<int>();
+ blockIdToBlockName[block] = blockName;
+ }
- if (face.find("tintindex") != face.end())
- faceData.tintIndex = true;
+ std::string blockName = blockIdToBlockName[block];
- element.faces[faceDir] = faceData;
- }
+ AssetBlockModel *model = GetAsset<AssetBlockModel>("/minecraft/models/" + blockName);
+ return (model == nullptr) ? &GetAsset<AssetBlockModel>("/minecraft/models/block/diamond_block")->blockModel : &model->blockModel;
+}
- model.Elements.push_back(element);
- }
- }
+std::string AssetManager::GetAssetNameByBlockId(BlockId block) {
+ for (auto& it : assetIds) {
+ BlockId value = it.second;
+ value.state = 0;
+ if (value == block)
+ return it.first;
+ }
+ return "#NF";
+}
- node.asset = std::make_unique<AssetBlockModel>();
- dynamic_cast<AssetBlockModel*>(node.asset.get())->blockModel = model;
- node.data.swap(std::vector<unsigned char>());
+Asset *AssetManager::GetAssetPtr(const std::string & assetName) {
+ AssetTreeNode *node;
+ if (assetName[0] != '/')
+ node = GetAssetByAssetName('/' + assetName);
+ else
+ node = GetAssetByAssetName(assetName);
+ if (!node)
+ return nullptr;
+ return node->asset.get();
}
void AssetManager::RecursiveWalkAsset(const std::string & assetPath, std::function<void(AssetTreeNode&)> fnc) {
@@ -430,7 +518,7 @@ void AssetManager::RecursiveWalkAsset(const std::string & assetPath, std::functi
walkAssetRecur(*assetNode);
}
-AssetTreeNode * AssetManager::GetAssetByAssetName(const std::string & assetName) {
+AssetTreeNode *AssetManager::GetAssetByAssetName(const std::string & assetName) {
AssetTreeNode *node = assetTree.get();
unsigned int pos = 1;
unsigned int prevPos = 1;
@@ -450,68 +538,14 @@ AssetTreeNode * AssetManager::GetAssetByAssetName(const std::string & assetName)
return node;
}
-void AssetManager::LoadTextures() {
- std::vector<TextureData> textureData;
- size_t id = 0;
- RecursiveWalkAsset("/minecraft/textures/", [&](AssetTreeNode &node) {
- TextureData data;
- AssetTexture *textureAsset = dynamic_cast<AssetTexture*>(node.asset.get());
- if (!textureAsset)
- return;
- data.data = std::move(textureAsset->textureData);
- data.width = textureAsset->realWidth;
- data.height = textureAsset->realHeight;
- textureData.push_back(data);
- textureAsset->id = id++;
- });
- atlas = std::make_unique<TextureAtlas>(textureData);
+GLuint AssetManager::GetTextureAtlasId()
+{
+ return atlas->GetRawTextureId();
}
-void AssetManager::ParseAssetTexture(AssetTreeNode &node) {
- SDL_RWops *rw = SDL_RWFromMem(node.data.data(), node.data.size());
- SDL_Surface *surface = IMG_LoadPNG_RW(rw);
-
- SDL_RWclose(rw);
- if (!surface) {
- return;
- }
-
- if (surface->format->format != SDL_PIXELFORMAT_RGBA8888) {
- SDL_Surface *temp = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_RGBA8888, 0);
- std::swap(temp, surface);
- if (!temp) {
- std::swap(temp, surface);
- }
- SDL_FreeSurface(temp);
- }
-
- SDL_LockSurface(surface);
-
- node.asset = std::make_unique<AssetTexture>();
- AssetTexture *asset = dynamic_cast<AssetTexture*>(node.asset.get());
- size_t dataLen = surface->h * surface->pitch;
- asset->textureData.resize(dataLen);
- std::memcpy(asset->textureData.data(), surface->pixels, dataLen);
- asset->realWidth = surface->w;
- asset->realHeight = surface->h;
-
- SDL_UnlockSurface(surface);
- SDL_FreeSurface(surface);
-
- node.data.swap(std::vector<unsigned char>());
+TextureCoord AssetManager::GetTexture(const std::string assetName) {
+ AssetTexture *asset = GetAsset<AssetTexture>(assetName);
+ if (!asset)
+ return {};
+ return atlas->GetTexture(asset->id);
}
-
-void AssetManager::ParseAsset(AssetTreeNode &node) {
- if (node.data.empty() || node.asset)
- return;
-
- if (node.parent->name == "block" && node.parent->parent->name == "models") {
- ParseAssetBlockModel(node);
- return;
- }
-
- if (node.data[0] == 0x89 && node.data[1] == 'P' && node.data[2] == 'N' && node.data[3] == 'G') {
- ParseAssetTexture(node);
- return;
- }
-} \ No newline at end of file
diff --git a/src/AssetManager.hpp b/src/AssetManager.hpp
index 3975b37..2940b5f 100644
--- a/src/AssetManager.hpp
+++ b/src/AssetManager.hpp
@@ -119,60 +119,25 @@ struct AssetTexture : Asset {
size_t id;
};
-class AssetManager {
- std::map<std::string, BlockId> assetIds;
- std::map<BlockId, std::string> blockIdToBlockName;
- std::unique_ptr<AssetTreeNode> assetTree;
- std::unique_ptr<TextureAtlas> atlas;
-public:
- AssetManager();
-
- ~AssetManager();
-
- void LoadIds();
-
- static AssetManager& Instance();
+namespace AssetManager {
+ void InitAssetManager();
const BlockModel *GetBlockModelByBlockId(BlockId block);
std::string GetAssetNameByBlockId(BlockId block);
- void ParseBlockModels();
-
- void LoadAssets();
+ Asset *GetAssetPtr(const std::string &assetName);
template <typename T>
- T *GetAsset(const std::string &assetName) {
- AssetTreeNode *node;
- if (assetName[0] != '/')
- node = GetAssetByAssetName('/'+assetName);
- else
- node = GetAssetByAssetName(assetName);
- if (!node)
- return nullptr;
- return dynamic_cast<T*>(node->asset.get());
+ T *GetAsset(const std::string &assetName) {
+ return dynamic_cast<T*>(GetAssetPtr(assetName));
}
- void ParseAsset(AssetTreeNode &node);
-
- void ParseAssetBlockModel(AssetTreeNode &node);
-
void RecursiveWalkAsset(const std::string &assetPath, std::function<void(AssetTreeNode&)> fnc);
AssetTreeNode *GetAssetByAssetName(const std::string &assetName);
+
+ GLuint GetTextureAtlasId();
- void LoadTextures();
-
- void ParseAssetTexture(AssetTreeNode &node);
-
- inline GLuint GetTextureAtlasId() {
- return atlas->GetRawTextureId();
- }
-
- inline TextureCoord GetTexture(const std::string assetName) {
- AssetTexture *asset = GetAsset<AssetTexture>(assetName);
- if (!asset)
- return {};
- return atlas->GetTexture(asset->id);
- }
+ TextureCoord GetTexture(const std::string assetName);
};
diff --git a/src/Render.cpp b/src/Render.cpp
index 88fe2cc..314840d 100644
--- a/src/Render.cpp
+++ b/src/Render.cpp
@@ -22,6 +22,8 @@ Render::Render(unsigned int windowWidth, unsigned int windowHeight,
glCheckError();
InitGlew();
glCheckError();
+ AssetManager::InitAssetManager();
+ glCheckError();
PrepareToRendering();
glCheckError();
@@ -93,7 +95,7 @@ void Render::InitGlew() {
void Render::PrepareToRendering() {
//TextureAtlas texture
glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D_ARRAY, AssetManager::Instance().GetTextureAtlasId());
+ glBindTexture(GL_TEXTURE_2D_ARRAY, AssetManager::GetTextureAtlasId());
ImGui_ImplSdlGL3_Init(window);
}
@@ -421,7 +423,7 @@ void Render::RenderGui() {
case State::Inventory: {
auto renderSlot = [](const SlotDataType &slot, int i) -> bool {
return ImGui::Button(((slot.BlockId == -1 ? " ##" :
- AssetManager::Instance().GetAssetNameByBlockId(BlockId{ (unsigned short)slot.BlockId,0 }) + " x" + std::to_string(slot.ItemCount) + "##")
+ AssetManager::GetAssetNameByBlockId(BlockId{ (unsigned short)slot.BlockId,0 }) + " x" + std::to_string(slot.ItemCount) + "##")
+ std::to_string(i)).c_str());
};
ImGui::SetNextWindowPosCenter();
diff --git a/src/RendererSectionData.cpp b/src/RendererSectionData.cpp
index fb2135a..d066141 100644
--- a/src/RendererSectionData.cpp
+++ b/src/RendererSectionData.cpp
@@ -59,7 +59,7 @@ const BlockModel* GetInternalBlockModel(const BlockId& id, std::vector<std::pair
if (it.first == id)
return it.second;
}
- idModels.push_back(std::make_pair(id, AssetManager::Instance().GetBlockModelByBlockId(id)));
+ idModels.push_back(std::make_pair(id, AssetManager::GetBlockModelByBlockId(id)));
return idModels.back().second;
}
diff --git a/src/RendererWorld.cpp b/src/RendererWorld.cpp
index ed4a4a3..d4586f5 100644
--- a/src/RendererWorld.cpp
+++ b/src/RendererWorld.cpp
@@ -427,10 +427,10 @@ void RendererWorld::PrepareRender() {
skyShader = new Shader("./shaders/sky.vs", "./shaders/sky.fs");
skyShader->Use();
glUniform1i(glGetUniformLocation(skyShader->Program, "textureAtlas"), 0);
- TextureCoord sunTexture = AssetManager::Instance().GetTexture("/minecraft/textures/environment/sun");
+ TextureCoord sunTexture = AssetManager::GetTexture("/minecraft/textures/environment/sun");
glUniform4f(glGetUniformLocation(skyShader->Program, "sunTexture"), sunTexture.x, sunTexture.y, sunTexture.w, sunTexture.h);
glUniform1f(glGetUniformLocation(skyShader->Program, "sunTextureLayer"), sunTexture.layer);
- TextureCoord moonTexture = AssetManager::Instance().GetTexture("/minecraft/textures/environment/moon_phases");
+ TextureCoord moonTexture = AssetManager::GetTexture("/minecraft/textures/environment/moon_phases");
moonTexture.w /= 4.0f; //First phase will be fine for now
moonTexture.h /= 2.0f;
glUniform4f(glGetUniformLocation(skyShader->Program, "moonTexture"), moonTexture.x, moonTexture.y, moonTexture.w, moonTexture.h);