diff --git a/src/application.cpp b/src/application.cpp index 7f5736f..c60f890 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -31,12 +31,13 @@ #include "input/mouse.hpp" #include "input/game-controller.hpp" #include "rasterizer/rasterizer.hpp" +#include "resources/image.hpp" #include #include #include +#include +#include #include -//#include "utility/timestamp.hpp" -//#include application::application(): closed(false), @@ -299,6 +300,41 @@ void application::change_state(const state_type& next_state) } } +std::shared_ptr application::capture_frame() const +{ + int w = viewport_dimensions[0]; + int h = viewport_dimensions[1]; + + std::shared_ptr frame = std::make_shared(); + frame->format(3, false); + frame->resize(w, h); + + // Read pixel data from framebuffer into image + unsigned char* pixels = new unsigned char[w * h * 3]; + glReadBuffer(GL_BACK); + glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, frame->get_pixels()); + + return std::move(frame); +} + +void application::save_frame(const std::string& path) const +{ + logger->push_task("Saving screenshot to \"" + path + "\""); + + auto frame = capture_frame(); + + std::thread + ( + [frame, path] + { + stbi_flip_vertically_on_write(1); + stbi_write_png(path.c_str(), frame->get_width(), frame->get_height(), frame->get_channels(), frame->get_pixels(), frame->get_width() * frame->get_channels()); + } + ).detach(); + + logger->pop_task(EXIT_SUCCESS); +} + void application::set_update_callback(const update_callback_type& callback) { update_callback = callback; @@ -598,34 +634,3 @@ void application::window_resized() ui_system->set_viewport(viewport); */ } - -/* -void application::take_screenshot() -{ - std::string filename = screenshots_path + "antkeeper-" + timestamp() + ".png"; - - logger->push_task("Saving screenshot to \"" + filename + "\""); - - int x = viewport[0]; - int y = viewport[1]; - int w = viewport[2]; - int h = viewport[3]; - - // Read pixel data from framebuffer - unsigned char* pixels = new unsigned char[w * h * 3]; - glReadBuffer(GL_BACK); - glReadPixels(x, y, w, h, GL_RGB, GL_UNSIGNED_BYTE, pixels); - - std::thread screenshot_thread(application::save_image, filename, w, h, pixels); - screenshot_thread.detach(); - - logger->pop_task(EXIT_SUCCESS); -} -*/ - -void application::save_image(const std::string& filename, int w, int h, const unsigned char* pixels) -{ - stbi_flip_vertically_on_write(1); - stbi_write_png(filename.c_str(), w, h, 3, pixels, w * 3); - delete[] pixels; -} diff --git a/src/application.hpp b/src/application.hpp index 592174b..5cfbd4e 100644 --- a/src/application.hpp +++ b/src/application.hpp @@ -23,6 +23,7 @@ #include #include #include +#include #include // Forward declarations @@ -36,6 +37,7 @@ class logger; class mouse; class performance_sampler; class rasterizer; +class image; /** * @@ -81,6 +83,20 @@ public: */ void change_state(const state_type& state); + /** + * Captures a screenshot of last rendered frame. + * + * @return Image containing the captured frame. + */ + std::shared_ptr capture_frame() const; + + /** + * Captures a screenshot of last rendered frame. + * + * @return Image containing the captured frame. + */ + void save_frame(const std::string& path) const; + /** * Sets the update callback, which is executed at regular intervals until the application is closed. The update callback expects two parameters, the first being the total time in seconds since the application was executed (t), and the second being the time in seconds since the last update (dt). dt will always be a fixed value, and is determined by the user-specified update rate. * @@ -143,8 +159,6 @@ public: */ void set_vsync(bool vsync); - void take_screenshot(); - /// Returns the dimensions of the current display. const std::array& get_display_dimensions() const; @@ -181,7 +195,6 @@ private: void translate_sdl_events(); void window_resized(); - static void save_image(const std::string& filename, int w, int h, const unsigned char* pixels); bool closed; int exit_status; diff --git a/src/game/bootloader.cpp b/src/game/bootloader.cpp index f2aec2e..8e4daf5 100644 --- a/src/game/bootloader.cpp +++ b/src/game/bootloader.cpp @@ -92,6 +92,7 @@ #include #include #include +#include "utility/timestamp.hpp" static void parse_options(game_context* ctx, int argc, char** argv); static void setup_resources(game_context* ctx); @@ -361,6 +362,15 @@ void load_strings(game_context* ctx) build_string_table_map(&ctx->string_table_map, *ctx->string_table); ctx->language_code = ctx->config->get("language"); + ctx->language_index = -1; + for (int i = 2; i < (*ctx->string_table)[0].size(); ++i) + { + if ((*ctx->string_table)[0][i] == ctx->language_code) + ctx->language_index = i; + } + + logger->log("lang index: " + std::to_string(ctx->language_index)); + ctx->strings = &ctx->string_table_map[ctx->language_code]; logger->pop_task(EXIT_SUCCESS); @@ -864,17 +874,18 @@ void setup_controls(game_context* ctx) } ); - + // Create screenshot control ctx->screenshot_control = new control(); - /*ctx->screenshot_control.set_activated_callback([this]() - { + ctx->screenshot_control->set_activated_callback + ( [ctx]() { - ctx->app->take_screenshot(); + std::string path = ctx->screenshots_path + "antkeeper-" + timestamp() + ".png"; + ctx->app->save_frame(path); } - });*/ + ); // Create menu back control ctx->menu_back_control = new control();