diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c
index f23753ee53ff4ef65833cd3c661b80391e45526a..867a86a1504325523190caf7fc1d0c2547294298 100644
--- a/src/hardware/hw_draw.c
+++ b/src/hardware/hw_draw.c
@@ -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
diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h
index a5ac82001084f5bf755c6025b1bbcfdccb40432d..ab40256977c42a38b05d2c220f12529ca0bc322d 100644
--- a/src/hardware/hw_drv.h
+++ b/src/hardware/hw_drv.h
@@ -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
diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c
index 9eb013a132e9c5d2e9970b6e85d0803c5a06bb3d..fb8555aa9afefb94f3dbea7f8e02180ee1b15399 100644
--- a/src/hardware/r_opengl/r_opengl.c
+++ b/src/hardware/r_opengl/r_opengl.c
@@ -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
diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c
index 05ac6450e2267c0c08182775cece05eeaefabeab..33bcfd6f34b523f0fa329215e5feed310c19b8e8 100644
--- a/src/sdl/hwsym_sdl.c
+++ b/src/sdl/hwsym_sdl.c
@@ -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);
diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c
index 87ce84158ed90afe61d422dd3b8bffa817a6677b..2df8a6ff53fccf869af02adbca28843b3a02731a 100644
--- a/src/sdl/i_video.c
+++ b/src/sdl/i_video.c
@@ -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);
diff --git a/src/sdl12/hwsym_sdl.c b/src/sdl12/hwsym_sdl.c
index 49340138f46bc5a98223f8895fd175b18ccad18d..3a10d8253848e1b8e5c1c78c193ec5c62c6de160 100644
--- a/src/sdl12/hwsym_sdl.c
+++ b/src/sdl12/hwsym_sdl.c
@@ -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);
diff --git a/src/sdl12/i_video.c b/src/sdl12/i_video.c
index 349e06cbab345d3ca064bf1e6ce169b669706a77..076ce4fd29b7271246f716cd40ad743c926c9c48 100644
--- a/src/sdl12/i_video.c
+++ b/src/sdl12/i_video.c
@@ -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);