#include "Display.hpp" #include "Game.hpp" Display::Display(Node* parent) : Node(parent) { get_delegate().subscribe(&Display::respond, this); } glm::ivec2 Display::get_window_size() { glm::ivec2 size; SDL_GetWindowSize(get_root()->get_window(), &size.x, &size.y); return size; } Box Display::get_window_box() { return Box(glm::vec2(0, 0), get_window_size()); } void Display::get_screen_pixels(unsigned char* pixels, int w, int h, int x, int y) { if (get_root()->is_gl_context) { GLenum format; #if SDL_BYTEORDER == SDL_BIG_ENDIAN format = GL_BGRA; #else format = GL_RGBA; #endif glReadBuffer(GL_FRONT); glReadPixels(x, y, w, h, format, GL_UNSIGNED_BYTE, pixels); // SDL_Log("(%i, %i, %i) (%i, %i, %i, %i)", // glCheckFramebufferStatus(GL_FRAMEBUFFER), // glCheckFramebufferStatus(GL_READ_FRAMEBUFFER), // glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER), // pixels[0], pixels[1], pixels[2], pixels[3]); } else { Uint32 format; #if SDL_BYTEORDER == SDL_BIG_ENDIAN format = SDL_PIXELFORMAT_ARGB8888; #else format = SDL_PIXELFORMAT_ABGR8888; #endif SDL_RenderReadPixels( get_root()->renderer, NULL, format, pixels, bpp / 8 * w); } } 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, get_root()->is_gl_context); delete[] pixels; return surface; } SDL_Surface* Display::get_screen_surface_from_pixels( unsigned char* pixels, bool flip) { glm::ivec2 size = get_window_size(); SDL_Surface* surface; Uint32 rmask, gmask, bmask, amask; #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif if (flip) { SDL_Surface* pixel_surface = SDL_CreateRGBSurfaceFrom( pixels, size.x, size.y, bpp, bpp / 8 * size.x, rmask, gmask, bmask, amask); surface = zoomSurface(pixel_surface, 1, -1, SMOOTHING_OFF); SDL_FreeSurface(pixel_surface); } else { surface = SDL_CreateRGBSurface(0, size.x, size.y, bpp, rmask, gmask, bmask, amask); std::memcpy(surface->pixels, pixels, bpp / 8 * size.x * size.y); } return surface; } void Display::respond(SDL_Event& event) { if (get_delegate().compare(event, "fullscreen")) { toggle_fullscreen(); } } void Display::toggle_fullscreen() { if (SDL_GetWindowFlags(get_root()->get_window()) & SDL_WINDOW_FULLSCREEN) { SDL_Log("fullscreen requested"); SDL_SetWindowFullscreen(get_root()->window, 0); } else { SDL_Log("exit fullscreen requested"); SDL_SetWindowFullscreen(get_root()->get_window(), SDL_WINDOW_FULLSCREEN); } }