diff --git a/.gitignore b/.gitignore index b603471..625b1dc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ # build results bin/ obj/ -src/generated/ imgui.ini # IDE files diff --git a/dependencies/compile_resources.sh b/dependencies/compile_resources.sh new file mode 100644 index 0000000..992bb8e --- /dev/null +++ b/dependencies/compile_resources.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +set -eo pipefail +echo 'compiling resources...' +inputs="" +for f in $(find ../../embedded_resources -type f); do + inputs+="-i $f " +done +mkdir -p ../obj +mkdir -p ../bin +set -x +./resource_embedder -o '../obj/embedded_resources.c' -d '../../embedded_resources' $inputs +gcc -Wall -Wextra -O2 -DEMBEDDED_RESOURCE_DEFINITION -c ../obj/embedded_resources.c -o ../bin/resources.o +set +x +# header without definitions +./resource_embedder -o '../../src/Resources/embedded_resources.h' +echo "embedded resources header was created at src/Resources/embedded_resources.h" diff --git a/dependencies/resource_embedder b/dependencies/resource_embedder index 9cc2fd7..b921791 160000 --- a/dependencies/resource_embedder +++ b/dependencies/resource_embedder @@ -1 +1 @@ -Subproject commit 9cc2fd7814eb6172b753fa1c7e2bea9656033755 +Subproject commit b921791be512bffc252ab555e47d48e0fb8261b5 diff --git a/embedded_resources/fonts/DroidSans.ttf b/embedded_resources/fonts/DroidSans.ttf new file mode 100644 index 0000000..767c63a Binary files /dev/null and b/embedded_resources/fonts/DroidSans.ttf differ diff --git a/project.config b/project.config index 04d3f30..f2768be 100644 --- a/project.config +++ b/project.config @@ -16,7 +16,7 @@ SRC_CPP="$(find src -name '*.cpp')" # See cbuild/example_dependency_configs DEPENDENCY_CONFIGS_DIR='dependencies' # List of dependency config files in DEPENDENCY_CONFIGS_DIR separated by space. -ENABLED_DEPENDENCIES='imgui precompiled' +ENABLED_DEPENDENCIES='precompiled resources imgui' # OBJDIR structure: # ├── objects/ - Compiled object files. Cleans on each call of build task @@ -179,7 +179,6 @@ case "$TASK" in # deletes generated files clean) TASK_SCRIPT=cbuild/default_tasks/clean.sh - POST_TASK_SCRIPT=tasks/clean_additions.sh ;; # nothing to do "" | no_task) diff --git a/src/GUI/MainWindow.cpp b/src/GUI/MainWindow.cpp index ea6125f..fa97ac9 100644 --- a/src/GUI/MainWindow.cpp +++ b/src/GUI/MainWindow.cpp @@ -1,6 +1,10 @@ +#include +#include +#include #include "MainWindow.hpp" -#include "backends/imgui_impl_sdl2.h" -#include "backends/imgui_impl_opengl3.h" +#include "exceptions.hpp" +#include "../format.hpp" +#include "../Resources/fonts.hpp" namespace ougge::GUI { @@ -71,6 +75,8 @@ void MainWindow::init(const char* window_title){ // Setup Dear ImGui style ImGui::StyleColorsDark(); + f32 dpi = getDPI(); + io.FontDefault = Resources::ImFont_LoadFromResource(default_font, default_font_size, dpi); } // Wait, poll and handle events (inputs, window resize, etc.) diff --git a/src/GUI/MainWindow.hpp b/src/GUI/MainWindow.hpp index 94a1094..c4c8c20 100644 --- a/src/GUI/MainWindow.hpp +++ b/src/GUI/MainWindow.hpp @@ -3,11 +3,7 @@ #include #include #include -#include -#include #include "../std.hpp" -#include "../format.hpp" -#include "exceptions.hpp" /// converts hex color to float vector #define RGBAHexToF(R8,G8,B8,A8) ImVec4(((u8)35)/255.0f, ((u8)35)/255.0f, ((u8)50)/255.0f, ((u8)255)/255.0f) diff --git a/src/Resources/Resources.cpp b/src/Resources/Resources.cpp new file mode 100644 index 0000000..6c9b014 --- /dev/null +++ b/src/Resources/Resources.cpp @@ -0,0 +1,84 @@ +#include +#include +#include +#include "../UsefulException.hpp" +#include "../format.hpp" +#include "Resources.hpp" +#include "embedded_resources.h" + + +namespace ougge::Resources { + +Resource::Resource(const std::string& path, const std::size_t size, StreamFactoryMethod open_read_steam_func) + : path(path), size(size), openStream(open_read_steam_func) +{} + +MemoryStreamBuf::MemoryStreamBuf(void* _p, const std::size_t n){ + char* p=(char*)_p; + setg(p, p, p + n); + setp(p, p + n); +} + +class MemoryStreamRead : public std::istream { +public: + MemoryStreamRead(const void* p, const std::size_t n) + : std::istream(new MemoryStreamBuf((void*)p, n)) + {} + + virtual ~MemoryStreamRead(){ + delete rdbuf(); + } +}; + +static std::unordered_map* _resourceMap = nullptr; + +void loadEmbeddedResources(){ + for(int i = 0; i < EmbeddedResource_table_count; i++){ + const EmbeddedResource& e = EmbeddedResource_table[i]; + std::cout <<"loading resource '" << e.path << "' " + << formatSizeHumanReadable(e.size) << std::endl; + + auto embedded_resource_factory = [e]() -> std::unique_ptr { + return std::make_unique(e.data, e.size); + }; + + auto r = _resourceMap->emplace(e.path, + Resource(e.path, e.size, embedded_resource_factory)); + if(!r.second) + throw UsefulException(format("can't load duplicate resource '%s'", e.path)); + } +} + +void init(){ + if(_resourceMap != nullptr) + throw UsefulException("resource has been initialized already"); + _resourceMap = new std::unordered_map(); + loadEmbeddedResources(); +} + +Resource& getResource(const std::string& path){ + auto it = _resourceMap->find(path); + if(it == _resourceMap->end()) + throw UsefulException(format("can't find resource '%s'", path.c_str())); + return it->second; +} + +std::string formatSizeHumanReadable(std::size_t b){ + std::stringstream ss; + ss.precision(3); + std::size_t k = b / 1024; + std::size_t m = k / 1024; + std::size_t g = m / 1024; + + if(g) + ss< +#include +#include + +namespace ougge::Resources { + +// call this in main() +void init(); + +std::string formatSizeHumanReadable(std::size_t byte_n); + +class Resource { +public: + const std::string path; + const std::size_t size; + + using StreamFactoryMethod = std::function< std::unique_ptr () >; + + Resource(const std::string& path, const std::size_t size, StreamFactoryMethod open_read_steam_func); + + const StreamFactoryMethod openStream; +}; + +class MemoryStreamBuf : public std::streambuf { +public: + MemoryStreamBuf(void* p, const std::size_t n); +}; + + +Resource& getResource(const std::string& path); + +} \ No newline at end of file diff --git a/src/Resources/embedded_resources.h b/src/Resources/embedded_resources.h new file mode 100644 index 0000000..817e24a --- /dev/null +++ b/src/Resources/embedded_resources.h @@ -0,0 +1,63 @@ +//////////////////////////////////////////////////////////////// +// This file was generated by resource_embedder // +// https://timerix.ddns.net:3322/Timerix/resource_embedder // +//////////////////////////////////////////////////////////////// +// USAGE: // +// Put it in a SOURCE file to define variables // +// #define EMBEDDED_RESOURCE_DEFINITION // +// #define EMBEDDED_RESOURCE_POSTFIX your_postfix // +// #include "../../src/Resources/embedded_resources.h" // +// // +// Put it in a HEADER file to declare external variables // +// #define EMBEDDED_RESOURCE_POSTFIX your_postfix // +// #include "../../src/Resources/embedded_resources.h" // +// // +// Then you can access embedded files through // +// EmbeddedResource_table_your_postfix. You can get table // +// content by index and put it into a hashtable or a map. // +//////////////////////////////////////////////////////////////// + +#pragma once +#if __cplusplus +extern "C" { +#endif + +#include + +typedef struct { + const char* path; + const char* data; + size_t size; +} EmbeddedResource; + +#define RSCAT(A,B,C...) A##B##C +#ifdef EMBEDDED_RESOURCE_POSTFIX + #define _EmbeddedResource_table(P) \ + RSCAT(EmbeddedResource_table_, P) + #define _EmbeddedResource_table_count(P) \ + RSCAT(EmbeddedResource_table_, P, _count) +#else + #define _EmbeddedResource_table(P) \ + EmbeddedResource_table + #define _EmbeddedResource_table_count(P) \ + EmbeddedResource_table_count +#endif +extern const EmbeddedResource _EmbeddedResource_table(EMBEDDED_RESOURCE_POSTFIX)[]; +extern const int _EmbeddedResource_table_count(EMBEDDED_RESOURCE_POSTFIX); + +#ifdef EMBEDDED_RESOURCE_DEFINITION +const EmbeddedResource _EmbeddedResource_table(EMBEDDED_RESOURCE_POSTFIX)[]={ + +}; + +const int _EmbeddedResource_table_count(EMBEDDED_RESOURCE_POSTFIX)=0; +#endif // EMBEDDED_RESOURCE_DEFINITION + +#undef _EmbeddedResource_table +#undef _EmbeddedResource_table_count +#undef EMBEDDED_RESOURCE_POSTFIX +#undef RSCAT + +#if __cplusplus +} +#endif diff --git a/src/Resources/fonts.cpp b/src/Resources/fonts.cpp new file mode 100644 index 0000000..c866a9b --- /dev/null +++ b/src/Resources/fonts.cpp @@ -0,0 +1,33 @@ +#include +#include "Resources.hpp" +#include +#include + +namespace ougge::Resources { + +// select all glyphs from font +static const ImWchar glyph_ranges[] = { + 0x0020, 0xFFFF, 0 +}; + +ImFont* ImFont_LoadFromFile(const std::string& file_path, f32 font_size, f32 dpi){ + ImGuiIO& io = ImGui::GetIO(); + font_size *= dpi; + return io.Fonts->AddFontFromFileTTF(file_path.c_str(), font_size, nullptr, glyph_ranges); +} + +ImFont* ImFont_LoadFromResource(const std::string& font_name, f32 font_size, f32 dpi){ + ImGuiIO& io = ImGui::GetIO(); + font_size *= dpi; + ImFontConfig font_cfg = ImFontConfig(); + std::sprintf(font_cfg.Name, "%s %ipx", font_name.c_str(), (i32)font_size); + + Resource& res = getResource("fonts/" + font_name + ".ttf"); + char* font_data = new char[res.size]; + res.openStream()->read(font_data, res.size); + + return io.Fonts->AddFontFromMemoryTTF((void*)(font_data), res.size, + font_size, &font_cfg, glyph_ranges); +} + +} diff --git a/src/Resources/fonts.hpp b/src/Resources/fonts.hpp new file mode 100644 index 0000000..63aea47 --- /dev/null +++ b/src/Resources/fonts.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "imgui.h" +#include "../std.hpp" + +namespace ougge::Resources { + +ImFont* ImFont_LoadFromFile(const std::string& file_path, f32 font_size, f32 dpi); + +ImFont* ImFont_LoadFromResource(const std::string& font_name, f32 font_size, f32 dpi); + +} diff --git a/src/format.cpp b/src/format.cpp index 8d98bce..8eb6fb4 100644 --- a/src/format.cpp +++ b/src/format.cpp @@ -1,8 +1,7 @@ -#include #include #include +#include "format.hpp" #include "UsefulException.hpp" -#include "std.hpp" std::string _format(const std::string& format_str, const size_t args_count, ...){ va_list vl; diff --git a/src/format.hpp b/src/format.hpp index 493df97..9c9485b 100644 --- a/src/format.hpp +++ b/src/format.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include "std.hpp" std::string _format(const std::string& format_str, const size_t args_count, ...); diff --git a/src/main.cpp b/src/main.cpp index cbb22f3..08fa535 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,8 @@ #define SDL_MAIN_HANDLED -#include "GUI/MainWindow.hpp" -#include "std.hpp" #include +#include "std.hpp" +#include "GUI/MainWindow.hpp" +#include "Resources/Resources.hpp" using namespace ougge; @@ -10,6 +11,7 @@ int main(int argc, const char** argv){ std::cerr<<"\e[93msetlocale failed!\n"; try { + Resources::init(); GUI::MainWindow w; w.init("ougge"); w.startAndWait(); diff --git a/src/std.hpp b/src/std.hpp index 4f2f404..b10c880 100644 --- a/src/std.hpp +++ b/src/std.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include typedef int8_t i8; typedef uint8_t u8; diff --git a/tasks/clean_additions.sh b/tasks/clean_additions.sh deleted file mode 100644 index 83fa64f..0000000 --- a/tasks/clean_additions.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -try_delete_dir_or_file src/generated