diff --git a/CMakeLists.txt b/CMakeLists.txt index 5726b27..74afdb6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,7 +52,8 @@ add_executable(Graph src/dofpass.cpp src/imguipass.cpp src/skypass.cpp - src/shadowpass.cpp) + src/shadowpass.cpp + src/config.cpp) target_compile_options(Graph PUBLIC -fno-exceptions @@ -90,4 +91,5 @@ add_data(Graph data/test.cim data/bokeh.png data/scene.obj - data/tile.jpg) + data/tile.jpg + data/graphics_presets.cfg) diff --git a/data/graphics_presets.cfg b/data/graphics_presets.cfg new file mode 100644 index 0000000..9d70aac --- /dev/null +++ b/data/graphics_presets.cfg @@ -0,0 +1,8 @@ +[Low] +shadowResolution=128 + +[Medium] +shadowResolution=256 + +[High] +shadowResolution=512 diff --git a/include/config.h b/include/config.h new file mode 100644 index 0000000..d0b85ec --- /dev/null +++ b/include/config.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include + +class Config { +public: + bool load(const char* from); + void save(const char* to); + + void set(const char* category, const char* key, const std::string& value); + std::string get(const char* category, const char* key); + +private: + std::map> categories; +}; diff --git a/include/renderer.h b/include/renderer.h index 6e65933..c089b3d 100644 --- a/include/renderer.h +++ b/include/renderer.h @@ -68,6 +68,10 @@ struct RenderTarget { VkDescriptorSet* dofSets = nullptr; }; +struct GraphicsConfig { + int shadowResolution; +}; + class World; class Mesh; class Camera; @@ -75,7 +79,7 @@ class Material; class Renderer { public: - Renderer(); + Renderer(GraphicsConfig config); ~Renderer(); void render(World& world, Camera& camera, RenderTarget* target); @@ -97,6 +101,10 @@ public: void fillMaterialBuffers(Material* material); void destroyMaterialBuffers(Material* material); + GraphicsConfig getConfig() const { + return config_; + } + VkInstance getInstance() const { return instance_; } @@ -144,6 +152,8 @@ private: void createDescriptorPool(); void createMaterialSetLayout(); + GraphicsConfig config_; + VkInstance instance_ = nullptr; #ifdef DEBUG diff --git a/shaders/mesh.frag b/shaders/mesh.frag index 2adc1f7..3dba3fe 100644 --- a/shaders/mesh.frag +++ b/shaders/mesh.frag @@ -37,7 +37,7 @@ float filterPCF(vec4 sc) { const float scale = 1.5; const float dx = scale * 1.0 / float(texDim.x); const float dy = scale * 1.0 / float(texDim.y); - const int range = 2; + const int range = 1; float shadowFactor = 0.0; int count = 0; diff --git a/src/config.cpp b/src/config.cpp new file mode 100644 index 0000000..fb2b374 --- /dev/null +++ b/src/config.cpp @@ -0,0 +1,53 @@ +#include "config.h" + +#include +#include + +bool Config::load(const char* from) { + std::ifstream file(from); + if(!file) + return false; + + std::string line, currentCategory; + while(std::getline(file, line)) { + //category + if(line[0] == '[') + currentCategory = line.substr(1, line.length() - 2); + + //key/value + if(line.find('=') != std::string::npos) { + std::string key, value; + key = line.substr(0, line.find('=')); + value = line.substr(line.find('=') + 1, line.length()); + + categories[currentCategory][key] = value; + } + } + + return true; +} + +void Config::save(const char* to) { + std::ofstream file(to); + if(!file) + return; + + std::string currentCategory; + for(auto itr : categories) { + file << "[" << itr.first << "]\n"; + + for(auto itr2 : itr.second) { + file << itr2.first << "=" << itr2.second << "\n"; + } + + file << "\n"; + } +} + +void Config::set(const char* category, const char* key, const std::string& value) { + categories[category][key] = value; +} + +std::string Config::get(const char* category, const char* key) { + return categories[category][key]; +} diff --git a/src/main.cpp b/src/main.cpp index 1f2bbe6..4938ff5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,6 +17,7 @@ #include "camera.h" #include "cinematic.h" #include "material.h" +#include "config.h" SDL_Window* window = nullptr; Renderer* renderer = nullptr; @@ -40,6 +41,8 @@ int windowY = SDL_WINDOWPOS_CENTERED; int windowWidth = 640; int windowHeight = 480; int windowFullscreen = 0; +std::string currentGraphicsPreset = "Medium"; +GraphicsConfig graphicsConfig; int toInt(const std::string &str) { std::stringstream ss(str); @@ -51,51 +54,42 @@ int toInt(const std::string &str) { return num; } -void readConfig() { - std::ifstream file("config.txt"); - if(!file) +void loadGraphicsConfig() { + Config config; + if(!config.load("data/graphics_presets.cfg")) return; - std::string line; - while(std::getline(file, line)) { - if(line.find('=') != std::string::npos) { - std::string key, value; - key = line.substr(0, line.find('=')); - value = line.substr(line.find('=') + 1, line.length()); + graphicsConfig.shadowResolution = toInt(config.get(currentGraphicsPreset.c_str(), "shadowResolution")); +} - if(key == "x") { - windowX = toInt(value); - } else if(key == "y") { - windowY = toInt(value); - } else if(key == "width") { - windowWidth = toInt(value); - } else if(key == "height") { - windowHeight = toInt(value); - } else if(key == "fullscreen") { - windowFullscreen = toInt(value); - } - } - } +void readConfig() { + Config config; + if(!config.load("user.cfg")) + return; + + windowX = toInt(config.get("Window", "x")); + windowY = toInt(config.get("Window", "y")); + windowWidth = toInt(config.get("Window", "width")); + windowHeight = toInt(config.get("Window", "height")); + windowFullscreen = toInt(config.get("Window", "fullscreen")); + + currentGraphicsPreset = config.get("Graphics", "preset"); + + loadGraphicsConfig(); } void writeConfig() { - std::ofstream file("config.txt"); - if(!file) - return; + Config config; - int x, y; - SDL_GetWindowPosition(window, &x, &y); + config.set("Window", "x", std::to_string(windowX)); + config.set("Window", "y", std::to_string(windowY)); + config.set("Window", "width", std::to_string(windowWidth)); + config.set("Window", "height", std::to_string(windowHeight)); + config.set("Window", "fullscreen", std::to_string(windowFullscreen)); - file << "x=" << x << "\n"; - file << "y=" << y << "\n"; + config.set("Graphics", "preset", currentGraphicsPreset); - int w, h; - SDL_GetWindowSize(window, &w, &h); - - file << "width=" << w << "\n"; - file << "height=" << h << "\n"; - - file << "fullscreen=" << windowFullscreen << "\n"; + config.save("user.cfg"); } Mesh* loadMesh(const char* path) { @@ -228,7 +222,7 @@ int main(int argc, char* argv[]) { ImGui::StyleColorsDark(); - renderer = new Renderer(); + renderer = new Renderer(graphicsConfig); VkSurfaceKHR surface = nullptr; SDL_Vulkan_CreateSurface(window, renderer->getInstance(), &surface); diff --git a/src/renderer.cpp b/src/renderer.cpp index 45a9de4..e2311b9 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -14,7 +14,7 @@ #include "camera.h" #include "material.h" -Renderer::Renderer() { +Renderer::Renderer(GraphicsConfig config) : config_(config) { createInstance(); #ifdef DEBUG if(enableDebug) diff --git a/src/shadowpass.cpp b/src/shadowpass.cpp index 0060ba5..4eabd3e 100644 --- a/src/shadowpass.cpp +++ b/src/shadowpass.cpp @@ -29,15 +29,15 @@ ShadowPass::~ShadowPass() { void ShadowPass::render(VkCommandBuffer commandBuffer, World& world) { VkViewport viewport = {}; - viewport.width = 512; - viewport.height = 512; + viewport.width = renderer_.getConfig().shadowResolution; + viewport.height = renderer_.getConfig().shadowResolution; viewport.maxDepth = 1.0f; vkCmdSetViewport(commandBuffer, 0, 1, &viewport); VkRect2D scissor = {}; - scissor.extent.width = 512; - scissor.extent.height = 512; + scissor.extent.width = renderer_.getConfig().shadowResolution; + scissor.extent.height = renderer_.getConfig().shadowResolution; vkCmdSetScissor(commandBuffer, 0, 1, &scissor); @@ -48,8 +48,8 @@ void ShadowPass::render(VkCommandBuffer commandBuffer, World& world) { renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; renderPassBeginInfo.framebuffer = shadowFramebuffer_; renderPassBeginInfo.renderPass = renderPass_; - renderPassBeginInfo.renderArea.extent.width = 512; - renderPassBeginInfo.renderArea.extent.height = 512; + renderPassBeginInfo.renderArea.extent.width = renderer_.getConfig().shadowResolution; + renderPassBeginInfo.renderArea.extent.height = renderer_.getConfig().shadowResolution; renderPassBeginInfo.clearValueCount = 1; renderPassBeginInfo.pClearValues = &clearColor; @@ -113,8 +113,8 @@ void ShadowPass::createFramebuffer() { imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; imageCreateInfo.imageType = VK_IMAGE_TYPE_2D; imageCreateInfo.format = VK_FORMAT_D32_SFLOAT; - imageCreateInfo.extent.width = 512; - imageCreateInfo.extent.height = 512; + imageCreateInfo.extent.width = renderer_.getConfig().shadowResolution; + imageCreateInfo.extent.height = renderer_.getConfig().shadowResolution; imageCreateInfo.extent.depth = 1; imageCreateInfo.mipLevels = 1; imageCreateInfo.arrayLayers = 1; @@ -151,8 +151,8 @@ void ShadowPass::createFramebuffer() { framebufferInfo.renderPass = renderPass_; framebufferInfo.attachmentCount = 1; framebufferInfo.pAttachments = &shadowImageView_; - framebufferInfo.width = 512; - framebufferInfo.height = 512; + framebufferInfo.width = renderer_.getConfig().shadowResolution; + framebufferInfo.height = renderer_.getConfig().shadowResolution; framebufferInfo.layers = 1; vkCreateFramebuffer(renderer_.getDevice(), &framebufferInfo, nullptr, &shadowFramebuffer_);