Magnum::GL::Context class

Magnum OpenGL context.

Provides access to OpenGL version and extension information and manages Magnum's internal OpenGL state tracker.

Creating a context

In order to use any Magnum OpenGL functionality, an instance of this class has to exist and be made current. If you use any Platform::*Application classes, an instance available through Context::current() is automatically created during construction (or after Platform::*Application::create() / tryCreate() and you can safely assume the instance is available during the whole *Application lifetime. It's also possible to create the context without using any *Application class using the Platform::GLContext subclass, see Platform support for more information.

Various options can be passed using the Configuration class, which is then extended by various Platform::*Application::GLConfiguration and Platform::Windowless*Application::Configuration subclasses.

Command-line options

In addition to the Configuration, the context is configurable through command-line options, that are passed either from the Platform::*Application classes or from the Platform::GLContext class. In case an option is set in both the Configuration and on command-line / environment, the two are combined together — flags ORed together, lists joined. Usage:

<application> [--magnum-help] [--magnum-disable-workarounds LIST]
              [--magnum-disable-extensions LIST]
              [--magnum-gpu-validation off|on]
              [--magnum-log default|quiet|verbose] ...

Arguments:

Note that all options are prefixed with --magnum- to avoid conflicts with options passed to the application itself. Options that don't have this prefix are completely ignored, see documentation of the Utility::Arguments class for details.

Particular application implementations add more options for DPI scaling or GPU selection, see Platform::Sdl2Application, Platform::GlfwApplication and Platform::WindowlessEglApplication for details.

Using multiple OpenGL contexts

By default, Magnum assumes you have one OpenGL context active at all times, and all state tracking is done by the Context instance that's associated with it. When you are using multiple OpenGL contexts, each of them needs to have a corresponding Context instance active at the same time, and you need to ensure you only access OpenGL objects that were created by the same context as is currently active.

To prevent accidents in common cases, the Context class expects that no other instance is active during its creation. In order to create additional instances for other OpenGL contexts, first you need to "unset" the current one with makeCurrent() and then create another instance, which will then become implicitly active:

Platform::GLContext context;

SDL_GL_MakeCurrent(_window, _otherGLContext); // or other platform-specific API
Platform::GLContext::makeCurrent(nullptr);

Platform::GLContext other;

Once all needed instances are created, switch between them right after making the underlying GL context current:

Platform::GLContext::makeCurrent(&context);

GL::Buffer a; // implicitly tied to `context`

Platform::GLContext::makeCurrent(&other);

GL::Buffer b; // implicitly tied to `other`

Thread safety

If Corrade is compiled with CORRADE_BUILD_MULTITHREADED (the default), the hasCurrent() and current() accessors are thread-local, matching the OpenGL context thread locality. This might cause some performance penalties — if you are sure that you never need to have multiple independent thread-local Magnum context, build Corrade with the option disabled.

Derived classes

class Magnum::Platform::GLContext
Platform-specific OpenGL context.

Public types

class Configuration new in Git master
Configuration.
enum class Flag: GLint { Debug = GL_CONTEXT_FLAG_DEBUG_BIT, ForwardCompatible = GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT, NoError = GL_CONTEXT_FLAG_NO_ERROR_BIT, RobustAccess = GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT }
Context flag.
enum class State: UnsignedInt { Buffers = 1 << 0, UnbindPixelBuffer = 1 << 1, Framebuffers = 1 << 2, Meshes = 1 << 3, MeshVao = 1 << 4, BindScratchVao = 1 << 5, PixelStorage = 1 << 6, Renderer = 1 << 7, Shaders = 1 << 8, Textures = 1 << 9, TransformFeedback = 1 << 10, EnterExternal = MeshVao |UnbindPixelBuffer, ExitExternal = Buffers|Framebuffers|Meshes|MeshVao|PixelStorage|Renderer|Shaders|Textures |TransformFeedback }
State to reset.
enum class DetectedDriver: UnsignedShort { Amd = 1 << 0, Angle = 1 << 1, IntelWindows = 1 << 2, Mesa = 1 << 3, NVidia = 1 << 4, Svga3D = 1 << 5, SwiftShader = 1 << 6 new in 2019.10, ArmMali = 1 << 7 new in 2019.10, QualcommAdreno = 1 << 8 new in Git master }
Detected driver.
using Flags = Containers::EnumSet<Flag>
Context flags.
using States = Containers::EnumSet<State>
States to reset.
using DetectedDrivers = Containers::EnumSet<DetectedDriver>
Detected drivers.

Public static functions

static auto hasCurrent() -> bool
Whether there is any current context.
static auto current() -> Context&
Current context.
static void makeCurrent(Context* context) new in 2019.10
Make a context current.

Constructors, destructors, conversion operators

Context(const Context&) deleted
Copying is not allowed.
Context(Context&& other) noexcept
Move constructor.

Public functions

auto operator=(const Context&) -> Context& deleted
Copying is not allowed.
auto operator=(Context&&) -> Context& deleted
Move assignment is not allowed.
auto version() const -> Version
OpenGL version.
auto vendorString() const -> Containers::StringView
Vendor string.
auto vendorStringUnmasked() const -> Containers::StringView new in Git master
Unmasked vendor string.
auto rendererString() const -> Containers::StringView
Renderer string.
auto rendererStringUnmasked() const -> Containers::StringView new in Git master
Unmasked renderer string.
auto versionString() const -> Containers::StringView
Version string.
auto shadingLanguageVersionString() const -> Containers::StringView
Shading language version string.
auto shadingLanguageVersionStrings() const -> Containers::Array<Containers::StringView>
Shading language version strings.
auto extensionStrings() const -> Containers::Array<Containers::StringView>
Extension strings.
auto flags() const -> Flags
Context flags.
auto supportedExtensions() const -> Containers::ArrayView<const Extension> deprecated in Git master
Supported extensions.
auto isCoreProfile() -> bool
Detect if current OpenGL context is a core profile.
auto isVersionSupported(Version version) const -> bool
Whether given OpenGL version is supported.
auto supportedVersion(std::initializer_list<Version> versions) const -> Version
Get supported OpenGL version.
template<class E>
auto isExtensionSupported() const -> bool
Whether given extension is supported.
template<class E>
auto isExtensionSupported(Version version) const -> bool
Whether given extension is supported in given version.
auto isExtensionSupported(const Extension& extension) const -> bool
Whether given extension is supported.
template<class E>
auto isExtensionDisabled() const -> bool
Whether given extension is disabled.
template<class E>
auto isExtensionDisabled(Version version) const -> bool
Whether given extension is disabled for given version.
auto isExtensionDisabled(const Extension& extension) const -> bool
Whether given extension is disabled.
void resetState(States states = ~States{})
Reset internal state tracker.
auto detectedDriver() -> DetectedDrivers
Detect driver.

Enum documentation

enum class Magnum::GL::Context::Flag: GLint

Context flag.

Enumerators
Debug

Debug context. Enabled automatically by Platform windowed and windowless application implementations if the Configuration::Flag::GpuValidation flag is set or if the --magnum-gpu-validation command-line option is set to on.

ForwardCompatible

Forward compatible context

NoError

Context without error reporting. Enabled automatically by Platform windowed and windowless application implementations if the Configuration::Flag::GpuValidationNoError flag is set or if the --magnum-gpu-validation command-line option is set to no-error.

RobustAccess

Context with robust access

enum class Magnum::GL::Context::State: UnsignedInt

State to reset.

Enumerators
Buffers

Reset tracked buffer-related bindings and state

UnbindPixelBuffer

Unbind currently bound PBO.

Not all third-party code is aware of PBOs, and if a PBO is bound when Magnum transfers control to an unaware code, it can cause various issues with textures. This is a similar, but rarer, case to State::MeshVao / State::BindScratchVao.

Framebuffers

Reset tracked framebuffer-related bindings and state

Meshes

Reset tracked mesh-related bindings

MeshVao

Unbind currently bound VAO.

Magnum by default uses VAOs — each time a Mesh is drawn or configured, its VAO is bound, but it is not unbound afterwards to avoid needless state changes. This may introduce problems when using third-party OpenGL code — it may break internal state of a mesh that was used the most recently. Similar issue can happen the other way. Calling resetState() with State::MeshVao included unbounds any currently bound VAO to fix such case.

BindScratchVao

Bind a "scratch" VAO on core profile.

Use if external code is not VAO-aware and would otherwise try to enable vertex attributes on the default (zero) VAO, causing GL errors. Meant to be used together with State::MeshVao (or State::EnterExternal).

Does nothing on compatibility profile and ES / WebGL platforms, as using the default VAO is allowed there.

PixelStorage

Reset tracked pixel storage-related state

Renderer

Reset tracked renderer-related state

Shaders

Reset tracked shader-related bindings

Textures

Reset tracked texture-related bindings and state

TransformFeedback

Reset tracked transform feedback-related bindings

EnterExternal

Reset state on entering section with external OpenGL code.

Resets all state that could cause external code to accidentally modify Magnum objects. This includes State::MeshVao and State::UnbindPixelBuffer. In some pathological cases you may want to enable State::BindScratchVao as well.

ExitExternal

Reset state on exiting section with external OpenGL code.

Resets Magnum state tracker to avoid being confused by external state changes. This resets all states, however State::UnbindPixelBuffer is excluded as Magnum's state tracker will ensure no PBO is bound when calling related OpenGL APIs.

enum class Magnum::GL::Context::DetectedDriver: UnsignedShort

Detected driver.

On WebGL, if WEBGL_debug_renderer_info is not available and the browser doesn't report the real values through vendorString() and rendererString(), driver detection can be performed only for limited cases — see documentation of particular values for more information.

Enumerators
Amd

Proprietary AMD desktop drivers on Windows and Linux. In contrast, AMDGPU Mesa drivers report as DetectedDriver::Mesa instead.

Angle

OpenGL ES implementation by ANGLE (translated to D3D), used by browsers on Windows for WebGL. See also DetectedDriver::SwiftShader. On WebGL, if WEBGL_debug_renderer_info is not available, the detection is attempted by checking for a presence of ANGLE_instanced_arrays on WebGL 1 (which may also be implemented by other drivers than ANGLE) or WEBGL_multi_draw on WebGL 2 (which may not be available yet on older ANGLE versions), and as a fallback by checking if the line size range is just 1, which is always the case on D3D but not always on GL.

IntelWindows

Intel desktop drivers on Windows

Mesa

Mesa drivers on Windows and Linux. In particular, Intel, AMD and NVidia Mesa drivers match as this. See also DetectedDriver::Svga3D.

NVidia

Proprietary NVidia drivers on Windows and Linux

Svga3D

VMware guest GL driver SVGA3D, implemented using Mesa, both Windows and Linux guests. See https://www.mesa3d.org/vmware-guest.html for more information. Detected in combination with DetectedDriver::Mesa.

SwiftShader new in 2019.10

SwiftShader software renderer for OpenGL ES. Usually used by browsers in cases where a GPU isn't available. See also DetectedDriver::Angle.

ArmMali new in 2019.10

ARM Mali drivers on OpenGL ES.

QualcommAdreno new in Git master

Qualcomm Adreno drivers for OpenGL ES.

Typedef documentation

typedef Containers::EnumSet<Flag> Magnum::GL::Context::Flags

Context flags.

typedef Containers::EnumSet<State> Magnum::GL::Context::States

States to reset.

typedef Containers::EnumSet<DetectedDriver> Magnum::GL::Context::DetectedDrivers

Detected drivers.

Function documentation

static bool Magnum::GL::Context::hasCurrent()

Whether there is any current context.

If Corrade is built with CORRADE_BUILD_MULTITHREADED, current context is thread-local instead of global (the default).

static Context& Magnum::GL::Context::current()

Current context.

Expect that there is current context. If Corrade is built with CORRADE_BUILD_MULTITHREADED, current context is thread-local instead of global (the default).

static void Magnum::GL::Context::makeCurrent(Context* context) new in 2019.10

Make a context current.

To be used when you need to manage multiple OpenGL contexts. See Using multiple OpenGL contexts for more information.

Version Magnum::GL::Context::version() const

OpenGL version.

Containers::StringView Magnum::GL::Context::vendorString() const

Vendor string.

The result is not cached, repeated queries will result in repeated OpenGL calls. The returned view is always Containers::StringViewFlag::NullTerminated and Global. In WebGL the vendor string is implicitly masked away, use vendorStringUnmasked() to access the real vendor string, if available.

Containers::StringView Magnum::GL::Context::vendorStringUnmasked() const new in Git master

Unmasked vendor string.

A WebGL counterpart to vendorString() that returns the real vendor string. If WEBGL_debug_renderer_info is not available, returns the same as vendorString().

The result is not cached, repeated queries will result in repeated OpenGL calls. The returned view is always Containers::StringViewFlag::NullTerminated and Global.

Containers::StringView Magnum::GL::Context::rendererString() const

Renderer string.

The result is not cached, repeated queries will result in repeated OpenGL calls. The returned view is always Containers::StringViewFlag::NullTerminated and Global. In WebGL the renderer string is implicitly masked away, use rendererStringUnmasked() to access the real renderer string, if available.

Containers::StringView Magnum::GL::Context::rendererStringUnmasked() const new in Git master

Unmasked renderer string.

A WebGL counterpart to rendererString() that returns the real renderer string. If WEBGL_debug_renderer_info is not available, returns the same as rendererString().

The result is not cached, repeated queries will result in repeated OpenGL calls. The returned view is always Containers::StringViewFlag::NullTerminated and Global.

Containers::StringView Magnum::GL::Context::versionString() const

Version string.

The result is not cached, repeated queries will result in repeated OpenGL calls. The returned view is always Containers::StringViewFlag::NullTerminated and Global.

Containers::StringView Magnum::GL::Context::shadingLanguageVersionString() const

Shading language version string.

The result is not cached, repeated queries will result in repeated OpenGL calls. The returned view is always Containers::StringViewFlag::NullTerminated and Global.

Containers::Array<Containers::StringView> Magnum::GL::Context::shadingLanguageVersionStrings() const

Shading language version strings.

The result is not cached, repeated queries will result in repeated OpenGL calls. The returned view is always Containers::StringViewFlag::NullTerminated and Global.

Containers::Array<Containers::StringView> Magnum::GL::Context::extensionStrings() const

Extension strings.

The result is not cached, repeated queries will result in repeated OpenGL calls. Note that this function returns list of all extensions reported by the driver (even those not supported by Magnum), see Extension::extensions() or isExtensionSupported() for alternatives. The returned views are always Containers::StringViewFlag::NullTerminated and Global.

Flags Magnum::GL::Context::flags() const

Context flags.

Containers::ArrayView<const Extension> Magnum::GL::Context::supportedExtensions() const

Supported extensions.

The list contains only extensions from OpenGL versions newer than the current.

bool Magnum::GL::Context::isCoreProfile()

Detect if current OpenGL context is a core profile.

The result is cached, repeated queries don't result in repeated OpenGL calls.

bool Magnum::GL::Context::isVersionSupported(Version version) const

Whether given OpenGL version is supported.

Version Magnum::GL::Context::supportedVersion(std::initializer_list<Version> versions) const

Get supported OpenGL version.

Returns first supported OpenGL version from passed list. Convenient equivalent to subsequent isVersionSupported() calls — the two following examples produce the same result:

GL::Version v1 = GL::Context::current().isVersionSupported(GL::Version::GL330) ?
    GL::Version::GL330 : GL::Version::GL210;
GL::Version v2 = GL::Context::current().supportedVersion({
    GL::Version::GL330, GL::Version::GL210});

If no version from the list is supported, returns lowest available OpenGL version (Version::GL210 for desktop OpenGL, Version::GLES200 for OpenGL ES).

template<class E>
bool Magnum::GL::Context::isExtensionSupported() const

Whether given extension is supported.

Extensions usable with this function are listed in the Extensions namespace in the Magnum/GL/Extensions.h header and in the OpenGL support tables. Example usage:

if(GL::Context::current().isExtensionSupported<GL::Extensions::ARB::tessellation_shader>()) {
    // draw fancy detailed model
} else {
    // texture fallback
}

template<class E>
bool Magnum::GL::Context::isExtensionSupported(Version version) const

Whether given extension is supported in given version.

Similar to isExtensionSupported(), but checks also that the minimal required version of the extension is larger or equal to version. Useful mainly in shader compilation when the decisions depend on selected GLSL version, for example:

const GL::Version version = GL::Context::current().supportedVersion({
    GL::Version::GL320, GL::Version::GL300, GL::Version::GL210});
if(GL::Context::current().isExtensionSupported<GL::Extensions::ARB::explicit_attrib_location>(version)) {
    // Called only if ARB_explicit_attrib_location is supported
    // *and* version is higher than GL 3.1
}

bool Magnum::GL::Context::isExtensionSupported(const Extension& extension) const

Whether given extension is supported.

Can be used e.g. for listing extensions available on current hardware, but for general usage prefer isExtensionSupported() const, as it does most operations in compile time.

template<class E>
bool Magnum::GL::Context::isExtensionDisabled() const

Whether given extension is disabled.

Can be used for detecting driver bug workarounds. Disabled extensions return false in isExtensionSupported() even if they are advertised as being supported by the driver.

template<class E>
bool Magnum::GL::Context::isExtensionDisabled(Version version) const

Whether given extension is disabled for given version.

Similar to above, but can also check for extensions which are disabled only for particular versions.

bool Magnum::GL::Context::isExtensionDisabled(const Extension& extension) const

Whether given extension is disabled.

Can be used e.g. for listing extensions available on current hardware, but for general usage prefer isExtensionDisabled() const, as it does most operations at compile time.

void Magnum::GL::Context::resetState(States states = ~States{})

Reset internal state tracker.

The engine internally tracks object bindings and other state to avoid redundant OpenGL calls. In some cases (e.g. when non-Magnum code makes GL calls) the internal tracker no longer reflects actual state. Equivalently the third party code can cause accidental modifications of Magnum objects. It's thus advised to call this function as a barrier between Magnum code and third-party GL code.

The default, when calling this function with no parameters, will reset all state. That's the safest option, but may have considerable performance impact when third-party and Magnum code is combined very often. For greater control it's possible to reset only particular states from the State enum.

See also State tracking and interaction with third-party code for more information.

DetectedDrivers Magnum::GL::Context::detectedDriver()

Detect driver.

Tries to detect driver using various OpenGL state queries. Once the detection is done, the result is cached, repeated queries don't result in repeated GL calls. Used primarily for enabling driver-specific workarounds.

Debug& operator<<(Debug& debug, Context::Flag value)

Debug output operator.

Debug& operator<<(Debug& debug, Context::Flags value)

Debug output operator.

Debug& operator<<(Debug& debug, Context::DetectedDriver value)

Debug output operator.

Debug& operator<<(Debug& debug, Context::DetectedDrivers value)

Debug output operator.