get screen pixels uses gl or sdl

This commit is contained in:
Frank DeMarco 2019-06-16 03:05:02 -04:00
parent 7e51a04b71
commit 30e6c970d3
16 changed files with 463 additions and 126 deletions

View File

@ -86,45 +86,51 @@ GLuint get_gl_texture_from_surface(SDL_Surface *surface, GLint mipmap_filter)
SDL_Surface* get_framerate_indicator_surface(int frame_count)
{
TTF_Font *font = TTF_OpenFont("resource/SourceCodePro-Regular.otf", 14);
SDL_Surface *shaded = TTF_RenderText_Shaded(
font, std::to_string(frame_count).c_str(), {0, 0, 0}, {255, 255, 255});
SDL_Surface *converted = SDL_ConvertSurfaceFormat(shaded, SDL_PIXELFORMAT_ARGB8888, 0);
SDL_Surface *flipped = zoomSurface(converted, 1, -1, SMOOTHING_OFF);
TTF_Font* font = TTF_OpenFont("resource/SourceCodePro-Regular.otf", 14);
std::string padded = sfw::pad(frame_count, 2);
SDL_Surface* shaded = TTF_RenderText_Shaded(
font, padded.c_str(), {0, 0, 0}, {255, 255, 255});
SDL_Surface* converted = SDL_ConvertSurfaceFormat(
shaded, SDL_PIXELFORMAT_ARGB8888, 0);
SDL_Surface* flipped = zoomSurface(converted, 1, -1, SMOOTHING_OFF);
SDL_FreeSurface(shaded);
SDL_FreeSurface(converted);
if (not flipped)
{
fprintf(stderr, "Could not create text %s\n", SDL_GetError());
}
TTF_CloseFont(font);
return flipped;
}
void set_framerate_indicator(int frame_count, GLuint id)
{
printf("%i %i", frame_count, id);
SDL_Surface *message = get_framerate_indicator_surface(frame_count);
SDL_Surface* message = get_framerate_indicator_surface(frame_count);
glBindTexture(GL_TEXTURE_2D, id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, message->w, message->h, 0, GL_BGRA, GL_UNSIGNED_BYTE,
message->pixels);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, message->w, message->h, GL_BGRA,
GL_UNSIGNED_BYTE, message->pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
SDL_FreeSurface(message);
}
Mushroom::Mushroom(Node *parent) : Sprite(parent, "resource/shrooms")
{
set_frame_length(500);
std::cout << "mushroom constructor " << this << std::endl;
}
void Mushroom::update()
{
Game *game = get_root();
move(direction);
int x = location.get_x();
if (x > game->sw or x < 0)
glm::ivec2 resolution = get_display().get_window_size();
if (x > resolution.x or x < 0)
{
direction = -direction;
if (x > game->sw)
if (x > resolution.x)
{
move(game->sw - x);
move(resolution.x - x);
}
else
{
@ -140,11 +146,6 @@ Demo::Demo()
Mix_PlayMusic(music, -1);
load_gl_context();
delegate.subscribe(&Demo::respond, this);
// audio_file.open("audio.raw", std::ios::binary);
// SDL_AudioSpec spec;
// audio_device_id = SDL_OpenAudioDevice(NULL, SDL_TRUE, &spec, &spec, 0);
// SDL_Log("opened audio device %i", audio_device_id);
// SDL_PauseAudioDevice(audio_device_id, SDL_FALSE);
}
void Demo::load_sdl_context()
@ -168,7 +169,7 @@ void Demo::load_gl_context()
v6-v1-v0
v1-v6-v7 (left)
v7-v2-v1
v7-v4-v3 (bottom)
v7-v4-v3 (bottom)
v3-v2-v7
v4-v7-v6 (back)
v6-v5-v4
@ -212,12 +213,14 @@ void Demo::load_gl_context()
vertices.insert(vertices.end(), background_vertices.begin(), background_vertices.end());
vertices.insert(vertices.end(), framerate_indicator_vertices.begin(),
framerate_indicator_vertices.end());
projection = glm::perspective(glm::radians(45.0f),
(float) sw / (float) sh, 0.1f, 100.0f);
glm::ivec2 resolution = get_display().get_window_size();
projection = glm::perspective(
glm::radians(45.0f), resolution.x / (float) resolution.y, 0.1f,
100.0f);
view = glm::lookAt(
glm::vec3(4, 3, 3), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
SDL_Surface *surface = rotateSurface90Degrees(IMG_Load("resource/tile.png"), 2);
printf("tile.png bytes per pixel %i\n", surface->format->BytesPerPixel);
SDL_Log("tile.png bytes per pixel %i", surface->format->BytesPerPixel);
space_texture_id = get_gl_texture_from_surface(surface, GL_LINEAR);
SDL_FreeSurface(surface);
std::array<glm::vec2, 6> framerate_indicator_uv = {
@ -292,14 +295,15 @@ void Demo::load_gl_context()
glBindAttribLocation(flat_program, 3, "pos");
link_shader(flat_program);
mvp_id = glGetUniformLocation(world_program, "MVP");
GLuint sampler_uniform_id = glGetUniformLocation(world_program, "myTextureSampler");
// GLuint sampler_uniform_id = glGetUniformLocation(world_program, "myTextureSampler");
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, space_texture_id);
glUniform1i(sampler_uniform_id, 0);
// glUniform1i(sampler_uniform_id, 0);
glDepthFunc(GL_LESS);
frame_count_timestamp = SDL_GetTicks();
framerate_texture_id = get_gl_texture_from_surface(
get_framerate_indicator_surface(frame_count), GL_LINEAR);
SDL_Surface* fps_surface = get_framerate_indicator_surface(frame_count);
framerate_texture_id = get_gl_texture_from_surface(fps_surface, GL_LINEAR);
SDL_FreeSurface(fps_surface);
}
void Demo::respond(SDL_Event& event)
@ -320,6 +324,17 @@ void Demo::respond(SDL_Event& event)
Mix_Chunk* music = Mix_LoadWAV("resource/Ag.ogg");
Mix_PlayChannel(-1, music, 0);
}
else if (delegate.compare(event, "fullscreen"))
{
if (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN)
{
SDL_SetWindowFullscreen(window, 0);
}
else
{
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
}
}
}
void Demo::update()
@ -328,18 +343,7 @@ void Demo::update()
// {
// if (event.type == SDL_KEYDOWN)
// {
// if (event.key.keysym.sym == SDLK_F11)
// {
// if (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN)
// {
// SDL_SetWindowFullscreen(window, 0);
// }
// else
// {
// SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
// }
// }
// else if (SDL_GetModState() & KMOD_CTRL)
// if (SDL_GetModState() & KMOD_CTRL)
// {
// if (event.key.keysym.sym == SDLK_f)
// {

View File

@ -37,6 +37,7 @@
#include "Sprite.hpp"
#include "Input.hpp"
#include "Delegate.hpp"
#include "extension.hpp"
struct Mushroom : Sprite
{
@ -60,11 +61,8 @@ struct Demo : Game
GLuint vbo, space_texture_id, mvp_id, framerate_texture_id, flat_program,
world_program, fake_texture_id;
glm::mat4 projection, view, model = glm::mat4(1.0f), mvp;
int abc, def, ghi, jkl, mno, pqr, stu, vwx, yz;
Mushroom mushroom = Mushroom(this);
Sprite grass = Sprite(this, "resource/Field.png");
// SDL_AudioDeviceID audio_device_id;
// std::ofstream audio_file;
Demo();
void load_sdl_context();

View File

@ -36,13 +36,16 @@ $(SDLGFX2_DIR)%.o: $(SDLGFX2_DIR)%.c $(SDLGFX2_DIR)%.h
$(GLEW_DIR)%.o: $(GLEW_DIR)%.c $(GLEW_DIR)%.h
$(CC_LINUX) $(CFLAGS) $< -o $@
$(SFW_SRC_DIR)Sprite.o: $(addprefix $(SFW_SRC_DIR),Game.*pp Location.*pp Node.*pp)
$(SFW_SRC_DIR)Sprite.o: $(addprefix $(SFW_SRC_DIR),Game.*pp Location.*pp Node.*pp Animation.*pp)
$(SFW_SRC_DIR)Game.o: $(addprefix $(SFW_SRC_DIR),Sprite.*pp Configuration.*pp Delegate.*pp Display.*pp \
Recorder.*pp Node.*pp Input.*pp)
$(SFW_SRC_DIR)Node.o: $(addprefix $(SFW_SRC_DIR),Game.*pp Configuration.*pp Delegate.*pp)
$(SFW_SRC_DIR)Animation.o: $(addprefix $(SFW_SRC_DIR),Timer.*pp)
$(SFW_SRC_DIR)Recorder.o: $(addprefix $(SFW_SRC_DIR),extension.*pp Node.*pp Delegate.*pp)
$(SFW_SRC_DIR)Input.o: $(addprefix $(SFW_SRC_DIR),Delegate.*pp)
$(SFW_SRC_DIR)Recorder.o: $(addprefix $(SFW_SRC_DIR),extension.*pp Node.*pp Delegate.*pp Animation.*pp)
$(SFW_SRC_DIR)Input.o: $(addprefix $(SFW_SRC_DIR),Delegate.*pp Node.*pp)
$(SFW_SRC_DIR)Configuration.o: $(addprefix $(SFW_SRC_DIR),Node.*pp)
$(SFW_SRC_DIR)Delegate.o: $(addprefix $(SFW_SRC_DIR),Node.*pp)
$(SFW_SRC_DIR)Display.o: $(addprefix $(SFW_SRC_DIR),Node.*pp)
$(SFW_SRC_DIR)%.o: $(addprefix $(SFW_SRC_DIR),%.cpp %.hpp)
$(CPPC_LINUX) $(CPP_FLAGS) $(SDL_FLAGS) $< -o $@

View File

@ -1,7 +1,8 @@
{
"display":
{
"dimensions": [640, 480]
"dimensions": [864, 486],
"fps": 60
},
"path":
{
@ -14,12 +15,12 @@
"keys":
{
"context": " ",
"print-video-memory": "?",
"play-sound": "s"
"print-video-memory-size": "v",
"play-sound": ""
},
"recording":
{
"write-mp4": true,
"video-frame-length": 16.667
"video-frame-length": 33.334
}
}

View File

@ -22,14 +22,16 @@ void Configuration::set_defaults()
{"down", "down"},
{"left", "left"},
{"pause", "enter"},
{"fullscreen", {"ALT", "enter"}}
{"fullscreen", {"ALT", "enter"}},
{"show-fps", {"CTRL", "f"}}
};
sys_config["path"] = {
{"screenshots", "."},
{"video", "."}
};
sys_config["display"] = {
{"dimensions", {640, 480}}
{"dimensions", {640, 480}},
{"fps", 60}
};
sys_config["recording"] = {
{"screenshot-prefix", "screenshot-"},
@ -43,6 +45,12 @@ void Configuration::set_defaults()
{"max-video-memory", 1000},
{"mp4-pixel-format", "yuv444p"}
};
sys_config["fps-indicator"] = {
{"width", .05},
{"height", .04},
{"background", {255, 255, 255}},
{"foreground", {0, 0, 0}}
};
}
void Configuration::load()

View File

@ -12,13 +12,27 @@ glm::ivec2 Display::get_window_size()
void Display::get_screen_pixels(unsigned char* pixels, int w, int h, int x, int y)
{
GLenum format;
if (get_root()->is_gl_context)
{
GLenum format;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
format = GL_RGB;
format = GL_RGBA;
#else
format = GL_BGR;
format = GL_BGRA;
#endif
glReadPixels(x, y, w, h, format, GL_UNSIGNED_BYTE, pixels);
glReadPixels(x, y, w, h, format, GL_UNSIGNED_BYTE, pixels);
}
else
{
Uint32 format;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
format = SDL_PIXELFORMAT_ABGR8888;
#else
format = SDL_PIXELFORMAT_ARGB8888;
#endif
SDL_RenderReadPixels(
get_root()->renderer, NULL, format, pixels, bpp / 8 * w);
}
}
SDL_Surface* Display::get_screen_surface()
@ -26,17 +40,28 @@ SDL_Surface* Display::get_screen_surface()
glm::ivec2 size = get_window_size();
unsigned char* pixels = new unsigned char[bpp / 8 * size.x * size.y];
get_screen_pixels(pixels, size.x, size.y);
SDL_Surface* surface = get_screen_surface_from_pixels(pixels);
SDL_Surface* surface = get_screen_surface_from_pixels(
pixels, get_root()->is_gl_context);
delete[] pixels;
return surface;
}
SDL_Surface* Display::get_screen_surface_from_pixels(unsigned char* pixels)
SDL_Surface* Display::get_screen_surface_from_pixels(
unsigned char* pixels, bool flip)
{
glm::ivec2 size = get_window_size();
SDL_Surface* surface = SDL_CreateRGBSurfaceFrom(
pixels, size.x, size.y, bpp, bpp / 8 * size.x, 0, 0, 0, 0);
SDL_Surface* zoomed_surface = zoomSurface(surface, 1, -1, SMOOTHING_OFF);
SDL_FreeSurface(surface);
return zoomed_surface;
SDL_Surface* surface;
if (flip)
{
SDL_Surface* pixel_surface = SDL_CreateRGBSurfaceFrom(
pixels, size.x, size.y, bpp, bpp / 8 * size.x, 0, 0, 0, 0);
surface = zoomSurface(pixel_surface, 1, -1, SMOOTHING_OFF);
SDL_FreeSurface(pixel_surface);
}
else
{
surface = SDL_CreateRGBSurface(0, size.x, size.y, bpp, 0, 0, 0, 0);
std::memcpy(surface->pixels, pixels, bpp / 8 * size.x * size.y);
}
return surface;
}

View File

@ -19,13 +19,13 @@
struct Display : Node
{
const static int bpp = 24;
const static int bpp = 32;
Display(Node*);
glm::ivec2 get_window_size();
void get_screen_pixels(unsigned char*, int, int, int = 0, int = 0);
SDL_Surface* get_screen_surface();
SDL_Surface* get_screen_surface_from_pixels(unsigned char*);
SDL_Surface* get_screen_surface_from_pixels(unsigned char*, bool);
};

View File

@ -1,14 +1,22 @@
#include "Game.hpp"
// FPSIndicator::FPSIndicator(Node* parent) : Node(parent) {}
// FPSIndicator::update()
// {
// }
Game::Game()
{
set_framerate(get_configuration()["display"]["fps"]);
delegate.subscribe(&Game::handle_quit_event, this, SDL_QUIT);
std::cout << "GLEW " << glewGetString(GLEW_VERSION) << std::endl;
SDL_Log("GLEW %s", glewGetString(GLEW_VERSION));
putenv("SDL_VIDEO_X11_LEGACY_FULLSCREEN=0");
putenv("SDL_VIDEO_CENTERED=1");
putenv("SDL_VIDEO_CENTERED=0");
SDL_version version;
SDL_GetVersion(&version);
printf("SDL %d.%d.%d\n", version.major, version.minor, version.patch);
SDL_Log("SDL %d.%d.%d", version.major, version.minor, version.patch);
fprintf(stderr, "stderr test message\n");
SDL_SetMainReady();
// SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
@ -24,8 +32,9 @@ Game::Game()
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
print_gl_attributes();
std::vector<int> window_size = get_configuration()["display"]["dimensions"];
window = SDL_CreateWindow("TARE control", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
sw, sh, SDL_WINDOW_OPENGL);
window_size[0], window_size[1], SDL_WINDOW_OPENGL);
if (window == NULL)
{
print_sdl_error("Could not create window");
@ -39,8 +48,8 @@ Game::Game()
}
else
{
printf("initialized SDL ttf %d.%d.%d\n", SDL_TTF_MAJOR_VERSION,
SDL_TTF_MINOR_VERSION, SDL_TTF_PATCHLEVEL);
SDL_Log("initialized SDL ttf %d.%d.%d", SDL_TTF_MAJOR_VERSION,
SDL_TTF_MINOR_VERSION, SDL_TTF_PATCHLEVEL);
}
if (Mix_Init(MIX_INIT_FLAC) == 0)
{
@ -49,22 +58,26 @@ Game::Game()
}
else
{
printf("initialized SDL mixer %d.%d.%d\n", SDL_MIXER_MAJOR_VERSION,
SDL_MIXER_MINOR_VERSION, SDL_MIXER_PATCHLEVEL);
SDL_Log("initialized SDL mixer %d.%d.%d", SDL_MIXER_MAJOR_VERSION,
SDL_MIXER_MINOR_VERSION, SDL_MIXER_PATCHLEVEL);
}
if (Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT,
MIX_DEFAULT_CHANNELS, 1024) < 0)
{
print_sdl_error("Could not set up audio");
}
std::cout << "Using audio driver: " << SDL_GetCurrentAudioDriver() <<
std::endl;
SDL_Log("Using audio driver: %s", SDL_GetCurrentAudioDriver());
const int audio_device_count = SDL_GetNumAudioDevices(SDL_TRUE);
for (int ii = 0; ii < audio_device_count; ii++)
{
std::cout << "Found audio capture device " << ii << ": " <<
SDL_GetAudioDeviceName(ii, SDL_TRUE) << std::endl;
SDL_Log("Found audio capture device %i: %s", ii,
SDL_GetAudioDeviceName(ii, SDL_TRUE));
}
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
SDL_Log("big endian, using GL_RGBA and SDL_PIXELFORMAT_ABGR8888");
#else
SDL_Log("little endian, using GL_BGRA and SDL_PIXELFORMAT_ARGB8888");
#endif
last_frame_timestamp = SDL_GetTicks();
}
@ -88,7 +101,14 @@ 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);
std::cout << "GL CONTEXT: " << major << ", " << minor << std::endl;
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::load_sdl_context()
@ -103,6 +123,15 @@ void Game::load_sdl_context()
print_sdl_error("Could not create renderer");
flag_to_end();
}
else
{
SDL_RendererInfo info;
SDL_GetRendererInfo(renderer, &info);
SDL_Log("renderer name: %s, flags: %i, texture formats: %i, "
"max texture w: %i, max texture h: %i", info.name, info.flags,
info.num_texture_formats, info.max_texture_width,
info.max_texture_height);
}
is_gl_context = false;
}
@ -129,11 +158,212 @@ void Game::load_gl_context()
message << "GLEW could not initialize " << glewGetErrorString(error);
print_error(message.str());
}
printf("OpenGL %s, renderer %s, shading language %s\n", glGetString(GL_VERSION),
glGetString(GL_RENDERER), glGetString(GL_SHADING_LANGUAGE_VERSION));
SDL_Log("OpenGL %s, renderer %s, shading language %s",
glGetString(GL_VERSION), glGetString(GL_RENDERER),
glGetString(GL_SHADING_LANGUAGE_VERSION));
is_gl_context = true;
}
GLuint Game::create_gl_texture()
{
GLuint id;
glCreateTextures(GL_TEXTURE_2D, 1, &id);
glBindTexture(GL_TEXTURE_2D, id);
return id;
}
bool Game::log_gl_errors()
{
GLenum error;
bool error_logged = false;
while ((error = glGetError()) != GL_NO_ERROR)
{
error_logged = true;
if (error == GL_INVALID_ENUM)
{
SDL_LogError(
SDL_LOG_CATEGORY_APPLICATION,
"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");
}
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");
}
else if (error == GL_INVALID_FRAMEBUFFER_OPERATION)
{
SDL_LogError(
SDL_LOG_CATEGORY_APPLICATION,
"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");
}
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.");
}
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.");
}
}
return error_logged;
}
void Game::log_surface_format(SDL_Surface* surface, std::string preface)
{
SDL_PixelFormat* format = surface->format;
std::string pixel_format;
if (format->format == SDL_PIXELFORMAT_UNKNOWN)
{
pixel_format = "SDL_PIXELFORMAT_UNKNOWN";
}
else if (format->format == SDL_PIXELFORMAT_INDEX1LSB)
{
pixel_format = "SDL_PIXELFORMAT_INDEX1LSB";
}
else if (format->format == SDL_PIXELFORMAT_INDEX1MSB)
{
pixel_format = "SDL_PIXELFORMAT_INDEX1MSB";
}
else if (format->format == SDL_PIXELFORMAT_INDEX4LSB)
{
pixel_format = "SDL_PIXELFORMAT_INDEX4LSB";
}
else if (format->format == SDL_PIXELFORMAT_INDEX4MSB)
{
pixel_format = "SDL_PIXELFORMAT_INDEX4MSB";
}
else if (format->format == SDL_PIXELFORMAT_INDEX8)
{
pixel_format = "SDL_PIXELFORMAT_INDEX8";
}
else if (format->format == SDL_PIXELFORMAT_RGB332)
{
pixel_format = "SDL_PIXELFORMAT_RGB332";
}
else if (format->format == SDL_PIXELFORMAT_RGB444)
{
pixel_format = "SDL_PIXELFORMAT_RGB444";
}
else if (format->format == SDL_PIXELFORMAT_RGB555)
{
pixel_format = "SDL_PIXELFORMAT_RGB555";
}
else if (format->format == SDL_PIXELFORMAT_BGR555)
{
pixel_format = "SDL_PIXELFORMAT_BGR555";
}
else if (format->format == SDL_PIXELFORMAT_ARGB4444)
{
pixel_format = "SDL_PIXELFORMAT_ARGB4444";
}
else if (format->format == SDL_PIXELFORMAT_RGBA4444)
{
pixel_format = "SDL_PIXELFORMAT_RGBA4444";
}
else if (format->format == SDL_PIXELFORMAT_ABGR4444)
{
pixel_format = "SDL_PIXELFORMAT_ABGR4444";
}
else if (format->format == SDL_PIXELFORMAT_BGRA4444)
{
pixel_format = "SDL_PIXELFORMAT_BGRA4444";
}
else if (format->format == SDL_PIXELFORMAT_ARGB1555)
{
pixel_format = "SDL_PIXELFORMAT_ARGB1555";
}
else if (format->format == SDL_PIXELFORMAT_RGBA5551)
{
pixel_format = "SDL_PIXELFORMAT_RGBA5551";
}
else if (format->format == SDL_PIXELFORMAT_ABGR1555)
{
pixel_format = "SDL_PIXELFORMAT_ABGR1555";
}
else if (format->format == SDL_PIXELFORMAT_BGRA5551)
{
pixel_format = "SDL_PIXELFORMAT_BGRA5551";
}
else if (format->format == SDL_PIXELFORMAT_RGB565)
{
pixel_format = "SDL_PIXELFORMAT_RGB565";
}
else if (format->format == SDL_PIXELFORMAT_BGR565)
{
pixel_format = "SDL_PIXELFORMAT_BGR565";
}
else if (format->format == SDL_PIXELFORMAT_RGB24)
{
pixel_format = "SDL_PIXELFORMAT_RGB24";
}
else if (format->format == SDL_PIXELFORMAT_BGR24)
{
pixel_format = "SDL_PIXELFORMAT_BGR24";
}
else if (format->format == SDL_PIXELFORMAT_RGB888)
{
pixel_format = "SDL_PIXELFORMAT_RGB888";
}
else if (format->format == SDL_PIXELFORMAT_RGBX8888)
{
pixel_format = "SDL_PIXELFORMAT_RGBX8888";
}
else if (format->format == SDL_PIXELFORMAT_BGR888)
{
pixel_format = "SDL_PIXELFORMAT_BGR888";
}
else if (format->format == SDL_PIXELFORMAT_BGRX8888)
{
pixel_format = "SDL_PIXELFORMAT_BGRX8888";
}
else if (format->format == SDL_PIXELFORMAT_ARGB8888)
{
pixel_format = "SDL_PIXELFORMAT_ARGB8888";
}
else if (format->format == SDL_PIXELFORMAT_RGBA8888)
{
pixel_format = "SDL_PIXELFORMAT_RGBA8888";
}
else if (format->format == SDL_PIXELFORMAT_ABGR8888)
{
pixel_format = "SDL_PIXELFORMAT_ABGR8888";
}
else if (format->format == SDL_PIXELFORMAT_BGRA8888)
{
pixel_format = "SDL_PIXELFORMAT_BGRA8888";
}
else if (format->format == SDL_PIXELFORMAT_ARGB2101010)
{
pixel_format = "SDL_PIXELFORMAT_ARGB2101010";
}
SDL_Log("%s bpp: %i mask: %i %i %i %i format: %s", preface.c_str(),
format->BytesPerPixel, format->Rmask, format->Gmask, format->Bmask,
format->Amask, pixel_format.c_str());
}
void Game::run()
{
while (not done)

View File

@ -21,6 +21,14 @@
#include "Display.hpp"
#include "Recorder.hpp"
#include "Input.hpp"
// #include "Sprite.hpp"
// struct FPSIndicator : Sprite
// {
// FPSIndicator(Node*);
// };
struct Game : Node
{
@ -33,10 +41,11 @@ struct Game : Node
SDL_Window* window;
SDL_Renderer* renderer = NULL;
SDL_GLContext glcontext = NULL;
int sw = 640, sh = 480, framerate = 60, frame_time_overflow = 0,
last_frame_timestamp, frame_count_timestamp, ticks,
last_frame_length;
float frame_length = 1000.0 / framerate;
// 768, 432
// 864, 486
int frame_time_overflow = 0, framerate, ticks, last_frame_timestamp,
frame_count_timestamp, last_frame_length;
float frame_length;
bool done = false, show_framerate = false, is_gl_context = true;
Configuration configuration = Configuration(this);
Delegate delegate = Delegate(this);
@ -51,6 +60,9 @@ struct Game : Node
void print_gl_attributes();
void load_sdl_context();
void load_gl_context();
GLuint create_gl_texture();
bool log_gl_errors();
void log_surface_format(SDL_Surface*, std::string = "surface");
void run();
void flag_to_end();
virtual void update() {};
@ -67,4 +79,6 @@ struct Game : Node
};
#include "Sprite.hpp"
#endif

View File

@ -75,23 +75,20 @@ void Input::add_to_key_map(
void Input::respond(SDL_Event &event)
{
// if (event.type == SDL_KEYDOWN)
// {
SDL_Keymod mod = SDL_GetModState();
for (KeyCombination& combination : key_map)
SDL_Keymod mod = SDL_GetModState();
for (KeyCombination& combination : key_map)
{
if (event.key.keysym.sym == combination.key and
(not combination.ctrl || mod & KMOD_CTRL) and
(not combination.shift || mod & KMOD_SHIFT) and
(not combination.alt || mod & KMOD_ALT))
{
if (event.key.keysym.sym == combination.key and
(not combination.ctrl || mod & KMOD_CTRL) and
(not combination.shift || mod & KMOD_SHIFT) and
(not combination.alt || mod & KMOD_ALT))
{
SDL_Event relay;
bool* cancel = new bool(event.type == SDL_KEYDOWN ? false : true);
relay.type = Delegate::command_event_type;
relay.user.data1 = &combination.command;
relay.user.data2 = cancel;
SDL_PushEvent(&relay);
}
SDL_Event relay;
bool* cancel = new bool(event.type == SDL_KEYDOWN ? false : true);
relay.type = Delegate::command_event_type;
relay.user.data1 = &combination.command;
relay.user.data2 = cancel;
SDL_PushEvent(&relay);
}
// }
}
}

View File

@ -1,12 +1,16 @@
#include "Node.hpp"
#include "Game.hpp"
#include "Display.hpp"
#include "Delegate.hpp"
// #include "Display.hpp"
// #include "Delegate.hpp"
Node::Node() : Node(NULL) {}
Node::Node(Node *parent) : parent(parent)
Node::Node(Node *parent, bool active) : parent(parent)
{
if (active)
{
activate();
}
std::cout << "Constructing ";
print_branch();
}
@ -18,6 +22,16 @@ Node::~Node()
get_delegate().unsubscribe(this);
}
void Node::activate()
{
active = true;
}
void Node::deactivate()
{
active = false;
}
nlohmann::json& Node::get_configuration()
{
return get_root()->configuration.config;

View File

@ -17,10 +17,13 @@ struct Node
{
Node *parent = NULL;
bool active = false;
Node();
Node(Node*);
Node(Node*, bool = false);
virtual ~Node();
void activate();
void deactivate();
Game* get_root();
nlohmann::json& get_configuration();
Delegate& get_delegate();

View File

@ -133,7 +133,7 @@ void Recorder::open_audio_file()
void Recorder::add_frame()
{
glm::ivec2 size = get_display().get_window_size();
int bytes = Display::bpp / 8 * size.x * size.y;
int bytes = 32 / 8 * size.x * size.y;
unsigned char* pixels = new unsigned char[bytes];
get_display().get_screen_pixels(pixels, size.x, size.y);
int max_length = get_configuration()["recording"]["max-stash-length"];
@ -142,13 +142,16 @@ void Recorder::add_frame()
{
delete[] current_stash.pixel_buffers.front();
current_stash.pixel_buffers.erase(current_stash.pixel_buffers.begin());
current_stash.flipped.erase(current_stash.flipped.begin());
}
current_stash.pixel_buffers.push_back(pixels);
current_stash.flipped.push_back(get_root()->is_gl_context);
if (is_recording)
{
unsigned char* vid_pixels = new unsigned char[bytes];
memcpy(vid_pixels, pixels, bytes);
video_stashes.back().pixel_buffers.push_back(vid_pixels);
video_stashes.back().flipped.push_back(get_root()->is_gl_context);
if (video_stashes.back().pixel_buffers.size() * get_frame_length() > max_length)
{
std::function<void(bool, int)> f =
@ -166,20 +169,30 @@ void Recorder::add_frame()
int Recorder::get_memory_size()
{
glm::ivec2 window = get_display().get_window_size();
int bytes_per_buffer = Display::bpp / 8 * window.x * window.y;
int count = 0;
int bytes_per_frame = Display::bpp / 8 * window.x * window.y,
size_in_bytes = 0;
for (Stash& stash : in_game_stashes)
{
count += stash.pixel_buffers.size();
size_in_bytes += stash.pixel_buffers.size() * bytes_per_frame;
for (int& length : stash.audio_buffer_lengths)
{
size_in_bytes += length;
}
}
for (Stash& stash : video_stashes)
{
count += stash.pixel_buffers.size();
size_in_bytes += stash.pixel_buffers.size() * bytes_per_frame;
}
size_in_bytes += current_stash.pixel_buffers.size() * bytes_per_frame;
for (int& length : current_stash.audio_buffer_lengths)
{
size_in_bytes += length;
}
size_in_bytes += most_recent_stash.pixel_buffers.size() * bytes_per_frame;
for (int& length : most_recent_stash.audio_buffer_lengths)
{
size_in_bytes += length;
}
count += current_stash.pixel_buffers.size();
count += most_recent_stash.pixel_buffers.size();
int size_in_bytes = 0;
size_in_bytes = count * bytes_per_buffer;
return size_in_bytes / 1000000;
}
@ -196,8 +209,7 @@ void Recorder::make_directory()
void Recorder::write_stash_frames(bool is_video, int index)
{
int frame_offset = is_video ? video_stashes[index].frame_offset : 0;
std::cout << "Writing stash index " << index << " to " << current_video_directory << "..." <<
std::endl;
SDL_Log("Writing stash index %i to %s...", index, current_video_directory.c_str());
SDL_Surface* frame;
GifWriter gif_writer;
int gif_frame_length = get_configuration()["recording"]["gif-frame-length"];
@ -211,12 +223,14 @@ void Recorder::write_stash_frames(bool is_video, int index)
if (is_video)
{
frame = get_display().get_screen_surface_from_pixels(
video_stashes[index].pixel_buffers.front());
video_stashes[index].pixel_buffers.front(),
video_stashes[index].flipped.front());
}
else
{
frame = get_display().get_screen_surface_from_pixels(
most_recent_stash.pixel_buffers.front());
most_recent_stash.pixel_buffers.front(),
most_recent_stash.flipped.front());
}
std::stringstream name;
name << sfw::pad(ii, 5) << ".png";
@ -235,7 +249,9 @@ void Recorder::write_stash_frames(bool is_video, int index)
gif_write_overflow += elapsed - (last_gif_write + gif_frame_length);
last_gif_write = elapsed;
}
GifWriteFrame(&gif_writer, (const uint8_t*) frame->pixels,
SDL_Surface* converted = SDL_ConvertSurfaceFormat(
frame, SDL_PIXELFORMAT_ABGR8888, 0);
GifWriteFrame(&gif_writer, (const uint8_t*) converted->pixels,
frame->w, frame->h, gif_frame_length / 10);
}
elapsed += get_frame_length();
@ -244,12 +260,16 @@ void Recorder::write_stash_frames(bool is_video, int index)
delete[] video_stashes[index].pixel_buffers.front();
video_stashes[index].pixel_buffers.erase(
video_stashes[index].pixel_buffers.begin());
video_stashes[index].flipped.erase(
video_stashes[index].flipped.begin());
}
else
{
delete[] most_recent_stash.pixel_buffers.front();
most_recent_stash.pixel_buffers.erase(
most_recent_stash.pixel_buffers.begin());
most_recent_stash.flipped.erase(
most_recent_stash.flipped.begin());
}
SDL_FreeSurface(frame);
}
@ -268,6 +288,7 @@ void Recorder::keep_stash()
{
delete[] stash.pixel_buffers.back();
stash.pixel_buffers.pop_back();
stash.flipped.pop_back();
}
in_game_stashes.erase(in_game_stashes.begin());
}

View File

@ -23,6 +23,7 @@
struct Stash
{
std::vector<unsigned char*> pixel_buffers;
std::vector<bool> flipped;
std::vector<Uint8*> audio_buffers;
std::vector<int> audio_buffer_lengths;
int frame_offset;

View File

@ -1,11 +1,17 @@
#include "Sprite.hpp"
#include "Game.hpp"
Sprite::Sprite(Node *parent) : Node(parent) {}
Sprite::Sprite(Node *parent) : Node(parent, true) {}
Sprite::Sprite(Node *parent, std::string path) : Node(parent)
Sprite::Sprite(Node *parent, std::string path) : Node(parent, true)
{
associate(path);
animation.play();
}
void Sprite::set_frame_length(float length)
{
animation.set_frame_length(length);
}
void Sprite::associate(std::string path)
@ -70,15 +76,23 @@ void Sprite::unload()
}
}
void Sprite::update()
void Sprite::advance_frame()
{
int w, h;
SDL_Texture *frame = frames[frame_ii++];
SDL_QueryTexture(frame, NULL, NULL, &w, &h);
SDL_Rect frame_rect = {location.get_x(), location.get_y(), w, h};
SDL_RenderCopy(get_root()->renderer, frame, NULL, &frame_rect);
if (frame_ii >= frames.size())
if (++frame_ii >= frames.size())
{
frame_ii = 0;
}
}
void Sprite::update()
{
if (active)
{
animation.update();
int w, h;
SDL_Texture *frame = frames[frame_ii];
SDL_QueryTexture(frame, NULL, NULL, &w, &h);
SDL_Rect frame_rect = {location.get_x(), location.get_y(), w, h};
SDL_RenderCopy(get_root()->renderer, frame, NULL, &frame_rect);
}
}

View File

@ -12,6 +12,7 @@
#include "Node.hpp"
#include "Game.hpp"
#include "Location.hpp"
#include "Animation.hpp"
struct Sprite : Node
{
@ -20,14 +21,17 @@ struct Sprite : Node
std::vector<fs::path> frame_paths;
int frame_ii = 0;
Location location;
Animation animation = Animation(&Sprite::advance_frame, this);
Sprite(Node*);
Sprite(Node*, std::string);
void set_frame_length(float);
void associate(std::string);
void load();
void load_file(fs::path);
void add_frame(SDL_Texture*);
void unload();
void advance_frame();
void update();
std::string get_class_name() { return "Sprite"; }