mirror of https://github.com/OpenRCT2/OpenRCT2.git
implement OpenGL screenshot
This commit is contained in:
parent
b0b0b82fd1
commit
db01547ae6
|
@ -47,6 +47,7 @@ IDrawingEngine * DrawingEngineFactory::CreateOpenGL()
|
|||
extern "C"
|
||||
{
|
||||
#include "../../../config.h"
|
||||
#include "../../../interface/screenshot.h"
|
||||
#include "../../../interface/window.h"
|
||||
#include "../../../intro.h"
|
||||
#include "../../drawing.h"
|
||||
|
@ -328,8 +329,11 @@ public:
|
|||
|
||||
sint32 Screenshot() override
|
||||
{
|
||||
// Not implemented
|
||||
return -1;
|
||||
_canvasFramebuffer->Bind();
|
||||
void * pixels = _canvasFramebuffer->GetPixels();
|
||||
int result = screenshot_dump_png_32bpp(_width, _height, pixels);
|
||||
Memory::Free(pixels);
|
||||
return result;
|
||||
}
|
||||
|
||||
void CopyRect(sint32 x, sint32 y, sint32 width, sint32 height, sint32 dx, sint32 dy) override
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#pragma endregion
|
||||
|
||||
#include <SDL_video.h>
|
||||
#include "../../../core/Memory.hpp"
|
||||
#include "OpenGLFramebuffer.h"
|
||||
|
||||
constexpr GLuint BACKBUFFER_ID = 0;
|
||||
|
@ -56,3 +57,24 @@ void OpenGLFramebuffer::Bind()
|
|||
glBindFramebuffer(GL_FRAMEBUFFER, _id);
|
||||
glViewport(0, 0, (GLsizei)_width, (GLsizei)_height);
|
||||
}
|
||||
|
||||
void * OpenGLFramebuffer::GetPixels() const
|
||||
{
|
||||
void * pixels = Memory::Allocate<void>(_width * _height * 4);
|
||||
glReadPixels(0, 0, _width, _height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
// Flip pixels vertically
|
||||
void * flippedPixels = Memory::Allocate<void>(_width * _height * 4);
|
||||
size_t stride = _width * 4;
|
||||
uint8 * src = (uint8 *)pixels + ((_height - 1) * stride);
|
||||
uint8 * dst = (uint8 *)flippedPixels;
|
||||
for (sint32 y = 0; y < _height; y++)
|
||||
{
|
||||
Memory::Copy(dst, src, stride);
|
||||
src -= stride;
|
||||
dst += stride;
|
||||
}
|
||||
Memory::Free(pixels);
|
||||
|
||||
return flippedPixels;
|
||||
}
|
||||
|
|
|
@ -39,4 +39,5 @@ public:
|
|||
GLuint GetTexture() const { return _texture; }
|
||||
|
||||
void Bind();
|
||||
void * GetPixels() const;
|
||||
};
|
||||
|
|
|
@ -171,6 +171,67 @@ bool image_io_png_write(const rct_drawpixelinfo *dpi, const rct_palette *palette
|
|||
return true;
|
||||
}
|
||||
|
||||
static void image_io_png_warning(png_structp png_ptr, const char *b)
|
||||
{
|
||||
log_warning(b);
|
||||
}
|
||||
|
||||
static void image_io_png_error(png_structp png_ptr, const char *b)
|
||||
{
|
||||
log_error(b);
|
||||
}
|
||||
|
||||
bool image_io_png_write_32bpp(sint32 width, sint32 height, const void *pixels, const utf8 *path)
|
||||
{
|
||||
// Setup PNG
|
||||
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, image_io_png_error, image_io_png_warning);
|
||||
if (png_ptr == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
if (info_ptr == NULL) {
|
||||
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Open file for writing
|
||||
SDL_RWops *file = SDL_RWFromFile(path, "wb");
|
||||
if (file == NULL) {
|
||||
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
|
||||
return false;
|
||||
}
|
||||
png_set_write_fn(png_ptr, file, my_png_write_data, my_png_flush);
|
||||
|
||||
// Set error handler
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
SDL_RWclose(file);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write header
|
||||
png_set_IHDR(
|
||||
png_ptr, info_ptr, width, height, 8,
|
||||
PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT
|
||||
);
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
|
||||
// Write pixels
|
||||
uint8 *bits = (uint8*)pixels;
|
||||
for (int y = 0; y < height; y++) {
|
||||
png_write_row(png_ptr, (png_byte *)bits);
|
||||
bits += width * 4;
|
||||
}
|
||||
|
||||
// Finish
|
||||
png_write_end(png_ptr, NULL);
|
||||
SDL_RWclose(file);
|
||||
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void my_png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
SDL_RWops *file = (SDL_RWops*)png_get_io_ptr(png_ptr);
|
||||
|
|
|
@ -23,5 +23,6 @@
|
|||
bool image_io_png_read(uint8 **pixels, uint32 *width, uint32 *height, const utf8 *path);
|
||||
|
||||
bool image_io_png_write(const rct_drawpixelinfo *dpi, const rct_palette *palette, const utf8 *path);
|
||||
bool image_io_png_write_32bpp(sint32 width, sint32 height, const void *pixels, const utf8 *path);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -115,6 +115,22 @@ int screenshot_dump_png(rct_drawpixelinfo *dpi)
|
|||
}
|
||||
}
|
||||
|
||||
int screenshot_dump_png_32bpp(sint32 width, sint32 height, const void *pixels)
|
||||
{
|
||||
// Get a free screenshot path
|
||||
int index;
|
||||
char path[MAX_PATH] = "";
|
||||
if ((index = screenshot_get_next_path(path)) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (image_io_png_write_32bpp(width, height, pixels, path)) {
|
||||
return index;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void screenshot_giant()
|
||||
{
|
||||
int originalRotation = get_current_rotation();
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
void screenshot_check();
|
||||
int screenshot_dump();
|
||||
int screenshot_dump_png(rct_drawpixelinfo *dpi);
|
||||
int screenshot_dump_png_32bpp(sint32 width, sint32 height, const void *pixels);
|
||||
|
||||
void screenshot_giant();
|
||||
int cmdline_for_screenshot(const char **argv, int argc);
|
||||
|
|
Loading…
Reference in New Issue