diff --git a/source/Irrlicht/OpenGL/Common.h b/source/Irrlicht/OpenGL/Common.h index 4069307c..2155a9a9 100644 --- a/source/Irrlicht/OpenGL/Common.h +++ b/source/Irrlicht/OpenGL/Common.h @@ -32,5 +32,19 @@ namespace video typedef COpenGLCoreRenderTarget COpenGL3RenderTarget; typedef COpenGLCoreCacheHandler COpenGL3CacheHandler; + enum class OpenGLSpec: u8 { + Core, + Compat, + ES, + // WebGL, // TODO + }; + + struct OpenGLVersion { + OpenGLSpec Spec; + u8 Major; + u8 Minor; + u8 Release; + }; + } } diff --git a/source/Irrlicht/OpenGL/Driver.cpp b/source/Irrlicht/OpenGL/Driver.cpp index 461a2f14..e47fc736 100644 --- a/source/Irrlicht/OpenGL/Driver.cpp +++ b/source/Irrlicht/OpenGL/Driver.cpp @@ -203,8 +203,7 @@ COpenGL3DriverBase::~COpenGL3DriverBase() QuadIndexCount = QuadsIndices.size(); } - bool COpenGL3DriverBase::genericDriverInit(const core::dimension2d& screenSize, bool stencilBuffer) - { + void COpenGL3DriverBase::initVersion() { Name = glGetString(GL_VERSION); printVersion(); @@ -212,7 +211,12 @@ COpenGL3DriverBase::~COpenGL3DriverBase() VendorName = glGetString(GL_VENDOR); os::Printer::log(VendorName.c_str(), ELL_INFORMATION); - // load extensions + Version = getVersionFromOpenGL(); + } + + bool COpenGL3DriverBase::genericDriverInit(const core::dimension2d& screenSize, bool stencilBuffer) + { + initVersion(); initExtensions(); // reset cache handler @@ -231,7 +235,7 @@ COpenGL3DriverBase::~COpenGL3DriverBase() DriverAttributes->setAttribute("MaxIndices", (s32)MaxIndices); DriverAttributes->setAttribute("MaxTextureSize", (s32)MaxTextureSize); DriverAttributes->setAttribute("MaxTextureLODBias", MaxTextureLODBias); - DriverAttributes->setAttribute("Version", Version); + DriverAttributes->setAttribute("Version", 100 * Version.Major + Version.Minor); DriverAttributes->setAttribute("AntiAlias", AntiAlias); glPixelStorei(GL_PACK_ALIGNMENT, 1); diff --git a/source/Irrlicht/OpenGL/Driver.h b/source/Irrlicht/OpenGL/Driver.h index 84cc62be..1122c790 100644 --- a/source/Irrlicht/OpenGL/Driver.h +++ b/source/Irrlicht/OpenGL/Driver.h @@ -285,6 +285,9 @@ namespace video //! inits the opengl-es driver virtual bool genericDriverInit(const core::dimension2d& screenSize, bool stencilBuffer); + void initVersion(); + virtual OpenGLVersion getVersionFromOpenGL() const = 0; + void chooseMaterial2D(); ITexture* createDeviceDependentTexture(const io::path& name, IImage* image) override; @@ -341,6 +344,7 @@ namespace video core::stringw Name; core::stringc VendorName; SIrrlichtCreationParameters Params; + OpenGLVersion Version; //! bool to make all renderstates reset if set to true. bool ResetRenderStates; diff --git a/source/Irrlicht/OpenGL3/Driver.cpp b/source/Irrlicht/OpenGL3/Driver.cpp index 925c6eaf..975bf557 100644 --- a/source/Irrlicht/OpenGL3/Driver.cpp +++ b/source/Irrlicht/OpenGL3/Driver.cpp @@ -11,8 +11,24 @@ namespace video { return EDT_OPENGL3; } + OpenGLVersion COpenGL3Driver::getVersionFromOpenGL() const { + GLint major, minor, profile; + glGetIntegerv(GL_MAJOR_VERSION, &major); + glGetIntegerv(GL_MINOR_VERSION, &minor); + glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &profile); + // The spec is clear a context can’t be both core and compatibility at the same time. + // However, the returned value is a mask. Ask Khronos why. -- numzero + if (profile & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) + return {OpenGLSpec::Compat, (u8)major, (u8)minor, 0}; + if (profile & GL_CONTEXT_CORE_PROFILE_BIT) + return {OpenGLSpec::Core, (u8)major, (u8)minor, 0}; + os::Printer::log("Got unrecognized OpenGL profile", ELL_ERROR); + return {OpenGLSpec::Core, (u8)major, (u8)minor, 0}; + } + IVideoDriver* createOpenGL3Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager) { + os::Printer::log("Using COpenGL3Driver", ELL_INFORMATION); COpenGL3Driver* driver = new COpenGL3Driver(params, io, contextManager); driver->genericDriverInit(params.WindowSize, params.Stencilbuffer); // don't call in constructor, it uses virtual function calls of driver return driver; diff --git a/source/Irrlicht/OpenGL3/Driver.h b/source/Irrlicht/OpenGL3/Driver.h index cb30432c..66dc01b4 100644 --- a/source/Irrlicht/OpenGL3/Driver.h +++ b/source/Irrlicht/OpenGL3/Driver.h @@ -8,11 +8,17 @@ namespace irr { namespace video { + /// OpenGL 3+ driver + /// + /// For OpenGL 3.2 and higher. Compatibility profile is required currently. class COpenGL3Driver : public COpenGL3DriverBase { friend IVideoDriver* createOpenGL3Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager); public: using COpenGL3DriverBase::COpenGL3DriverBase; E_DRIVER_TYPE getDriverType() const override; + + protected: + OpenGLVersion getVersionFromOpenGL() const override; }; } diff --git a/source/Irrlicht/OpenGLES2/Driver.cpp b/source/Irrlicht/OpenGLES2/Driver.cpp index 2b034644..2e293fe4 100644 --- a/source/Irrlicht/OpenGLES2/Driver.cpp +++ b/source/Irrlicht/OpenGLES2/Driver.cpp @@ -11,8 +11,19 @@ namespace video { return EDT_OGLES2; } + OpenGLVersion COpenGLES2Driver::getVersionFromOpenGL() const { + auto version_string = reinterpret_cast(glGetString(GL_VERSION)); + int major, minor; + if (sscanf(version_string, "OpenGL ES %d.%d", &major, &minor) != 2) { + os::Printer::log("Failed to parse OpenGL ES version string", version_string, ELL_ERROR); + return {OpenGLSpec::ES, 0, 0, 0}; + } + return {OpenGLSpec::ES, (u8)major, (u8)minor, 0}; + } + IVideoDriver* createOGLES2Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager) { + os::Printer::log("Using COpenGLES2Driver", ELL_INFORMATION); COpenGLES2Driver* driver = new COpenGLES2Driver(params, io, contextManager); driver->genericDriverInit(params.WindowSize, params.Stencilbuffer); // don't call in constructor, it uses virtual function calls of driver return driver; diff --git a/source/Irrlicht/OpenGLES2/Driver.h b/source/Irrlicht/OpenGLES2/Driver.h index cdfb2fec..3dc234d7 100644 --- a/source/Irrlicht/OpenGLES2/Driver.h +++ b/source/Irrlicht/OpenGLES2/Driver.h @@ -8,11 +8,17 @@ namespace irr { namespace video { + /// OpenGL ES 2+ driver + /// + /// For OpenGL ES 2.0 and higher. class COpenGLES2Driver : public COpenGL3DriverBase { friend IVideoDriver* createOGLES2Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager); public: using COpenGL3DriverBase::COpenGL3DriverBase; E_DRIVER_TYPE getDriverType() const override; + + protected: + OpenGLVersion getVersionFromOpenGL() const override; }; }