1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-16 21:59:55 +00:00
openmw/components/sdlutil/sdlgraphicswindow.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

286 lines
7.9 KiB
C++
Raw Normal View History

#include "sdlgraphicswindow.hpp"
#include <SDL_video.h>
#ifdef OPENMW_GL4ES_MANUAL_INIT
#include "gl4es_init.h"
#endif
namespace SDLUtil
{
GraphicsWindowSDL2::~GraphicsWindowSDL2()
{
close(true);
}
2015-05-13 14:50:47 +00:00
GraphicsWindowSDL2::GraphicsWindowSDL2(osg::GraphicsContext::Traits* traits, VSyncMode vsyncMode)
2020-11-13 07:39:47 +00:00
: mWindow(nullptr)
, mContext(nullptr)
, mValid(false)
2015-05-13 14:50:47 +00:00
, mRealized(false)
, mOwnsWindow(false)
, mVSyncMode(vsyncMode)
2015-05-13 14:50:47 +00:00
{
_traits = traits;
init();
if (GraphicsWindowSDL2::valid())
{
setState(new osg::State);
getState()->setGraphicsContext(this);
2022-09-22 18:26:05 +00:00
2015-05-13 14:50:47 +00:00
if (_traits.valid() && _traits->sharedContext.valid())
2022-09-22 18:26:05 +00:00
{
2015-05-13 14:50:47 +00:00
getState()->setContextID(_traits->sharedContext->getState()->getContextID());
incrementContextIDUsageCount(getState()->getContextID());
}
else
{
getState()->setContextID(osg::GraphicsContext::createNewContextID());
2022-09-22 18:26:05 +00:00
}
2015-05-13 14:50:47 +00:00
}
}
bool GraphicsWindowSDL2::setWindowDecorationImplementation(bool flag)
2022-09-22 18:26:05 +00:00
{
if (!mWindow)
return false;
SDL_SetWindowBordered(mWindow, flag ? SDL_TRUE : SDL_FALSE);
return true;
}
bool GraphicsWindowSDL2::setWindowRectangleImplementation(int x, int y, int width, int height)
{
if (!mWindow)
return false;
int w, h;
SDL_GetWindowSize(mWindow, &w, &h);
int dw, dh;
SDL_GL_GetDrawableSize(mWindow, &dw, &dh);
SDL_SetWindowPosition(mWindow, x, y);
SDL_SetWindowSize(mWindow, width / (dw / w), height / (dh / h));
return true;
}
void GraphicsWindowSDL2::setWindowName(const std::string& name)
{
if (!mWindow)
return;
SDL_SetWindowTitle(mWindow, name.c_str());
_traits->windowName = name;
}
void GraphicsWindowSDL2::setCursor(MouseCursor mouseCursor)
{
_traits->useCursor = false;
}
void GraphicsWindowSDL2::init()
2022-09-22 18:26:05 +00:00
{
if (mValid)
2022-09-22 18:26:05 +00:00
return;
if (!_traits.valid())
return;
WindowData* inheritedWindowData = dynamic_cast<WindowData*>(_traits->inheritedWindowData.get());
mWindow = inheritedWindowData ? inheritedWindowData->mWindow : nullptr;
2018-10-09 06:21:12 +00:00
mOwnsWindow = (mWindow == nullptr);
if (mOwnsWindow)
2022-09-22 18:26:05 +00:00
{
2018-10-09 06:21:12 +00:00
OSG_FATAL << "Error: No SDL window provided." << std::endl;
2022-09-22 18:26:05 +00:00
return;
}
// SDL will change the current context when it creates a new one, so we
// have to get the current one to be able to restore it afterward.
SDL_Window* oldWin = SDL_GL_GetCurrentWindow();
SDL_GLContext oldCtx = SDL_GL_GetCurrentContext();
#if defined(ANDROID) || defined(OPENMW_GL4ES_MANUAL_INIT)
int major = 1;
int minor = 1;
char* ver = getenv("OPENMW_GLES_VERSION");
if (ver && strcmp(ver, "2") == 0)
2022-09-22 18:26:05 +00:00
{
major = 2;
minor = 0;
2022-09-22 18:26:05 +00:00
}
else if (ver && strcmp(ver, "3") == 0)
2022-09-22 18:26:05 +00:00
{
major = 3;
minor = 2;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor);
#endif
mContext = SDL_GL_CreateContext(mWindow);
if (!mContext)
2022-09-22 18:26:05 +00:00
{
OSG_FATAL << "Error: Unable to create OpenGL graphics context: " << SDL_GetError() << std::endl;
return;
}
#ifdef OPENMW_GL4ES_MANUAL_INIT
openmw_gl4es_init(mWindow);
2022-09-22 18:26:05 +00:00
#endif
setSwapInterval(mVSyncMode);
2022-09-22 18:26:05 +00:00
// 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;
2022-09-22 18:26:05 +00:00
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;
2022-09-22 18:26:05 +00:00
SDL_GL_MakeCurrent(oldWin, oldCtx);
2022-09-22 18:26:05 +00:00
mValid = true;
2022-09-22 18:26:05 +00:00
getEventQueue()->syncWindowRectangleWithGraphicsContext();
}
bool GraphicsWindowSDL2::realizeImplementation()
2022-09-22 18:26:05 +00:00
{
if (mRealized)
2022-09-22 18:26:05 +00:00
{
OSG_NOTICE << "GraphicsWindowSDL2::realizeImplementation() Already realized" << std::endl;
return true;
2022-09-22 18:26:05 +00:00
}
if (!mValid)
init();
if (!mValid)
return false;
2015-06-07 21:51:54 +00:00
SDL_ShowWindow(mWindow);
getEventQueue()->syncWindowRectangleWithGraphicsContext();
mRealized = true;
return true;
}
bool GraphicsWindowSDL2::makeCurrentImplementation()
{
if (!mRealized)
2022-09-22 18:26:05 +00:00
{
OSG_WARN << "Warning: GraphicsWindow not realized, cannot do makeCurrent." << std::endl;
return false;
2022-09-22 18:26:05 +00:00
}
return SDL_GL_MakeCurrent(mWindow, mContext) == 0;
}
2018-10-09 06:21:12 +00:00
bool GraphicsWindowSDL2::releaseContextImplementation()
2022-09-22 18:26:05 +00:00
{
if (!mRealized)
2022-09-22 18:26:05 +00:00
{
2018-10-09 06:21:12 +00:00
OSG_WARN << "Warning: GraphicsWindow not realized, cannot do releaseContext." << std::endl;
return false;
}
return SDL_GL_MakeCurrent(nullptr, nullptr) == 0;
2022-09-22 18:26:05 +00:00
}
void GraphicsWindowSDL2::closeImplementation()
{
if (mContext)
SDL_GL_DeleteContext(mContext);
2018-10-09 06:21:12 +00:00
mContext = nullptr;
if (mWindow && mOwnsWindow)
SDL_DestroyWindow(mWindow);
2018-10-09 06:21:12 +00:00
mWindow = nullptr;
mValid = false;
mRealized = false;
}
void GraphicsWindowSDL2::swapBuffersImplementation()
{
if (!mRealized)
return;
SDL_GL_SwapWindow(mWindow);
}
void GraphicsWindowSDL2::setSyncToVBlank(bool on)
{
throw std::runtime_error(
"setSyncToVBlank with bool argument is not supported. Use the VSyncMode argument instead.");
}
void GraphicsWindowSDL2::setSyncToVBlank(VSyncMode mode)
{
SDL_Window* oldWin = SDL_GL_GetCurrentWindow();
SDL_GLContext oldCtx = SDL_GL_GetCurrentContext();
SDL_GL_MakeCurrent(mWindow, mContext);
setSwapInterval(mode);
SDL_GL_MakeCurrent(oldWin, oldCtx);
}
void GraphicsWindowSDL2::setSwapInterval(VSyncMode mode)
{
mVSyncMode = mode;
if (mode == VSyncMode::Adaptive)
{
if (SDL_GL_SetSwapInterval(-1) == -1)
{
OSG_NOTICE << "Adaptive vsync unsupported" << std::endl;
setSwapInterval(VSyncMode::Enabled);
}
}
else if (mode == VSyncMode::Enabled)
{
if (SDL_GL_SetSwapInterval(1) == -1)
{
OSG_NOTICE << "Vertical synchronization unsupported, disabling" << std::endl;
setSwapInterval(VSyncMode::Disabled);
}
}
2022-09-22 18:26:05 +00:00
else
{
SDL_GL_SetSwapInterval(0);
2022-09-22 18:26:05 +00:00
}
}
2022-09-22 18:26:05 +00:00
void GraphicsWindowSDL2::raiseWindow()
{
SDL_RaiseWindow(mWindow);
}
2015-05-13 13:03:21 +00:00
}