get screen pixels uses gl or sdl
This commit is contained in:
parent
7e51a04b71
commit
30e6c970d3
|
@ -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)
|
||||
// {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 $@
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
|
260
src/Game.cpp
260
src/Game.cpp
|
@ -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)
|
||||
|
|
22
src/Game.hpp
22
src/Game.hpp
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
20
src/Node.cpp
20
src/Node.cpp
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"; }
|
||||
|
||||
|
|
Loading…
Reference in New Issue