From d8484a86e04705e3bfce104b7df687499f962423 Mon Sep 17 00:00:00 2001 From: Ronald Kinard Date: Thu, 13 Nov 2014 18:06:38 -0600 Subject: [PATCH] Virtual resolutions in OpenGL Also made fades use core functions if they are available. --- src/hardware/hw_drv.h | 4 ++ src/hardware/hw_main.c | 10 +++ src/hardware/hw_main.h | 2 + src/hardware/r_opengl/r_opengl.c | 112 ++++++++++++++++++++++++++++++- src/sdl/hwsym_sdl.c | 2 + src/sdl/i_video.c | 26 ++----- src/sdl/ogl_sdl.c | 9 +++ src/sdl/ogl_sdl.h | 2 + 8 files changed, 142 insertions(+), 25 deletions(-) diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 76fce5e4..e0c2f327 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 0ae24585..04175d50 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 96994644..af7d821b 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 631bb665..6b37a666 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 44ddf830..54f5da3a 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 566fb5b9..433ce17f 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 6cbecaf3..ba7e6517 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 72f130a5..7e144644 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);