resources

This commit is contained in:
Timerix 2024-07-30 21:51:25 +03:00
parent 660fb5247c
commit 22c64c9e9b
17 changed files with 259 additions and 18 deletions

1
.gitignore vendored
View File

@ -1,7 +1,6 @@
# build results
bin/
obj/
src/generated/
imgui.ini
# IDE files

16
dependencies/compile_resources.sh vendored Normal file
View File

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

@ -1 +1 @@
Subproject commit 9cc2fd7814eb6172b753fa1c7e2bea9656033755
Subproject commit b921791be512bffc252ab555e47d48e0fb8261b5

Binary file not shown.

View File

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

View File

@ -1,6 +1,10 @@
#include <backends/imgui_impl_sdl2.h>
#include <backends/imgui_impl_opengl3.h>
#include <iostream>
#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.)

View File

@ -3,11 +3,7 @@
#include <SDL.h>
#include <SDL_opengl.h>
#include <imgui.h>
#include <iostream>
#include <string>
#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)

View File

@ -0,0 +1,84 @@
#include <unordered_map>
#include <fstream>
#include <sstream>
#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<std::string, Resource>* _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<std::istream> {
return std::make_unique<MemoryStreamRead>(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<std::string, Resource>();
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<<m / 1024.0f<<'G';
else if(m)
ss<<k / 1024.0f<<'M';
else if(k)
ss<<b / 1024.0f<<'K';
else ss<<b;
return ss.str();
}
}

View File

@ -0,0 +1,35 @@
#pragma once
#include "../std.hpp"
#include <iostream>
#include <memory>
#include <functional>
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<std::istream> () >;
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);
}

View File

@ -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 <stdint.h>
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

33
src/Resources/fonts.cpp Normal file
View File

@ -0,0 +1,33 @@
#include <imgui.h>
#include "Resources.hpp"
#include <cstdio>
#include <cstring>
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);
}
}

12
src/Resources/fonts.hpp Normal file
View File

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

View File

@ -1,8 +1,7 @@
#include <string>
#include <sstream>
#include <stdarg.h>
#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;

View File

@ -1,6 +1,5 @@
#pragma once
#include <string>
#include "std.hpp"
std::string _format(const std::string& format_str, const size_t args_count, ...);

View File

@ -1,7 +1,8 @@
#define SDL_MAIN_HANDLED
#include "GUI/MainWindow.hpp"
#include "std.hpp"
#include <iostream>
#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();

View File

@ -1,6 +1,7 @@
#pragma once
#include <cstdint>
#include <string>
typedef int8_t i8;
typedef uint8_t u8;

View File

@ -1,3 +0,0 @@
#!/usr/bin/env bash
try_delete_dir_or_file src/generated