mirror of https://github.com/OpenMW/openmw.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
4.3 KiB
C++
144 lines
4.3 KiB
C++
#include "sdlvideowrapper.hpp"
|
|
|
|
#include <components/debug/debuglog.hpp>
|
|
#include <components/sdlutil/sdlgraphicswindow.hpp>
|
|
#include <components/settings/settings.hpp>
|
|
|
|
#include <osgViewer/Viewer>
|
|
|
|
#include <SDL_video.h>
|
|
|
|
namespace SDLUtil
|
|
{
|
|
|
|
VideoWrapper::VideoWrapper(SDL_Window* window, osg::ref_ptr<osgViewer::Viewer> viewer)
|
|
: mWindow(window)
|
|
, mViewer(viewer)
|
|
, mGamma(1.f)
|
|
, mContrast(1.f)
|
|
, mHasSetGammaContrast(false)
|
|
{
|
|
SDL_GetWindowGammaRamp(mWindow, mOldSystemGammaRamp, &mOldSystemGammaRamp[256], &mOldSystemGammaRamp[512]);
|
|
}
|
|
|
|
VideoWrapper::~VideoWrapper()
|
|
{
|
|
SDL_SetWindowFullscreen(mWindow, 0);
|
|
|
|
// If user hasn't touched the defaults no need to restore
|
|
if (mHasSetGammaContrast)
|
|
SDL_SetWindowGammaRamp(mWindow, mOldSystemGammaRamp, &mOldSystemGammaRamp[256], &mOldSystemGammaRamp[512]);
|
|
}
|
|
|
|
void VideoWrapper::setSyncToVBlank(int mode)
|
|
{
|
|
VSyncMode vsyncMode = VSyncMode::Disabled;
|
|
if (mode == 1)
|
|
vsyncMode = VSyncMode::Enabled;
|
|
else if (mode == 2)
|
|
vsyncMode = VSyncMode::Adaptive;
|
|
|
|
osgViewer::Viewer::Windows windows;
|
|
mViewer->getWindows(windows);
|
|
mViewer->stopThreading();
|
|
for (osgViewer::Viewer::Windows::iterator it = windows.begin(); it != windows.end(); ++it)
|
|
{
|
|
osgViewer::GraphicsWindow* win = *it;
|
|
if (GraphicsWindowSDL2* sdl2win = dynamic_cast<GraphicsWindowSDL2*>(win))
|
|
sdl2win->setSyncToVBlank(vsyncMode);
|
|
else
|
|
win->setSyncToVBlank(static_cast<bool>(mode));
|
|
}
|
|
mViewer->startThreading();
|
|
}
|
|
|
|
void VideoWrapper::setGammaContrast(float gamma, float contrast)
|
|
{
|
|
if (gamma == mGamma && contrast == mContrast)
|
|
return;
|
|
|
|
mGamma = gamma;
|
|
mContrast = contrast;
|
|
|
|
mHasSetGammaContrast = true;
|
|
|
|
Uint16 red[256], green[256], blue[256];
|
|
for (int i = 0; i < 256; i++)
|
|
{
|
|
float k = i / 256.0f;
|
|
k = (k - 0.5f) * contrast + 0.5f;
|
|
k = pow(k, 1.f / gamma);
|
|
k *= 256;
|
|
float value = k * 256;
|
|
if (value > 65535)
|
|
value = 65535;
|
|
else if (value < 0)
|
|
value = 0;
|
|
|
|
red[i] = green[i] = blue[i] = static_cast<Uint16>(value);
|
|
}
|
|
if (SDL_SetWindowGammaRamp(mWindow, red, green, blue) < 0)
|
|
Log(Debug::Warning) << "Couldn't set gamma: " << SDL_GetError();
|
|
}
|
|
|
|
void VideoWrapper::setVideoMode(int width, int height, Settings::WindowMode windowMode, bool windowBorder)
|
|
{
|
|
SDL_SetWindowFullscreen(mWindow, 0);
|
|
|
|
if (SDL_GetWindowFlags(mWindow) & SDL_WINDOW_MAXIMIZED)
|
|
SDL_RestoreWindow(mWindow);
|
|
|
|
int w, h;
|
|
SDL_GetWindowSize(mWindow, &w, &h);
|
|
int dw, dh;
|
|
SDL_GL_GetDrawableSize(mWindow, &dw, &dh);
|
|
|
|
if (windowMode == Settings::WindowMode::Fullscreen || windowMode == Settings::WindowMode::WindowedFullscreen)
|
|
{
|
|
SDL_DisplayMode mode;
|
|
SDL_GetWindowDisplayMode(mWindow, &mode);
|
|
mode.w = width / (dw / w);
|
|
mode.h = height / (dh / h);
|
|
SDL_SetWindowDisplayMode(mWindow, &mode);
|
|
SDL_SetWindowFullscreen(mWindow,
|
|
windowMode == Settings::WindowMode::Fullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP);
|
|
}
|
|
else
|
|
{
|
|
SDL_SetWindowSize(mWindow, width / (dw / w), height / (dh / h));
|
|
SDL_SetWindowBordered(mWindow, windowBorder ? SDL_TRUE : SDL_FALSE);
|
|
|
|
centerWindow();
|
|
}
|
|
}
|
|
|
|
void VideoWrapper::centerWindow()
|
|
{
|
|
// Resize breaks the sdl window in some cases; see issue: #5539
|
|
SDL_Rect rect{};
|
|
int x = 0;
|
|
int y = 0;
|
|
int w = 0;
|
|
int h = 0;
|
|
auto index = SDL_GetWindowDisplayIndex(mWindow);
|
|
SDL_GetDisplayBounds(index, &rect);
|
|
SDL_GetWindowSize(mWindow, &w, &h);
|
|
|
|
x = rect.x;
|
|
y = rect.y;
|
|
|
|
// Center dimensions that do not fill the screen
|
|
if (w < rect.w)
|
|
{
|
|
x = rect.x + rect.w / 2 - w / 2;
|
|
}
|
|
if (h < rect.h)
|
|
{
|
|
y = rect.y + rect.h / 2 - h / 2;
|
|
}
|
|
|
|
SDL_SetWindowPosition(mWindow, x, y);
|
|
}
|
|
|
|
}
|