From 964879bc5e2ed2b97475dac366788fabf0ae825e Mon Sep 17 00:00:00 2001 From: myT Date: Wed, 22 Nov 2017 18:26:26 +0100 Subject: [PATCH] changed r_mode and added r_blitMode --- changelog.txt | 12 +++++++++++ code/linux/sdl_glimp.cpp | 16 +++++---------- code/renderer/tr_gl2.cpp | 36 +++++++++++++++++++++++++++++--- code/renderer/tr_help.h | 20 +++++++++++++----- code/renderer/tr_init.cpp | 43 +++++++++++++++++++++++++++++---------- code/renderer/tr_local.h | 22 +++++++++++++++++--- code/win32/win_glimp.cpp | 40 ++++++++++++++++-------------------- 7 files changed, 134 insertions(+), 55 deletions(-) diff --git a/changelog.txt b/changelog.txt index f0e9456..5fad7f5 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,18 @@ DD Mmm 17 - 1.49 +chg: r_mode selects the video mode + r_mode 0 (default) = no screen mode change, desktop resolution + r_mode 1 = no screen mode change, custom resolution, custom upscale mode + r_mode 2 = screen mode change, custom resolution (for the CRT users) + Custom resolution means using r_width and r_height. + Custom upscale mode means using r_blitMode. + +add: r_blitMode selects the upscale mode used by r_mode 1 + r_blitMode 0 (default) = aspect-ratio preserving (black bars if necessary) + r_blitMode 1 = no scaling, centered + r_blitMode 2 = full-screen stretching (no black bars) + add: cvar_trim command to remove all user-created cvars add: with compatible mods, drop and disconnect errors will be displayed in the UI diff --git a/code/linux/sdl_glimp.cpp b/code/linux/sdl_glimp.cpp index 65b13f7..18834a6 100644 --- a/code/linux/sdl_glimp.cpp +++ b/code/linux/sdl_glimp.cpp @@ -151,20 +151,14 @@ void Sys_GL_Init() SDL_Rect deskropRect; sdl_GetSafeDesktopRect(&deskropRect); - - const qbool desktopRes = !R_GetModeInfo(&glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect); - if (desktopRes) { - glConfig.vidWidth = deskropRect.w; - glConfig.vidHeight = deskropRect.h; - glConfig.windowAspect = (float)glConfig.vidWidth / (float)glConfig.vidHeight; - } + R_ConfigureVideoMode(deskropRect.w, deskropRect.h); Uint32 windowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN; - if (r_fullscreen->integer) { - if (desktopRes) - windowFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP; - else + if (glInfo.winFullscreen) { + if (glInfo.vidFullscreen) windowFlags |= SDL_WINDOW_FULLSCREEN; + else + windowFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP; } // @TODO: make a cvar defaulting to an empty string for this? e.g. value: "libGL.so.1" diff --git a/code/renderer/tr_gl2.cpp b/code/renderer/tr_gl2.cpp index 1689dc7..b83eeb6 100644 --- a/code/renderer/tr_gl2.cpp +++ b/code/renderer/tr_gl2.cpp @@ -572,15 +572,43 @@ static void GL2_FBO_Swap() static void GL2_FBO_BlitSSToBackBuffer() { + // fixing up the blit mode here to avoid unnecessary qglClear calls + int blitMode = r_blitMode->integer; + if ( r_mode->integer != VIDEOMODE_UPSCALE ) + blitMode = BLITMODE_STRETCHED; + + if ( blitMode != BLITMODE_STRETCHED ) { + qglBindFramebuffer( GL_FRAMEBUFFER, 0 ); + qglClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); + qglClear( GL_COLOR_BUFFER_BIT ); + } + const FrameBuffer& fbo = frameBuffersPostProcess[frameBufferReadIndex]; qglBindFramebuffer( GL_READ_FRAMEBUFFER, fbo.fbo ); qglBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 ); qglReadBuffer( GL_COLOR_ATTACHMENT0 ); qglDrawBuffer( GL_BACK ); - const int w = glConfig.vidWidth; - const int h = glConfig.vidHeight; - qglBlitFramebuffer( 0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_LINEAR ); + const int sw = glConfig.vidWidth; + const int sh = glConfig.vidHeight; + const int dw = glInfo.winWidth; + const int dh = glInfo.winHeight; + if ( blitMode == BLITMODE_STRETCHED ) { + qglBlitFramebuffer( 0, 0, sw, sh, 0, 0, dw, dh, GL_COLOR_BUFFER_BIT, GL_LINEAR ); + } else if ( blitMode == BLITMODE_CENTERED ) { + const int dx = ( dw - sw ) / 2; + const int dy = ( dh - sh ) / 2; + qglBlitFramebuffer( 0, 0, sw, sh, dx, dy, dx + sw, dy + sh, GL_COLOR_BUFFER_BIT, GL_LINEAR ); + } else { // blitMode == BLITMODE_ASPECT + const float rx = (float)dw / (float)sw; + const float ry = (float)dh / (float)sh; + const float ar = min( rx, ry ); + const int w = (int)( sw * ar ); + const int h = (int)( sh * ar ); + const int x = ( dw - w ) / 2; + const int y = ( dh - h ) / 2; + qglBlitFramebuffer( 0, 0, sw, sh, x, y, x + w, y + h, GL_COLOR_BUFFER_BIT, GL_LINEAR ); + } } @@ -778,6 +806,8 @@ void GL2_EndFrame() // we disable depth test, depth write and blending GL_State( GLS_DEPTHTEST_DISABLE ); + qglScissor( 0, 0, glInfo.winWidth, glInfo.winHeight ); + GL2_PostProcessGamma(); GL2_PostProcessGreyscale(); diff --git a/code/renderer/tr_help.h b/code/renderer/tr_help.h index b099ffa..697159c 100644 --- a/code/renderer/tr_help.h +++ b/code/renderer/tr_help.h @@ -29,12 +29,22 @@ " 2 = 4x" #define help_r_mode \ -"enables custom resolution for r_fullscreen 1\n" \ -" 0 = desktop resolution\n" \ -" 1 = custom resolution (r_width x r_height)" +"video mode to use when r_fullscreen is 1\n" \ +" 0 = no video mode change, desktop resolution\n" \ +" 1 = no video mode change, custom resolution, custom upscaling\n" \ +" 2 = video mode change, custom resolution\n" \ +"Custom resolutions use r_width and r_height.\n" \ +"Custom upscaling uses r_blitMode." -#define help_r_mode0 \ -"\nOnly used when r_mode is 0 and r_fullscreen is 1." +#define help_r_blitMode \ +"image upscaling mode for r_mode 1\n" \ +"This will only be active when r_fullscreen is 1 and r_mode is 1.\n" \ +" 0 = aspect-ratio preserving upscale (black bars if necessary)\n" \ +" 1 = no scaling, centered\n" \ +" 2 = full-screen stretching (no black bars)" + +#define help_r_mode01 \ +"\nOnly used when r_mode is 0 or 1 and r_fullscreen is 1." #define help_r_subdivisions \ "tessellation step size for patch surfaces\n" \ diff --git a/code/renderer/tr_init.cpp b/code/renderer/tr_init.cpp index 94e1ee3..2be5907 100644 --- a/code/renderer/tr_init.cpp +++ b/code/renderer/tr_init.cpp @@ -71,6 +71,7 @@ cvar_t *r_ignoreGLErrors; cvar_t *r_vertexLight; cvar_t *r_uiFullScreen; cvar_t *r_mode; +cvar_t *r_blitMode; cvar_t *r_nobind; cvar_t *r_singleShader; cvar_t *r_roundImagesDown; @@ -280,15 +281,34 @@ void GL_CheckErrors() } -qbool R_GetModeInfo(int* width, int* height, float* aspect) +void R_ConfigureVideoMode( int desktopWidth, int desktopHeight ) { - if (r_fullscreen->integer && !r_mode->integer) - return qfalse; + glInfo.winFullscreen = !!r_fullscreen->integer; + glInfo.vidFullscreen = r_fullscreen->integer && r_mode->integer == VIDEOMODE_CHANGE; - *width = r_width->integer; - *height = r_height->integer; - *aspect = r_customaspect->value; - return qtrue; + if (r_fullscreen->integer && r_mode->integer == VIDEOMODE_DESKTOPRES) { + glConfig.vidWidth = desktopWidth; + glConfig.vidHeight = desktopHeight; + glConfig.windowAspect = (float)glConfig.vidWidth / (float)glConfig.vidHeight; + glInfo.winWidth = desktopWidth; + glInfo.winHeight = desktopHeight; + return; + } + + if (r_fullscreen->integer && r_mode->integer == VIDEOMODE_UPSCALE) { + glConfig.vidWidth = r_width->integer; + glConfig.vidHeight = r_height->integer; + glConfig.windowAspect = (float)glConfig.vidWidth / (float)glConfig.vidHeight; + glInfo.winWidth = desktopWidth; + glInfo.winHeight = desktopHeight; + return; + } + + glConfig.vidWidth = r_width->integer; + glConfig.vidHeight = r_height->integer; + glConfig.windowAspect = (float)glConfig.vidWidth / (float)glConfig.vidHeight; + glInfo.winWidth = r_width->integer; + glInfo.winHeight = r_height->integer; } @@ -517,11 +537,12 @@ static const cvarTableItem_t r_cvars[] = { &r_colorMipLevels, "r_colorMipLevels", "0", CVAR_LATCH, CVART_BOOL, NULL, NULL, "colorizes textures based on their mip level" }, { &r_detailTextures, "r_detailtextures", "1", CVAR_ARCHIVE | CVAR_LATCH, CVART_BOOL, NULL, NULL, "enables detail textures shader stages" }, { &r_overBrightBits, "r_overBrightBits", "1", CVAR_ARCHIVE | CVAR_LATCH, CVART_INTEGER, "0", "2", help_r_overBrightBits }, - { &r_mode, "r_mode", "0", CVAR_ARCHIVE | CVAR_LATCH, CVART_BOOL, NULL, NULL, help_r_mode }, + { &r_mode, "r_mode", "0", CVAR_ARCHIVE | CVAR_LATCH, CVART_INTEGER, "0", XSTRING(VIDEOMODE_MAX), help_r_mode }, + { &r_blitMode, "r_blitMode", "0", CVAR_ARCHIVE, CVART_INTEGER, "0", XSTRING(BLITMODE_MAX), help_r_blitMode }, { &r_fullscreen, "r_fullscreen", "1", CVAR_ARCHIVE | CVAR_LATCH, CVART_BOOL, NULL, NULL, "full-screen mode" }, - { &r_width, "r_width", "1280", CVAR_ARCHIVE | CVAR_LATCH, CVART_INTEGER, "320", "65535", "custom window width" help_r_mode0 }, - { &r_height, "r_height", "720", CVAR_ARCHIVE | CVAR_LATCH, CVART_INTEGER, "240", "65535", "custom window height" help_r_mode0 }, - { &r_customaspect, "r_customaspect", "1", CVAR_ARCHIVE | CVAR_LATCH, CVART_INTEGER, "0.1", "10", "custom pixel aspect ratio" help_r_mode0 }, + { &r_width, "r_width", "1280", CVAR_ARCHIVE | CVAR_LATCH, CVART_INTEGER, "320", "65535", "custom window/render width" help_r_mode01 }, + { &r_height, "r_height", "720", CVAR_ARCHIVE | CVAR_LATCH, CVART_INTEGER, "240", "65535", "custom window/render height" help_r_mode01 }, + { &r_customaspect, "r_customaspect", "1", CVAR_ARCHIVE | CVAR_LATCH, CVART_INTEGER, "0.1", "10", "custom pixel aspect ratio" help_r_mode01 }, { &r_vertexLight, "r_vertexLight", "0", CVAR_ARCHIVE | CVAR_LATCH, CVART_BOOL, NULL, NULL, "disables lightmap texture blending" }, // note that r_subdivisions > 64 will create rendering artefacts because you'll see the other side of a curved surface when against it { &r_subdivisions, "r_subdivisions", "1", CVAR_ARCHIVE | CVAR_LATCH, CVART_FLOAT, "1", "64", help_r_subdivisions }, diff --git a/code/renderer/tr_local.h b/code/renderer/tr_local.h index 67807b5..004c958 100644 --- a/code/renderer/tr_local.h +++ b/code/renderer/tr_local.h @@ -923,6 +923,19 @@ extern glstate_t glState; // outside of TR since it shouldn't be cleared during // // cvars // + +// r_mode +#define VIDEOMODE_DESKTOPRES 0 // no mode change, render size = desktop size +#define VIDEOMODE_UPSCALE 1 // no mode change, render size < desktop size +#define VIDEOMODE_CHANGE 2 // mode change - only makes sense for CRT users +#define VIDEOMODE_MAX 2 + +// r_blitMode +#define BLITMODE_ASPECT 0 // aspect-ratio preserving stretch +#define BLITMODE_CENTERED 1 // no stretch, displayed at the center +#define BLITMODE_STRETCHED 2 // dumb stretch, takes the full screen +#define BLITMODE_MAX 2 + extern cvar_t *r_verbose; // used for verbose debug spew extern cvar_t *r_measureOverdraw; // enables stencil buffer overdraw measurement @@ -943,7 +956,8 @@ extern cvar_t *r_novis; // disable/enable usage of PVS extern cvar_t *r_nocull; extern cvar_t *r_nocurves; -extern cvar_t *r_mode; // video mode +extern cvar_t *r_mode; // see VIDEOMODE_* +extern cvar_t *r_blitMode; // see BLITMODE_* extern cvar_t *r_fullscreen; extern cvar_t *r_displayRefresh; // optional display refresh option @@ -1084,7 +1098,7 @@ qbool R_GetEntityToken( char *buffer, int size ); model_t* R_AllocModel(); void R_Init(); -qbool R_GetModeInfo( int* width, int* height, float* aspect ); +void R_ConfigureVideoMode( int desktopWidth, int desktopHeight ); // writes to glConfig and glInfo #define IMG_NOPICMIP 0x0001 // images that must never be downsampled #define IMG_NOMIPMAP 0x0002 // 2D elements that will never be "distant" - implies IMG_NOPICMIP @@ -1487,8 +1501,10 @@ extern glconfig_t glConfig; // the "private" glconfig: implementation specifics for the renderer struct glinfo_t { // used by platform layer - qbool isFullscreen; + qbool winFullscreen; // the window takes the entire screen + qbool vidFullscreen; // change the video mode int displayFrequency; + int winWidth, winHeight; // used by renderer GLint maxTextureSize; diff --git a/code/win32/win_glimp.cpp b/code/win32/win_glimp.cpp index 32dc34b..3d6c046 100644 --- a/code/win32/win_glimp.cpp +++ b/code/win32/win_glimp.cpp @@ -340,7 +340,7 @@ static qbool GLW_InitDriver() // responsible for creating the Win32 window and initializing the OpenGL driver. -static qbool GLW_CreateWindow( int width, int height ) +static qbool GLW_CreateWindow() { static qbool s_classRegistered = qfalse; @@ -377,13 +377,13 @@ static qbool GLW_CreateWindow( int width, int height ) RECT r; r.left = 0; r.top = 0; - r.right = width; - r.bottom = height; + r.right = glInfo.winWidth; + r.bottom = glInfo.winHeight; int style = WS_VISIBLE | WS_CLIPCHILDREN; int exstyle = 0; - if ( glInfo.isFullscreen ) + if ( glInfo.winFullscreen ) { style |= WS_POPUP; exstyle |= WS_EX_TOPMOST; @@ -402,7 +402,7 @@ static qbool GLW_CreateWindow( int width, int height ) int dx = 0; int dy = 0; - if ( !glInfo.isFullscreen ) + if ( !glInfo.winFullscreen ) { dx = ri.Cvar_Get( "vid_xpos", "0", 0 )->integer; dy = ri.Cvar_Get( "vid_ypos", "0", 0 )->integer; @@ -548,25 +548,21 @@ void WIN_SetDesktopDisplaySettings() } -static qbool GLW_SetMode( qbool cdsFullscreen ) +static qbool GLW_SetMode() { - glInfo.isFullscreen = cdsFullscreen; WIN_UpdateMonitorIndexFromCvar(); - if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect ) ) { - const RECT& monRect = g_wv.monitorRects[g_wv.monitor]; - glConfig.vidWidth = monRect.right - monRect.left; - glConfig.vidHeight = monRect.bottom - monRect.top; - glConfig.windowAspect = (float)glConfig.vidWidth / glConfig.vidHeight; - cdsFullscreen = qfalse; - } - //ri.Printf( PRINT_DEVELOPER, "...setting mode %dx%d %s\n", glConfig.vidWidth, glConfig.vidHeight, cdsFullscreen ? "FS" : "W" ); + + const RECT& monRect = g_wv.monitorRects[g_wv.monitor]; + const int desktopWidth = (int)(monRect.right - monRect.left); + const int desktopHeight = (int)(monRect.bottom - monRect.top); + R_ConfigureVideoMode( desktopWidth, desktopHeight ); DEVMODE dm; ZeroMemory( &dm, sizeof( dm ) ); dm.dmSize = sizeof( dm ); - if (cdsFullscreen != glw_state.cdsDevModeValid) { - if (cdsFullscreen) { + if (glInfo.vidFullscreen != glw_state.cdsDevModeValid) { + if (glInfo.vidFullscreen) { dm.dmPelsWidth = glConfig.vidWidth; dm.dmPelsHeight = glConfig.vidHeight; dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; @@ -584,7 +580,7 @@ static qbool GLW_SetMode( qbool cdsFullscreen ) dm.dmPosition.y = monRect.top; dm.dmFields |= DM_POSITION; - glInfo.isFullscreen = GLW_SetDisplaySettings( dm ); + glInfo.vidFullscreen = GLW_SetDisplaySettings( dm ); } else { @@ -592,7 +588,7 @@ static qbool GLW_SetMode( qbool cdsFullscreen ) } } - if (!GLW_CreateWindow( glConfig.vidWidth, glConfig.vidHeight )) + if (!GLW_CreateWindow()) return qfalse; if (EnumDisplaySettingsA( GLW_GetCurrentDisplayDeviceName(), ENUM_CURRENT_SETTINGS, &dm )) @@ -608,7 +604,7 @@ static qbool GLW_LoadOpenGL() // load the driver and bind our function pointers to it if ( WIN_LoadGL( "opengl32" ) ) { // create the window and set up the context - if ( GLW_SetMode( (qbool)!!r_fullscreen->integer ) ) { + if ( GLW_SetMode() ) { return qtrue; } } @@ -708,7 +704,7 @@ void Sys_GL_Shutdown() void WIN_UpdateResolution( int width, int height ) { - glConfig.vidWidth = width; - glConfig.vidHeight = height; + glInfo.winWidth = width; + glInfo.winHeight = height; }