content-pack resources support

This commit is contained in:
MihailRis 2023-12-14 02:30:39 +03:00
parent c6d2266026
commit 396ee31bcc
43 changed files with 170 additions and 90 deletions

View File

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

Before

Width:  |  Height:  |  Size: 129 B

After

Width:  |  Height:  |  Size: 129 B

View File

Before

Width:  |  Height:  |  Size: 163 B

After

Width:  |  Height:  |  Size: 163 B

View File

Before

Width:  |  Height:  |  Size: 131 B

After

Width:  |  Height:  |  Size: 131 B

View File

Before

Width:  |  Height:  |  Size: 171 KiB

After

Width:  |  Height:  |  Size: 171 KiB

View File

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

@ -7,19 +7,20 @@
#include <memory>
#include "../constants.h"
#include "../files/engine_paths.h"
using std::filesystem::path;
using std::unique_ptr;
AssetsLoader::AssetsLoader(Assets* assets, path resdir)
: assets(assets), resdir(resdir) {
AssetsLoader::AssetsLoader(Assets* assets, const ResPaths* paths)
: assets(assets), paths(paths) {
}
void AssetsLoader::addLoader(int tag, aloader_func func) {
loaders[tag] = func;
}
void AssetsLoader::add(int tag, const path filename, const std::string alias) {
void AssetsLoader::add(int tag, const std::string filename, const std::string alias) {
entries.push(aloader_entry{ tag, filename, alias });
}
@ -37,7 +38,7 @@ bool AssetsLoader::loadNext() {
return false;
}
aloader_func loader = found->second;
bool status = loader(assets, entry.filename, entry.alias);
bool status = loader(assets, paths, entry.filename, entry.alias);
entries.pop();
return status;
}
@ -50,20 +51,19 @@ void AssetsLoader::createDefaults(AssetsLoader& loader) {
}
void AssetsLoader::addDefaults(AssetsLoader& loader) {
path resdir = loader.getDirectory();
loader.add(ASSET_SHADER, resdir/path(SHADERS_FOLDER"/main"), "main");
loader.add(ASSET_SHADER, resdir/path(SHADERS_FOLDER"/lines"), "lines");
loader.add(ASSET_SHADER, resdir/path(SHADERS_FOLDER"/ui"), "ui");
loader.add(ASSET_SHADER, resdir/path(SHADERS_FOLDER"/ui3d"), "ui3d");
loader.add(ASSET_SHADER, resdir/path(SHADERS_FOLDER"/background"), "background");
loader.add(ASSET_SHADER, resdir/path(SHADERS_FOLDER"/skybox_gen"), "skybox_gen");
loader.add(ASSET_SHADER, SHADERS_FOLDER"/main", "main");
loader.add(ASSET_SHADER, SHADERS_FOLDER"/lines", "lines");
loader.add(ASSET_SHADER, SHADERS_FOLDER"/ui", "ui");
loader.add(ASSET_SHADER, SHADERS_FOLDER"/ui3d", "ui3d");
loader.add(ASSET_SHADER, SHADERS_FOLDER"/background", "background");
loader.add(ASSET_SHADER, SHADERS_FOLDER"/skybox_gen", "skybox_gen");
loader.add(ASSET_ATLAS, resdir/path(TEXTURES_FOLDER"/blocks"), "blocks");
loader.add(ASSET_TEXTURE, resdir/path(TEXTURES_FOLDER"/menubg.png"), "menubg");
loader.add(ASSET_ATLAS, TEXTURES_FOLDER"/blocks", "blocks");
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/menubg.png", "menubg");
loader.add(ASSET_FONT, resdir/path(FONTS_FOLDER"/font"), "normal");
loader.add(ASSET_FONT, FONTS_FOLDER"/font", "normal");
}
path AssetsLoader::getDirectory() const {
return resdir;
const ResPaths* AssetsLoader::getPaths() const {
return paths;
}

View File

@ -3,7 +3,6 @@
#include <string>
#include <functional>
#include <filesystem>
#include <map>
#include <queue>
@ -12,13 +11,14 @@ const short ASSET_SHADER = 2;
const short ASSET_FONT = 3;
const short ASSET_ATLAS = 4;
class ResPaths;
class Assets;
typedef std::function<bool(Assets*, const std::filesystem::path&, const std::string&)> aloader_func;
typedef std::function<bool(Assets*, const ResPaths*, const std::string&, const std::string&)> aloader_func;
struct aloader_entry {
int tag;
const std::filesystem::path filename;
const std::string filename;
const std::string alias;
};
@ -26,11 +26,11 @@ class AssetsLoader {
Assets* assets;
std::map<int, aloader_func> loaders;
std::queue<aloader_entry> entries;
std::filesystem::path resdir;
const ResPaths* paths;
public:
AssetsLoader(Assets* assets, std::filesystem::path resdir);
AssetsLoader(Assets* assets, const ResPaths* paths);
void addLoader(int tag, aloader_func func);
void add(int tag, const std::filesystem::path filename, const std::string alias);
void add(int tag, const std::string filename, const std::string alias);
bool hasNext() const;
bool loadNext();
@ -38,7 +38,7 @@ public:
static void createDefaults(AssetsLoader& loader);
static void addDefaults(AssetsLoader& loader);
std::filesystem::path getDirectory() const;
const ResPaths* getPaths() const;
};
#endif // ASSETS_ASSETS_LOADER_H

View File

@ -1,8 +1,10 @@
#include "asset_loaders.h"
#include <iostream>
#include <filesystem>
#include "Assets.h"
#include "../files/files.h"
#include "../files/engine_paths.h"
#include "../coders/png.h"
#include "../graphics/Shader.h"
#include "../graphics/Texture.h"
@ -18,9 +20,10 @@ using std::filesystem::path;
namespace fs = std::filesystem;
bool assetload::texture(Assets* assets,
const path filename,
const ResPaths* paths,
const string filename,
const string name) {
Texture* texture = png::load_texture(filename.string());
Texture* texture = png::load_texture(paths->find(filename).string());
if (texture == nullptr) {
std::cerr << "failed to load texture '" << name << "'" << std::endl;
return false;
@ -30,10 +33,11 @@ bool assetload::texture(Assets* assets,
}
bool assetload::shader(Assets* assets,
const path filename,
const string name) {
path vertexFile = path(filename.string()+".glslv");
path fragmentFile = path(filename.string()+".glslf");
const ResPaths* paths,
const string filename,
const string name) {
path vertexFile = paths->find(filename+".glslv");
path fragmentFile = paths->find(filename+".glslf");
string vertexSource = files::read_string(vertexFile);
string fragmentSource = files::read_string(fragmentFile);
@ -49,13 +53,16 @@ bool assetload::shader(Assets* assets,
}
bool assetload::atlas(Assets* assets,
const path directory,
const string name) {
const ResPaths* paths,
const string directory,
const string name) {
AtlasBuilder builder;
for (const auto& entry : fs::directory_iterator(directory)) {
path file = entry.path();
for (const auto& file : paths->listdir(directory)) {
if (file.extension() == ".png") {
string name = file.stem().string();
if (builder.has(name)) {
continue; // skip duplicates
}
std::unique_ptr<ImageData> image (png::load_image(file.string()));
image->fixAlphaColor();
builder.add(name, image.release());
@ -67,11 +74,13 @@ bool assetload::atlas(Assets* assets,
}
bool assetload::font(Assets* assets,
const path filename,
const string name) {
const ResPaths* paths,
const string filename,
const string name) {
vector<Texture*> pages;
for (size_t i = 0; i <= 4; i++) {
string name = filename.string() + "_" + std::to_string(i) + ".png";
string name = filename + "_" + std::to_string(i) + ".png";
name = paths->find(name).string();
Texture* texture = png::load_texture(name);
if (texture == nullptr) {
std::cerr << "failed to load bitmap font '" << name;

View File

@ -2,23 +2,27 @@
#define ASSETS_ASSET_LOADERS_H_
#include <string>
#include <filesystem>
class ResPaths;
class Assets;
namespace assetload {
bool texture(Assets* assets,
const std::filesystem::path filename,
const ResPaths* paths,
const std::string filename,
const std::string name);
bool shader(Assets* assets,
const std::filesystem::path filename,
const std::string name);
bool atlas(Assets* assets,
const std::filesystem::path directory,
const ResPaths* paths,
const std::string filename,
const std::string name);
bool atlas(Assets* assets,
const ResPaths* paths,
const std::string directory,
const std::string name);
bool font(Assets* assets,
const std::filesystem::path filename,
const std::string name);
const ResPaths* paths,
const std::string filename,
const std::string name);
}
#endif // ASSETS_ASSET_LOADERS_H_

View File

@ -5,25 +5,22 @@
#include "../util/stringutil.h"
#include "../typedefs.h"
#include "../files/files.h"
#include "../files/engine_paths.h"
using std::string;
using std::filesystem::path;
namespace fs = std::filesystem;
path GLSLExtension::getHeaderPath(string name) {
return libFolder/path(name+".glsl");
}
void GLSLExtension::setLibFolder(path folder) {
this->libFolder = folder;
}
void GLSLExtension::setVersion(string version) {
this->version = version;
}
void GLSLExtension::setPaths(const ResPaths* paths) {
this->paths = paths;
}
void GLSLExtension::loadHeader(string name) {
path file = getHeaderPath(name);
path file = paths->find("shaders/lib/"+name+".glsl");
string source = files::read_string(file);
addHeader(name, source);
}
@ -117,7 +114,6 @@ const string GLSLExtension::process(const path file, const string& source) {
"expected '#include <filename>' syntax");
}
string name = line.substr(1, line.length()-2);
path hfile = getHeaderPath(name);
if (!hasHeader(name)) {
loadHeader(name);
}

View File

@ -2,19 +2,21 @@
#define CODERS_GLSL_EXTESION_H_
#include <string>
#include <vector>
#include <unordered_map>
#include <filesystem>
class ResPaths;
class GLSLExtension {
std::unordered_map<std::string, std::string> headers;
std::unordered_map<std::string, std::string> defines;
std::filesystem::path libFolder;
std::string version = "330 core";
const ResPaths* paths = nullptr;
void loadHeader(std::string name);
std::filesystem::path getHeaderPath(std::string name);
public:
void setLibFolder(std::filesystem::path folder);
void setPaths(const ResPaths* paths);
void setVersion(std::string version);
void define(std::string name, std::string value);
@ -30,4 +32,4 @@ public:
const std::string process(const std::filesystem::path file, const std::string& source);
};
#endif // CODERS_GLSL_EXTESION_H_
#endif // CODERS_GLSL_EXTESION_H_

View File

@ -52,29 +52,8 @@ Engine::Engine(EngineSettings& settings, EnginePaths* paths)
auto resdir = paths->getResources();
contentPacks.push_back({"base", resdir/path("content/base")});
{
ContentBuilder contentBuilder;
setup_definitions(&contentBuilder);
for (auto& pack : contentPacks) {
ContentLoader loader(pack.folder);
loader.load(&contentBuilder);
}
content.reset(contentBuilder.build());
}
Shader::preprocessor->setLibFolder(paths->getResources()/path("shaders/lib"));
loadContent();
assets = new Assets();
std::cout << "-- loading assets" << std::endl;
AssetsLoader loader(assets, paths->getResources());
AssetsLoader::createDefaults(loader);
AssetsLoader::addDefaults(loader);
while (loader.hasNext()) {
if (!loader.loadNext()) {
delete assets;
Window::terminate();
throw initialize_error("could not to initialize assets");
}
}
Audio::initialize();
gui = new GUI();
if (settings.ui.language == "auto") {
@ -120,7 +99,7 @@ void Engine::mainloop() {
gui->act(delta);
screen->update(delta);
screen->draw(delta);
gui->draw(&batch, assets);
gui->draw(&batch, assets.get());
Window::swapInterval(settings.display.swapInterval);
Window::swapBuffers();
@ -135,7 +114,7 @@ Engine::~Engine() {
Audio::finalize();
std::cout << "-- shutting down" << std::endl;
delete assets;
assets.reset();
Window::terminate();
std::cout << "-- engine finished" << std::endl;
}
@ -149,7 +128,7 @@ EngineSettings& Engine::getSettings() {
}
Assets* Engine::getAssets() {
return assets;
return assets.get();
}
void Engine::setScreen(shared_ptr<Screen> screen) {
@ -173,3 +152,33 @@ void Engine::setLanguage(string locale) {
langs::setup(paths->getResources(), locale, contentPacks);
menus::create_menus(this, gui->getMenu());
}
void Engine::loadContent() {
auto resdir = paths->getResources();
ContentBuilder contentBuilder;
setup_definitions(&contentBuilder);
vector<path> resRoots;
for (auto& pack : contentPacks) {
ContentLoader loader(pack.folder);
loader.load(&contentBuilder);
resRoots.push_back(pack.folder);
}
content.reset(contentBuilder.build());
resPaths.reset(new ResPaths(resdir, resRoots));
Shader::preprocessor->setPaths(resPaths.get());
assets.reset(new Assets());
std::cout << "-- loading assets" << std::endl;
AssetsLoader loader(assets.get(), resPaths.get());
AssetsLoader::createDefaults(loader);
AssetsLoader::addDefaults(loader);
while (loader.hasNext()) {
if (!loader.loadNext()) {
assets.reset();
Window::terminate();
throw initialize_error("could not to initialize assets");
}
}
}

View File

@ -8,13 +8,15 @@
#include "typedefs.h"
#include "settings.h"
#include "assets/Assets.h"
#include "content/Content.h"
#include "content/ContentPack.h"
#include "files/engine_paths.h"
class Assets;
class Level;
class Screen;
class EnginePaths;
class ResPaths;
namespace gui {
class GUI;
@ -26,12 +28,13 @@ public:
};
class Engine {
Assets* assets;
std::unique_ptr<Assets> assets = nullptr;
std::shared_ptr<Screen> screen = nullptr;
std::vector<ContentPack> contentPacks;
EngineSettings& settings;
std::unique_ptr<Content> content = nullptr;
EnginePaths* paths;
std::unique_ptr<ResPaths> resPaths = nullptr;
uint64_t frame = 0;
double lastTime = 0.0;
@ -54,6 +57,7 @@ public:
const Content* getContent() const;
std::vector<ContentPack>& getContentPacks();
void setLanguage(std::string locale);
void loadContent();
};
#endif // SRC_ENGINE_H_

View File

@ -8,6 +8,7 @@
namespace fs = std::filesystem;
using std::string;
using std::vector;
using fs::path;
path EnginePaths::getUserfiles() const {
@ -56,3 +57,38 @@ void EnginePaths::setUserfiles(path folder) {
void EnginePaths::setResources(path folder) {
this->resources = folder;
}
ResPaths::ResPaths(path mainRoot, vector<path> roots)
: mainRoot(mainRoot), roots(roots) {
}
path ResPaths::find(const string& filename) const {
for (auto& root : roots) {
path file = root / path(filename);
if (fs::exists(file)) {
return file;
}
}
return mainRoot / path(filename);
}
vector<path> ResPaths::listdir(const string& folderName) const {
vector<path> entries;
for (auto& root : roots) {
path folder = root / path(folderName);
if (!fs::is_directory(folder))
continue;
for (const auto& entry : fs::directory_iterator(folder)) {
entries.push_back(entry.path());
}
}
{
path folder = mainRoot / path(folderName);
if (!fs::is_directory(folder))
return entries;
for (const auto& entry : fs::directory_iterator(folder)) {
entries.push_back(entry.path());
}
}
return entries;
}

View File

@ -2,6 +2,7 @@
#define FILES_ENGINE_PATHS_H_
#include <string>
#include <vector>
#include <filesystem>
class EnginePaths {
@ -19,4 +20,15 @@ public:
void setResources(std::filesystem::path folder);
};
class ResPaths {
std::filesystem::path mainRoot;
std::vector<std::filesystem::path> roots;
public:
ResPaths(std::filesystem::path mainRoot,
std::vector<std::filesystem::path> roots);
std::filesystem::path find(const std::string& filename) const;
std::vector<std::filesystem::path> listdir(const std::string& folder) const;
};
#endif // FILES_ENGINE_PATHS_H_

View File

@ -41,15 +41,20 @@ ImageData* Atlas::getImage() const {
void AtlasBuilder::add(string name, ImageData* image) {
entries.push_back(atlasentry{name, shared_ptr<ImageData>(image)});
names.insert(name);
}
bool AtlasBuilder::has(string name) const {
return names.find(name) != names.end();
}
Atlas* AtlasBuilder::build(uint extrusion, uint maxResolution) {
unique_ptr<uint[]> sizes (new uint[entries.size() * 2]);
for (uint i = 0; i < entries.size(); i++) {
auto& entry = entries[i];
uint index = 0;
for (auto& entry : entries) {
auto image = entry.image;
sizes[i*2] = image->getWidth();
sizes[i*2+1] = image->getHeight();
sizes[index++] = image->getWidth();
sizes[index++] = image->getHeight();
}
LMPacker packer(sizes.get(), entries.size()*2);
sizes.reset(nullptr);

View File

@ -1,6 +1,7 @@
#ifndef GRAPHICS_ATLAS_H_
#define GRAPHICS_ATLAS_H_
#include <set>
#include <string>
#include <memory>
#include <vector>
@ -33,10 +34,12 @@ struct atlasentry {
};
class AtlasBuilder {
std::vector<atlasentry> entries;
std::vector<atlasentry> entries;
std::set<std::string> names;
public:
AtlasBuilder() {}
void add(std::string name, ImageData* image);
bool has(std::string name) const;
Atlas* build(uint extrusion, uint maxResolution=8192);
};