mirror of
https://github.com/dhewm/dhewm3.git
synced 2025-02-07 17:01:21 +00:00
HighDPI support, hopefully
This commit is contained in:
parent
28d81ed5f5
commit
5376c6d74c
6 changed files with 84 additions and 16 deletions
|
@ -1,5 +1,7 @@
|
||||||
#ifndef IMGUI_DISABLE
|
#ifndef IMGUI_DISABLE
|
||||||
|
|
||||||
|
#include <SDL.h> // to show display size
|
||||||
|
|
||||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
@ -1833,6 +1835,22 @@ static void DrawVideoOptionsMenu()
|
||||||
AddTooltip( "r_customWidth / r_customHeight" );
|
AddTooltip( "r_customWidth / r_customHeight" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int sdlDisplayIdx = SDL_GetWindowDisplayIndex( SDL_GL_GetCurrentWindow() );
|
||||||
|
SDL_Rect displayRect = {};
|
||||||
|
SDL_GetDisplayBounds( sdlDisplayIdx, &displayRect );
|
||||||
|
if ( (int)glConfig.winWidth != glConfig.vidWidth ) {
|
||||||
|
ImGui::TextDisabled( "Current Resolution: %g x %g (Physical: %d x %d)",
|
||||||
|
glConfig.winWidth, glConfig.winHeight, glConfig.vidWidth, glConfig.vidHeight );
|
||||||
|
AddDescrTooltip( "Apparently your system is using a HighDPI mode, where the logical resolution (used to specify"
|
||||||
|
" window sizes) is lower than the physical resolution (number of pixels actually rendered)." );
|
||||||
|
float scale = float(glConfig.vidWidth)/glConfig.winWidth;
|
||||||
|
int pw = scale * displayRect.w;
|
||||||
|
int ph = scale * displayRect.h;
|
||||||
|
ImGui::TextDisabled( "Display Size: %d x %d (Physical: %d x %d)", displayRect.w, displayRect.h, pw, ph );
|
||||||
|
} else {
|
||||||
|
ImGui::TextDisabled( "Current Resolution: %d x %d", glConfig.vidWidth, glConfig.vidHeight );
|
||||||
|
ImGui::TextDisabled( "Display Size: %d x %d", displayRect.w, displayRect.h );
|
||||||
|
}
|
||||||
|
|
||||||
static const char* msaaLevels[] = { "No Antialiasing", "2x", "4x", "8x", "16x" };
|
static const char* msaaLevels[] = { "No Antialiasing", "2x", "4x", "8x", "16x" };
|
||||||
const char* curLvl = msaaLevels[msaaModeIndex];
|
const char* curLvl = msaaLevels[msaaModeIndex];
|
||||||
|
|
|
@ -79,6 +79,7 @@ typedef struct glconfig_s {
|
||||||
bool textureNonPowerOfTwoAvailable;
|
bool textureNonPowerOfTwoAvailable;
|
||||||
bool depthBoundsTestAvailable;
|
bool depthBoundsTestAvailable;
|
||||||
|
|
||||||
|
// GL framebuffer size, see also winWidth and winHeight
|
||||||
int vidWidth, vidHeight; // passed to R_BeginFrame
|
int vidWidth, vidHeight; // passed to R_BeginFrame
|
||||||
|
|
||||||
int displayFrequency;
|
int displayFrequency;
|
||||||
|
@ -92,6 +93,23 @@ typedef struct glconfig_s {
|
||||||
// DG: current video backend is known to need opaque default framebuffer
|
// DG: current video backend is known to need opaque default framebuffer
|
||||||
// used if r_fillWindowAlphaChan == -1
|
// used if r_fillWindowAlphaChan == -1
|
||||||
bool shouldFillWindowAlpha;
|
bool shouldFillWindowAlpha;
|
||||||
|
|
||||||
|
// For some reason people decided that we need displays with ultra small pixels,
|
||||||
|
// so everything rendered on them must be scaled up to be legible.
|
||||||
|
// unfortunately, this bullshit feature was "improved" upon by deciding that the best
|
||||||
|
// way to implement "High DPI" was to pretend that windows have fewer pixels than they
|
||||||
|
// actually do, so the window size you get and mouse coordinates in them etc
|
||||||
|
// are in e.g. 1024x768, while the physical window size is e.g. 1536x1152 pixels
|
||||||
|
// (when the scaling factor is 1.5), and ideally the GL framebuffer has the physical
|
||||||
|
// window size so things still look crisp.
|
||||||
|
// Of course the reasonable solution would be to go back and time and nuke Cupertino,
|
||||||
|
// where this nonsense scheme was invented, but as I lack the necessary funds,
|
||||||
|
// I reluctantly add winWidth and winHeight and adjust the code that deals with window
|
||||||
|
// coordinates, as far as that's possible..
|
||||||
|
// (Isn't it fun that you have a 2256x1504 display, tell SDL to create a 1920x1080 window
|
||||||
|
// and you get one that's much bigger and doesn't fit on the screen?)
|
||||||
|
|
||||||
|
float winWidth, winHeight; // logical window size (different to vidWidth/height in HighDPI cases)
|
||||||
} glconfig_t;
|
} glconfig_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -171,7 +189,11 @@ public:
|
||||||
virtual bool IsOpenGLRunning( void ) const = 0;
|
virtual bool IsOpenGLRunning( void ) const = 0;
|
||||||
|
|
||||||
virtual bool IsFullScreen( void ) const = 0;
|
virtual bool IsFullScreen( void ) const = 0;
|
||||||
|
// NOTE: this is the physical width of the GL drawable (framebuffer) in pixels,
|
||||||
|
// *not* the logical window size (in case of HighDPI that's not the same!)
|
||||||
virtual int GetScreenWidth( void ) const = 0;
|
virtual int GetScreenWidth( void ) const = 0;
|
||||||
|
// NOTE: this is the physical height of the GL drawable (framebuffer) in pixels,
|
||||||
|
// *not* the logical window size (in case of HighDPI that's not the same!)
|
||||||
virtual int GetScreenHeight( void ) const = 0;
|
virtual int GetScreenHeight( void ) const = 0;
|
||||||
|
|
||||||
// allocate a renderWorld to be used for drawing
|
// allocate a renderWorld to be used for drawing
|
||||||
|
|
|
@ -1914,6 +1914,10 @@ static void GfxInfo_f( const idCmdArgs &args ) {
|
||||||
"fullscreen"
|
"fullscreen"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char* fsmode = fsstrings[r_fullscreen.GetBool()];
|
||||||
|
if ( r_fullscreen.GetBool() && r_fullscreenDesktop.GetBool() )
|
||||||
|
fsmode = "desktop-fullscreen";
|
||||||
|
|
||||||
common->Printf( "\nGL_VENDOR: %s\n", glConfig.vendor_string );
|
common->Printf( "\nGL_VENDOR: %s\n", glConfig.vendor_string );
|
||||||
common->Printf( "GL_RENDERER: %s\n", glConfig.renderer_string );
|
common->Printf( "GL_RENDERER: %s\n", glConfig.renderer_string );
|
||||||
common->Printf( "GL_VERSION: %s\n", glConfig.version_string );
|
common->Printf( "GL_VERSION: %s\n", glConfig.version_string );
|
||||||
|
@ -1923,13 +1927,14 @@ static void GfxInfo_f( const idCmdArgs &args ) {
|
||||||
common->Printf( "GL_MAX_TEXTURE_COORDS_ARB: %d\n", glConfig.maxTextureCoords );
|
common->Printf( "GL_MAX_TEXTURE_COORDS_ARB: %d\n", glConfig.maxTextureCoords );
|
||||||
common->Printf( "GL_MAX_TEXTURE_IMAGE_UNITS_ARB: %d\n", glConfig.maxTextureImageUnits );
|
common->Printf( "GL_MAX_TEXTURE_IMAGE_UNITS_ARB: %d\n", glConfig.maxTextureImageUnits );
|
||||||
common->Printf( "\nPIXELFORMAT: color(%d-bits) Z(%d-bit) stencil(%d-bits)\n", glConfig.colorBits, glConfig.depthBits, glConfig.stencilBits );
|
common->Printf( "\nPIXELFORMAT: color(%d-bits) Z(%d-bit) stencil(%d-bits)\n", glConfig.colorBits, glConfig.depthBits, glConfig.stencilBits );
|
||||||
common->Printf( "MODE: %d, %d x %d %s hz:", r_mode.GetInteger(), glConfig.vidWidth, glConfig.vidHeight, fsstrings[r_fullscreen.GetBool()] );
|
common->Printf( "MODE: %d, %d x %d %s hz:", r_mode.GetInteger(), glConfig.vidWidth, glConfig.vidHeight, fsmode );
|
||||||
|
|
||||||
if ( glConfig.displayFrequency ) {
|
if ( glConfig.displayFrequency ) {
|
||||||
common->Printf( "%d\n", glConfig.displayFrequency );
|
common->Printf( "%d\n", glConfig.displayFrequency );
|
||||||
} else {
|
} else {
|
||||||
common->Printf( "N/A\n" );
|
common->Printf( "N/A\n" );
|
||||||
}
|
}
|
||||||
|
common->Printf( "Logical Window size: %g x %g\n", glConfig.winWidth, glConfig.winHeight );
|
||||||
|
|
||||||
const char *active[2] = { "", " (ACTIVE)" };
|
const char *active[2] = { "", " (ACTIVE)" };
|
||||||
|
|
||||||
|
@ -2033,8 +2038,8 @@ void R_VidRestart_f( const idCmdArgs &args ) {
|
||||||
globalImages->ReloadAllImages();
|
globalImages->ReloadAllImages();
|
||||||
} else {
|
} else {
|
||||||
glimpParms_t parms;
|
glimpParms_t parms;
|
||||||
parms.width = glConfig.vidWidth;
|
parms.width = glConfig.winWidth; // DG: HighDPI adjustment: explicitly use window size
|
||||||
parms.height = glConfig.vidHeight;
|
parms.height = glConfig.winHeight;
|
||||||
parms.fullScreen = ( forceWindow ) ? false : r_fullscreen.GetBool();
|
parms.fullScreen = ( forceWindow ) ? false : r_fullscreen.GetBool();
|
||||||
parms.displayHz = r_displayRefresh.GetInteger();
|
parms.displayHz = r_displayRefresh.GetInteger();
|
||||||
parms.multiSamples = r_multiSamples.GetInteger();
|
parms.multiSamples = r_multiSamples.GetInteger();
|
||||||
|
|
|
@ -165,6 +165,8 @@ bool GLimp_Init(glimpParms_t parms) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
|
flags |= SDL_WINDOW_ALLOW_HIGHDPI;
|
||||||
|
|
||||||
/* Doom3 has the nasty habit of modifying the default framebuffer's alpha channel and then
|
/* Doom3 has the nasty habit of modifying the default framebuffer's alpha channel and then
|
||||||
* relying on those modifications in blending operations (using GL_DST_(ONE_MINUS_)ALPHA).
|
* relying on those modifications in blending operations (using GL_DST_(ONE_MINUS_)ALPHA).
|
||||||
* So far that hasn't been much of a problem, because Windows, macOS, X11 etc
|
* So far that hasn't been much of a problem, because Windows, macOS, X11 etc
|
||||||
|
@ -272,14 +274,14 @@ try_again:
|
||||||
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
|
|
||||||
const char* windowMode = "";
|
if ( r_fullscreen.GetBool() && r_fullscreenDesktop.GetBool() ) {
|
||||||
if(r_fullscreen.GetBool()) {
|
common->Printf( "Will create a pseudo-fullscreen window at the current desktop resolution\n" );
|
||||||
windowMode = r_fullscreenDesktop.GetBool() ? "desktop-fullscreen-" : "fullscreen-";
|
} else {
|
||||||
|
const char* windowMode = r_fullscreen.GetBool() ? "fullscreen-" : "";
|
||||||
|
common->Printf("Will create a %swindow with resolution %dx%d (r_mode = %d)\n",
|
||||||
|
windowMode, parms.width, parms.height, r_mode.GetInteger());
|
||||||
}
|
}
|
||||||
|
|
||||||
common->Printf("Will create a %swindow with resolution %dx%d (r_mode = %d)\n",
|
|
||||||
windowMode, parms.width, parms.height, r_mode.GetInteger());
|
|
||||||
|
|
||||||
int displayIndex = 0;
|
int displayIndex = 0;
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 4)
|
#if SDL_VERSION_ATLEAST(2, 0, 4)
|
||||||
// try to put the window on the display the mousecursor currently is on
|
// try to put the window on the display the mousecursor currently is on
|
||||||
|
@ -407,11 +409,23 @@ try_again:
|
||||||
GLimp_SetSwapInterval( r_swapInterval.GetInteger() );
|
GLimp_SetSwapInterval( r_swapInterval.GetInteger() );
|
||||||
r_swapInterval.ClearModified();
|
r_swapInterval.ClearModified();
|
||||||
|
|
||||||
SDL_GetWindowSize(window, &glConfig.vidWidth, &glConfig.vidHeight);
|
// for HighDPI, window size and drawable size can differ
|
||||||
|
int ww=0, wh=0;
|
||||||
|
SDL_GetWindowSize(window, &ww, &wh);
|
||||||
|
glConfig.winWidth = ww;
|
||||||
|
glConfig.winHeight = wh;
|
||||||
|
SDL_GL_GetDrawableSize(window, &glConfig.vidWidth, &glConfig.vidHeight);
|
||||||
|
|
||||||
SetSDLIcon(); // for SDL2 this must be done after creating the window
|
SetSDLIcon(); // for SDL2 this must be done after creating the window
|
||||||
|
|
||||||
glConfig.isFullscreen = (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN;
|
glConfig.isFullscreen = (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN;
|
||||||
|
const char* fsStr = glConfig.isFullscreen ? "fullscreen " : "";
|
||||||
|
if ( ww != glConfig.vidWidth ) {
|
||||||
|
common->Printf( "Got a HighDPI %swindow with physical resolution %d x %d and virtual resolution %d x %d\n",
|
||||||
|
fsStr, glConfig.vidWidth, glConfig.vidHeight, ww, wh );
|
||||||
|
} else {
|
||||||
|
common->Printf( "Got a %swindow with resolution %d x %d\n", fsStr, ww, wh );
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
SDL_WM_SetCaption(ENGINE_VERSION, ENGINE_VERSION);
|
SDL_WM_SetCaption(ENGINE_VERSION, ENGINE_VERSION);
|
||||||
|
|
||||||
|
|
|
@ -187,6 +187,11 @@ static float GetDefaultDPI()
|
||||||
|
|
||||||
static float GetDefaultScale()
|
static float GetDefaultScale()
|
||||||
{
|
{
|
||||||
|
if ( glConfig.winWidth != glConfig.vidWidth ) {
|
||||||
|
// in HighDPI mode, the font sizes are already scaled (to window coordinates), apparently
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
// TODO: different reference DPI on mac? also, doesn't work that well on my laptop..
|
||||||
float ret = GetDefaultDPI() / 96.0f;
|
float ret = GetDefaultDPI() / 96.0f;
|
||||||
ret = round(ret*2.0)*0.5; // round to .0 or .5
|
ret = round(ret*2.0)*0.5; // round to .0 or .5
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -464,8 +469,8 @@ bool ShouldShowCursor()
|
||||||
// in a black bar (Doom3 cursor is not drawn there), show the ImGui cursor
|
// in a black bar (Doom3 cursor is not drawn there), show the ImGui cursor
|
||||||
if ( r_scaleMenusTo43.GetBool() ) {
|
if ( r_scaleMenusTo43.GetBool() ) {
|
||||||
ImVec2 mousePos = ImGui::GetMousePos();
|
ImVec2 mousePos = ImGui::GetMousePos();
|
||||||
float w = renderSystem->GetScreenWidth();
|
float w = glConfig.winWidth;
|
||||||
float h = renderSystem->GetScreenHeight();
|
float h = glConfig.winHeight;
|
||||||
float aspectRatio = w/h;
|
float aspectRatio = w/h;
|
||||||
static const float virtualAspectRatio = float(VIRTUAL_WIDTH)/float(VIRTUAL_HEIGHT); // 4:3 = 1.333
|
static const float virtualAspectRatio = float(VIRTUAL_WIDTH)/float(VIRTUAL_HEIGHT); // 4:3 = 1.333
|
||||||
if(aspectRatio > 1.4f) {
|
if(aspectRatio > 1.4f) {
|
||||||
|
|
|
@ -36,6 +36,8 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
|
|
||||||
#include "ui/UserInterfaceLocal.h"
|
#include "ui/UserInterfaceLocal.h"
|
||||||
|
|
||||||
|
#include "renderer/tr_local.h" // glConfig for winWidth/winHeight
|
||||||
|
|
||||||
extern idCVar r_skipGuiShaders; // 1 = don't render any gui elements on surfaces
|
extern idCVar r_skipGuiShaders; // 1 = don't render any gui elements on surfaces
|
||||||
extern idCVar r_scaleMenusTo43; // DG: for the "scale menus to 4:3" hack
|
extern idCVar r_scaleMenusTo43; // DG: for the "scale menus to 4:3" hack
|
||||||
|
|
||||||
|
@ -355,12 +357,14 @@ const char *idUserInterfaceLocal::HandleEvent( const sysEvent_t *event, int _tim
|
||||||
// DG: this is a fullscreen GUI, scale the mousedelta added to cursorX/Y
|
// DG: this is a fullscreen GUI, scale the mousedelta added to cursorX/Y
|
||||||
// by 640/w, because the GUI pretends that everything is 640x480
|
// by 640/w, because the GUI pretends that everything is 640x480
|
||||||
// even if the actual resolution is higher => mouse moved too fast
|
// even if the actual resolution is higher => mouse moved too fast
|
||||||
float w = renderSystem->GetScreenWidth();
|
float w = glConfig.winWidth;
|
||||||
float h = renderSystem->GetScreenHeight();
|
float h = glConfig.winHeight;
|
||||||
if( w <= 0.0f || h <= 0.0f ) {
|
if( w <= 0.0f || h <= 0.0f ) {
|
||||||
w = VIRTUAL_WIDTH;
|
w = VIRTUAL_WIDTH;
|
||||||
h = VIRTUAL_HEIGHT;
|
h = VIRTUAL_HEIGHT;
|
||||||
}
|
}
|
||||||
|
const float realW = w;
|
||||||
|
const float realH = h;
|
||||||
|
|
||||||
if(r_scaleMenusTo43.GetBool()) {
|
if(r_scaleMenusTo43.GetBool()) {
|
||||||
// in case we're scaling menus to 4:3, we need to take that into account
|
// in case we're scaling menus to 4:3, we need to take that into account
|
||||||
|
@ -387,8 +391,8 @@ const char *idUserInterfaceLocal::HandleEvent( const sysEvent_t *event, int _tim
|
||||||
// Note: In case of scaling to 4:3, w and h are already scaled down
|
// Note: In case of scaling to 4:3, w and h are already scaled down
|
||||||
// to the 4:3 size that fits into the real resolution.
|
// to the 4:3 size that fits into the real resolution.
|
||||||
// Otherwise xOffset/yOffset will just be 0
|
// Otherwise xOffset/yOffset will just be 0
|
||||||
float xOffset = (renderSystem->GetScreenWidth() - w) * 0.5f;
|
float xOffset = (realW - w) * 0.5f;
|
||||||
float yOffset = (renderSystem->GetScreenHeight() - h) * 0.5f;
|
float yOffset = (realH - h) * 0.5f;
|
||||||
// offset the mouse coordinates into 4:3 area and scale down to 640x480
|
// offset the mouse coordinates into 4:3 area and scale down to 640x480
|
||||||
// yes, result could be negative, doesn't matter, code below checks that anyway
|
// yes, result could be negative, doesn't matter, code below checks that anyway
|
||||||
cursorX = (event->evValue - xOffset) * (float(VIRTUAL_WIDTH)/w);
|
cursorX = (event->evValue - xOffset) * (float(VIRTUAL_WIDTH)/w);
|
||||||
|
|
Loading…
Reference in a new issue