mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 23:12:24 +00:00
Added ability to turn off hi-res backing surface rendering on Retina displays
High resolution backing surface is enabled by default and controlled via vid_hidpi CVAR When it is set to false one pixel per point scale is used
This commit is contained in:
parent
e60d181e87
commit
0fd84bc853
2 changed files with 111 additions and 51 deletions
|
@ -86,13 +86,15 @@
|
||||||
- (NSRect)convertRectToBacking:(NSRect)aRect;
|
- (NSRect)convertRectToBacking:(NSRect)aRect;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#endif // NSAppKitVersionNumber10_7
|
#endif // !NSAppKitVersionNumber10_7
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
RenderBufferOptions rbOpts;
|
RenderBufferOptions rbOpts;
|
||||||
|
|
||||||
|
EXTERN_CVAR(Bool, vid_hidpi)
|
||||||
|
|
||||||
CVAR(Bool, use_mouse, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
CVAR(Bool, use_mouse, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
CVAR(Bool, m_noprescale, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
CVAR(Bool, m_noprescale, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
CVAR(Bool, m_filter, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
CVAR(Bool, m_filter, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
|
@ -585,7 +587,7 @@ NSSize GetRealContentViewSize(const NSWindow* const window)
|
||||||
// TODO: figure out why [NSView frame] returns different values in "fullscreen" and in window
|
// TODO: figure out why [NSView frame] returns different values in "fullscreen" and in window
|
||||||
// In "fullscreen" the result is multiplied by [NSScreen backingScaleFactor], but not in window
|
// In "fullscreen" the result is multiplied by [NSScreen backingScaleFactor], but not in window
|
||||||
|
|
||||||
return (IsHiDPISupported() && NSNormalWindowLevel == [window level])
|
return (vid_hidpi && NSNormalWindowLevel == [window level])
|
||||||
? [view convertSizeToBacking:frameSize]
|
? [view convertSizeToBacking:frameSize]
|
||||||
: frameSize;
|
: frameSize;
|
||||||
}
|
}
|
||||||
|
@ -840,10 +842,16 @@ void ProcessMouseWheelEvent(NSEvent* theEvent)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
@private
|
@private
|
||||||
FullscreenWindow* m_window;
|
FullscreenWindow* m_window;
|
||||||
|
|
||||||
bool m_openGLInitialized;
|
|
||||||
int m_multisample;
|
int m_multisample;
|
||||||
|
|
||||||
|
int m_width;
|
||||||
|
int m_height;
|
||||||
|
bool m_fullscreen;
|
||||||
|
bool m_hiDPI;
|
||||||
|
|
||||||
|
bool m_openGLInitialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)init;
|
- (id)init;
|
||||||
|
@ -864,7 +872,8 @@ void ProcessMouseWheelEvent(NSEvent* theEvent)
|
||||||
- (int)multisample;
|
- (int)multisample;
|
||||||
- (void)setMultisample:(int)multisample;
|
- (void)setMultisample:(int)multisample;
|
||||||
|
|
||||||
- (void)changeVideoResolution:(bool)fullscreen width:(int)width height:(int)height;
|
- (void)changeVideoResolution:(bool)fullscreen width:(int)width height:(int)height useHiDPI:(bool)hiDPI;
|
||||||
|
- (void)useHiDPI:(bool)hiDPI;
|
||||||
|
|
||||||
- (void)processEvents:(NSTimer*)timer;
|
- (void)processEvents:(NSTimer*)timer;
|
||||||
|
|
||||||
|
@ -883,9 +892,15 @@ static ApplicationDelegate* s_applicationDelegate;
|
||||||
- (id)init
|
- (id)init
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
||||||
|
m_multisample = 0;
|
||||||
|
|
||||||
|
m_width = -1;
|
||||||
|
m_height = -1;
|
||||||
|
m_fullscreen = false;
|
||||||
|
m_hiDPI = false;
|
||||||
|
|
||||||
m_openGLInitialized = false;
|
m_openGLInitialized = false;
|
||||||
m_multisample = 0;
|
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -1052,35 +1067,30 @@ static ApplicationDelegate* s_applicationDelegate;
|
||||||
pixelFormat:pixelFormat];
|
pixelFormat:pixelFormat];
|
||||||
[[glView openGLContext] makeCurrentContext];
|
[[glView openGLContext] makeCurrentContext];
|
||||||
|
|
||||||
if (IsHiDPISupported())
|
|
||||||
{
|
|
||||||
[glView setWantsBestResolutionOpenGLSurface:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
[m_window setContentView:glView];
|
[m_window setContentView:glView];
|
||||||
|
|
||||||
m_openGLInitialized = true;
|
m_openGLInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)fullscreenWithWidth:(int)width height:(int)height
|
- (void)switchToFullscreen
|
||||||
{
|
{
|
||||||
NSScreen* screen = [m_window screen];
|
NSScreen* screen = [m_window screen];
|
||||||
|
|
||||||
const NSRect screenFrame = [screen frame];
|
const NSRect screenFrame = [screen frame];
|
||||||
const NSRect displayRect = IsHiDPISupported()
|
const NSRect displayRect = vid_hidpi
|
||||||
? [screen convertRectToBacking:screenFrame]
|
? [screen convertRectToBacking:screenFrame]
|
||||||
: screenFrame;
|
: screenFrame;
|
||||||
|
|
||||||
const float displayWidth = displayRect.size.width;
|
const float displayWidth = displayRect.size.width;
|
||||||
const float displayHeight = displayRect.size.height;
|
const float displayHeight = displayRect.size.height;
|
||||||
|
|
||||||
const float pixelScaleFactorX = displayWidth / static_cast< float >(width );
|
const float pixelScaleFactorX = displayWidth / static_cast<float>(m_width );
|
||||||
const float pixelScaleFactorY = displayHeight / static_cast< float >(height);
|
const float pixelScaleFactorY = displayHeight / static_cast<float>(m_height);
|
||||||
|
|
||||||
rbOpts.pixelScale = std::min(pixelScaleFactorX, pixelScaleFactorY);
|
rbOpts.pixelScale = std::min(pixelScaleFactorX, pixelScaleFactorY);
|
||||||
|
|
||||||
rbOpts.width = width * rbOpts.pixelScale;
|
rbOpts.width = m_width * rbOpts.pixelScale;
|
||||||
rbOpts.height = height * rbOpts.pixelScale;
|
rbOpts.height = m_height * rbOpts.pixelScale;
|
||||||
|
|
||||||
rbOpts.shiftX = (displayWidth - rbOpts.width ) / 2.0f;
|
rbOpts.shiftX = (displayWidth - rbOpts.width ) / 2.0f;
|
||||||
rbOpts.shiftY = (displayHeight - rbOpts.height) / 2.0f;
|
rbOpts.shiftY = (displayHeight - rbOpts.height) / 2.0f;
|
||||||
|
@ -1092,18 +1102,18 @@ static ApplicationDelegate* s_applicationDelegate;
|
||||||
[m_window setFrameOrigin:NSMakePoint(0.0f, 0.0f)];
|
[m_window setFrameOrigin:NSMakePoint(0.0f, 0.0f)];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)windowedWithWidth:(int)width height:(int)height
|
- (void)switchToWindowed
|
||||||
{
|
{
|
||||||
rbOpts.pixelScale = 1.0f;
|
rbOpts.pixelScale = 1.0f;
|
||||||
|
|
||||||
rbOpts.width = static_cast< float >(width );
|
rbOpts.width = static_cast<float>(m_width );
|
||||||
rbOpts.height = static_cast< float >(height);
|
rbOpts.height = static_cast<float>(m_height);
|
||||||
|
|
||||||
rbOpts.shiftX = 0.0f;
|
rbOpts.shiftX = 0.0f;
|
||||||
rbOpts.shiftY = 0.0f;
|
rbOpts.shiftY = 0.0f;
|
||||||
|
|
||||||
const NSSize windowPixelSize = NSMakeSize(width, height);
|
const NSSize windowPixelSize = NSMakeSize(m_width, m_height);
|
||||||
const NSSize windowSize = IsHiDPISupported()
|
const NSSize windowSize = vid_hidpi
|
||||||
? [[m_window contentView] convertSizeFromBacking:windowPixelSize]
|
? [[m_window contentView] convertSizeFromBacking:windowPixelSize]
|
||||||
: windowPixelSize;
|
: windowPixelSize;
|
||||||
|
|
||||||
|
@ -1114,19 +1124,40 @@ static ApplicationDelegate* s_applicationDelegate;
|
||||||
[m_window center];
|
[m_window center];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)changeVideoResolution:(bool)fullscreen width:(int)width height:(int)height
|
- (void)changeVideoResolution:(bool)fullscreen width:(int)width height:(int)height useHiDPI:(bool)hiDPI
|
||||||
{
|
{
|
||||||
[self initializeOpenGL];
|
if (fullscreen == m_fullscreen
|
||||||
|
&& width == m_width
|
||||||
if (fullscreen)
|
&& height == m_height
|
||||||
|
&& hiDPI == m_hiDPI)
|
||||||
{
|
{
|
||||||
[self fullscreenWithWidth:width height:height];
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_fullscreen = fullscreen;
|
||||||
|
m_width = width;
|
||||||
|
m_height = height;
|
||||||
|
m_hiDPI = hiDPI;
|
||||||
|
|
||||||
|
[self initializeOpenGL];
|
||||||
|
|
||||||
|
if (IsHiDPISupported())
|
||||||
|
{
|
||||||
|
NSOpenGLView* const glView = [m_window contentView];
|
||||||
|
[glView setWantsBestResolutionOpenGLSurface:m_hiDPI];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_fullscreen)
|
||||||
|
{
|
||||||
|
[self switchToFullscreen];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
[self windowedWithWidth:width height:height];
|
[self switchToWindowed];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rbOpts.dirty = true;
|
||||||
|
|
||||||
const NSSize viewSize = GetRealContentViewSize(m_window);
|
const NSSize viewSize = GetRealContentViewSize(m_window);
|
||||||
|
|
||||||
glViewport(0, 0, viewSize.width, viewSize.height);
|
glViewport(0, 0, viewSize.width, viewSize.height);
|
||||||
|
@ -1145,6 +1176,19 @@ static ApplicationDelegate* s_applicationDelegate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)useHiDPI:(bool)hiDPI
|
||||||
|
{
|
||||||
|
if (!m_openGLInitialized)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[self changeVideoResolution:m_fullscreen
|
||||||
|
width:m_width
|
||||||
|
height:m_height
|
||||||
|
useHiDPI:hiDPI];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
- (void)processEvents:(NSTimer*)timer
|
- (void)processEvents:(NSTimer*)timer
|
||||||
{
|
{
|
||||||
|
@ -1230,6 +1274,22 @@ static ApplicationDelegate* s_applicationDelegate;
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
CUSTOM_CVAR(Bool, vid_hidpi, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
|
{
|
||||||
|
if (IsHiDPISupported())
|
||||||
|
{
|
||||||
|
[s_applicationDelegate useHiDPI:self];
|
||||||
|
}
|
||||||
|
else if (0 != self)
|
||||||
|
{
|
||||||
|
self = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
void I_SetMainWindowVisible(bool visible)
|
void I_SetMainWindowVisible(bool visible)
|
||||||
{
|
{
|
||||||
[s_applicationDelegate setMainWindowVisible:visible];
|
[s_applicationDelegate setMainWindowVisible:visible];
|
||||||
|
@ -1508,7 +1568,10 @@ static SDL_PixelFormat* GetPixelFormat()
|
||||||
|
|
||||||
SDL_Surface* SDL_SetVideoMode(int width, int height, int, Uint32 flags)
|
SDL_Surface* SDL_SetVideoMode(int width, int height, int, Uint32 flags)
|
||||||
{
|
{
|
||||||
[s_applicationDelegate changeVideoResolution:(SDL_FULLSCREEN & flags) width:width height:height];
|
[s_applicationDelegate changeVideoResolution:(SDL_FULLSCREEN & flags)
|
||||||
|
width:width
|
||||||
|
height:height
|
||||||
|
useHiDPI:vid_hidpi];
|
||||||
|
|
||||||
static SDL_Surface result;
|
static SDL_Surface result;
|
||||||
|
|
||||||
|
@ -1554,21 +1617,6 @@ void SDL_WM_SetCaption(const char* title, const char* icon)
|
||||||
// Window title is set in SDL_SetVideoMode()
|
// Window title is set in SDL_SetVideoMode()
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ResetSoftwareViewport()
|
|
||||||
{
|
|
||||||
// For an unknown reason the following call to glClear() is needed
|
|
||||||
// to avoid drawing of garbage in fullscreen mode
|
|
||||||
// when game video resolution's aspect ratio is different from display one
|
|
||||||
|
|
||||||
GLint viewport[2];
|
|
||||||
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport);
|
|
||||||
|
|
||||||
glViewport(0, 0, viewport[0], viewport[1]);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
glViewport(rbOpts.shiftX, rbOpts.shiftY, rbOpts.width, rbOpts.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
int SDL_WM_ToggleFullScreen(SDL_Surface* surface)
|
int SDL_WM_ToggleFullScreen(SDL_Surface* surface)
|
||||||
{
|
{
|
||||||
if (surface->flags & SDL_FULLSCREEN)
|
if (surface->flags & SDL_FULLSCREEN)
|
||||||
|
@ -1582,8 +1630,8 @@ int SDL_WM_ToggleFullScreen(SDL_Surface* surface)
|
||||||
|
|
||||||
[s_applicationDelegate changeVideoResolution:(SDL_FULLSCREEN & surface->flags)
|
[s_applicationDelegate changeVideoResolution:(SDL_FULLSCREEN & surface->flags)
|
||||||
width:surface->w
|
width:surface->w
|
||||||
height:surface->h];
|
height:surface->h
|
||||||
ResetSoftwareViewport();
|
useHiDPI:vid_hidpi];
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1638,8 +1686,6 @@ static void SetupSoftwareRendering(SDL_Surface* screen)
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
glOrtho(0.0, screen->w, screen->h, 0.0, -1.0, 1.0);
|
glOrtho(0.0, screen->w, screen->h, 0.0, -1.0, 1.0);
|
||||||
|
|
||||||
ResetSoftwareViewport();
|
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
glGenTextures(1, &s_frameBufferTexture);
|
glGenTextures(1, &s_frameBufferTexture);
|
||||||
|
@ -1660,12 +1706,24 @@ int SDL_Flip(SDL_Surface* screen)
|
||||||
{
|
{
|
||||||
SetupSoftwareRendering(screen);
|
SetupSoftwareRendering(screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rbOpts.dirty)
|
||||||
|
{
|
||||||
|
glViewport(rbOpts.shiftX, rbOpts.shiftY, rbOpts.width, rbOpts.height);
|
||||||
|
|
||||||
|
// TODO: Figure out why the following glClear() call is needed
|
||||||
|
// to avoid drawing of garbage in fullscreen mode when
|
||||||
|
// in-game's aspect ratio is different from display one
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
rbOpts.dirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
const int width = screen->w;
|
const int width = screen->w;
|
||||||
const int height = screen->h;
|
const int height = screen->h;
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,
|
||||||
width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, screen->pixels);
|
width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, screen->pixels);
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
|
|
@ -43,6 +43,8 @@ struct RenderBufferOptions
|
||||||
|
|
||||||
float width;
|
float width;
|
||||||
float height;
|
float height;
|
||||||
|
|
||||||
|
bool dirty;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern RenderBufferOptions rbOpts;
|
extern RenderBufferOptions rbOpts;
|
||||||
|
|
Loading…
Reference in a new issue