OpenGLRenderer: Choose between OpenGL/OpenGL ES at loading

This commit is contained in:
Jérôme Leclercq 2021-11-02 09:13:12 +01:00
parent d872428658
commit 9946c17a23
7 changed files with 79 additions and 28 deletions

View File

@ -28,6 +28,7 @@ namespace Nz::GL
std::unique_ptr<Context> CreateContext(const OpenGLDevice* device, const ContextParams& params, WindowHandle handle, Context* shareContext) const override;
inline EGLDisplay GetDefaultDisplay() const;
ContextType GetPreferredContextType() const override;
GLFunction LoadFunction(const char* name) const override;
@ -41,6 +42,7 @@ namespace Nz::GL
private:
bool ImplementFallback(const std::string_view& function);
ContextType m_preferredContextType;
EGLDisplay m_defaultDisplay;
DynLib m_eglLib;
};

View File

@ -22,6 +22,7 @@ namespace Nz::GL
using GLFunction = void(*)(void);
class Context;
enum class ContextType;
struct ContextParams;
class NAZARA_OPENGLRENDERER_API Loader
@ -33,6 +34,8 @@ namespace Nz::GL
virtual std::unique_ptr<Context> CreateContext(const OpenGLDevice* device, const ContextParams& params, Context* shareContext = nullptr) const = 0;
virtual std::unique_ptr<Context> CreateContext(const OpenGLDevice* device, const ContextParams& params, WindowHandle handle, Context* shareContext = nullptr) const = 0;
virtual ContextType GetPreferredContextType() const = 0;
virtual GLFunction LoadFunction(const char* name) const = 0;
};
}

View File

@ -26,6 +26,8 @@ namespace Nz::GL
std::unique_ptr<Context> CreateContext(const OpenGLDevice* device, const ContextParams& params, Context* shareContext) const override;
std::unique_ptr<Context> CreateContext(const OpenGLDevice* device, const ContextParams& params, WindowHandle handle, Context* shareContext) const override;
ContextType GetPreferredContextType() const override;
GLFunction LoadFunction(const char* name) const override;
#define NAZARA_OPENGLRENDERER_FUNC(name, sig) sig name = nullptr;

View File

@ -23,25 +23,11 @@ namespace Nz
OpenGLDevice::OpenGLDevice(GL::Loader& loader) :
m_loader(loader)
{
// Favor OpenGL on desktop and OpenGL ES on mobile
std::array<GL::ContextType, 2> contextTypes = {
#if defined(NAZARA_PLATFORM_DESKTOP)
GL::ContextType::OpenGL, GL::ContextType::OpenGL_ES
#else
GL::ContextType::OpenGL_ES, GL::ContextType::OpenGL
#endif
};
GL::ContextParams params;
params.type = loader.GetPreferredContextType();
for (GL::ContextType contextType : contextTypes)
{
GL::ContextParams params;
params.type = contextType;
m_referenceContext = loader.CreateContext(this, params);
if (m_referenceContext)
break;
}
m_referenceContext = loader.CreateContext(this, params);
if (!m_referenceContext)
throw std::runtime_error("failed to create reference context");

View File

@ -81,14 +81,38 @@ namespace Nz::GL
const char* vendor = eglQueryString(m_defaultDisplay, EGL_VENDOR);
NazaraNotice("Initialized EGL " + std::to_string(major) + "." + std::to_string(minor) + " display (" + vendor + ")");
// Try to create a dummy context in order to check EGL support (FIXME: is this really necessary?)
/*ContextParams params;
EGLContextBase baseContext(nullptr, *this);
if (!baseContext.Create(params))
throw std::runtime_error("failed to create load context");
// Try to create a dummy context in order to check OpenGL / OpenGL ES support
if (!baseContext.Initialize(params))
throw std::runtime_error("failed to load OpenGL functions");*/
// Favor OpenGL on desktop and OpenGL ES on mobile
std::array<GL::ContextType, 2> contextTypes = {
#if defined(NAZARA_PLATFORM_DESKTOP)
GL::ContextType::OpenGL, GL::ContextType::OpenGL_ES
#else
GL::ContextType::OpenGL_ES, GL::ContextType::OpenGL
#endif
};
ContextParams params;
bool created = false;
for (GL::ContextType contextType : contextTypes)
{
params.type = contextType;
EGLContextBase baseContext(nullptr, *this);
if (!baseContext.Create(params) || baseContext.GetParams().type != contextType)
continue;
if (!baseContext.Initialize(params)) //< Is this really necessary?
continue;
created = true;
m_preferredContextType = contextType;
break;
}
if (!created)
throw std::runtime_error("failed to create or initialize base context");
}
EGLLoader::~EGLLoader()
@ -170,6 +194,11 @@ namespace Nz::GL
return context;
}
ContextType EGLLoader::GetPreferredContextType() const
{
return m_preferredContextType;
}
GLFunction EGLLoader::LoadFunction(const char* name) const
{
GLFunction func = reinterpret_cast<GLFunction>(m_eglLib.GetSymbol(name));

View File

@ -19,6 +19,8 @@ namespace Nz::GL
bool WGLContext::Create(const WGLContext* baseContext, const ContextParams& params, const WGLContext* shareContext)
{
Destroy();
// Creating a context requires a device context, create window to get one
HWNDHandle window(::CreateWindowA("STATIC", nullptr, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, nullptr, nullptr, GetModuleHandle(nullptr), nullptr));
if (!window)
@ -47,6 +49,8 @@ namespace Nz::GL
{
NazaraAssert(window.type == WindowManager::Windows, "expected Windows window");
Destroy();
m_deviceContext = ::GetDC(static_cast<HWND>(window.windows.window));
if (!m_deviceContext)
{

View File

@ -50,12 +50,32 @@ namespace Nz::GL
throw std::runtime_error("failed to create load context");
ContextParams params;
// Favor OpenGL on desktop and OpenGL ES on mobile
std::array<GL::ContextType, 2> contextTypes = {
#if defined(NAZARA_PLATFORM_DESKTOP)
GL::ContextType::OpenGL, GL::ContextType::OpenGL_ES
#else
GL::ContextType::OpenGL_ES, GL::ContextType::OpenGL
#endif
};
if (!m_baseContext.Create(&loadContext, params))
throw std::runtime_error("failed to create load context");
bool created = false;
for (GL::ContextType contextType : contextTypes)
{
params.type = contextType;
if (!m_baseContext.Initialize(params))
throw std::runtime_error("failed to load OpenGL functions");
if (!m_baseContext.Create(&loadContext, params) || m_baseContext.GetParams().type != contextType)
continue;
if (!m_baseContext.Initialize(params))
continue;
created = true;
break;
}
if (!created)
throw std::runtime_error("failed to create or initialize base context");
}
std::unique_ptr<Context> WGLLoader::CreateContext(const OpenGLDevice* device, const ContextParams& params, Context* shareContext) const
@ -94,6 +114,11 @@ namespace Nz::GL
return context;
}
ContextType WGLLoader::GetPreferredContextType() const
{
return m_baseContext.GetParams().type;
}
GLFunction WGLLoader::LoadFunction(const char* name) const
{
GLFunction func = reinterpret_cast<GLFunction>(wglGetProcAddress(name));