Fix screenshot functionality in fullscreen in SDL2

This commit is contained in:
Sryder 2018-03-08 22:28:38 +00:00
parent 77af3a8f95
commit 121fcd8369
7 changed files with 103 additions and 0 deletions

View file

@ -769,6 +769,9 @@ UINT8 *HWR_GetScreenshot(void)
if (!buf)
return NULL;
// returns 24bit 888 RGB
#ifdef HAVE_SDL
if (!HWD.pfnReadScreenTexture(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf))
#endif
HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf);
return buf;
}
@ -782,8 +785,19 @@ boolean HWR_Screenshot(const char *lbmname)
return false;
// returns 24bit 888 RGB
#ifdef HAVE_SDL
// Sryder: SDL2 uses borderless fullscreen mode, and creates a screen texture to upscale to the screen size.
// This breaks screenshots because the code here takes a screenshot of just the resolution from the bottom
// left corner, while the "true" resolution is the monitor resolution. We can either take a screenshot of
// the true resolution or just use the already made screen texture
// NOTE: The SDL1.2 version should get a return of false from ReadScreenTexture as no screen texture will have
// been made, this will also mean that if the screen texture doesn't exist for some reason it will fall
// back to the old version
if (!HWD.pfnReadScreenTexture(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf))
#endif
HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf);
#ifdef USE_PNG
ret = M_SavePNG(lbmname, buf, vid.width, vid.height, NULL);
#else

View file

@ -58,6 +58,9 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags);
EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor);
EXPORT void HWRAPI(SetTexture) (FTextureInfo *TexInfo);
EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 *dst_data);
#ifdef HAVE_SDL
EXPORT boolean HWRAPI(ReadScreenTexture) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 * dst_data);
#endif
EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip);
EXPORT void HWRAPI(ClearMipMapCache) (void);
@ -104,6 +107,9 @@ struct hwdriver_s
ClearBuffer pfnClearBuffer;
SetTexture pfnSetTexture;
ReadRect pfnReadRect;
#ifdef HAVE_SDL
ReadScreenTexture pfnReadScreenTexture;
#endif
GClipRect pfnGClipRect;
ClearMipMapCache pfnClearMipMapCache;
SetSpecialState pfnSetSpecialState;//Hurdler: added for backward compatibility

View file

@ -260,6 +260,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...)
#define pglTexEnvi glTexEnvi
#define pglTexParameteri glTexParameteri
#define pglTexImage2D glTexImage2D
#define pglGetTexImage glGetTexImage
/* Fog */
#define pglFogf glFogf
@ -381,6 +382,8 @@ typedef void (APIENTRY * PFNglTexParameteri) (GLenum target, GLenum pname, GLint
static PFNglTexParameteri pglTexParameteri;
typedef void (APIENTRY * PFNglTexImage2D) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
static PFNglTexImage2D pglTexImage2D;
typedef void (APIENTRY * PFNglGetTexImage) (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
static PFNglGetTexImage pglGetTexImage;
/* Fog */
typedef void (APIENTRY * PFNglFogf) (GLenum pname, GLfloat param);
@ -507,6 +510,7 @@ boolean SetupGLfunc(void)
GETOPENGLFUNC(pglTexEnvi , glTexEnvi)
GETOPENGLFUNC(pglTexParameteri , glTexParameteri)
GETOPENGLFUNC(pglTexImage2D , glTexImage2D)
GETOPENGLFUNC(pglGetTexImage , glGetTexImage)
GETOPENGLFUNC(pglFogf , glFogf)
GETOPENGLFUNC(pglFogfv , glFogfv)
@ -933,6 +937,81 @@ EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height,
#endif
}
#ifdef HAVE_SDL
EXPORT boolean HWRAPI(ReadScreenTexture) (INT32 x, INT32 y, INT32 width,
INT32 height, INT32 dst_stride,
UINT16 * dst_data)
{
#ifdef KOS_GL_COMPATIBILITY
(void)x;
(void)y;
(void)width;
(void)height;
(void)dst_stride;
(void)dst_data;
#else
INT32 i, j;
INT32 texsize = 2048;
GLubyte *image;
// DBG_Printf ("ReadScreenTexture()\n");
if (screentexture == 0)
return false; // No screen texture
if(screen_width <= 1024)
texsize = 1024;
if(screen_width <= 512)
texsize = 512;
if (x < 0)
x = 0;
if (x + width > screen_width)
width = screen_width - x;
if (y < 0)
y = 0;
if (y + height > screen_height)
height = screen_height - y;
image = malloc(texsize*texsize*3*sizeof (*image));
if (!image)
return false;
pglBindTexture(GL_TEXTURE_2D, finalScreenTexture);
tex_downloaded = finalScreenTexture;
pglGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
if (dst_stride == width*3)
{
UINT8 *dest = (void *)dst_data;
for (i = y + height-1; i >= y; i--)
{
for (j = x; j < width + x; j++)
{
dest[((height-1-i-y)*width+j-x)*3] = image[(i*texsize+j)*3];
dest[((height-1-i-y)*width+j-x)*3+1] = image[(i*texsize+j)*3+1];
dest[((height-1-i-y)*width+j-x)*3+2] = image[(i*texsize+j)*3+2];
}
}
}
else
{
// Sryder: NOTE: I'm not entirely sure this works, as far as I know nothing in the game uses it.
for (i = y + height-1; i >= y; i--)
{
for (j = x; j < width + x; j++)
{
dst_data[(height-1-i-y)*width+j-x] =
(UINT16)(
((image[(i*texsize+j)*3]>>3)<<11) |
((image[(i*texsize+j)*3+1]>>2)<<5) |
((image[(i*texsize+j)*3+2]>>3)));
}
}
}
free(image);
return true;
#endif
}
#endif
// -----------------+
// GClipRect : Defines the 2D hardware clipping window

View file

@ -83,6 +83,7 @@ void *hwSym(const char *funcName,void *handle)
GETFUNC(ClearBuffer);
GETFUNC(SetTexture);
GETFUNC(ReadRect);
GETFUNC(ReadScreenTexture);
GETFUNC(GClipRect);
GETFUNC(ClearMipMapCache);
GETFUNC(SetSpecialState);

View file

@ -1430,6 +1430,7 @@ void I_StartupGraphics(void)
HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL);
HWD.pfnSetTexture = hwSym("SetTexture",NULL);
HWD.pfnReadRect = hwSym("ReadRect",NULL);
HWD.pfnReadScreenTexture= hwSym("ReadScreenTexture",NULL);
HWD.pfnGClipRect = hwSym("GClipRect",NULL);
HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL);
HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL);

View file

@ -89,6 +89,7 @@ void *hwSym(const char *funcName,void *handle)
GETFUNC(ClearBuffer);
GETFUNC(SetTexture);
GETFUNC(ReadRect);
GETFUNC(ReadScreenTexture);
GETFUNC(GClipRect);
GETFUNC(ClearMipMapCache);
GETFUNC(SetSpecialState);

View file

@ -1960,6 +1960,7 @@ void I_StartupGraphics(void)
HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL);
HWD.pfnSetTexture = hwSym("SetTexture",NULL);
HWD.pfnReadRect = hwSym("ReadRect",NULL);
HWD.pfnReadScreenTexture= hwSym("ReadScreenTexture",NULL);
HWD.pfnGClipRect = hwSym("GClipRect",NULL);
HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL);
HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL);