From f90ec88e6728ce865bcf892c810a36abd90d9001 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Thu, 19 Mar 2015 14:10:36 +0100 Subject: [PATCH] extracted configuration of various parts --- running | 37 ++++++++++++++++++++++++++++++++----- src/app.cpp | 12 +++++++----- src/app.hpp | 11 ++++++++++- src/chunk.cpp | 6 +++--- src/chunk.hpp | 7 ++++++- src/generator.cpp | 10 +++++----- src/generator.hpp | 9 ++++++++- src/init.cpp | 17 ++++++++++++++--- src/init.hpp | 2 +- src/interface.cpp | 31 +++++++++++++++++++------------ src/interface.hpp | 16 ++++++++++++---- src/runtime.cpp | 33 ++++++++++++++++++++++++++++----- src/runtime.hpp | 4 +++- src/world.cpp | 21 ++++++++++----------- src/world.hpp | 20 +++++++++++++++++++- 15 files changed, 177 insertions(+), 59 deletions(-) diff --git a/running b/running index bfea07c..be21009 100644 --- a/running +++ b/running @@ -1,18 +1,45 @@ Arguments ========= -blank - normal execution +Runtime +------- -blank [-n] +[-n] terminate after frames -blank -t +-t terminate after milliseconds -blank -t +[-n] -t terminate after n frames, assume milliseconds pass each frame +Application +----------- + +-d + disable double buffering + +-m + set sample size to (samples per pixel) + +--no-vsync + disable vsync + +Interface +--------- + +--no-keyboard + disable keyboard input handling + +--no-mouse + disable mouse input handling + +--no-hud + disable HUD drawing (includes the selected block outline) + +World +----- + blank -s use (unsigned integer) as the world seed. default is 0 diff --git a/src/app.cpp b/src/app.cpp index b7e71ec..a6f81f1 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -6,20 +6,22 @@ namespace blank { -Application::Application(unsigned int seed) +Application::Application(const Config &config) : init_sdl() , init_img() -, init_gl() +, init_gl(config.doublebuf, config.multisampling) , window() , ctx(window.CreateContext()) , init_glew() , program() , cam() -, world(seed) -, interface(world) +, world(config.world) +, interface(config.interface, world) , test_controller(MakeTestEntity(world)) , running(false) { - GLContext::EnableVSync(); + if (config.vsync) { + GLContext::EnableVSync(); + } glClearColor(0.0, 0.0, 0.0, 1.0); } diff --git a/src/app.hpp b/src/app.hpp index c8a6fb5..23dcd0c 100644 --- a/src/app.hpp +++ b/src/app.hpp @@ -14,7 +14,16 @@ namespace blank { class Application { public: - explicit Application(unsigned int seed); + struct Config { + bool vsync = true; + bool doublebuf = true; + int multisampling = 1; + + Interface::Config interface = Interface::Config(); + World::Config world = World::Config(); + }; + + explicit Application(const Config &); Application(const Application &) = delete; Application &operator =(const Application &) = delete; diff --git a/src/chunk.cpp b/src/chunk.cpp index 66b049f..70a2563 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -470,15 +470,15 @@ glm::mat4 Chunk::ToTransform(int idx) const { } -ChunkLoader::ChunkLoader(const BlockTypeRegistry ®, const Generator &gen) +ChunkLoader::ChunkLoader(const Config &config, const BlockTypeRegistry ®, const Generator &gen) : base(0, 0, 0) , reg(reg) , gen(gen) , loaded() , to_generate() , to_free() -, load_dist(6) -, unload_dist(8) { +, load_dist(config.load_dist) +, unload_dist(config.unload_dist) { } diff --git a/src/chunk.hpp b/src/chunk.hpp index d8408ec..840bac0 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -158,7 +158,12 @@ class Generator; class ChunkLoader { public: - ChunkLoader(const BlockTypeRegistry &, const Generator &); + struct Config { + int load_dist = 6; + int unload_dist = 8; + }; + + ChunkLoader(const Config &, const BlockTypeRegistry &, const Generator &); void Generate(const Chunk::Pos &from, const Chunk::Pos &to); void GenerateSurrounding(const Chunk::Pos &); diff --git a/src/generator.cpp b/src/generator.cpp index c1a7a08..43d932c 100644 --- a/src/generator.cpp +++ b/src/generator.cpp @@ -5,11 +5,11 @@ namespace blank { -Generator::Generator(unsigned int seed) -: solidNoise(seed) -, typeNoise(seed + 1) -, stretch(64.0f) -, solid_threshold(0.8f) +Generator::Generator(const Config &config) +: solidNoise(config.solid_seed) +, typeNoise(config.type_seed) +, stretch(config.stretch) +, solid_threshold(config.solid_threshold) , space(0) , light(0) , solids() { diff --git a/src/generator.hpp b/src/generator.hpp index b3e8ffb..3d7ceaf 100644 --- a/src/generator.hpp +++ b/src/generator.hpp @@ -13,7 +13,14 @@ namespace blank { class Generator { public: - explicit Generator(unsigned int seed); + struct Config { + unsigned int solid_seed = 0; + unsigned int type_seed = 0; + float stretch = 64.0f; + float solid_threshold = 0.8f; + }; + + explicit Generator(const Config &); void operator ()(Chunk &) const; diff --git a/src/init.cpp b/src/init.cpp index 061e848..73a7309 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -46,7 +46,7 @@ InitIMG::~InitIMG() { } -InitGL::InitGL() { +InitGL::InitGL(bool double_buffer, int sample_size) { if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3) != 0) { sdl_error("SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3)"); } @@ -57,8 +57,19 @@ InitGL::InitGL() { sdl_error("SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE)"); } - if (SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1) != 0) { - sdl_error("SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1)"); + if (double_buffer) { + if (SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1) != 0) { + sdl_error("SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1)"); + } + } + + if (sample_size > 1) { + if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1) != 0) { + sdl_error("SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS)"); + } + if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, sample_size) != 0) { + sdl_error("SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES)"); + } } } diff --git a/src/init.hpp b/src/init.hpp index 6064fca..d08437b 100644 --- a/src/init.hpp +++ b/src/init.hpp @@ -36,7 +36,7 @@ public: class InitGL { public: - InitGL(); + explicit InitGL(bool double_buffer = true, int sample_size = 1); InitGL(const InitGL &) = delete; InitGL &operator =(const InitGL &) = delete; diff --git a/src/interface.cpp b/src/interface.cpp index f4b13b0..c0bfc02 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -11,7 +11,7 @@ namespace blank { -Interface::Interface(World &world) +Interface::Interface(const Config &config, World &world) : world(world) , ctrl(world.Player()) , hud(world.BlockTypes()) @@ -20,9 +20,7 @@ Interface::Interface(World &world) , aim_normal() , outline() , outline_transform(1.0f) -, move_velocity(0.005f) -, pitch_sensitivity(-0.0025f) -, yaw_sensitivity(-0.001f) +, config(config) , remove(0) , selection(1) , front(false) @@ -37,6 +35,8 @@ Interface::Interface(World &world) void Interface::Handle(const SDL_KeyboardEvent &event) { + if (config.keyboard_disabled) return; + switch (event.keysym.sym) { case SDLK_w: front = event.state == SDL_PRESSED; @@ -130,11 +130,14 @@ void Interface::Print(const Block &block) { void Interface::Handle(const SDL_MouseMotionEvent &event) { - ctrl.RotateYaw(event.xrel * yaw_sensitivity); - ctrl.RotatePitch(event.yrel * pitch_sensitivity); + if (config.mouse_disabled) return; + ctrl.RotateYaw(event.xrel * config.yaw_sensitivity); + ctrl.RotatePitch(event.yrel * config.pitch_sensitivity); } void Interface::Handle(const SDL_MouseButtonEvent &event) { + if (config.mouse_disabled) return; + if (event.state != SDL_PRESSED) return; if (event.button == 1) { @@ -172,6 +175,8 @@ void Interface::RemoveBlock() { void Interface::Handle(const SDL_MouseWheelEvent &event) { + if (config.mouse_disabled) return; + if (event.y < 0) { SelectNext(); } else if (event.y > 0) { @@ -205,19 +210,19 @@ void Interface::Handle(const SDL_WindowEvent &event) { void Interface::Update(int dt) { glm::vec3 vel; if (right && !left) { - vel.x = move_velocity; + vel.x = config.move_velocity; } else if (left && !right) { - vel.x = -move_velocity; + vel.x = -config.move_velocity; } if (up && !down) { - vel.y = move_velocity; + vel.y = config.move_velocity; } else if (down && !up) { - vel.y = -move_velocity; + vel.y = -config.move_velocity; } if (back && !front) { - vel.z = move_velocity; + vel.z = config.move_velocity; } else if (front && !back) { - vel.z = -move_velocity; + vel.z = -config.move_velocity; } ctrl.Velocity(vel); ctrl.Update(dt); @@ -238,6 +243,8 @@ void Interface::Update(int dt) { void Interface::Render(DirectionalLighting &program) { + if (config.visual_disabled) return; + if (aim_chunk) { program.SetM(outline_transform); outline.Draw(); diff --git a/src/interface.hpp b/src/interface.hpp index d3d58e8..7bfd715 100644 --- a/src/interface.hpp +++ b/src/interface.hpp @@ -18,7 +18,17 @@ class World; class Interface { public: - explicit Interface(World &); + struct Config { + float move_velocity = 0.005f; + float pitch_sensitivity = -0.0025f; + float yaw_sensitivity = -0.001f; + + bool keyboard_disabled = false; + bool mouse_disabled = false; + bool visual_disabled = false; + }; + + Interface(const Config &, World &); void Handle(const SDL_KeyboardEvent &); void Handle(const SDL_MouseMotionEvent &); @@ -57,9 +67,7 @@ private: OutlineModel outline; glm::mat4 outline_transform; - float move_velocity; - float pitch_sensitivity; - float yaw_sensitivity; + Config config; Block remove; Block selection; diff --git a/src/runtime.cpp b/src/runtime.cpp index 9fb644c..18a06bf 100644 --- a/src/runtime.cpp +++ b/src/runtime.cpp @@ -16,7 +16,7 @@ Runtime::Runtime() , mode(NORMAL) , n(0) , t(0) -, seed(0) { +, config() { } @@ -43,13 +43,35 @@ void Runtime::ReadArgs(int argc, const char *const *argv) { options = false; } else { // long option - cerr << "unknown option " << arg << endl; - error = true; + if (strcmp(arg + 2, "no-vsync") == 0) { + config.vsync = false; + } else if (strcmp(arg + 2, "no-keyboard") == 0) { + config.interface.keyboard_disabled = true; + } else if (strcmp(arg + 2, "no-mouse") == 0) { + config.interface.mouse_disabled = true; + } else if (strcmp(arg + 2, "no-hud") == 0) { + config.interface.visual_disabled = true; + } else { + cerr << "unknown option " << arg << endl; + error = true; + } } } else { // short options for (int j = 1; arg[j] != '\0'; ++j) { switch (arg[j]) { + case 'd': + config.doublebuf = false; + break; + case 'm': + ++i; + if (i >= argc || argv[i] == nullptr || argv[i][0] == '\0') { + cerr << "missing argument to -m" << endl; + error = true; + } else { + config.multisampling = strtoul(argv[i], nullptr, 10); + } + break; case 'n': ++i; if (i >= argc || argv[i] == nullptr || argv[i][0] == '\0') { @@ -65,7 +87,8 @@ void Runtime::ReadArgs(int argc, const char *const *argv) { cerr << "missing argument to -s" << endl; error = true; } else { - seed = strtoul(argv[i], nullptr, 10); + config.world.gen.solid_seed = strtoul(argv[i], nullptr, 10); + config.world.gen.type_seed = config.world.gen.solid_seed; } break; case 't': @@ -121,7 +144,7 @@ int Runtime::Execute() { return 1; } - Application app(seed); + Application app(config); switch (mode) { default: case NORMAL: diff --git a/src/runtime.hpp b/src/runtime.hpp index 01f6cdd..1fbc4db 100644 --- a/src/runtime.hpp +++ b/src/runtime.hpp @@ -1,6 +1,8 @@ #ifndef BLANK_RUNTIME_HPP_ #define BLANK_RUNTIME_HPP_ +#include "app.hpp" + #include @@ -28,7 +30,7 @@ private: Mode mode; std::size_t n; std::size_t t; - unsigned int seed; + Application::Config config; }; diff --git a/src/world.cpp b/src/world.cpp index 30e9229..756c66f 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -6,14 +6,17 @@ namespace blank { -World::World(unsigned int seed) +World::World(const Config &config) : blockType() , blockShape({{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }}) , stairShape({{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }}, { 0.0f, 0.0f }) , slabShape({{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.0f, 0.5f }}) -, generate(seed) -, chunks(blockType, generate) -, player() { +, generate(config.gen) +, chunks(config.load, blockType, generate) +, player() +, entities() +, light_direction(config.light_direction) +, fog_density(config.fog_density) { BlockType::Faces block_fill = { true, true, true, true, true, true }; BlockType::Faces slab_fill = { false, true, false, false, false, false }; BlockType::Faces stair_fill = { false, true, false, false, false, true }; @@ -107,7 +110,7 @@ World::World(unsigned int seed) generate.Solids({ 1, 4, 7, 10 }); player = &AddEntity(); - player->Position({ 4.0f, 4.0f, 4.0f }); + player->Position(config.spawn); chunks.GenerateSurrounding(player->ChunkCoords()); } @@ -198,12 +201,8 @@ void World::Update(int dt) { void World::Render(DirectionalLighting &program) { - program.SetLightDirection({ -1.0f, -3.0f, -2.0f }); - // fade out reaches 1/e (0.3679) at 1/fog_density, - // gets less than 0.01 at e/(2 * fog_density) - // I chose 0.011 because it yields 91 and 124 for those, so - // slightly less than 6 and 8 chunks - program.SetFogDensity(0.011f); + program.SetLightDirection(light_direction); + program.SetFogDensity(fog_density); program.SetView(glm::inverse(player->Transform(player->ChunkCoords()))); for (Chunk &chunk : chunks.Loaded()) { diff --git a/src/world.hpp b/src/world.hpp index bca1e0c..3dd04fb 100644 --- a/src/world.hpp +++ b/src/world.hpp @@ -17,7 +17,22 @@ namespace blank { class World { public: - explicit World(unsigned int seed); + struct Config { + // initial player position + glm::vec3 spawn = { 4.0f, 4.0f, 4.0f }; + // direction facing towards(!) the light + glm::vec3 light_direction = { -1.0f, -3.0f, -2.0f }; + // fade out reaches 1/e (0.3679) at 1/fog_density, + // gets less than 0.01 at e/(2 * fog_density) + // I chose 0.011 because it yields 91 and 124 for those, so + // slightly less than 6 and 8 chunks + float fog_density = 0.011f; + + Generator::Config gen = Generator::Config(); + ChunkLoader::Config load = ChunkLoader::Config(); + }; + + explicit World(const Config &); bool Intersection( const Ray &, @@ -51,6 +66,9 @@ private: Entity *player; std::list entities; + glm::vec3 light_direction; + float fog_density; + }; } -- 2.39.2