move gl attributes to right before opening gl context; file to string func
This commit is contained in:
parent
17adaed169
commit
569e203409
305
src/Game.cpp
305
src/Game.cpp
|
@ -41,8 +41,8 @@ void FramerateIndicator::refresh()
|
|||
|
||||
Game::Game()
|
||||
{
|
||||
// set the appropriate priority level for the default log category so either info level messages
|
||||
// and higher are enabled or debug level messages are enabled, depending on the global configuration
|
||||
/* Set the appropriate priority level for the default log category so either info level messages
|
||||
* and higher are enabled or debug level messages are enabled, depending on the global configuration */
|
||||
SDL_LogPriority default_log_category_priority;
|
||||
if (get_configuration()["log"]["debug-to-file"] || get_configuration()["log"]["debug-to-stdout"])
|
||||
{
|
||||
|
@ -53,44 +53,43 @@ Game::Game()
|
|||
default_log_category_priority = SDL_LOG_PRIORITY_INFO;
|
||||
}
|
||||
SDL_LogSetPriority(DEFAULT_SDL_LOG_CATEGORY, default_log_category_priority);
|
||||
// set custom log function (prints to stdout/stderr and to file if enabled)
|
||||
/* set custom log function that prints to stdout/stderr and to file if enabled */
|
||||
SDL_LogSetOutputFunction(&Game::sdl_log_override, this);
|
||||
// pretty print config to debug log
|
||||
std::stringstream config_formatted;
|
||||
config_formatted << std::setw(4) << get_configuration() << std::endl;
|
||||
SDL_LogDebug(DEFAULT_SDL_LOG_CATEGORY, "%s", config_formatted.str().c_str());
|
||||
/* pretty print config to debug log */
|
||||
std::ostringstream log_message;
|
||||
log_message << std::setw(4) << get_configuration() << std::endl;
|
||||
debug(log_message.str());
|
||||
/* tell SDL which render driver you will be requesting when calling SDL_CreateRenderer */
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, get_configuration()["display"]["render driver"].get<std::string>().c_str());
|
||||
/* initialize the buffer of frame lengths which will be used to calculate FPS */
|
||||
frame_length_history.reserve(5000);
|
||||
set_framerate(get_configuration()["display"]["framerate"]);
|
||||
delegate.subscribe(&Game::handle_quit_event, this, SDL_QUIT);
|
||||
putenv("SDL_VIDEO_X11_LEGACY_FULLSCREEN=0");
|
||||
// putenv("SDL_VIDEO_CENTERED=0");
|
||||
/* Needed for displaying fullscreen correctly on Linux (?) Also might need SDL_VIDEO_CENTERED (?) */
|
||||
std::string fullscreen_env_assigment = "SDL_VIDEO_X11_LEGACY_FULLSCREEN=0";
|
||||
putenv(const_cast<char*>(fullscreen_env_assigment.c_str()));
|
||||
/* log compiled and linked SDL versions */
|
||||
SDL_version version;
|
||||
log_message = std::ostringstream();
|
||||
SDL_VERSION(&version);
|
||||
log_message << "compiled against SDL " << static_cast<int>(version.major) << "." << static_cast<int>(version.minor) <<
|
||||
"." << static_cast<int>(version.patch) << std::endl;
|
||||
SDL_GetVersion(&version);
|
||||
SDL_Log("SDL %d.%d.%d", version.major, version.minor, version.patch);
|
||||
fprintf(stderr, "stderr test message\n");
|
||||
log_message << "linked to SDL " << static_cast<int>(version.major) << "." << static_cast<int>(version.minor) << "." <<
|
||||
static_cast<int>(version.patch);
|
||||
log(log_message.str());
|
||||
/* allows use of our own main function (?) see SDL_SetMainReady.html */
|
||||
SDL_SetMainReady();
|
||||
// SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
// SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
// SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
|
||||
// print_gl_attributes();
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
|
||||
{
|
||||
print_sdl_error("SDL could not initialize");
|
||||
flag_to_end();
|
||||
}
|
||||
// SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
// SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
// SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
|
||||
SDL_Log("GLEW %s", glewGetString(GLEW_VERSION));
|
||||
auto window_size = get_configuration()["display"]["dimensions"].get<glm::ivec2>();
|
||||
log_message = std::ostringstream();
|
||||
log_message << "GLEW " << glewGetString(GLEW_VERSION);
|
||||
log(log_message.str());
|
||||
glm::ivec2 window_size = get_configuration()["display"]["dimensions"].get<glm::ivec2>();
|
||||
/* Create a window with dimensions set in the config, centered, and flagged to be usable in OpenGL context */
|
||||
window = SDL_CreateWindow(
|
||||
get_configuration()["display"]["title"].get_ref<const std::string&>().c_str(), SDL_WINDOWPOS_CENTERED,
|
||||
SDL_WINDOWPOS_CENTERED, window_size.x, window_size.y, SDL_WINDOW_OPENGL);
|
||||
|
@ -99,6 +98,9 @@ Game::Game()
|
|||
print_sdl_error("Could not create window");
|
||||
flag_to_end();
|
||||
}
|
||||
/* Create an SDL renderer for clearing the screen to black and for logging renderer properties. Destroy renderer
|
||||
* when finished.
|
||||
*/
|
||||
if ((renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_TARGETTEXTURE | SDL_RENDERER_ACCELERATED)) == nullptr)
|
||||
{
|
||||
print_sdl_error("Could not create renderer");
|
||||
|
@ -107,8 +109,12 @@ Game::Game()
|
|||
else
|
||||
{
|
||||
int w, h;
|
||||
/* log the renderer resolution */
|
||||
SDL_GetRendererOutputSize(renderer, &w, &h);
|
||||
SDL_Log("renderer output size is (%i, %i)", w, h);
|
||||
log_message = std::ostringstream();
|
||||
log_message << "renderer output size is " << w << "x" << h;
|
||||
log(log_message.str());
|
||||
/* clear screen to black */
|
||||
SDL_SetRenderTarget(renderer, nullptr);
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||
SDL_RenderClear(renderer);
|
||||
|
@ -151,22 +157,89 @@ Game::Game()
|
|||
const int audio_device_count = SDL_GetNumAudioDevices(SDL_TRUE);
|
||||
for (int ii = 0; ii < audio_device_count; ii++)
|
||||
{
|
||||
SDL_Log("Found audio capture device %i: %s", ii,
|
||||
SDL_GetAudioDeviceName(ii, SDL_TRUE));
|
||||
SDL_Log("Found audio capture device %i: %s", ii, SDL_GetAudioDeviceName(ii, SDL_TRUE));
|
||||
}
|
||||
audio.load_sfx();
|
||||
audio.load_bgm();
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
SDL_Log("big endian");
|
||||
log("big endian");
|
||||
#else
|
||||
SDL_Log("little endian");
|
||||
log("little endian");
|
||||
#endif
|
||||
last_frame_timestamp = SDL_GetTicks();
|
||||
}
|
||||
|
||||
Game::~Game()
|
||||
void Game::load_sdl_context()
|
||||
{
|
||||
get_delegate().unsubscribe(this);
|
||||
if (glcontext != nullptr)
|
||||
{
|
||||
SDL_GL_DeleteContext(glcontext);
|
||||
glcontext = nullptr;
|
||||
}
|
||||
SDL_RendererInfo renderer_info;
|
||||
int render_driver_count = SDL_GetNumRenderDrivers();
|
||||
SDL_Log("Render drivers:");
|
||||
for (int ii = 0; ii < render_driver_count; ii++)
|
||||
{
|
||||
SDL_GetRenderDriverInfo(ii, &renderer_info);
|
||||
log_renderer_info(renderer_info);
|
||||
}
|
||||
if ((renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_TARGETTEXTURE | SDL_RENDERER_ACCELERATED)) == nullptr)
|
||||
{
|
||||
print_sdl_error("Could not create renderer");
|
||||
flag_to_end();
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_Log("Current renderer:");
|
||||
SDL_GetRendererInfo(renderer, &renderer_info);
|
||||
log_renderer_info(renderer_info);
|
||||
SDL_Log("Renderer supports the use of render targets? %d", SDL_RenderTargetSupported(renderer));
|
||||
}
|
||||
is_gl_context = false;
|
||||
log_display_mode();
|
||||
}
|
||||
|
||||
void Game::load_gl_context()
|
||||
{
|
||||
if (renderer != nullptr)
|
||||
{
|
||||
SDL_DestroyRenderer(renderer);
|
||||
renderer = nullptr;
|
||||
}
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
||||
if ((glcontext = SDL_GL_CreateContext(window)) == nullptr)
|
||||
{
|
||||
print_sdl_error("Could not get GL context");
|
||||
flag_to_end();
|
||||
}
|
||||
/* try enabling vsync */
|
||||
if (SDL_GL_SetSwapInterval(1) == 0)
|
||||
{
|
||||
log("enabled vsync");
|
||||
}
|
||||
else
|
||||
{
|
||||
log("vsync not supported");
|
||||
}
|
||||
GLenum error = glewInit();
|
||||
std::ostringstream message;
|
||||
if (error != GLEW_OK)
|
||||
{
|
||||
message << "GLEW could not initialize " << glewGetErrorString(error);
|
||||
print_error(message.str());
|
||||
}
|
||||
message << "OpenGL " << glGetString(GL_VERSION) << ", renderer " << glGetString(GL_RENDERER) << ", shading language " <<
|
||||
glGetString(GL_SHADING_LANGUAGE_VERSION);
|
||||
log(message.str());
|
||||
is_gl_context = true;
|
||||
log_display_mode();
|
||||
}
|
||||
|
||||
/* Overrides SDL's default log function to log a message to stdout/stderr and, if log is enabled in the
|
||||
|
@ -221,21 +294,6 @@ void Game::print_sdl_error(const std::string& message)
|
|||
sfw::print_sdl_error(message);
|
||||
}
|
||||
|
||||
void Game::print_gl_attributes()
|
||||
{
|
||||
int major, minor;
|
||||
SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major);
|
||||
SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor);
|
||||
SDL_Log("GL CONTEXT: %i, %i", major, minor);
|
||||
int r, g, b, a, buf;
|
||||
SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &r);
|
||||
SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &g);
|
||||
SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &b);
|
||||
SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &a);
|
||||
SDL_GL_GetAttribute(SDL_GL_BUFFER_SIZE, &buf);
|
||||
SDL_Log("GL PIXELS: red: %i green: %i blue: %i alpha: %i", r, g, b, a);
|
||||
}
|
||||
|
||||
void Game::print_frame_length_history()
|
||||
{
|
||||
for (float& frame_length : frame_length_history)
|
||||
|
@ -245,65 +303,62 @@ void Game::print_frame_length_history()
|
|||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void Game::load_sdl_context()
|
||||
/* Create, compile and return the ID of a GL shader from the GLSL code at path */
|
||||
GLuint Game::load_shader(const fs::path& path, GLenum type) const
|
||||
{
|
||||
if (glcontext != nullptr)
|
||||
GLuint shader = glCreateShader(type);
|
||||
std::fstream file = std::fstream(path);
|
||||
std::ostringstream message;
|
||||
std::string contents = sfw::file_to_string(path);
|
||||
glShaderSource(shader, 1, reinterpret_cast<const GLchar**>(&contents), 0);
|
||||
// glShaderSource(shader, 1, const_cast<const GLchar**>(&buf), 0);
|
||||
glCompileShader(shader);
|
||||
GLint is_compiled;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &is_compiled);
|
||||
if (is_compiled == GL_TRUE)
|
||||
{
|
||||
SDL_GL_DeleteContext(glcontext);
|
||||
glcontext = nullptr;
|
||||
}
|
||||
SDL_RendererInfo renderer_info;
|
||||
int render_driver_count = SDL_GetNumRenderDrivers();
|
||||
SDL_Log("Render drivers:");
|
||||
for (int ii = 0; ii < render_driver_count; ii++)
|
||||
{
|
||||
SDL_GetRenderDriverInfo(ii, &renderer_info);
|
||||
log_renderer_info(renderer_info);
|
||||
}
|
||||
if ((renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_TARGETTEXTURE | SDL_RENDERER_ACCELERATED)) == nullptr)
|
||||
{
|
||||
print_sdl_error("Could not create renderer");
|
||||
flag_to_end();
|
||||
message << "compiled shader at " << path;
|
||||
log(message.str());
|
||||
return shader;
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_Log("Current renderer:");
|
||||
SDL_GetRendererInfo(renderer, &renderer_info);
|
||||
log_renderer_info(renderer_info);
|
||||
SDL_Log("Renderer supports the use of render targets? %d", SDL_RenderTargetSupported(renderer));
|
||||
/* log error by allocating a string to copy the GL error message buffer into */
|
||||
std::string error_info;
|
||||
GLint max_length;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &max_length);
|
||||
error_info.resize(max_length, 0);
|
||||
glGetShaderInfoLog(shader, error_info.size(), nullptr, error_info.data());
|
||||
message << "failed to compile " << path << ": " << error_info;
|
||||
log(message.str());
|
||||
return -1;
|
||||
}
|
||||
is_gl_context = false;
|
||||
log_display_mode();
|
||||
}
|
||||
|
||||
void Game::load_gl_context()
|
||||
bool Game::link_shader(GLuint program) const
|
||||
{
|
||||
if (renderer != nullptr)
|
||||
glLinkProgram(program);
|
||||
int is_linked;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, (int *) &is_linked);
|
||||
std::ostringstream message;
|
||||
if (is_linked == GL_TRUE)
|
||||
{
|
||||
SDL_DestroyRenderer(renderer);
|
||||
renderer = NULL;
|
||||
message << "linked shader program " << program;
|
||||
log(message.str());
|
||||
return true;
|
||||
}
|
||||
// SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
// SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
// SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
|
||||
print_gl_attributes();
|
||||
if ((glcontext = SDL_GL_CreateContext(window)) == NULL)
|
||||
else
|
||||
{
|
||||
print_sdl_error("Could not get GL context");
|
||||
flag_to_end();
|
||||
/* log error by allocating a string to copy the GL error message buffer into */
|
||||
std::string error_info;
|
||||
GLint max_length;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &max_length);
|
||||
error_info.resize(max_length, 0);
|
||||
glGetProgramInfoLog(program, error_info.size(), nullptr, error_info.data());
|
||||
message << "failed linking shader program " << program << ": " << error_info;
|
||||
log(message.str());
|
||||
return false;
|
||||
}
|
||||
GLenum error = glewInit();
|
||||
if (error != GLEW_OK)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "GLEW could not initialize " << glewGetErrorString(error);
|
||||
print_error(message.str());
|
||||
}
|
||||
SDL_Log("OpenGL %s, renderer %s, shading language %s",
|
||||
glGetString(GL_VERSION), glGetString(GL_RENDERER),
|
||||
glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
is_gl_context = true;
|
||||
log_display_mode();
|
||||
}
|
||||
|
||||
/* Send an info priority message to SDL's log output function, which is overridden by our own member
|
||||
|
@ -338,76 +393,65 @@ bool Game::log_gl_errors(std::string suffix)
|
|||
while ((error = glGetError()) != GL_NO_ERROR)
|
||||
{
|
||||
error_logged = true;
|
||||
std::ostringstream message;
|
||||
if (error == GL_INVALID_ENUM)
|
||||
{
|
||||
SDL_LogError(
|
||||
SDL_LOG_CATEGORY_APPLICATION,
|
||||
"GL_INVALID_ENUM, an unacceptable value is specified for an "
|
||||
"enumerated argument %s", suffix.c_str());
|
||||
message << "GL_INVALID_ENUM, an unacceptable value is specified for an enumerated argument";
|
||||
}
|
||||
else if (error == GL_INVALID_VALUE)
|
||||
{
|
||||
SDL_LogError(
|
||||
SDL_LOG_CATEGORY_APPLICATION,
|
||||
"GL_INVALID_VALUE, a numeric argument is out of range %s", suffix.c_str());
|
||||
message << "GL_INVALID_VALUE, a numeric argument is out of range";
|
||||
}
|
||||
else if (error == GL_INVALID_OPERATION)
|
||||
{
|
||||
SDL_LogError(
|
||||
SDL_LOG_CATEGORY_APPLICATION,
|
||||
"GL_INVALID_OPERATION, the specified operation is not allowed "
|
||||
"in the current state %s", suffix.c_str());
|
||||
message << "GL_INVALID_OPERATION, the specified operation is not allowed in the current state";
|
||||
}
|
||||
else if (error == GL_INVALID_FRAMEBUFFER_OPERATION)
|
||||
{
|
||||
SDL_LogError(
|
||||
SDL_LOG_CATEGORY_APPLICATION,
|
||||
"GL_INVALID_FRAMEBUFFER_OPERATION, the framebuffer object is "
|
||||
"not complete %s", suffix.c_str());
|
||||
message << "GL_INVALID_FRAMEBUFFER_OPERATION, the framebuffer object is not complete";
|
||||
}
|
||||
else if (error == GL_OUT_OF_MEMORY)
|
||||
{
|
||||
SDL_LogError(
|
||||
SDL_LOG_CATEGORY_APPLICATION,
|
||||
"GL_OUT_OF_MEMORY, there is not enough memory left to execute "
|
||||
"the command %s", suffix.c_str());
|
||||
message << "GL_OUT_OF_MEMORY, there is not enough memory left to execute the command";
|
||||
}
|
||||
else if (error == GL_STACK_UNDERFLOW)
|
||||
{
|
||||
SDL_LogError(
|
||||
SDL_LOG_CATEGORY_APPLICATION,
|
||||
"GL_STACK_UNDERFLOW, an attempt has been made to perform an "
|
||||
"operation that would cause an internal stack to underflow. %s", suffix.c_str());
|
||||
message << "GL_STACK_UNDERFLOW, an attempt has been made to perform an operation that would " <<
|
||||
"cause an internal stack to underflow";
|
||||
}
|
||||
else if (error == GL_STACK_OVERFLOW)
|
||||
{
|
||||
SDL_LogError(
|
||||
SDL_LOG_CATEGORY_APPLICATION,
|
||||
"GL_STACK_OVERFLOW, an attempt has been made to perform an "
|
||||
"operation that would cause an internal stack to overflow. %s", suffix.c_str());
|
||||
message << "GL_STACK_OVERFLOW, an attempt has been made to perform an operation that would " <<
|
||||
"cause an internal stack to overflow";
|
||||
}
|
||||
if (!suffix.empty())
|
||||
{
|
||||
message << " " << suffix;
|
||||
}
|
||||
log(message.str());
|
||||
}
|
||||
return error_logged;
|
||||
}
|
||||
|
||||
// from SDL_GetCurrentDisplayMode.html
|
||||
/* Write resolution, monitor refresh rate, and pixel format to the log. Code taken from SDL_GetCurrentDisplayMode.html
|
||||
* on the SDL wiki */
|
||||
void Game::log_display_mode()
|
||||
{
|
||||
SDL_DisplayMode current;
|
||||
std::ostringstream message;
|
||||
for (int ii = 0; ii < SDL_GetNumVideoDisplays(); ii++)
|
||||
{
|
||||
int mode = SDL_GetCurrentDisplayMode(ii, ¤t);
|
||||
if (mode != 0)
|
||||
{
|
||||
SDL_Log("Could not get display mode for video display #%d: %s", ii,
|
||||
SDL_GetError());
|
||||
message << "Could not get display mode for video display #" << ii << ": " << SDL_GetError();
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_Log("Display #%d: display mode is %dx%dpx @ %dhz %s", ii,
|
||||
current.w, current.h, current.refresh_rate,
|
||||
get_pixel_format_string(current.format).c_str());
|
||||
message << "Display #" << ii << ": display mode is " << current.w << "x" << current.h << "px @ " <<
|
||||
current.refresh_rate << "hz " << get_pixel_format_string(current.format);
|
||||
}
|
||||
log(message.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -716,3 +760,8 @@ void Game::quit()
|
|||
Mix_Quit();
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
Game::~Game()
|
||||
{
|
||||
get_delegate().unsubscribe(this);
|
||||
}
|
||||
|
|
15
src/Game.hpp
15
src/Game.hpp
|
@ -7,6 +7,7 @@
|
|||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <ctime>
|
||||
#include <fstream>
|
||||
|
||||
#define SDL_MAIN_HANDLED
|
||||
#include "SDL.h"
|
||||
|
@ -29,9 +30,10 @@
|
|||
#include "Configuration.hpp"
|
||||
#include "Delegate.hpp"
|
||||
#include "Recorder.hpp"
|
||||
#include "extension.hpp"
|
||||
#include "Sprite.hpp"
|
||||
#include "Audio.hpp"
|
||||
#include "filesystem.hpp"
|
||||
#include "extension.hpp"
|
||||
|
||||
struct FramerateIndicator : Sprite
|
||||
{
|
||||
|
@ -59,8 +61,8 @@ public:
|
|||
|
||||
static const int DEFAULT_SDL_LOG_CATEGORY = SDL_LOG_CATEGORY_CUSTOM;
|
||||
SDL_Window* window;
|
||||
SDL_Renderer* renderer = NULL;
|
||||
SDL_GLContext glcontext = NULL;
|
||||
SDL_Renderer* renderer = nullptr;
|
||||
SDL_GLContext glcontext = nullptr;
|
||||
int frame_count_this_second = 0, framerate, ticks, last_frame_length;
|
||||
float frame_length = 1000.0 / 60.0, frame_time_overflow = 0, last_frame_timestamp,
|
||||
last_frame_count_timestamp, emscripten_previous_time;
|
||||
|
@ -76,18 +78,18 @@ public:
|
|||
FramerateIndicator framerate_indicator = FramerateIndicator(this);
|
||||
|
||||
Game();
|
||||
~Game();
|
||||
virtual void reset() { activate(); }
|
||||
void print_error(const std::string&);
|
||||
void print_sdl_error(const std::string&);
|
||||
void print_gl_attributes();
|
||||
void print_frame_length_history();
|
||||
void load_sdl_context();
|
||||
void load_gl_context();
|
||||
GLuint load_shader(const fs::path&, GLenum) const;
|
||||
bool link_shader(GLuint program) const;
|
||||
void log(const std::string&, const int = DEFAULT_SDL_LOG_CATEGORY) const;
|
||||
void debug(const std::string&, const int = DEFAULT_SDL_LOG_CATEGORY) const;
|
||||
void log_renderer_info(SDL_RendererInfo&);
|
||||
bool log_gl_errors(std::string);
|
||||
bool log_gl_errors(std::string = "");
|
||||
void log_display_mode();
|
||||
void log_surface_format(SDL_Surface*, std::string = "surface");
|
||||
std::string get_pixel_format_string(Uint32);
|
||||
|
@ -107,6 +109,7 @@ public:
|
|||
void handle_quit_event(SDL_Event&);
|
||||
void quit();
|
||||
virtual std::string get_class_name() const { return "Game"; }
|
||||
~Game();
|
||||
|
||||
template<typename T>
|
||||
float weight(T amount)
|
||||
|
|
|
@ -323,25 +323,26 @@ void Recorder::finish_writing_video()
|
|||
{
|
||||
write_mp4();
|
||||
}
|
||||
std::cout << "Wrote video frames to " << current_video_directory.string() <<
|
||||
std::endl;
|
||||
std::cout << "Wrote video frames to " << current_video_directory.string() << std::endl;
|
||||
writing_recording = false;
|
||||
}
|
||||
|
||||
/* Launch a system command that calls ffmpeg to write an x264 encoded MP4 from the image frames written.
|
||||
* This requires ffmpeg to be installed on the user's system. Might only work on Linux (?) */
|
||||
void Recorder::write_mp4()
|
||||
{
|
||||
glm::ivec2 size = get_display().get_window_size();
|
||||
std::stringstream mp4_command;
|
||||
std::string pixel_format =
|
||||
get_configuration()["recording"]["mp4-pixel-format"].get<std::string>();
|
||||
std::ostringstream mp4_command;
|
||||
std::string pixel_format = get_configuration()["recording"]["mp4-pixel-format"].get<std::string>();
|
||||
fs::path images_match = current_video_directory / "%05d.png";
|
||||
mp4_command << "ffmpeg -f s16le -ac 2 -ar 22050 -i " << current_audio_path.string() <<
|
||||
" -f image2 -framerate " << (1000 / get_frame_length()) <<
|
||||
" -i " << images_match.string() << " -s " << size.x << "x" << size.y <<
|
||||
" -c:v libx264 -crf 17 -pix_fmt " << pixel_format << " " <<
|
||||
current_video_directory.string() << ".mp4";
|
||||
std::cout << mp4_command.str() << std::endl;
|
||||
std::system(mp4_command.str().c_str());
|
||||
std::string mp4_command_str = mp4_command.str();
|
||||
std::cout << mp4_command_str << std::endl;
|
||||
std::system(mp4_command_str.c_str());
|
||||
}
|
||||
|
||||
void Recorder::write_audio(Uint8* stream, int len)
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
#include <cstdlib>
|
||||
|
||||
#include "sdl2-gfx/SDL2_gfxPrimitives.h"
|
||||
|
||||
#include "Pixels.hpp"
|
||||
#include "extension.hpp"
|
||||
|
||||
|
@ -571,6 +567,37 @@ fs::path sfw::get_next_file_name(
|
|||
return path;
|
||||
}
|
||||
|
||||
/* Read the file at path into a string and return the string */
|
||||
std::string sfw::file_to_string(const fs::path& path)
|
||||
{
|
||||
std::fstream file;
|
||||
file.open(path);
|
||||
std::ostringstream message;
|
||||
std::string m_str;
|
||||
if (!file.is_open())
|
||||
{
|
||||
message << "failed to open " << path;
|
||||
message.str();
|
||||
SDL_Log("%s", m_str.c_str());
|
||||
return "";
|
||||
}
|
||||
else
|
||||
{
|
||||
message << "opened file " << path;
|
||||
m_str = message.str();
|
||||
SDL_Log("%s", m_str.c_str());
|
||||
file.seekg(0, std::ios::end);
|
||||
size_t size = file.tellg();
|
||||
std::string contents;
|
||||
contents.resize(size + 1, '\0');
|
||||
file.seekg(0, std::ios::beg);
|
||||
file.read(contents.data(), size);
|
||||
contents[size] = '\0';
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_CUSTOM, "%s", contents.c_str());
|
||||
return contents;
|
||||
}
|
||||
}
|
||||
|
||||
void sfw::print_error(const std::string& message)
|
||||
{
|
||||
std::cerr << message << std::endl;
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include <stdexcept>
|
||||
#include <map>
|
||||
#include <cmath>
|
||||
#include <fstream>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "SDL.h"
|
||||
#include "SDL_image.h"
|
||||
|
@ -60,8 +62,8 @@ namespace sfw
|
|||
SDL_Texture* get_pixel_scaled_texture(SDL_Renderer*, SDL_Texture*, int = 1, int = scaler::scale2x);
|
||||
SDL_Surface* get_surface_from_pixels(Pixels&);
|
||||
std::vector<fs::path> glob(fs::path);
|
||||
fs::path get_next_file_name(
|
||||
fs::path, int = 0, std::string = "", std::string = "");
|
||||
fs::path get_next_file_name(fs::path, int = 0, std::string = "", std::string = "");
|
||||
std::string file_to_string(const fs::path&);
|
||||
void print_error(const std::string&);
|
||||
void print_sdl_error(const std::string&);
|
||||
|
||||
|
|
Loading…
Reference in New Issue