Merge branch '4771-and-4631' into 'master'

Try lower MSAA level if the requested value isn't available

Closes #4471 and #4631

See merge request OpenMW/openmw!297

(cherry picked from commit b3db387512340a5e9a77427c2d7d9d88c2340056)

da0aef7a Retrieve SDL OpenGL attributes after context creation
a51e63b3 Try lower MSAA levels if OpenGL context doesn't have what we requested
c4e92a0a Update CHANGELOG.md
pull/3007/head
psi29a 4 years ago
parent 87028e1640
commit 22c3588d0d

@ -10,6 +10,7 @@
Bug #4021: Attributes and skills are not stored as floats
Bug #4055: Local scripts don't inherit variables from their base record
Bug #4623: Corprus implementation is incorrect
Bug #4631: Setting MSAA level too high doesn't fall back to highest supported level
Bug #4764: Data race in osg ParticleSystem
Bug #4774: Guards are ignorant of an invisible player that tries to attack them
Bug #5108: Savegame bloating due to inefficient fog textures format

@ -525,65 +525,80 @@ void OMW::Engine::createWindow(Settings::Manager& settings)
checkSDLError(SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, antialiasing));
}
while (!mWindow)
osg::ref_ptr<SDLUtil::GraphicsWindowSDL2> graphicsWindow;
while (!graphicsWindow || !graphicsWindow->valid())
{
mWindow = SDL_CreateWindow("OpenMW", pos_x, pos_y, width, height, flags);
if (!mWindow)
while (!mWindow)
{
// Try with a lower AA
if (antialiasing > 0)
mWindow = SDL_CreateWindow("OpenMW", pos_x, pos_y, width, height, flags);
if (!mWindow)
{
Log(Debug::Warning) << "Warning: " << antialiasing << "x antialiasing not supported, trying " << antialiasing/2;
antialiasing /= 2;
Settings::Manager::setInt("antialiasing", "Video", antialiasing);
checkSDLError(SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, antialiasing));
continue;
}
else
{
std::stringstream error;
error << "Failed to create SDL window: " << SDL_GetError();
throw std::runtime_error(error.str());
// Try with a lower AA
if (antialiasing > 0)
{
Log(Debug::Warning) << "Warning: " << antialiasing << "x antialiasing not supported, trying " << antialiasing/2;
antialiasing /= 2;
Settings::Manager::setInt("antialiasing", "Video", antialiasing);
checkSDLError(SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, antialiasing));
continue;
}
else
{
std::stringstream error;
error << "Failed to create SDL window: " << SDL_GetError();
throw std::runtime_error(error.str());
}
}
}
}
setWindowIcon();
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
SDL_GetWindowPosition(mWindow, &traits->x, &traits->y);
SDL_GetWindowSize(mWindow, &traits->width, &traits->height);
traits->windowName = SDL_GetWindowTitle(mWindow);
traits->windowDecoration = !(SDL_GetWindowFlags(mWindow)&SDL_WINDOW_BORDERLESS);
traits->screenNum = SDL_GetWindowDisplayIndex(mWindow);
// We tried to get rid of the hardcoding but failed: https://github.com/OpenMW/openmw/pull/1771
// Here goes kcat's quote:
// It's ultimately a chicken and egg problem, and the reason why the code is like it was in the first place.
// It needs a context to get the current attributes, but it needs the attributes to set up the context.
// So it just specifies the same values that were given to SDL in the hopes that it's good enough to what the window eventually gets.
traits->red = 8;
traits->green = 8;
traits->blue = 8;
traits->alpha = 0; // set to 0 to stop ScreenCaptureHandler reading the alpha channel
traits->depth = 24;
traits->stencil = 8;
traits->vsync = vsync;
traits->doubleBuffer = true;
traits->inheritedWindowData = new SDLUtil::GraphicsWindowSDL2::WindowData(mWindow);
osg::ref_ptr<SDLUtil::GraphicsWindowSDL2> graphicsWindow = new SDLUtil::GraphicsWindowSDL2(traits);
if(!graphicsWindow->valid()) throw std::runtime_error("Failed to create GraphicsContext");
setWindowIcon();
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
SDL_GetWindowPosition(mWindow, &traits->x, &traits->y);
SDL_GetWindowSize(mWindow, &traits->width, &traits->height);
traits->windowName = SDL_GetWindowTitle(mWindow);
traits->windowDecoration = !(SDL_GetWindowFlags(mWindow)&SDL_WINDOW_BORDERLESS);
traits->screenNum = SDL_GetWindowDisplayIndex(mWindow);
traits->vsync = vsync;
traits->inheritedWindowData = new SDLUtil::GraphicsWindowSDL2::WindowData(mWindow);
graphicsWindow = new SDLUtil::GraphicsWindowSDL2(traits);
if (!graphicsWindow->valid()) throw std::runtime_error("Failed to create GraphicsContext");
if (traits->samples < antialiasing)
{
Log(Debug::Warning) << "Warning: Framebuffer MSAA level is only " << traits->samples << "x instead of " << antialiasing << "x. Trying " << antialiasing / 2 << "x instead.";
graphicsWindow->closeImplementation();
SDL_DestroyWindow(mWindow);
mWindow = nullptr;
antialiasing /= 2;
Settings::Manager::setInt("antialiasing", "Video", antialiasing);
checkSDLError(SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, antialiasing));
continue;
}
if (traits->red < 8)
Log(Debug::Warning) << "Warning: Framebuffer only has a " << traits->red << " bit red channel.";
if (traits->green < 8)
Log(Debug::Warning) << "Warning: Framebuffer only has a " << traits->green << " bit green channel.";
if (traits->blue < 8)
Log(Debug::Warning) << "Warning: Framebuffer only has a " << traits->blue << " bit blue channel.";
if (traits->depth < 8)
Log(Debug::Warning) << "Warning: Framebuffer only has " << traits->red << " bits of depth precision.";
traits->alpha = 0; // set to 0 to stop ScreenCaptureHandler reading the alpha channel
}
osg::ref_ptr<osg::Camera> camera = mViewer->getCamera();
camera->setGraphicsContext(graphicsWindow);
camera->setViewport(0, 0, traits->width, traits->height);
camera->setViewport(0, 0, graphicsWindow->getTraits()->width, graphicsWindow->getTraits()->height);
if (Debug::shouldDebugOpenGL())
mViewer->setRealizeOperation(new Debug::EnableGLDebugOperation());
mViewer->realize();
mViewer->getEventQueue()->getCurrentEventState()->setWindowRectangle(0, 0, traits->width, traits->height);
mViewer->getEventQueue()->getCurrentEventState()->setWindowRectangle(0, 0, graphicsWindow->getTraits()->width, graphicsWindow->getTraits()->height);
}
void OMW::Engine::setWindowIcon()

@ -118,6 +118,29 @@ void GraphicsWindowSDL2::init()
setSwapInterval(_traits->vsync);
// Update traits with what we've actually been given
// Use intermediate to avoid signed/unsigned mismatch
int intermediateLocation;
SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &intermediateLocation);
_traits->red = intermediateLocation;
SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &intermediateLocation);
_traits->green = intermediateLocation;
SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &intermediateLocation);
_traits->blue = intermediateLocation;
SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &intermediateLocation);
_traits->alpha = intermediateLocation;
SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &intermediateLocation);
_traits->depth = intermediateLocation;
SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &intermediateLocation);
_traits->stencil = intermediateLocation;
SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &intermediateLocation);
_traits->doubleBuffer = intermediateLocation;
SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &intermediateLocation);
_traits->sampleBuffers = intermediateLocation;
SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &intermediateLocation);
_traits->samples = intermediateLocation;
SDL_GL_MakeCurrent(oldWin, oldCtx);
mValid = true;

Loading…
Cancel
Save