Browse Source

Add support for adaptive v-sync. Add support for changing the render resolution. Move framebuffer creation, destruction, and resizing into dedicated functions

master
C. J. Howard 1 year ago
parent
commit
3c26a6fe64
20 changed files with 338 additions and 196 deletions
  1. +1
    -0
      CMakeLists.txt
  2. +39
    -13
      src/application.cpp
  3. +11
    -10
      src/application.hpp
  4. +12
    -10
      src/game/context.hpp
  5. +145
    -0
      src/game/graphics.cpp
  6. +35
    -0
      src/game/graphics.hpp
  7. +2
    -2
      src/game/menu.hpp
  8. +21
    -65
      src/game/states/boot.cpp
  9. +2
    -5
      src/game/states/controls-menu.cpp
  10. +2
    -2
      src/game/states/credits.cpp
  11. +2
    -5
      src/game/states/extras-menu.cpp
  12. +4
    -9
      src/game/states/gamepad-config-menu.cpp
  13. +36
    -27
      src/game/states/graphics-menu.cpp
  14. +4
    -9
      src/game/states/keyboard-config-menu.cpp
  15. +2
    -5
      src/game/states/language-menu.cpp
  16. +4
    -6
      src/game/states/main-menu.cpp
  17. +8
    -12
      src/game/states/nuptial-flight.cpp
  18. +2
    -5
      src/game/states/options-menu.cpp
  19. +5
    -9
      src/game/states/pause-menu.cpp
  20. +1
    -2
      src/game/states/splash.cpp

+ 1
- 0
CMakeLists.txt View File

@ -1,5 +1,6 @@
cmake_minimum_required(VERSION 3.7)
option(VERSION_STRING "Project version string" "0.0.0")
project(antkeeper VERSION ${VERSION_STRING} LANGUAGES CXX)

+ 39
- 13
src/application.cpp View File

@ -44,7 +44,7 @@ application::application():
update_callback(nullptr),
render_callback(nullptr),
fullscreen(true),
v_sync(true),
v_sync(false),
cursor_visible(true),
display_dimensions({0, 0}),
display_dpi(0.0f),
@ -187,16 +187,7 @@ application::application():
SDL_GL_GetDrawableSize(sdl_window, &viewport_dimensions[0], &viewport_dimensions[1]);
// Set v-sync mode
int swap_interval = (v_sync) ? 1 : 0;
logger->push_task((swap_interval) ? "Enabling v-sync" : "Disabling v-sync");
if (SDL_GL_SetSwapInterval(swap_interval) != 0)
{
logger->pop_task(EXIT_FAILURE);
}
else
{
logger->pop_task(EXIT_SUCCESS);
}
set_v_sync(true);
// Init SDL joystick and gamepad subsystems
logger->push_task("Initializing SDL Joystick and Game Controller subsystems");
@ -496,8 +487,43 @@ void application::set_v_sync(bool v_sync)
{
if (this->v_sync != v_sync)
{
this->v_sync = v_sync;
SDL_GL_SetSwapInterval((v_sync) ? 1 : 0);
if (v_sync)
{
logger->push_task("Enabling adaptive v-sync");
if (SDL_GL_SetSwapInterval(-1) != 0)
{
logger->pop_task(EXIT_FAILURE);
logger->push_task("Enabling synchronized v-sync");
if (SDL_GL_SetSwapInterval(-1) != 0)
{
logger->pop_task(EXIT_FAILURE);
}
else
{
this->v_sync = v_sync;
logger->pop_task(EXIT_SUCCESS);
}
}
else
{
this->v_sync = v_sync;
logger->pop_task(EXIT_SUCCESS);
}
}
else
{
logger->push_task("Disabling v-sync");
if (SDL_GL_SetSwapInterval(0) != 0)
{
logger->pop_task(EXIT_FAILURE);
}
else
{
this->v_sync = v_sync;
logger->pop_task(EXIT_SUCCESS);
}
}
}
}

+ 11
- 10
src/application.hpp View File

@ -29,6 +29,7 @@
#include "input/keyboard.hpp"
#include "input/mouse.hpp"
#include "input/gamepad.hpp"
#include "utility/fundamental-types.hpp"
// Forward declarations
typedef struct SDL_Window SDL_Window;
@ -192,16 +193,16 @@ public:
void add_game_controller_mappings(const void* mappings, std::size_t size);
/// Returns the dimensions of the current display.
const std::array<int, 2>& get_display_dimensions() const;
const int2& get_display_dimensions() const;
/// Returns the DPI of the display.
float get_display_dpi() const;
/// Returns the dimensions of the window.
const std::array<int, 2>& get_window_dimensions() const;
const int2& get_window_dimensions() const;
/// Returns the dimensions of the window's drawable viewport.
const std::array<int, 2>& get_viewport_dimensions() const;
const int2& get_viewport_dimensions() const;
/// Returns `true` if the window is in fullscreen mode, `false` otherwise.
bool is_fullscreen() const;
@ -243,11 +244,11 @@ private:
bool fullscreen;
bool v_sync;
bool cursor_visible;
std::array<int, 2> display_dimensions;
int2 display_dimensions;
float display_dpi;
std::array<int, 2> window_dimensions;
std::array<int, 2> viewport_dimensions;
std::array<int, 2> mouse_position;
int2 window_dimensions;
int2 viewport_dimensions;
int2 mouse_position;
double update_rate;
debug::logger* logger;
@ -275,7 +276,7 @@ inline debug::logger* application::get_logger()
return logger;
}
inline const std::array<int, 2>& application::get_display_dimensions() const
inline const int2& application::get_display_dimensions() const
{
return display_dimensions;
}
@ -285,12 +286,12 @@ inline float application::get_display_dpi() const
return display_dpi;
}
inline const std::array<int, 2>& application::get_window_dimensions() const
inline const int2& application::get_window_dimensions() const
{
return window_dimensions;
}
inline const std::array<int, 2>& application::get_viewport_dimensions() const
inline const int2& application::get_viewport_dimensions() const
{
return viewport_dimensions;
}

+ 12
- 10
src/game/context.hpp View File

@ -44,6 +44,7 @@
#include <string>
#include <unordered_map>
#include <vector>
#include <queue>
#include "resources/json.hpp"
#include "type/typeface.hpp"
#include "type/bitmap-font.hpp"
@ -110,7 +111,7 @@ namespace render
namespace game {
/// Structure containing the state of a game.
/// Container for data that is shared between game states.
struct context
{
application* app;
@ -158,17 +159,18 @@ struct context
render::material title_font_material;
// Framebuffers
gl::framebuffer* shadow_map_framebuffer;
gl::texture_2d* hdr_color_texture;
gl::texture_2d* hdr_depth_texture;
gl::framebuffer* hdr_framebuffer;
gl::texture_2d* bloom_color_texture;
gl::framebuffer* bloom_framebuffer;
gl::texture_2d* shadow_map_depth_texture;
gl::framebuffer* framebuffer_hdr;
gl::texture_2d* framebuffer_hdr_color;
gl::texture_2d* framebuffer_hdr_depth;
gl::framebuffer* framebuffer_bloom; // General purpose framebuffer A
gl::texture_2d* bloom_texture;
gl::framebuffer* shadow_map_framebuffer;
// Rendering
gl::rasterizer* rasterizer;
render::renderer* renderer;
int2 render_resolution;
float render_resolution_scale;
gl::vertex_buffer* billboard_vbo;
gl::vertex_array* billboard_vao;
@ -179,14 +181,11 @@ struct context
render::clear_pass* ui_clear_pass;
render::material_pass* ui_material_pass;
render::compositor* ui_compositor;
render::bloom_pass* common_bloom_pass;
render::final_pass* common_final_pass;
render::clear_pass* underground_clear_pass;
render::material_pass* underground_material_pass;
render::compositor* underground_compositor;
render::clear_pass* surface_shadow_map_clear_pass;
render::shadow_map_pass* surface_shadow_map_pass;
render::clear_pass* surface_clear_pass;
@ -300,6 +299,9 @@ struct context
// State management
std::optional<application::state> paused_state;
// Misc
std::queue<std::function<void()>> function_queue;
// Debug
debug::cli* cli;
};

+ 145
- 0
src/game/graphics.cpp View File

@ -0,0 +1,145 @@
/*
* Copyright (C) 2021 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#include "game/graphics.hpp"
#include "gl/framebuffer.hpp"
#include "gl/texture-2d.hpp"
#include "gl/texture-wrapping.hpp"
#include "gl/texture-filter.hpp"
#include "debug/logger.hpp"
namespace game {
namespace graphics {
static void resize_framebuffer_attachment(gl::texture_2d& texture, const int2& resolution);
void create_framebuffers(game::context& ctx)
{
ctx.logger->push_task("Creating framebuffers");
// Load render resolution scale from config
ctx.render_resolution_scale = 1.0f;
if (ctx.config->contains("render_resolution"))
ctx.render_resolution_scale = (*ctx.config)["render_resolution"].get<float>();
// Calculate render resolution
const int2& viewport_dimensions = ctx.app->get_viewport_dimensions();
ctx.render_resolution = {static_cast<int>(viewport_dimensions.x * ctx.render_resolution_scale + 0.5f), static_cast<int>(viewport_dimensions.y * ctx.render_resolution_scale + 0.5f)};
// Create HDR framebuffer (32F color, 32F depth)
ctx.hdr_color_texture = new gl::texture_2d(ctx.render_resolution.x, ctx.render_resolution.y, gl::pixel_type::float_32, gl::pixel_format::rgb);
ctx.hdr_color_texture->set_wrapping(gl::texture_wrapping::extend, gl::texture_wrapping::extend);
ctx.hdr_color_texture->set_filters(gl::texture_min_filter::linear, gl::texture_mag_filter::linear);
ctx.hdr_color_texture->set_max_anisotropy(0.0f);
ctx.hdr_depth_texture = new gl::texture_2d(ctx.render_resolution.x, ctx.render_resolution.y, gl::pixel_type::float_32, gl::pixel_format::ds);
ctx.hdr_depth_texture->set_wrapping(gl::texture_wrapping::extend, gl::texture_wrapping::extend);
ctx.hdr_depth_texture->set_filters(gl::texture_min_filter::linear, gl::texture_mag_filter::linear);
ctx.hdr_depth_texture->set_max_anisotropy(0.0f);
ctx.hdr_framebuffer = new gl::framebuffer(ctx.render_resolution.x, ctx.render_resolution.y);
ctx.hdr_framebuffer->attach(gl::framebuffer_attachment_type::color, ctx.hdr_color_texture);
ctx.hdr_framebuffer->attach(gl::framebuffer_attachment_type::depth, ctx.hdr_depth_texture);
ctx.hdr_framebuffer->attach(gl::framebuffer_attachment_type::stencil, ctx.hdr_depth_texture);
// Calculate bloom resolution
int2 bloom_resolution = ctx.render_resolution / 2;
// Create bloom framebuffer (16F color, no depth)
ctx.bloom_color_texture = new gl::texture_2d(bloom_resolution.x, bloom_resolution.y, gl::pixel_type::float_16, gl::pixel_format::rgb);
ctx.bloom_color_texture->set_wrapping(gl::texture_wrapping::extend, gl::texture_wrapping::extend);
ctx.bloom_color_texture->set_filters(gl::texture_min_filter::linear, gl::texture_mag_filter::linear);
ctx.bloom_color_texture->set_max_anisotropy(0.0f);
ctx.bloom_framebuffer = new gl::framebuffer(bloom_resolution.x, bloom_resolution.y);
ctx.bloom_framebuffer->attach(gl::framebuffer_attachment_type::color, ctx.bloom_color_texture);
// Load shadow map resolution from config
int shadow_map_resolution = 4096;
if (ctx.config->contains("shadow_map_resolution"))
shadow_map_resolution = (*ctx.config)["shadow_map_resolution"].get<int>();
// Create shadow map framebuffer
ctx.shadow_map_depth_texture = new gl::texture_2d(shadow_map_resolution, shadow_map_resolution, gl::pixel_type::float_32, gl::pixel_format::d);
ctx.shadow_map_depth_texture->set_wrapping(gl::texture_wrapping::extend, gl::texture_wrapping::extend);
ctx.shadow_map_depth_texture->set_filters(gl::texture_min_filter::linear, gl::texture_mag_filter::linear);
ctx.shadow_map_depth_texture->set_max_anisotropy(0.0f);
ctx.shadow_map_framebuffer = new gl::framebuffer(shadow_map_resolution, shadow_map_resolution);
ctx.shadow_map_framebuffer->attach(gl::framebuffer_attachment_type::depth, ctx.shadow_map_depth_texture);
ctx.logger->pop_task(EXIT_SUCCESS);
}
void destroy_framebuffers(game::context& ctx)
{
ctx.logger->push_task("Destroying framebuffers");
// Delete HDR framebuffer and its attachments
delete ctx.hdr_framebuffer;
ctx.hdr_framebuffer = nullptr;
delete ctx.hdr_color_texture;
ctx.hdr_color_texture = nullptr;
delete ctx.hdr_depth_texture;
ctx.hdr_depth_texture = nullptr;
// Delete bloom framebuffer and its attachments
delete ctx.bloom_framebuffer;
ctx.bloom_framebuffer = nullptr;
delete ctx.bloom_color_texture;
ctx.bloom_color_texture = nullptr;
// Delete shadow map framebuffer and its attachments
delete ctx.shadow_map_framebuffer;
ctx.shadow_map_framebuffer = nullptr;
delete ctx.shadow_map_depth_texture;
ctx.shadow_map_depth_texture = nullptr;
ctx.logger->pop_task(EXIT_SUCCESS);
}
void change_render_resolution(game::context& ctx, float scale)
{
ctx.logger->push_task("Changing render resolution");
// Update render resolution scale
ctx.render_resolution_scale = scale;
// Recalculate render resolution
const int2& viewport_dimensions = ctx.app->get_viewport_dimensions();
ctx.render_resolution = {static_cast<int>(viewport_dimensions.x * ctx.render_resolution_scale + 0.5f), static_cast<int>(viewport_dimensions.y * ctx.render_resolution_scale + 0.5f)};
// Resize HDR framebuffer and attachments
ctx.hdr_framebuffer->resize({ctx.render_resolution.x, ctx.render_resolution.y});
resize_framebuffer_attachment(*ctx.hdr_color_texture, ctx.render_resolution);
resize_framebuffer_attachment(*ctx.hdr_depth_texture, ctx.render_resolution);
// Recalculate bloom resolution
int2 bloom_resolution = ctx.render_resolution / 2;
// Resize bloom framebuffer and attachments
ctx.bloom_framebuffer->resize({bloom_resolution.x, bloom_resolution.y});
resize_framebuffer_attachment(*ctx.bloom_color_texture, bloom_resolution);
ctx.logger->pop_task(EXIT_SUCCESS);
}
void resize_framebuffer_attachment(gl::texture_2d& texture, const int2& resolution)
{
texture.resize(resolution.x, resolution.y, texture.get_pixel_type(), texture.get_pixel_format(), texture.get_color_space(), nullptr);
}
} // namespace graphics
} // namespace game

+ 35
- 0
src/game/graphics.hpp View File

@ -0,0 +1,35 @@
/*
* Copyright (C) 2021 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ANTKEEPER_GAME_GRAPHICS_HPP
#define ANTKEEPER_GAME_GRAPHICS_HPP
#include "game/context.hpp"
namespace game {
namespace graphics {
void create_framebuffers(game::context& ctx);
void destroy_framebuffers(game::context& ctx);
void change_render_resolution(game::context& ctx, float scale);
} // namespace graphics
} // namespace game
#endif // ANTKEEPER_GAME_GRAPHICS_HPP

+ 2
- 2
src/game/menu.hpp View File

@ -26,7 +26,7 @@ namespace game {
namespace menu {
/// Delay, in seconds, to when menu input should be activated.
static constexpr float input_delay = 0.01f;
static constexpr float input_delay = 0.025f;
/// RGBA color of active menu items.
static constexpr float4 active_color{1.0f, 1.0f, 1.0f, 1.0f};
@ -35,7 +35,7 @@ static constexpr float4 active_color{1.0f, 1.0f, 1.0f, 1.0f};
static constexpr float4 inactive_color{1.0f, 1.0f, 1.0f, 0.5f};
/// Opacity of the menu background.
static constexpr float bg_opacity = 0.75f;
static constexpr float bg_opacity = 2.0f / 3.0f;
/// Padding of the mouseover bounds, as a percentage of the font size.
static constexpr float mouseover_padding = 0.1f;

+ 21
- 65
src/game/states/boot.cpp View File

@ -88,6 +88,7 @@
#include "game/controls.hpp"
#include "game/save.hpp"
#include "game/menu.hpp"
#include "game/graphics.hpp"
#include "utility/timestamp.hpp"
#include <cxxopts.hpp>
#include <dirent.h>
@ -472,51 +473,8 @@ void setup_rendering(game::context* ctx)
// Get rasterizer from application
ctx->rasterizer = ctx->app->get_rasterizer();
// Load render resolution
ctx->render_resolution_scale = 1.0f;
if (ctx->config->contains("render_resolution"))
ctx->render_resolution_scale = (*ctx->config)["render_resolution"].get<float>();
// Get default framebuffer
const gl::framebuffer& default_framebuffer = ctx->rasterizer->get_default_framebuffer();
const auto& viewport_dimensions = default_framebuffer.get_dimensions();
// Create HDR framebuffer (32F color, 32F depth)
ctx->framebuffer_hdr_color = new gl::texture_2d(viewport_dimensions[0], viewport_dimensions[1], gl::pixel_type::float_32, gl::pixel_format::rgb);
ctx->framebuffer_hdr_color->set_wrapping(gl::texture_wrapping::extend, gl::texture_wrapping::extend);
ctx->framebuffer_hdr_color->set_filters(gl::texture_min_filter::linear, gl::texture_mag_filter::linear);
ctx->framebuffer_hdr_color->set_max_anisotropy(0.0f);
ctx->framebuffer_hdr_depth = new gl::texture_2d(viewport_dimensions[0], viewport_dimensions[1], gl::pixel_type::float_32, gl::pixel_format::ds);
ctx->framebuffer_hdr_depth->set_wrapping(gl::texture_wrapping::extend, gl::texture_wrapping::extend);
ctx->framebuffer_hdr_depth->set_filters(gl::texture_min_filter::linear, gl::texture_mag_filter::linear);
ctx->framebuffer_hdr_depth->set_max_anisotropy(0.0f);
ctx->framebuffer_hdr = new gl::framebuffer(viewport_dimensions[0], viewport_dimensions[1]);
ctx->framebuffer_hdr->attach(gl::framebuffer_attachment_type::color, ctx->framebuffer_hdr_color);
ctx->framebuffer_hdr->attach(gl::framebuffer_attachment_type::depth, ctx->framebuffer_hdr_depth);
ctx->framebuffer_hdr->attach(gl::framebuffer_attachment_type::stencil, ctx->framebuffer_hdr_depth);
// Create shadow map framebuffer
int shadow_map_resolution = 4096;
if (ctx->config->contains("shadow_map_resolution"))
{
shadow_map_resolution = (*ctx->config)["shadow_map_resolution"].get<int>();
}
ctx->shadow_map_depth_texture = new gl::texture_2d(shadow_map_resolution, shadow_map_resolution, gl::pixel_type::float_32, gl::pixel_format::d);
ctx->shadow_map_depth_texture->set_wrapping(gl::texture_wrapping::extend, gl::texture_wrapping::extend);
ctx->shadow_map_depth_texture->set_filters(gl::texture_min_filter::linear, gl::texture_mag_filter::linear);
ctx->shadow_map_depth_texture->set_max_anisotropy(0.0f);
ctx->shadow_map_framebuffer = new gl::framebuffer(shadow_map_resolution, shadow_map_resolution);
ctx->shadow_map_framebuffer->attach(gl::framebuffer_attachment_type::depth, ctx->shadow_map_depth_texture);
// Create bloom pingpong framebuffers (16F color, no depth)
int bloom_width = viewport_dimensions[0] >> 1;
int bloom_height = viewport_dimensions[1] >> 1;
ctx->bloom_texture = new gl::texture_2d(bloom_width, bloom_height, gl::pixel_type::float_16, gl::pixel_format::rgb);
ctx->bloom_texture->set_wrapping(gl::texture_wrapping::extend, gl::texture_wrapping::extend);
ctx->bloom_texture->set_filters(gl::texture_min_filter::linear, gl::texture_mag_filter::linear);
ctx->bloom_texture->set_max_anisotropy(0.0f);
ctx->framebuffer_bloom = new gl::framebuffer(bloom_width, bloom_height);
ctx->framebuffer_bloom->attach(gl::framebuffer_attachment_type::color, ctx->bloom_texture);
// Create framebuffers
game::graphics::create_framebuffers(*ctx);
// Load blue noise texture
gl::texture_2d* blue_noise_map = ctx->resource_manager->load<gl::texture_2d>("blue-noise.tex");
@ -526,14 +484,14 @@ void setup_rendering(game::context* ctx)
// Setup common render passes
{
ctx->common_bloom_pass = new render::bloom_pass(ctx->rasterizer, ctx->framebuffer_bloom, ctx->resource_manager);
ctx->common_bloom_pass->set_source_texture(ctx->framebuffer_hdr_color);
ctx->common_bloom_pass = new render::bloom_pass(ctx->rasterizer, ctx->bloom_framebuffer, ctx->resource_manager);
ctx->common_bloom_pass->set_source_texture(ctx->hdr_color_texture);
ctx->common_bloom_pass->set_brightness_threshold(1.0f);
ctx->common_bloom_pass->set_blur_iterations(5);
ctx->common_final_pass = new render::final_pass(ctx->rasterizer, &ctx->rasterizer->get_default_framebuffer(), ctx->resource_manager);
ctx->common_final_pass->set_color_texture(ctx->framebuffer_hdr_color);
ctx->common_final_pass->set_bloom_texture(ctx->bloom_texture);
ctx->common_final_pass->set_color_texture(ctx->hdr_color_texture);
ctx->common_final_pass->set_bloom_texture(ctx->bloom_color_texture);
ctx->common_final_pass->set_blue_noise_texture(blue_noise_map);
}
@ -553,12 +511,12 @@ void setup_rendering(game::context* ctx)
// Setup underground compositor
{
ctx->underground_clear_pass = new render::clear_pass(ctx->rasterizer, ctx->framebuffer_hdr);
ctx->underground_clear_pass = new render::clear_pass(ctx->rasterizer, ctx->hdr_framebuffer);
ctx->underground_clear_pass->set_cleared_buffers(true, true, false);
ctx->underground_clear_pass->set_clear_color({1, 0, 1, 0});
ctx->underground_clear_pass->set_clear_depth(0.0f);
ctx->underground_material_pass = new render::material_pass(ctx->rasterizer, ctx->framebuffer_hdr, ctx->resource_manager);
ctx->underground_material_pass = new render::material_pass(ctx->rasterizer, ctx->hdr_framebuffer, ctx->resource_manager);
ctx->underground_material_pass->set_fallback_material(ctx->fallback_material);
ctx->app->get_event_dispatcher()->subscribe<mouse_moved_event>(ctx->underground_material_pass);
@ -578,20 +536,20 @@ void setup_rendering(game::context* ctx)
ctx->surface_shadow_map_pass = new render::shadow_map_pass(ctx->rasterizer, ctx->shadow_map_framebuffer, ctx->resource_manager);
ctx->surface_shadow_map_pass->set_split_scheme_weight(0.75f);
ctx->surface_clear_pass = new render::clear_pass(ctx->rasterizer, ctx->framebuffer_hdr);
ctx->surface_clear_pass = new render::clear_pass(ctx->rasterizer, ctx->hdr_framebuffer);
ctx->surface_clear_pass->set_cleared_buffers(true, true, true);
ctx->surface_clear_pass->set_clear_depth(0.0f);
ctx->surface_sky_pass = new render::sky_pass(ctx->rasterizer, ctx->framebuffer_hdr, ctx->resource_manager);
ctx->surface_sky_pass = new render::sky_pass(ctx->rasterizer, ctx->hdr_framebuffer, ctx->resource_manager);
ctx->app->get_event_dispatcher()->subscribe<mouse_moved_event>(ctx->surface_sky_pass);
ctx->surface_material_pass = new render::material_pass(ctx->rasterizer, ctx->framebuffer_hdr, ctx->resource_manager);
ctx->surface_material_pass = new render::material_pass(ctx->rasterizer, ctx->hdr_framebuffer, ctx->resource_manager);
ctx->surface_material_pass->set_fallback_material(ctx->fallback_material);
ctx->surface_material_pass->shadow_map_pass = ctx->surface_shadow_map_pass;
ctx->surface_material_pass->shadow_map = ctx->shadow_map_depth_texture;
ctx->app->get_event_dispatcher()->subscribe<mouse_moved_event>(ctx->surface_material_pass);
ctx->surface_outline_pass = new render::outline_pass(ctx->rasterizer, ctx->framebuffer_hdr, ctx->resource_manager);
ctx->surface_outline_pass = new render::outline_pass(ctx->rasterizer, ctx->hdr_framebuffer, ctx->resource_manager);
ctx->surface_outline_pass->set_outline_width(0.25f);
ctx->surface_outline_pass->set_outline_color(float4{1.0f, 1.0f, 1.0f, 1.0f});
@ -1209,6 +1167,14 @@ void setup_callbacks(game::context* ctx)
ctx->underground_scene->update_tweens();
ctx->ui_scene->update_tweens();
// Process function queue
while (!ctx->function_queue.empty())
{
ctx->function_queue.front()();
ctx->function_queue.pop();
}
// Advance timeline
ctx->timeline->advance(dt);
// Update controls
@ -1227,14 +1193,6 @@ void setup_callbacks(game::context* ctx)
}
);
ctx->terrain_system->update(t, dt);
//ctx->vegetation_system->update(t, dt);
ctx->snapping_system->update(t, dt);
@ -1244,7 +1202,6 @@ void setup_callbacks(game::context* ctx)
ctx->behavior_system->update(t, dt);
ctx->locomotion_system->update(t, dt);
ctx->camera_system->update(t, dt);
ctx->orbit_system->update(t, dt);
ctx->blackbody_system->update(t, dt);
ctx->atmosphere_system->update(t, dt);
@ -1254,7 +1211,6 @@ void setup_callbacks(game::context* ctx)
ctx->painting_system->update(t, dt);
ctx->proteome_system->update(t, dt);
ctx->animator->animate(dt);
ctx->render_system->update(t, dt);
}
);

+ 2
- 5
src/game/states/controls-menu.cpp View File

@ -25,7 +25,6 @@
#include "scene/text.hpp"
#include "debug/logger.hpp"
#include "game/menu.hpp"
#include "animation/timeline.hpp"
namespace game {
namespace state {
@ -132,10 +131,8 @@ void enter(game::context* ctx)
// Set menu back callback
ctx->menu_back_callback = select_back_callback;
// Schedule menu control setup
timeline* timeline = ctx->timeline;
float t = timeline->get_position();
timeline->add_sequence({{t + game::menu::input_delay, std::bind(game::menu::setup_controls, ctx)}});
// Queue menu control setup
ctx->function_queue.push(std::bind(game::menu::setup_controls, ctx));
// Fade in menu
game::menu::fade_in(ctx, nullptr);

+ 2
- 2
src/game/states/credits.cpp View File

@ -91,7 +91,7 @@ void enter(game::context* ctx)
{
auto id = event.get_event_type_id();
if (id != mouse_moved_event::event_type_id && id != mouse_wheel_scrolled_event::event_type_id && id != gamepad_axis_moved_event::event_type_id)
{
{
if (ctx->credits_text->get_color()[3] > 0.0f)
{
ctx->input_listener->set_enabled(false);
@ -101,7 +101,7 @@ void enter(game::context* ctx)
next_state.name = "extras_menu";
next_state.enter = std::bind(game::state::extras_menu::enter, ctx);
next_state.exit = std::bind(game::state::extras_menu::exit, ctx);
ctx->app->change_state(next_state);
ctx->app->queue_state(next_state);
}
}
}

+ 2
- 5
src/game/states/extras-menu.cpp View File

@ -25,7 +25,6 @@
#include "debug/logger.hpp"
#include "game/fonts.hpp"
#include "game/menu.hpp"
#include "animation/timeline.hpp"
namespace game {
namespace state {
@ -108,10 +107,8 @@ void enter(game::context* ctx)
// Set menu back callback
ctx->menu_back_callback = select_back_callback;
// Schedule menu control setup
timeline* timeline = ctx->timeline;
float t = timeline->get_position();
timeline->add_sequence({{t + game::menu::input_delay, std::bind(game::menu::setup_controls, ctx)}});
// Queue menu control setup
ctx->function_queue.push(std::bind(game::menu::setup_controls, ctx));
// Fade in menu
game::menu::fade_in(ctx, nullptr);

+ 4
- 9
src/game/states/gamepad-config-menu.cpp View File

@ -25,7 +25,6 @@
#include "resources/resource-manager.hpp"
#include "game/menu.hpp"
#include "game/controls.hpp"
#include "animation/timeline.hpp"
namespace game {
namespace state {
@ -261,10 +260,8 @@ static void add_control_item(game::context* ctx, const std::string& control_name
ctx->input_listener->set_enabled(false);
ctx->input_listener->set_callback(nullptr);
// Schedule re-enabling of menu controls
timeline* timeline = ctx->timeline;
float t = timeline->get_position();
timeline->add_sequence({{t + game::menu::input_delay, std::bind(game::menu::setup_controls, ctx)}});
// Queue menu control setup
ctx->function_queue.push(std::bind(game::menu::setup_controls, ctx));
}
);
ctx->input_listener->set_enabled(true);
@ -341,10 +338,8 @@ void enter(game::context* ctx)
// Set menu back callback
ctx->menu_back_callback = select_back_callback;
// Schedule menu control setup
timeline* timeline = ctx->timeline;
float t = timeline->get_position();
timeline->add_sequence({{t + game::menu::input_delay, std::bind(game::menu::setup_controls, ctx)}});
// Queue menu control setup
ctx->function_queue.push(std::bind(game::menu::setup_controls, ctx));
// Fade in menu
game::menu::fade_in(ctx, nullptr);

+ 36
- 27
src/game/states/graphics-menu.cpp View File

@ -24,29 +24,14 @@
#include "debug/logger.hpp"
#include "game/fonts.hpp"
#include "game/menu.hpp"
#include "game/graphics.hpp"
#include "animation/timeline.hpp"
namespace game {
namespace state {
namespace graphics_menu {
static void update_value_text_content(game::context* ctx)
{
bool fullscreen = ctx->app->is_fullscreen();
float resolution = ctx->render_resolution_scale;
bool v_sync = ctx->app->get_v_sync();
float font_size = ctx->font_size;
bool dyslexia_font = ctx->dyslexia_font;
const std::string string_on = (*ctx->strings)["on"];
const std::string string_off = (*ctx->strings)["off"];
std::get<1>(ctx->menu_item_texts[0])->set_content((fullscreen) ? string_on : string_off);
std::get<1>(ctx->menu_item_texts[1])->set_content(std::to_string(static_cast<int>(std::round(resolution * 100.0f))) + "%");
std::get<1>(ctx->menu_item_texts[2])->set_content((v_sync) ? string_on : string_off);
std::get<1>(ctx->menu_item_texts[3])->set_content(std::to_string(static_cast<int>(std::round(font_size * 100.0f))) + "%");
std::get<1>(ctx->menu_item_texts[4])->set_content((dyslexia_font) ? string_on : string_off);
}
static void update_value_text_content(game::context* ctx);
void enter(game::context* ctx)
{
@ -118,14 +103,18 @@ void enter(game::context* ctx)
{
// Increase resolution
if (ctx->controls["menu_modifier"]->is_active())
ctx->render_resolution_scale += 0.01f;
ctx->render_resolution_scale += 0.05f;
else
ctx->render_resolution_scale += 0.1f;
ctx->render_resolution_scale += 0.25f;
// Limit resolution
if (ctx->render_resolution_scale > 2.0f)
ctx->render_resolution_scale = 2.0f;
// Resize framebuffers
game::graphics::change_render_resolution(*ctx, ctx->render_resolution_scale);
// Update text
update_value_text_content(ctx);
game::menu::align_text(ctx);
game::menu::update_text_tweens(ctx);
@ -138,14 +127,18 @@ void enter(game::context* ctx)
{
// Increase resolution
if (ctx->controls["menu_modifier"]->is_active())
ctx->render_resolution_scale -= 0.01f;
ctx->render_resolution_scale -= 0.05f;
else
ctx->render_resolution_scale -= 0.1f;
ctx->render_resolution_scale -= 0.25f;
// Limit resolution
if (ctx->render_resolution_scale < 0.1f)
ctx->render_resolution_scale = 0.1f;
if (ctx->render_resolution_scale < 0.25f)
ctx->render_resolution_scale = 0.25f;
// Resize framebuffers
game::graphics::change_render_resolution(*ctx, ctx->render_resolution_scale);
// Update text
update_value_text_content(ctx);
game::menu::align_text(ctx);
game::menu::update_text_tweens(ctx);
@ -313,10 +306,8 @@ void enter(game::context* ctx)
// Set menu back callback
ctx->menu_back_callback = select_back_callback;
// Schedule menu control setup
timeline* timeline = ctx->timeline;
float t = timeline->get_position();
timeline->add_sequence({{t + game::menu::input_delay, std::bind(game::menu::setup_controls, ctx)}});
// Queue menu control setup
ctx->function_queue.push(std::bind(game::menu::setup_controls, ctx));
// Fade in menu
game::menu::fade_in(ctx, nullptr);
@ -332,6 +323,24 @@ void exit(game::context* ctx)
game::menu::delete_text(ctx);
}
static void update_value_text_content(game::context* ctx)
{
bool fullscreen = ctx->app->is_fullscreen();
float resolution = ctx->render_resolution_scale;
bool v_sync = ctx->app->get_v_sync();
float font_size = ctx->font_size;
bool dyslexia_font = ctx->dyslexia_font;
const std::string string_on = (*ctx->strings)["on"];
const std::string string_off = (*ctx->strings)["off"];
std::get<1>(ctx->menu_item_texts[0])->set_content((fullscreen) ? string_on : string_off);
std::get<1>(ctx->menu_item_texts[1])->set_content(std::to_string(static_cast<int>(std::round(resolution * 100.0f))) + "%");
std::get<1>(ctx->menu_item_texts[2])->set_content((v_sync) ? string_on : string_off);
std::get<1>(ctx->menu_item_texts[3])->set_content(std::to_string(static_cast<int>(std::round(font_size * 100.0f))) + "%");
std::get<1>(ctx->menu_item_texts[4])->set_content((dyslexia_font) ? string_on : string_off);
}
} // namespace graphics_menu
} // namespace state
} // namespace game

+ 4
- 9
src/game/states/keyboard-config-menu.cpp View File

@ -25,7 +25,6 @@
#include "resources/resource-manager.hpp"
#include "game/menu.hpp"
#include "game/controls.hpp"
#include "animation/timeline.hpp"
namespace game {
namespace state {
@ -216,10 +215,8 @@ static void add_control_item(game::context* ctx, const std::string& control_name
ctx->input_listener->set_enabled(false);
ctx->input_listener->set_callback(nullptr);
// Schedule re-enabling of menu controls
timeline* timeline = ctx->timeline;
float t = timeline->get_position();
timeline->add_sequence({{t + game::menu::input_delay, std::bind(game::menu::setup_controls, ctx)}});
// Queue menu control setup
ctx->function_queue.push(std::bind(game::menu::setup_controls, ctx));
}
);
ctx->input_listener->set_enabled(true);
@ -296,10 +293,8 @@ void enter(game::context* ctx)
// Set menu back callback
ctx->menu_back_callback = select_back_callback;
// Schedule menu control setup
timeline* timeline = ctx->timeline;
float t = timeline->get_position();
timeline->add_sequence({{t + game::menu::input_delay, std::bind(game::menu::setup_controls, ctx)}});
// Queue menu control setup
ctx->function_queue.push(std::bind(game::menu::setup_controls, ctx));
// Fade in menu
game::menu::fade_in(ctx, nullptr);

+ 2
- 5
src/game/states/language-menu.cpp View File

@ -24,7 +24,6 @@
#include "debug/logger.hpp"
#include "game/fonts.hpp"
#include "game/menu.hpp"
#include "animation/timeline.hpp"
namespace game {
namespace state {
@ -167,10 +166,8 @@ void enter(game::context* ctx)
// Set menu back callback
ctx->menu_back_callback = select_back_callback;
// Schedule menu control setup
timeline* timeline = ctx->timeline;
float t = timeline->get_position();
timeline->add_sequence({{t + game::menu::input_delay, std::bind(game::menu::setup_controls, ctx)}});
// Queue menu control setup
ctx->function_queue.push(std::bind(game::menu::setup_controls, ctx));
// Fade in menu
game::menu::fade_in(ctx, nullptr);

+ 4
- 6
src/game/states/main-menu.cpp View File

@ -75,7 +75,7 @@ void enter(game::context* ctx, bool fade_in)
const auto& title_aabb = static_cast<const geom::aabb<float>&>(ctx->title_text->get_local_bounds());
float title_w = title_aabb.max_point.x - title_aabb.min_point.x;
float title_h = title_aabb.max_point.y - title_aabb.min_point.y;
ctx->title_text->set_translation({std::round(-title_w * 0.5f), std::round(-title_h * 0.5f + (std::get<1>(ctx->app->get_viewport_dimensions()) / 3.0f) / 2.0f), 0.0f});
ctx->title_text->set_translation({std::round(-title_w * 0.5f), std::round(-title_h * 0.5f + (ctx->app->get_viewport_dimensions().y / 3.0f) / 2.0f), 0.0f});
ctx->title_text->update_tweens();
// Add title text to UI
@ -119,7 +119,7 @@ void enter(game::context* ctx, bool fade_in)
game::menu::update_text_color(ctx);
game::menu::update_text_font(ctx);
game::menu::align_text(ctx, true, false, (-std::get<1>(ctx->app->get_viewport_dimensions()) / 3.0f) / 2.0f);
game::menu::align_text(ctx, true, false, (-ctx->app->get_viewport_dimensions().y / 3.0f) / 2.0f);
game::menu::update_text_tweens(ctx);
game::menu::add_text_to_ui(ctx);
game::menu::setup_animations(ctx);
@ -221,10 +221,8 @@ void enter(game::context* ctx, bool fade_in)
// Set menu back callback
ctx->menu_back_callback = select_quit_callback;
// Schedule menu control setup
timeline* timeline = ctx->timeline;
float t = timeline->get_position();
timeline->add_sequence({{t + game::menu::input_delay, std::bind(game::menu::setup_controls, ctx)}});
// Queue menu control setup
ctx->function_queue.push(std::bind(game::menu::setup_controls, ctx));
if (fade_in)
{

+ 8
- 12
src/game/states/nuptial-flight.cpp View File

@ -37,7 +37,9 @@
#include "game/world.hpp"
#include "application.hpp"
#include "render/passes/clear-pass.hpp"
#include "animation/timeline.hpp"
#include <memory>
#include <iostream>
#include "state-machine.hpp"
namespace game {
namespace state {
@ -113,15 +115,12 @@ void enter(game::context* ctx)
ctx->surface_scene->update_tweens();
*/
// Schedule control setup
timeline* timeline = ctx->timeline;
float t = timeline->get_position();
timeline->add_sequence({{t + 0.01f, std::bind(enable_controls, ctx)}});
// Schedule fade in
// Queue fade in
ctx->fade_transition_color->set_value({1, 1, 1});
ctx->fade_transition->transition(5.0f, true, math::lerp<float, float>);
//timeline->add_sequence({{t + 10.0f, [ctx](){ctx->fade_transition->transition(5.0f, true, math::lerp<float, float>);}}});
ctx->function_queue.push(std::bind(&screen_transition::transition, ctx->fade_transition, 5.0f, true, math::lerp<float, float>, true));
// Queue control setup
ctx->function_queue.push(std::bind(enable_controls, ctx));
}
void exit(game::context* ctx)
@ -219,9 +218,6 @@ void setup_camera(game::context* ctx)
void enable_controls(game::context* ctx)
{
/// @WARNING!!! SOMETIMES THIS CALLBACK IS SKIPPED BY THE TIMELINE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ctx->logger->log("ENABLING CONTROLS");
// Get camera entities
entity::id camera_eid = ctx->entities["surface_cam"];
entity::id target_eid = ctx->entities["surface_cam_target"];

+ 2
- 5
src/game/states/options-menu.cpp View File

@ -29,7 +29,6 @@
#include "animation/ease.hpp"
#include "animation/animation.hpp"
#include "animation/animator.hpp"
#include "animation/timeline.hpp"
#include "application.hpp"
#include "scene/text.hpp"
@ -190,10 +189,8 @@ void enter(game::context* ctx)
// Set menu back callback
ctx->menu_back_callback = select_back_callback;
// Schedule menu control setup
timeline* timeline = ctx->timeline;
float t = timeline->get_position();
timeline->add_sequence({{t + game::menu::input_delay, std::bind(game::menu::setup_controls, ctx)}});
// Queue menu control setup
ctx->function_queue.push(std::bind(game::menu::setup_controls, ctx));
// Fade in menu
game::menu::fade_in(ctx, nullptr);

+ 5
- 9
src/game/states/pause-menu.cpp View File

@ -24,7 +24,6 @@
#include "animation/ease.hpp"
#include "animation/animation.hpp"
#include "animation/animator.hpp"
#include "animation/timeline.hpp"
#include "application.hpp"
#include "scene/text.hpp"
@ -83,7 +82,7 @@ void enter(game::context* ctx)
auto select_options_callback = [ctx]()
{
// Disable unpause control
//ctx->controls["pause"]->set_activated_callback(nullptr);
ctx->controls["pause"]->set_activated_callback(nullptr);
// Disable menu controls
game::menu::clear_controls(ctx);
@ -157,12 +156,9 @@ void enter(game::context* ctx)
// Set menu back callback
ctx->menu_back_callback = select_resume_callback;
// Schedule control setup
timeline* timeline = ctx->timeline;
float t = timeline->get_position();
timeline->add_sequence
({{
t + game::menu::input_delay,
// Queue control setup
ctx->function_queue.push
(
[ctx, select_resume_callback]()
{
// Enable unpause control
@ -171,7 +167,7 @@ void enter(game::context* ctx)
// Enable menu controls
game::menu::setup_controls(ctx);
}
}});
);
// Fade in menu and menu BG
game::menu::fade_in(ctx, nullptr);

+ 1
- 2
src/game/states/splash.cpp View File

@ -23,7 +23,6 @@
#include "animation/animation.hpp"
#include "animation/animator.hpp"
#include "animation/ease.hpp"
#include "animation/timeline.hpp"
#include "application.hpp"
#include "render/passes/clear-pass.hpp"
@ -126,7 +125,7 @@ void enter(game::context* ctx)
next_state.name = "main_menu";
next_state.enter = std::bind(game::state::main_menu::enter, ctx, true);
next_state.exit = std::bind(game::state::main_menu::exit, ctx);
ctx->app->change_state(next_state);
ctx->app->queue_state(next_state);
}
}
);

Loading…
Cancel
Save