202 lines
7.6 KiB
C++
202 lines
7.6 KiB
C++
#pragma once
|
|
|
|
#define UI_MARGIN 5
|
|
#define MIN_FPS 24
|
|
#define MAX_FPS 240
|
|
|
|
#include <toml.h>
|
|
#include <fstream>
|
|
#include <filesystem>
|
|
#include <optional>
|
|
#include "data/glm.hpp"
|
|
#include "data/circular_buffer.hpp"
|
|
#include "render/Renderer.hpp"
|
|
#include "world/Universe.hpp"
|
|
#include "control/Camera.hpp"
|
|
#include "contouring/index.hpp"
|
|
|
|
inline glm::vec4 fromHex(const std::string& str) {
|
|
std::array<int, 3> rgb = {UCHAR_MAX};
|
|
sscanf(str.c_str() + 1, "%02X%02X%02X", (unsigned int *)&rgb[0], (unsigned int *)&rgb[1], (unsigned int *)&rgb[2]);
|
|
return glm::vec4(rgb[0] * 1.f / UCHAR_MAX, rgb[1] * 1.f / UCHAR_MAX, rgb[2] * 1.f / UCHAR_MAX, 1);
|
|
}
|
|
inline std::string toHexa(const glm::vec4& rgb) {
|
|
std::ostringstream sstr;
|
|
sstr << std::hex << std::setw(2) << std::setfill('0') <<
|
|
static_cast<int>(rgb.x * UCHAR_MAX) << static_cast<int>(rgb.y * UCHAR_MAX) << static_cast<int>(rgb.z * UCHAR_MAX) << std::endl;
|
|
return sstr.str();
|
|
}
|
|
|
|
/// Savable game options
|
|
struct options {
|
|
const char *PATH = "config.toml";
|
|
/// Load from PATH
|
|
options() {
|
|
auto config = std::filesystem::exists(PATH) ? toml::parse_file(PATH) : toml::table();
|
|
target_fps = config["window"]["fps"].value_or(60);
|
|
samples = config["window"]["samples"].value_or(-1);
|
|
fullscreen = config["window"]["fullscreen"].value_or(false);
|
|
|
|
renderer.textures = config["render"]["textures"].value_or(renderer.textures);
|
|
renderer.mipMapLOD = config["render"]["texture_quality"].value_or(renderer.mipMapLOD);
|
|
renderer.main.pbr = config["render"]["pbr"].value_or(renderer.main.pbr);
|
|
renderer.main.triplanar = config["render"]["triplanar"].value_or(renderer.main.triplanar);
|
|
renderer.main.geometry = config["render"]["geometry"].value_or(renderer.main.geometry);
|
|
renderer.main.blend = config["render"]["blend"].value_or(renderer.main.blend);
|
|
renderer.main.fog = config["render"]["fog"].value_or(renderer.main.fog);
|
|
const std::string fog = config["render"]["fog_color"].value_or(std::string{"#000000"});
|
|
renderer.clear_color = fromHex(fog);
|
|
renderer.skybox = config["render"]["skybox"].value_or(renderer.skybox);
|
|
|
|
world.loadDistance = config["world"]["load_distance"].value_or(world.loadDistance);
|
|
world.keepDistance = config["world"]["keep_distance"].value_or(world.keepDistance);
|
|
world.folderPath = config["world"]["path"].value_or(world.folderPath);
|
|
voxel_density = config["world"]["voxel_density"].value_or(1);
|
|
|
|
culling = config["mesh"]["culling"].value_or(true);
|
|
contouring_idx = contouring::idxByName(config["mesh"]["mode"].value_or(std::string("")));
|
|
for(const auto& name: contouring::names) {
|
|
contouring_data.emplace(name, config["mesh"]["options"][name].value_or(std::string("")));
|
|
}
|
|
|
|
camera.far = config["camera"]["far"].value_or(camera.far);
|
|
camera.near = config["camera"]["near"].value_or(camera.near);
|
|
camera.fov = config["camera"]["fov"].value_or(camera.fov);
|
|
control.sensibility = config["control"]["sensibility"].value_or(control.sensibility);
|
|
control.speed = config["control"]["speed"].value_or(control.speed);
|
|
control.collide = config["control"]["collide"].value_or(control.collide);
|
|
|
|
overlay_show = config["overlay"]["visible"].value_or(true);
|
|
overlay_corner = config["overlay"]["corner"].value_or(3);
|
|
//TODO: console
|
|
|
|
show_debug_menu = config["show_debug"]["menu"].value_or(false);
|
|
show_debug_render = config["show_debug"]["render"].value_or(false);
|
|
show_debug_world = config["show_debug"]["world"].value_or(false);
|
|
show_debug_contouring = config["show_debug"]["contouring"].value_or(false);
|
|
show_debug_controls = config["show_debug"]["controls"].value_or(false);
|
|
|
|
editor_show = config["editor"]["visible"].value_or(false);
|
|
tool.material = config["editor"]["tool"]["material"].value_or<int>(tool.material);
|
|
tool.radius = config["editor"]["tool"]["radius"].value_or(tool.radius);
|
|
}
|
|
/// Write to PATH
|
|
void save() {
|
|
auto config = toml::table();
|
|
config.insert_or_assign("window", toml::table({
|
|
{"fps", target_fps},
|
|
{"samples", samples},
|
|
{"fullscreen", fullscreen},
|
|
}));
|
|
config.insert_or_assign("render", toml::table({
|
|
{"textures", renderer.textures},
|
|
{"texture_quality", renderer.mipMapLOD},
|
|
{"pbr", renderer.main.pbr},
|
|
{"triplanar", renderer.main.triplanar},
|
|
{"geometry", renderer.main.geometry},
|
|
{"blend", renderer.main.blend},
|
|
{"fog", renderer.main.fog},
|
|
{"fog_color", toHexa(renderer.clear_color)},
|
|
{"skybox", renderer.skybox}
|
|
}));
|
|
config.insert_or_assign("world", toml::table({
|
|
{"load_distance", world.loadDistance},
|
|
{"keep_distance", world.keepDistance},
|
|
{"voxel_density", voxel_density},
|
|
{"path", world.folderPath}
|
|
}));
|
|
config.insert_or_assign("mesh", toml::table({
|
|
{"culling", culling},
|
|
{"mode", contouring::names[contouring_idx]},
|
|
{"options", toml::table()}
|
|
}));
|
|
for(const auto& [key, val]: contouring_data) {
|
|
if(!val.empty())
|
|
config["mesh"]["options"].as_table()->insert_or_assign(key, val);
|
|
}
|
|
|
|
config.insert_or_assign("camera", toml::table({
|
|
{"far", camera.far},
|
|
{"near", camera.near},
|
|
{"fov", camera.fov}
|
|
}));
|
|
config.insert_or_assign("control", toml::table({
|
|
{"sensibility", control.sensibility},
|
|
{"speed", control.speed},
|
|
{"collide", control.collide}
|
|
}));
|
|
config.insert_or_assign("overlay", toml::table({
|
|
{"visible", overlay_show},
|
|
{"corner", overlay_corner}
|
|
}));
|
|
config.insert_or_assign("show_debug", toml::table({
|
|
{"menu", show_debug_menu},
|
|
{"render", show_debug_render},
|
|
{"world", show_debug_world},
|
|
{"contouring", show_debug_contouring},
|
|
{"controls", show_debug_controls}
|
|
}));
|
|
|
|
config.insert_or_assign("editor", toml::table({
|
|
{"visible", editor_show},
|
|
{"tool", toml::table({
|
|
{"material", (int)tool.material},
|
|
{"radius", tool.radius}
|
|
})}
|
|
}));
|
|
|
|
std::ofstream out;
|
|
out.open(PATH, std::ios::out | std::ios::trunc);
|
|
out << config << "\n\n";
|
|
out.close();
|
|
}
|
|
|
|
bool show_debug_menu;
|
|
bool show_debug_render;
|
|
int target_fps;
|
|
int samples;
|
|
bool fullscreen;
|
|
Renderer::options renderer;
|
|
|
|
bool show_debug_world;
|
|
world::Universe::options world;
|
|
int voxel_density;
|
|
|
|
bool show_debug_contouring;
|
|
bool culling;
|
|
int contouring_idx;
|
|
std::map<std::string, std::string> contouring_data;
|
|
|
|
bool show_debug_controls;
|
|
Controllable::options control;
|
|
Camera::options camera;
|
|
|
|
bool editor_show;
|
|
struct tool {
|
|
int radius = 2;
|
|
unsigned short material = 2;
|
|
} tool;
|
|
|
|
bool overlay_show;
|
|
int overlay_corner;
|
|
|
|
bool console_show = false;
|
|
bool console_scrool = true;
|
|
};
|
|
|
|
/// Live state
|
|
struct state {
|
|
bool capture_mouse = true;
|
|
camera_pos position = camera_pos(voxel_pos(0), 1);
|
|
std::optional<world::Universe::ray_target> look_at = {};
|
|
|
|
std::shared_ptr<contouring::Abstract> contouring;
|
|
|
|
std::array<char, 256> console_buffer;
|
|
};
|
|
|
|
/// Readonly metrics
|
|
struct reports {
|
|
size_t tris_count = 0;
|
|
size_t models_count = 0;
|
|
}; |