diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h
index 76fce5e475172bdf3fe39577ff83f696434f5aee..e0c2f32735cb8d2fbc451031e1e6ae7b4a74d9fd 100644
--- a/src/hardware/hw_drv.h
+++ b/src/hardware/hw_drv.h
@@ -84,6 +84,8 @@ EXPORT void HWRAPI(EndScreenWipe) (void);
 EXPORT void HWRAPI(DoScreenWipe) (float alpha);
 EXPORT void HWRAPI(DrawIntermissionBG) (void);
 EXPORT void HWRAPI(MakeScreenTexture) (void);
+EXPORT void HWRAPI(MakeScreenFinalTexture) (void);
+EXPORT void HWRAPI(DrawScreenFinalTexture) (int width, int height);
 // ==========================================================================
 //                                      HWR DRIVER OBJECT, FOR CLIENT PROGRAM
 // ==========================================================================
@@ -127,6 +129,8 @@ struct hwdriver_s
 	DoScreenWipe        pfnDoScreenWipe;
 	DrawIntermissionBG  pfnDrawIntermissionBG;
 	MakeScreenTexture   pfnMakeScreenTexture;
+	MakeScreenFinalTexture  pfnMakeScreenFinalTexture;
+	DrawScreenFinalTexture  pfnDrawScreenFinalTexture;
 };
 
 extern struct hwdriver_s hwdriver;
diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index 0ae245855c84e56771d605644b3563c8fff00006..04175d50496827f3f0940ecefe9e3fd1d8625842 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -5936,4 +5936,14 @@ void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum)
 		HWRWipeCounter = 1.0f;
 }
 
+void HWR_MakeScreenFinalTexture(void)
+{
+    HWD.pfnMakeScreenFinalTexture();
+}
+
+void HWR_DrawScreenFinalTexture(int width, int height)
+{
+    HWD.pfnDrawScreenFinalTexture(width, height);
+}
+
 #endif // HWRENDER
diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h
index 969946442d1e67ca55db6fde5e238ab5411459db..af7d821b1ac437632a062db460e09edffc2038bb 100644
--- a/src/hardware/hw_main.h
+++ b/src/hardware/hw_main.h
@@ -65,6 +65,8 @@ void HWR_StartScreenWipe(void);
 void HWR_EndScreenWipe(void);
 void HWR_DrawIntermissionBG(void);
 void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum);
+void HWR_MakeScreenFinalTexture(void);
+void HWR_DrawScreenFinalTexture(int width, int height);
 
 // This stuff is put here so MD2's can use them
 UINT32 HWR_Lighting(INT32 light, UINT32 color, UINT32 fadecolor, boolean fogblockpoly, boolean plane);
diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c
index 631bb66586fed9106a50d043de1bae43009f100f..6b37a66630dd543c2a323fbc831c1d1334c1c0fc 100644
--- a/src/hardware/r_opengl/r_opengl.c
+++ b/src/hardware/r_opengl/r_opengl.c
@@ -110,6 +110,7 @@ static GLint       viewport[4];
 static GLuint screentexture = 60000;
 static GLuint startScreenWipe = 60001;
 static GLuint endScreenWipe = 60002;
+static GLuint finalScreenTexture = 60003;
 #if 0
 GLuint screentexture = FIRST_TEX_AVAIL;
 #endif
@@ -269,8 +270,8 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...)
 #endif
 #ifndef MINI_GL_COMPATIBILITY
 /* 1.3 functions for multitexturing */
-#define pglActiveTexture, glActiveTexture;
-#define pglMultiTexCoord2f, glMultiTexCoord2f;
+#define pglActiveTexture glActiveTexture
+#define pglMultiTexCoord2f glMultiTexCoord2f
 #endif
 #else //!STATIC_OPENGL
 
@@ -520,13 +521,40 @@ boolean SetupGLfunc(void)
 // This has to be done after the context is created so the version number can be obtained
 boolean SetupGLFunc13(void)
 {
+	const GLubyte *version = pglGetString(GL_VERSION);
+	int glmajor, glminor;
+
+	gl13 = false;
 #ifdef MINI_GL_COMPATIBILITY
 	return false;
 #else
 #ifdef STATIC_OPENGL
 	gl13 = true;
 #else
-	if (isExtAvailable("GL_ARB_multitexture", gl_extensions))
+
+	// Parse the GL version
+	if (version != NULL)
+	{
+		if (sscanf(version, "%d.%d", &glmajor, &glminor) == 2)
+		{
+			// Look, we gotta prepare for the inevitable arrival of GL 2.0 code...
+			switch (glmajor)
+			{
+				case 1:
+					if (glminor == 3) gl13 = true;
+					break;
+				default:
+					break;
+			}
+		}
+	}
+
+	if (gl13)
+	{
+		pglActiveTexture = GetGLFunc("glActiveTexture");
+		pglMultiTexCoord2f = GetGLFunc("glMultiTexCoord2f");
+	}
+	else if (isExtAvailable("GL_ARB_multitexture", gl_extensions))
 	{
 		// Get the functions
 		pglActiveTexture  = GetGLFunc("glActiveTextureARB");
@@ -2245,6 +2273,7 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha)
 		pglActiveTexture(GL_TEXTURE0);
 		pglEnable(GL_TEXTURE_2D);
 		pglBindTexture(GL_TEXTURE_2D, endScreenWipe);
+		pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
 
 		pglActiveTexture(GL_TEXTURE1);
 		pglEnable(GL_TEXTURE_2D);
@@ -2339,4 +2368,81 @@ EXPORT void HWRAPI(MakeScreenTexture) (void)
 	tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now
 }
 
+EXPORT void HWRAPI(MakeScreenFinalTexture) (void)
+{
+	INT32 texsize = 2048;
+
+	// Use a power of two texture, dammit
+	if(screen_width <= 512)
+		texsize = 512;
+	else if(screen_width <= 1024)
+		texsize = 1024;
+
+	// Create screen texture
+	pglBindTexture(GL_TEXTURE_2D, finalScreenTexture);
+#ifdef KOS_GL_COMPATIBILITY
+	pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE);
+	pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE);
+#else
+	pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+#endif
+	Clamp2D(GL_TEXTURE_WRAP_S);
+	Clamp2D(GL_TEXTURE_WRAP_T);
+#ifndef KOS_GL_COMPATIBILITY
+	pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, texsize, texsize, 0);
+#endif
+
+	tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now
+
+}
+
+EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height)
+{
+	float xfix, yfix;
+	int lmaxx, lmaxy;
+	INT32 texsize = 2048;
+
+	lmaxx = width < screen_width ? screen_width : width;
+	lmaxy = height < screen_height ? screen_height : height;
+
+	if(screen_width <= 1024)
+		texsize = 1024;
+	if(screen_width <= 512)
+		texsize = 512;
+
+	xfix = 1/((float)(texsize)/((float)((screen_width))));
+	yfix = 1/((float)(texsize)/((float)((screen_height))));
+
+	//pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+	pglViewport(0, 0, width, height);
+
+	pglBindTexture(GL_TEXTURE_2D, finalScreenTexture);
+	pglBegin(GL_QUADS);
+
+		pglColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+		// Bottom left
+		pglTexCoord2f(0.0f, 0.0f);
+		pglVertex3f(-1, -1, 1.0f);
+
+		// Top left
+		pglTexCoord2f(0.0f, yfix);
+		pglVertex3f(-1, 1, 1.0f);
+
+		// Top right
+		pglTexCoord2f(xfix, yfix);
+		pglVertex3f(1, 1, 1.0f);
+
+		// Bottom right
+		pglTexCoord2f(xfix, 0.0f);
+		pglVertex3f(1, -1, 1.0f);
+
+	pglEnd();
+
+	SetModelView(screen_width, screen_height);
+	SetStates();
+
+	tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now
+}
+
 #endif //HWRENDER
diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c
index 44ddf830ca43f4eafc8049c31089b7ecb2a6d1cd..54f5da3a083da6d9b3b9159b059389cbc7bc8271 100644
--- a/src/sdl/hwsym_sdl.c
+++ b/src/sdl/hwsym_sdl.c
@@ -105,6 +105,8 @@ void *hwSym(const char *funcName,void *handle)
 	GETFUNC(DoScreenWipe);
 	GETFUNC(DrawIntermissionBG);
 	GETFUNC(MakeScreenTexture);
+	GETFUNC(MakeScreenFinalTexture);
+	GETFUNC(DrawScreenFinalTexture);
 #else //HWRENDER
 	if (0 == strcmp("FinishUpdate", funcName))
 		return funcPointer; //&FinishUpdate;
diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c
index 566fb5b961412edd6d45eeb673f336d908635df8..433ce17f751bcc23b535f6ccfcd56d9bc355678b 100644
--- a/src/sdl/i_video.c
+++ b/src/sdl/i_video.c
@@ -124,8 +124,8 @@ static      SDL_Color    localPalette[256];
 static      SDL_Rect   **modeList = NULL;
 static       Uint8       BitsPerPixel = 16;
 #endif
-static       Uint16      realwidth = BASEVIDWIDTH;
-static       Uint16      realheight = BASEVIDHEIGHT;
+Uint16      realwidth = BASEVIDWIDTH;
+Uint16      realheight = BASEVIDHEIGHT;
 static const Uint32      surfaceFlagsW = 0/*|SDL_RESIZABLE*/;
 static const Uint32      surfaceFlagsF = 0;
 static       SDL_bool    mousegrabok = SDL_TRUE;
@@ -221,26 +221,6 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
 
 	if (rendermode == render_opengl)
 	{
-		int sdlw, sdlh;
-		SDL_GetWindowSize(window, &sdlw, &sdlh);
-		// Logical fullscreen is not implemented yet for OpenGL, so...
-		// Special case handling
-		if (glfallbackresolution == SDL_FALSE && fullscreen && width != sdlw && height != sdlh)
-		{
-			if (VID_GetModeForSize(sdlw, sdlh) != -1)
-			{
-				wasfullscreen = SDL_TRUE;
-				VID_SetMode(VID_GetModeForSize(sdlw, sdlh));
-				return;
-			}
-			else
-			{
-				wasfullscreen = SDL_TRUE;
-				glfallbackresolution = SDL_TRUE;
-				VID_SetMode(-1);
-				return;
-			}
-		}
 		OglSdlSurface(vid.width, vid.height);
 	}
 
@@ -1779,6 +1759,8 @@ void I_StartupGraphics(void)
 		HWD.pfnDoScreenWipe     = hwSym("DoScreenWipe",NULL);
 		HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL);
 		HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL);
+		HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL);
+		HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL);
 		// check gl renderer lib
 		if (HWD.pfnGetRenderVersion() != VERSION)
 			I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n"));
diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c
index 6cbecaf3c87937b9b3911ba6759f8fc2a4f7d5a0..ba7e6517652b1d766c51a27c3136b570f16aef2d 100644
--- a/src/sdl/ogl_sdl.c
+++ b/src/sdl/ogl_sdl.c
@@ -201,13 +201,22 @@ boolean OglSdlSurface(INT32 w, INT32 h)
 void OglSdlFinishUpdate(boolean waitvbl)
 {
 	static boolean oldwaitvbl = false;
+	int sdlw, sdlh;
 	if (oldwaitvbl != waitvbl)
 	{
 		SDL_GL_SetSwapInterval(waitvbl ? 1 : 0);
 	}
+
 	oldwaitvbl = waitvbl;
 
+	SDL_GetWindowSize(window, &sdlw, &sdlh);
+
+	HWR_MakeScreenFinalTexture();
+	HWR_DrawScreenFinalTexture(sdlw, sdlh);
 	SDL_GL_SwapWindow(window);
+
+	SetModelView(realwidth, realheight);
+	SetStates();
 }
 
 EXPORT void HWRAPI( OglSdlSetPalette) (RGBA_t *palette, RGBA_t *pgamma)
diff --git a/src/sdl/ogl_sdl.h b/src/sdl/ogl_sdl.h
index 72f130a52ef0c0f3bfe39b9eb5271404941529b3..7e144644ce325d7c18b1d0916ad3fdae3f384421 100644
--- a/src/sdl/ogl_sdl.h
+++ b/src/sdl/ogl_sdl.h
@@ -27,6 +27,8 @@ void OglSdlFinishUpdate(boolean vidwait);
 extern SDL_Window *window;
 extern SDL_Renderer *renderer;
 extern SDL_GLContext sdlglcontext;
+extern Uint16      realwidth;
+extern Uint16      realheight;
 
 #ifdef _CREATE_DLL_
 EXPORT void HWRAPI( OglSdlSetPalette ) (RGBA_t *palette, RGBA_t *pgamma);