Skip to content

Commit

Permalink
Changed screenshot capturing method
Browse files Browse the repository at this point in the history
Now it's just reading the entire screen and doing all conversions on the GPU instead of just reading texture and processing it manually.
  • Loading branch information
ata4 committed Mar 6, 2018
1 parent 46b4059 commit 6af5b4c
Show file tree
Hide file tree
Showing 7 changed files with 23 additions and 55 deletions.
2 changes: 1 addition & 1 deletion core/screen.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
void screen_init(struct rdp_config* config);
void screen_swap(bool blank);
void screen_write(struct rdp_frame_buffer* fb, int32_t output_height);
void screen_read(struct rdp_frame_buffer* fb);
void screen_read(struct rdp_frame_buffer* fb, bool rgb);
void screen_set_fullscreen(bool fullscreen);
bool screen_get_fullscreen(void);
void screen_toggle_fullscreen(void);
Expand Down
34 changes: 10 additions & 24 deletions plugin-common/gl_screen.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,33 +184,19 @@ bool gl_screen_write(struct rdp_frame_buffer* fb, int32_t output_height)
return buffer_size_changed;
}

void gl_screen_read(struct rdp_frame_buffer* fb)
void gl_screen_read(struct rdp_frame_buffer* fb, bool rgb)
{
fb->width = tex_width;
fb->height = tex_display_height;
fb->pitch = tex_width;
GLint vp[4];
glGetIntegerv(GL_VIEWPORT, vp);

if (!fb->pixels) {
return;
}

// check if resampling is required
if (tex_display_height == tex_height) {
// size matches, direct copy
glGetTexImage(GL_TEXTURE_2D, 0, TEX_FORMAT, TEX_TYPE, (void*)fb->pixels);
} else {
// do nearest-neighbor resampling
int32_t* tex_buffer = malloc(tex_width * tex_display_height * sizeof(int32_t));
glGetTexImage(GL_TEXTURE_2D, 0, TEX_FORMAT, TEX_TYPE, tex_buffer);

for (int32_t y = 0; y < tex_display_height; y++) {
int32_t iy = y * tex_height / tex_display_height;
uint32_t os = tex_width * iy;
uint32_t od = tex_width * y;
memcpy(fb->pixels + od, tex_buffer + os, tex_width * sizeof(int32_t));
}
fb->width = vp[2];
fb->height = vp[3];
fb->pitch = fb->width;

free(tex_buffer);
if (fb->pixels) {
GLenum format = rgb ? GL_RGB : TEX_FORMAT;
GLenum type = rgb ? GL_UNSIGNED_BYTE : TEX_TYPE;
glReadPixels(vp[0], vp[1], vp[2], vp[3], format, type, fb->pixels);
}
}

Expand Down
2 changes: 1 addition & 1 deletion plugin-common/gl_screen.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@

void gl_screen_init(struct rdp_config* config);
bool gl_screen_write(struct rdp_frame_buffer* fb, int32_t output_height);
void gl_screen_read(struct rdp_frame_buffer* fb);
void gl_screen_read(struct rdp_frame_buffer* fb, bool rgb);
void gl_screen_render(int32_t win_width, int32_t win_height, int32_t win_x, int32_t win_y);
void gl_screen_close(void);
24 changes: 4 additions & 20 deletions plugin-mupen64plus/gfx_m64p.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,31 +224,15 @@ EXPORT void CALL ChangeWindow(void)
EXPORT void CALL ReadScreen2(void *dest, int *width, int *height, int front)
{
struct rdp_frame_buffer fb = { 0 };
screen_read(&fb);
screen_read(&fb, true);

*width = fb.width;
*height = fb.height;

if (!dest) {
return;
if (dest) {
fb.pixels = dest;
screen_read(&fb, true);
}

// convert BGRA to RGB and also flip image vertically
fb.pixels = malloc(fb.width * fb.height * sizeof(int32_t));
screen_read(&fb);

uint8_t* pdst = (uint8_t*)dest;
for (int32_t y = fb.height - 1; y >= 0; y--) {
uint8_t* psrc = (uint8_t*)(fb.pixels + y * fb.width);
for (int32_t x = 0; x < (int32_t)fb.width; x++) {
*pdst++ = psrc[2];
*pdst++ = psrc[1];
*pdst++ = psrc[0];
psrc += 4;
}
}

free(fb.pixels);
}

EXPORT void CALL SetRenderingCallback(void (*callback)(int))
Expand Down
4 changes: 2 additions & 2 deletions plugin-mupen64plus/screen.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ void screen_write(struct rdp_frame_buffer* buffer, int32_t output_height)
gl_screen_write(buffer, output_height);
}

void screen_read(struct rdp_frame_buffer* buffer)
void screen_read(struct rdp_frame_buffer* buffer, bool rgb)
{
gl_screen_read(buffer);
gl_screen_read(buffer, rgb);
}

void screen_set_fullscreen(bool _fullscreen)
Expand Down
8 changes: 3 additions & 5 deletions plugin-zilmar/gfx_1.3.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ GFX_INFO gfx;
static void write_screenshot(char* path)
{
struct rdp_frame_buffer fb = { 0 };
screen_read(&fb);
screen_read(&fb, false);

// prepare bitmap headers
BITMAPINFOHEADER ihdr = {0};
Expand Down Expand Up @@ -50,10 +50,8 @@ static void write_screenshot(char* path)
fseek(fp, fhdr.bfOffBits, SEEK_SET);

fb.pixels = malloc(ihdr.biSizeImage);
screen_read(&fb);
for (int32_t y = fb.height - 1; y >= 0; y--) {
fwrite(fb.pixels + fb.width * y, fb.width * sizeof(*fb.pixels), 1, fp);
}
screen_read(&fb, false);
fwrite(fb.pixels, ihdr.biSizeImage, 1, fp);
free(fb.pixels);

fclose(fp);
Expand Down
4 changes: 2 additions & 2 deletions plugin-zilmar/screen.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,9 @@ void screen_write(struct rdp_frame_buffer* buffer, int32_t output_height)
gl_screen_write(buffer, output_height);
}

void screen_read(struct rdp_frame_buffer* buffer)
void screen_read(struct rdp_frame_buffer* buffer, bool rgb)
{
gl_screen_read(buffer);
gl_screen_read(buffer, rgb);
}

void screen_swap(bool blank)
Expand Down

0 comments on commit 6af5b4c

Please sign in to comment.