126 lines
3.5 KiB
C++
126 lines
3.5 KiB
C++
#include "Display.hpp"
|
|
#include "Game.hpp"
|
|
|
|
Display::Display(Node* parent) : Node(parent)
|
|
{
|
|
get_delegate().subscribe(&Display::respond, this);
|
|
}
|
|
|
|
glm::ivec2 Display::get_window_size() const
|
|
{
|
|
glm::ivec2 size;
|
|
SDL_GetWindowSize(const_cast<SDL_Window*>(get_window()), &size.x, &size.y);
|
|
return size;
|
|
}
|
|
|
|
Box Display::get_window_box() const
|
|
{
|
|
return Box(glm::vec2(0, 0), get_window_size());
|
|
}
|
|
|
|
Uint32 Display::get_pixel_format(int display_index) const
|
|
{
|
|
SDL_DisplayMode display_mode;
|
|
if (SDL_GetCurrentDisplayMode(display_index, &display_mode) != 0)
|
|
{
|
|
SDL_Log("could not get display mode for index %i: %s", display_index, SDL_GetError());
|
|
return SDL_PIXELFORMAT_UNKNOWN;
|
|
}
|
|
else
|
|
{
|
|
return display_mode.format;
|
|
}
|
|
}
|
|
|
|
void Display::get_screen_pixels(unsigned char* pixels, int w, int h, int x, int y) const
|
|
{
|
|
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
|
|
{
|
|
SDL_Renderer* renderer = const_cast<SDL_Renderer*>(get_renderer());
|
|
SDL_SetRenderTarget(renderer, nullptr);
|
|
SDL_RenderPresent(renderer);
|
|
SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_RGBA32, pixels, bpp / 8 * w);
|
|
}
|
|
}
|
|
|
|
SDL_Surface* Display::get_screen_surface() const
|
|
{
|
|
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) const
|
|
{
|
|
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() const
|
|
{
|
|
SDL_Window* window = const_cast<SDL_Window*>(get_window());
|
|
if (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN)
|
|
{
|
|
SDL_Log("fullscreen requested");
|
|
SDL_SetWindowFullscreen(window, 0);
|
|
}
|
|
else
|
|
{
|
|
SDL_Log("exit fullscreen requested");
|
|
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
|
|
}
|
|
}
|