diff --git a/CONTRIBUTORS.md b/CREDITS.md
similarity index 58%
rename from CONTRIBUTORS.md
rename to CREDITS.md
index 5de717cf0..8697d8ae2 100644
--- a/CONTRIBUTORS.md
+++ b/CREDITS.md
@@ -1,3 +1,10 @@
+Third-party components
+----------------------
+
+* **flextGL** extension loader generator -- https://github.com/ginkgo/flextGL,
+ Copyright © 2011 Thomas Weber, licensed under
+ [MIT license](https://raw.githubusercontent.com/ginkgo/flextGL/master/COPYING)
+
Contributors to Magnum library
------------------------------
@@ -10,5 +17,9 @@ Contributors to Magnum library
port improvements
* Stefan Wasilewski ([@smw](https://github.com/smw)) -- Mac OS X port
improvements
+* Konstantinos Chatzilygeroudis ([@costashatz](https://github.com/costashatz)) --
+ Debian package
+* Olga Turanksaya ([@olga-python](https://github.com/olga-python)) -- Gentoo
+ ebuild
Big thanks to everyone involved!
diff --git a/Doxyfile b/Doxyfile
index bbf610f7c..0335627a3 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -258,9 +258,11 @@ ALIASES = \
"requires_gl42=@xrefitem requires-gl42 \"Requires OpenGL 4.2\" \"Functionality requiring OpenGL 4.2\"" \
"requires_gl43=@xrefitem requires-gl43 \"Requires OpenGL 4.3\" \"Functionality requiring OpenGL 4.3\"" \
"requires_gl44=@xrefitem requires-gl44 \"Requires OpenGL 4.4\" \"Functionality requiring OpenGL 4.4\"" \
+ "requires_gl45=@xrefitem requires-gl45 \"Requires OpenGL 4.5\" \"Functionality requiring OpenGL 4.5\"" \
"requires_extension=@xrefitem requires-extension \"Requires OpenGL extension\" \"Functionality requiring specific OpenGL extension\"" \
"extension{2}=\1_\2" \
"extension2{2}=\1_\2" \
+ "extension3{3}=\1_\2" \
"requires_gles30=@xrefitem requires-gles30 \"Requires OpenGL ES 3.0\" \"Functionality requiring OpenGL ES 3.0\"" \
"requires_gles31=@xrefitem requires-gles31 \"Requires OpenGL ES 3.1\" \"Functionality requiring OpenGL ES 3.1\"" \
"requires_gl=@xrefitem requires-gl \"Requires desktop OpenGL\" \"Functionality requiring desktop OpenGL (not available in OpenGL ES)\"" \
diff --git a/README.md b/README.md
index 645ecfff7..a5f2e32f5 100644
--- a/README.md
+++ b/README.md
@@ -41,7 +41,7 @@ SUPPORTED PLATFORMS
Graphics APIs:
-* **OpenGL** 2.1 through 4.4, core profile functionality and modern
+* **OpenGL** 2.1 through 4.5, core profile functionality and modern
extensions
* **OpenGL ES** 2.0, 3.0, 3.1 and extensions to match desktop OpenGL
functionality
@@ -77,9 +77,9 @@ INSTALLATION
============
You can either use packaging scripts, which are stored in `package/`
-subdirectory, or compile and install everything manually. Note that Doxygen
-documentation (see above or build your own using instructions below) contains
-more comprehensive guide for building, packaging and crosscompiling.
+subdirectory, or compile and install everything manually. Note that
+[Magnum documentation](http://mosra.cz/blog/magnum-doc/) contains more
+comprehensive guide for building, packaging and crosscompiling.
Minimal dependencies
--------------------
@@ -147,17 +147,20 @@ RELATED PROJECTS
The engine itself is kept as small as possible with only little dependencies.
Additional functionality, often depending on external libraries, is provided in
-separate repositories. Integration with various external math and physics
-libraries can be found at https://github.com/mosra/magnum-integration. Various
-importer plugins for image, audio and 3D model formats are maintained in
-separate repository, which can be found at https://github.com/mosra/magnum-plugins.
-
-There are also examples of engine usage, varying from simple *Hello World*-like
-example to more advanced applications, such as viewer for complex 3D models.
-Example repository is at https://github.com/mosra/magnum-examples.
-
-Repository with bootstrap projects for many use cases, helping you get up and
-running in no time is located at https://github.com/mosra/magnum-bootstrap.
+separate repositories.
+
+* **Magnum Bootstrap** -- bootstrap projects for many use cases, helping you
+ get up and running in no time: https://github.com/mosra/magnum-bootstrap
+* **Magnum Plugins** -- various importer plugins for image, font, audio and
+ 3D model formats is at https://github.com/mosra/magnum-plugins
+* **Magnum Integration** -- integration with various external math and
+ physics, get it at https://github.com/mosra/magnum-integration
+* **Magnum Examples** -- examples of engine usage, varying from simple
+ *Hello World*-like example to more advanced applications, such as viewer
+ for complex 3D models. See it at https://github.com/mosra/magnum-examples
+* **libRocket integration** -- integrates Magnum as rendering backend into
+ [libRocket](https://github.com/libRocket/libRocket) GUI library:
+ https://github.com/miguelmartin75/Magnum-libRocket
CONTACT
=======
@@ -172,11 +175,10 @@ idea? Feel free to visit my website or contact me at:
* E-mail -- mosra@centrum.cz
* Jabber -- mosra@jabbim.cz
-CONTRIBUTORS
-============
+CREDITS
+=======
-See [CONTRIBUTORS.md](CONTRIBUTORS.md) file for details. Big thanks to everyone
-involved!
+See [CREDITS.md](CREDITS.md) file for details. Big thanks to everyone involved!
LICENSE
=======
diff --git a/doc/building.dox b/doc/building.dox
index 5693d73a4..fa1592a2b 100644
--- a/doc/building.dox
+++ b/doc/building.dox
@@ -78,6 +78,15 @@ can be built and installed using these four commands:
See @ref building-features "below" for additional configuration options.
+If you have the dependencies installed in non-standard location (other than
+`/usr`, e.g. `/home/xyz/projects`), set `CMAKE_PREFIX_PATH` to that directory
+to help CMake find them. You can enter more different dirs if you separate them
+with semicolons.
+
+Also, if you plan to install the library to non-standard location, you might
+want to set `CMAKE_INSTALL_RPATH` to `lib/` subdir of given prefix (e.g.
+`/home/xyz/projects/lib`), so the dynamic libraries can be found at runtime.
+
@subsection building-windows Building on Windows
On Windows you can use either MinGW or MSVC 2013 compiler. It's then up to you
@@ -86,12 +95,11 @@ line. Note that for most convenient usage it's best use some dedicated
directory (e.g. `C:/Sys`) for installing dependencies instead of putting each
dependency to its own directory in `C:/Program Files`. Then add its `bin/`
subdir (e.g. `C:/Sys/bin`) to PATH so all the DLLs are found when running the
-executables. If you are using MinGW, the `C:/MinGW` directory is in most cases
+executables. If you are using MinGW, the `C:/MinGW` directory is in most cases
already prepared for exactly this.
-When running CMake, set `CMAKE_INSTALL_PREFIX` parameter to that directory so
-CMake knows where to look for installed libraries and where to install new
-ones.
+Then, when running CMake, set `CMAKE_PREFIX_PATH` and `CMAKE_INSTALL_PREFIX`
+value to that directory (e.g. `-DCMAKE_INSTALL_PREFIX=C:/Sys`).
@subsubsection building-windows-msvc Using Visual Studio
@@ -116,8 +124,8 @@ On Windows you can also use QtCreator (just QtCreator, you don't need the full
Qt SDK). Configure it to use CMake and either MSVC compiler or MinGW and and
then just open project's root `CMakeLists.txt` file within it. QtCreator then
asks you where to create build directory, allows you to specify initial CMake
-parameters (e.g. `CMAKE_FIND_ROOT_PATH` and `CMAKE_INSTALL_PREFIX`) and then
-you can just press *Configure* and everything is ready to be built.
+parameters (e.g. `CMAKE_PREFIX_PATH` and `CMAKE_INSTALL_PREFIX`) and then you
+can just press *Configure* and everything is ready to be built.
After the initial import you might want to reconfigure some CMake variables,
see @ref building-features "below" for more information.
@@ -307,6 +315,10 @@ project root:
makepkg -p package/archlinux/
+@subsection building-packages-gentoo Gentoo ebuilds
+
+Gentoo Git ebuild is available in `package/gentoo` directory.
+
@subsection building-packages-deb DEB packages
There is also `package/debian/` directory with all files needed for building
diff --git a/doc/cmake.dox b/doc/cmake.dox
index 46ba9862a..9a7199bc4 100644
--- a/doc/cmake.dox
+++ b/doc/cmake.dox
@@ -41,6 +41,11 @@ Note that the module files are updated as the library evolves, you are
encouraged to update your copies from time to time to avoid strange building
issues.
+If you installed the library or its dependencies to non-standard location
+(other than `/usr`, e.g. `/home/xyz/projects`), set `CMAKE_PREFIX_PATH` to that
+directory to help CMake find it. You can enter more different dirs if you
+separate them with semicolons.
+
Basic usage is:
find_package(Magnum REQUIRED)
diff --git a/doc/getting-started.dox b/doc/getting-started.dox
index e8d0ff721..21421ec26 100644
--- a/doc/getting-started.dox
+++ b/doc/getting-started.dox
@@ -164,14 +164,14 @@ straightforward way to create the project file is via the command-line:
mkdir build
cd build
- cmake -DCMAKE_FIND_ROOT_PATH="C:/Sys" ..
+ cmake -DCMAKE_PREFIX_PATH="C:/Sys" ..
You can also use CMake GUI. Then open the `MyApplication.sln` project file
generated by CMake in the build directory.
With QtCreator just open project's root `CMakeLists.txt` file. It then asks you
where to create build directory, allows you to specify initial CMake parameters
-(e.g. `CMAKE_FIND_ROOT_PATH`) and then you can just press *Configure* and
+(e.g. `CMAKE_PREFIX_PATH`) and then you can just press *Configure* and
everything is ready to be built.
If CMake isn't able to find the dependencies on Windows, you might want to look
diff --git a/doc/mainpage.dox b/doc/mainpage.dox
index 41f8e69f8..47140d8ed 100644
--- a/doc/mainpage.dox
+++ b/doc/mainpage.dox
@@ -67,7 +67,7 @@ recent C++11 features and to abstract away platform-specific issues.
Graphics APIs:
-- **OpenGL** 2.1 through 4.4, core profile functionality and modern
+- **OpenGL** 2.1 through 4.5, core profile functionality and modern
extensions
- **OpenGL ES** 2.0, 3.0, 3.1 and extensions to match desktop OpenGL
functionality
diff --git a/doc/opengl-mapping.dox b/doc/opengl-mapping.dox
index 06608e7f0..7d7c55992 100644
--- a/doc/opengl-mapping.dox
+++ b/doc/opengl-mapping.dox
@@ -38,255 +38,360 @@ Legend:
@section opengl-mapping-functions Functions
-OpenGL function | Matching API
--------------------------------------- | ------------
-@fn_gl{ActiveShaderProgram} | not needed as @fn_gl{ProgramUniform} calls are used
-@fn_gl{ActiveTexture} | @ref AbstractTexture::bind()
-@fn_gl{AttachShader} | @ref AbstractShaderProgram::attachShader()
+@subsection opengl-mapping-functions-a A
+
+OpenGL function | Matching API
+--------------------------------------- | ------------
+@fn_gl{ActiveShaderProgram} | not needed as @fn_gl{ProgramUniform} calls are used
+@fn_gl{ActiveTexture} | @ref AbstractTexture::bind()
+@fn_gl{AttachShader} | @ref AbstractShaderProgram::attachShader()
+
+@subsection opengl-mapping-functions-b B
+
+OpenGL function | Matching API
+--------------------------------------- | ------------
@fn_gl{BeginConditionalRender}, `glEndConditionalRender()` | @ref SampleQuery::beginConditionalRender(), \n @ref SampleQuery::endConditionalRender()
-@fn_gl{BeginQuery}, `glEndQuery()` | @ref PrimitiveQuery::begin(), \n @ref SampleQuery::begin(), \n @ref TimeQuery::begin(), \n @ref AbstractQuery::end()
+@fn_gl{BeginQuery}, `glEndQuery()` | @ref PrimitiveQuery::begin(), \n @ref SampleQuery::begin(), \n @ref TimeQuery::begin(), \n @ref AbstractQuery::end()
@fn_gl{BeginQueryIndexed}, `glEndQueryIndexed()` | |
@fn_gl{BeginTransformFeedback}, `glEndTransformFeedback()` | |
-@fn_gl{BindAttribLocation} | @ref AbstractShaderProgram::bindAttributeLocation()
-@fn_gl{BindBuffer} | not needed, handled internally in @ref Buffer and elsewhere
-@fn_gl{BindBufferBase}, \n @fn_gl{BindBuffersBase}, \n @fn_gl{BindBufferRange}, \n @fn_gl{BindBuffersRange} | |
-@fn_gl{BindFragDataLocation} | @ref AbstractShaderProgram::bindFragmentDataLocation()
-@fn_gl{BindFragDataLocationIndexed} | @ref AbstractShaderProgram::bindFragmentDataLocationIndexed()
-@fn_gl{BindFramebuffer} | @ref Framebuffer::bind()
+@fn_gl{BindAttribLocation} | @ref AbstractShaderProgram::bindAttributeLocation()
+@fn_gl{BindBuffer} | not needed, handled internally in @ref Buffer and elsewhere
+@fn_gl{BindBufferBase}, \n @fn_gl{BindBuffersBase}, \n @fn_gl{BindBufferRange}, \n @fn_gl{BindBuffersRange} | @ref Buffer::bind(), \n @ref Buffer::unbind()
+@fn_gl{BindFragDataLocation} | @ref AbstractShaderProgram::bindFragmentDataLocation()
+@fn_gl{BindFragDataLocationIndexed} | @ref AbstractShaderProgram::bindFragmentDataLocationIndexed()
+@fn_gl{BindFramebuffer} | @ref Framebuffer::bind()
@fn_gl{BindImageTexture}, \n @fn_gl{BindImageTextures} | |
-@fn_gl{BindProgramPipeline} | |
-@fn_gl{BindRenderbuffer} | not needed, handled internally in @ref Renderbuffer
+@fn_gl{BindProgramPipeline} | |
+@fn_gl{BindRenderbuffer} | not needed, handled internally in @ref Renderbuffer
@fn_gl{BindSampler}, \n @fn_gl{BindSamplers} | |
-@fn_gl{BindTexture}, \n @fn_gl{BindTextures}, \n @fn_gl_extension{BindMultiTexture,EXT,direct_state_access} | @ref AbstractTexture::bind()
-@fn_gl{BindTransformFeedback} | |
-@fn_gl{BindVertexArray} | not needed, handled internally in @ref Mesh
-@fn_gl{BindVertexBuffer}, \n @fn_gl{BindVertexBuffers} | |
-@fn_gl{BlendColor} | @ref Renderer::setBlendColor()
+@fn_gl{BindTexture}, \n @fn_gl{BindTextureUnit}, \n @fn_gl{BindTextures}, \n @fn_gl_extension{BindMultiTexture,EXT,direct_state_access} | @ref AbstractTexture::bind()
+@fn_gl{BindTransformFeedback} | |
+@fn_gl{BindVertexArray} | not needed, handled internally in @ref Mesh
+@fn_gl{BindVertexBuffer}, \n `glVertexArrayVertexBuffer()`, \n @fn_gl_extension{VertexArrayBindVertexBuffer,EXT,direct_state_access} \n @fn_gl{BindVertexBuffers}, \n `glVertexArrayVertexBuffers()` | |
+@fn_gl{BlendColor} | @ref Renderer::setBlendColor()
@fn_gl{BlendEquation}, \n @fn_gl{BlendEquationSeparate} | @ref Renderer::setBlendEquation()
@fn_gl{BlendFunc}, \n @fn_gl{BlendFuncSeparate} | @ref Renderer::setBlendFunction()
-@fn_gl{BlitFramebuffer} | @ref AbstractFramebuffer::blit()
-@fn_gl{BufferData}, \n @fn_gl_extension{NamedBufferData,EXT,direct_state_access} | @ref Buffer::setData()
-@fn_gl{BufferStorage} | |
-@fn_gl{BufferSubData}, \n @fn_gl_extension{NamedBufferSubData,EXT,direct_state_access} | @ref Buffer::setSubData()
-@fn_gl{CheckFramebufferStatus}, \n @fn_gl_extension{CheckNamedFramebufferStatus,EXT,direct_state_access} | @ref DefaultFramebuffer::checkStatus(), \n @ref Framebuffer::checkStatus()
-@fn_gl{ClampColor} | |
-@fn_gl{Clear} | @ref AbstractFramebuffer::clear()
-@fn_gl{ClearBuffer} | |
-@fn_gl{ClearBufferData} | |
-@fn_gl{ClearBufferSubData} | |
-@fn_gl{ClearColor} | @ref Renderer::setClearColor()
-@fn_gl{ClearDepth} | @ref Renderer::setClearDepth()
-@fn_gl{ClearStencil} | @ref Renderer::setClearStencil()
-@fn_gl{ClearTexImage} | |
-@fn_gl{ClearTexSubImage} | |
-@fn_gl{ClientWaitSync} | |
-@fn_gl{ColorMask} | @ref Renderer::setColorMask()
-@fn_gl{CompileShader} | @ref Shader::compile()
-@fn_gl{CompressedTexImage1D}, \n @fn_gl{CompressedTexImage2D}, \n @fn_gl{CompressedTexImage3D} | |
-@fn_gl{CompressedTexSubImage1D}, \n @fn_gl{CompressedTexSubImage2D}, \n @fn_gl{CompressedTexSubImage3D} | |
-@fn_gl{CopyBufferSubData}, \n @fn_gl_extension{NamedCopyBufferSubData,EXT,direct_state_access} | @ref Buffer::copy()
-@fn_gl{CopyImageSubData} | |
-@fn_gl{CopyTexImage1D}, \n @fn_gl{CopyTexImage2D} | |
-@fn_gl{CopyTexSubImage1D}, \n @fn_gl{CopyTexSubImage2D}, \n @fn_gl{CopyTexSubImage3D} | |
+@fn_gl{BlitFramebuffer}, \n `glBlitNamedFramebuffer()` | @ref AbstractFramebuffer::blit()
+@fn_gl{BufferData}, \n `glNamedBufferData()`, \n @fn_gl_extension{NamedBufferData,EXT,direct_state_access} | @ref Buffer::setData()
+@fn_gl{BufferStorage}, \n `glNamedBufferStorage()`, \n @fn_gl_extension{NamedBufferStorage,EXT,direct_state_access} | |
+@fn_gl{BufferSubData}, \n `glNamedBufferSubData()`, \n @fn_gl_extension{NamedBufferSubData,EXT,direct_state_access} | @ref Buffer::setSubData()
+
+@subsection opengl-mapping-functions-c C
+
+OpenGL function | Matching API
+--------------------------------------- | ------------
+@fn_gl{CheckFramebufferStatus}, \n `glCheckNamedFramebufferStatus()`, \n @fn_gl_extension{CheckNamedFramebufferStatus,EXT,direct_state_access} | @ref DefaultFramebuffer::checkStatus(), \n @ref Framebuffer::checkStatus()
+@fn_gl{ClampColor} | |
+@fn_gl{Clear} | @ref AbstractFramebuffer::clear()
+@fn_gl{ClearBuffer}, \n `glClearNamedFramebuffer()` | |
+@fn_gl{ClearBufferData}, \n `glClearNamedBufferData()`, \n @fn_gl_extension{ClearNamedBufferData,EXT,direct_state_access} | |
+@fn_gl{ClearBufferSubData}, \n `glClearNamedBufferSubData()`, \n @fn_gl_extension{ClearNamedBufferSubData,EXT,direct_state_access} | |
+@fn_gl{ClearColor} | @ref Renderer::setClearColor()
+@fn_gl{ClearDepth} | @ref Renderer::setClearDepth()
+@fn_gl{ClearStencil} | @ref Renderer::setClearStencil()
+@fn_gl{ClearTexImage} | |
+@fn_gl{ClearTexSubImage} | |
+@fn_gl{ClientWaitSync} | |
+@fn_gl{ClipControl} | |
+@fn_gl{ColorMask} | @ref Renderer::setColorMask()
+@fn_gl{CompileShader} | @ref Shader::compile()
+@fn_gl{CompressedTexImage1D}, \n @fn_gl_extension{CompressedTextureImage1D,EXT,direct_state_access}, \n @fn_gl{CompressedTexImage2D}, \n @fn_gl_extension{CompressedTextureImage2D,EXT,direct_state_access}, \n @fn_gl{CompressedTexImage3D}, \n @fn_gl_extension{CompressedTextureImage3D,EXT,direct_state_access} | |
+@fn_gl{CompressedTexSubImage1D}, \n `glCompressedTextureSubImage1D()`, \n @fn_gl_extension{CompressedTextureSubImage1D,EXT,direct_state_access}, \n @fn_gl{CompressedTexSubImage2D}, \n `glCompressedTextureSubImage2D()`, \n @fn_gl_extension{CompressedTextureSubImage2D,EXT,direct_state_access}, \n @fn_gl{CompressedTexSubImage3D}, \n `glCompressedTextureSubImage3D()`, \n @fn_gl_extension{CompressedTextureSubImage3D,EXT,direct_state_access} | |
+@fn_gl{CopyBufferSubData}, \n `glCopyNamedBufferSubData()`, \n @fn_gl_extension{NamedCopyBufferSubData,EXT,direct_state_access} | @ref Buffer::copy()
+@fn_gl{CopyImageSubData} | |
+@fn_gl{CopyTexImage1D}, \n @fn_gl_extension{CopyTextureImage1D,EXT,direct_state_access}, \n @fn_gl{CopyTexImage2D}, \n @fn_gl_extension{CopyTextureImage2D,EXT,direct_state_access} | |
+@fn_gl{CopyTexSubImage1D}, \n `glCopyTextureSubImage1D()`, \n @fn_gl_extension{CopyTextureSubImage1D,EXT,direct_state_access}, \n @fn_gl{CopyTexSubImage2D}, \n `glCopyTextureSubImage2D()`, \n @fn_gl_extension{CopyTextureSubImage2D,EXT,direct_state_access}, \n @fn_gl{CopyTexSubImage3D}, \n `glCopyTextureSubImage3D()`, \n @fn_gl_extension{CopyTextureSubImage3D,EXT,direct_state_access} | |
@fn_gl{CreateProgram}, @fn_gl{DeleteProgram} | @ref AbstractShaderProgram constructor and destructor
@fn_gl{CreateShader}, @fn_gl{DeleteShader} | @ref Shader constructor and destructor
-@fn_gl{CreateShaderProgram} | |
-@fn_gl{CullFace} | @ref Renderer::setFaceCullingMode()
-@fn_gl{DebugMessageCallback} | @ref DebugMessage::setCallback()
-@fn_gl{DebugMessageControl} | @ref DebugMessage::setEnabled()
+@fn_gl{CreateShaderProgram} | |
+@fn_gl{CullFace} | @ref Renderer::setFaceCullingMode()
+
+@subsection opengl-mapping-functions-d D
+
+OpenGL function | Matching API
+--------------------------------------- | ------------
+@fn_gl{DebugMessageCallback} | @ref DebugMessage::setCallback()
+@fn_gl{DebugMessageControl} | @ref DebugMessage::setEnabled()
@fn_gl{DebugMessageInsert}, \n @fn_gl_extension2{InsertEventMarker,EXT,debug_marker}, \n @fn_gl_extension{StringMarker,GREMEDY,string_marker} | @ref DebugMessage::insert()
-@fn_gl{DepthFunc} | @ref Renderer::setDepthFunction()
-@fn_gl{DepthMask} | @ref Renderer::setDepthMask()
-@fn_gl{DepthRange} | |
-@fn_gl{DepthRangeArray} | |
-@fn_gl{DepthRangeIndexed} | |
-@fn_gl{DetachShader} | |
-@fn_gl{DispatchCompute} | |
-@fn_gl{DispatchComputeIndirect} | |
+@fn_gl{DepthFunc} | @ref Renderer::setDepthFunction()
+@fn_gl{DepthMask} | @ref Renderer::setDepthMask()
+@fn_gl{DepthRange} | |
+@fn_gl{DepthRangeArray} | |
+@fn_gl{DepthRangeIndexed} | |
+@fn_gl{DetachShader} | |
+@fn_gl{DispatchCompute} | |
+@fn_gl{DispatchComputeIndirect} | |
@fn_gl{DrawArrays}, \n @fn_gl{DrawArraysInstanced}, \n @fn_gl{DrawArraysInstancedBaseInstance}, \n @fn_gl{DrawElements}, \n @fn_gl{DrawRangeElements}, \n @fn_gl{DrawElementsBaseVertex}, \n @fn_gl{DrawRangeElementsBaseVertex}, \n @fn_gl{DrawElementsInstanced}, \n @fn_gl{DrawElementsInstancedBaseInstance}, \n @fn_gl{DrawElementsInstancedBaseVertex}, \n @fn_gl{DrawElementsInstancedBaseVertexBaseInstance} | @ref Mesh::draw(), \n @ref MeshView::draw()
@fn_gl{DrawArraysIndirect}, \n @fn_gl{DrawElementsIndirect}, \n @fn_gl{MultiDrawArraysIndirect}, \n @fn_gl{MultiDrawElementsIndirect} | |
-@fn_gl{DrawBuffer}, \n @fn_gl_extension{FramebufferDrawBuffers,EXT,direct_state_access}, \n @fn_gl{DrawBuffers}, \n @fn_gl_extension{FramebufferDrawBuffers,EXT,direct_state_access} | @ref DefaultFramebuffer::mapForDraw(), \n @ref Framebuffer::mapForDraw()
+@fn_gl{DrawBuffer}, \n `glNamedFramebufferDrawBuffer()`, \n @fn_gl_extension{FramebufferDrawBuffer,EXT,direct_state_access}, \n @fn_gl{DrawBuffers}, \n `glNamedFramebufferDrawBuffers()`, \n @fn_gl_extension{FramebufferDrawBuffers,EXT,direct_state_access} | @ref DefaultFramebuffer::mapForDraw(), \n @ref Framebuffer::mapForDraw()
@fn_gl{DrawTransformFeedback}, \n @fn_gl{DrawTransformFeedbackInstanced}, \n @fn_gl{DrawTransformFeedbackStream}, \n @fn_gl{DrawTransformFeedbackStreamInstanced} | |
-@fn_gl{Enable}, `glDisable()` | @ref Renderer::setFeature()
-@fn_gl{EnableVertexAttribArray}, \n @fn_gl_extension{EnableVertexArrayAttrib,EXT,direct_state_access} \n @fn_gl2{DisableVertexAttribArray,EnableVertexAttribArray}, \n @fn_gl_extension{DisableVertexArrayAttrib,EXT,direct_state_access} | @ref Mesh::addVertexBuffer()
-@fn_gl{FenceSync}, @fn_gl{DeleteSync} | |
-@fn_gl{Finish} | @ref Renderer::finish()
-@fn_gl{Flush} | @ref Renderer::flush()
-@fn_gl{FlushMappedBufferRange}, \n @fn_gl_extension{FlushMappedNamedBufferRange,EXT,direct_state_access} | @ref Buffer::flushMappedRange()
-@fn_gl2{FramebufferParameter,FramebufferParameteri} | |
-@fn_gl{FramebufferRenderbuffer}, \n @fn_gl_extension{NamedFramebufferRenderbuffer,EXT,direct_state_access} | @ref Framebuffer::attachRenderbuffer()
-@fn_gl{FramebufferTexture} | not used, the functions below are used instead for compatibility reasons
+
+@subsection opengl-mapping-functions-e E
+
+OpenGL function | Matching API
+--------------------------------------- | ------------
+@fn_gl{Enable}, `glDisable()` | @ref Renderer::setFeature()
+@fn_gl{EnableVertexAttribArray}, \n `glEnableVertexArrayAttrib()`, \n @fn_gl_extension{EnableVertexArrayAttrib,EXT,direct_state_access}, \n `glDisableVertexAttribArray()`, \n `glDisableVertexArrayAttrib()`, \n `glDisableVertexArrayAttribEXT()` | @ref Mesh::addVertexBuffer()
+
+@subsection opengl-mapping-functions-f F
+
+OpenGL function | Matching API
+--------------------------------------- | ------------
+@fn_gl{FenceSync}, @fn_gl{DeleteSync} | |
+@fn_gl{Finish} | @ref Renderer::finish()
+@fn_gl{Flush} | @ref Renderer::flush()
+@fn_gl{FlushMappedBufferRange}, \n `glFlushMappedNamedBufferRange()`, \n @fn_gl_extension{FlushMappedNamedBufferRange,EXT,direct_state_access} | @ref Buffer::flushMappedRange()
+@fn_gl2{FramebufferParameter,FramebufferParameteri}, \n `glNamedFramebufferParameter()`, \n @fn_gl_extension{NamedFramebufferParameter,EXT,direct_state_access} | |
+@fn_gl{FramebufferRenderbuffer}, \n `glNamedFramebufferRenderbuffer()`, \n @fn_gl_extension{NamedFramebufferRenderbuffer,EXT,direct_state_access} | @ref Framebuffer::attachRenderbuffer()
+@fn_gl{FramebufferTexture}, \n `glNamedFramebufferTexture()`, \n @fn_gl_extension{NamedFramebufferTexture,EXT,direct_state_access} | not used, the functions below are used instead for compatibility reasons
@fn_gl2{FramebufferTexture1D,FramebufferTexture}, \n @fn_gl_extension{NamedFramebufferTexture1D,EXT,direct_state_access}, \n `glFramebufferTexture2D()`, \n `glNamedFramebufferTexture2DEXT()` | @ref Framebuffer::attachTexture()
@fn_gl2{FramebufferTexture3D,FramebufferTexture} | not used, @fn_gl{FramebufferTextureLayer} has more complete features
-@fn_gl{FramebufferTextureLayer}, \n @fn_gl_extension{NamedFramebufferTextureLayer,EXT,direct_state_access} | @ref Framebuffer::attachTextureLayer()
-@fn_gl{FrontFace} | @ref Renderer::setFrontFace()
-@fn_gl{GenBuffers}, @fn_gl{DeleteBuffers} | @ref Buffer constructor and destructor
-@fn_gl{GenFramebuffers}, @fn_gl{DeleteFramebuffers} | @ref Framebuffer constructor and destructor
-@fn_gl{GenProgramPipelines}, @fn_gl{DeleteProgramPipelines} | |
-@fn_gl{GenQueries}, @fn_gl{DeleteQueries} | @ref AbstractQuery constructor and destructor
-@fn_gl{GenRenderbuffers}, @fn_gl{DeleteRenderbuffers} | @ref Renderbuffer constructor and destructor
-@fn_gl{GenSamplers}, @fn_gl{DeleteSamplers} | |
-@fn_gl{GenTextures}, @fn_gl{DeleteTextures} | @ref AbstractTexture constructor and destructor
-@fn_gl{GenTransformFeedbacks}, @fn_gl{DeleteTransformFeedbacks} | |
-@fn_gl{GenVertexArrays}, @fn_gl{DeleteVertexArrays} | @ref Mesh constructor and destructor
-@fn_gl{GenerateMipmap}, \n @fn_gl_extension{GenerateTextureMipmap,EXT,direct_state_access} | @ref Texture::generateMipmap(), \n @ref TextureArray::generateMipmap(), \n @ref CubeMapTexture::generateMipmap(), \n @ref CubeMapTextureArray::generateMipmap()
-@fn_gl{Get} | see @ref opengl-mapping-state "table below"
+@fn_gl{FramebufferTextureLayer}, \n `glNamedFramebufferTextureLayer()`, \n @fn_gl_extension{NamedFramebufferTextureLayer,EXT,direct_state_access} | @ref Framebuffer::attachTextureLayer()
+@fn_gl{FrontFace} | @ref Renderer::setFrontFace()
+
+@subsection opengl-mapping-functions-g G
+
+OpenGL function | Matching API
+--------------------------------------- | ------------
+@fn_gl{GenBuffers}, \n @fn_gl{CreateBuffers}, \n @fn_gl{DeleteBuffers} | @ref Buffer constructor and destructor
+@fn_gl{GenFramebuffers}, \n @fn_gl{CreateFramebuffers}, \n @fn_gl{DeleteFramebuffers} | @ref Framebuffer constructor and destructor
+@fn_gl{GenProgramPipelines}, \n @fn_gl{CreateProgramPipelines}, \n @fn_gl{DeleteProgramPipelines} | |
+@fn_gl{GenQueries}, \n @fn_gl{CreateQueries}, \n @fn_gl{DeleteQueries} | @ref AbstractQuery constructor and destructor
+@fn_gl{GenRenderbuffers}, \n @fn_gl{CreateRenderbuffers}, \n @fn_gl{DeleteRenderbuffers} | @ref Renderbuffer constructor and destructor
+@fn_gl{GenSamplers}, \n @fn_gl{CreateSamplers}, \n @fn_gl{DeleteSamplers} | |
+@fn_gl{GenTextures}, \n @fn_gl{CreateTextures}, \n @fn_gl{DeleteTextures} | @ref AbstractTexture constructor and destructor
+@fn_gl{GenTransformFeedbacks}, \n @fn_gl{CreateTransformFeedbacks}, \n @fn_gl{DeleteTransformFeedbacks} | |
+@fn_gl{GenVertexArrays}, \n @fn_gl{CreateVertexArrays}, \n @fn_gl{DeleteVertexArrays} | @ref Mesh constructor and destructor
+@fn_gl{GenerateMipmap}, \n `glGenerateTextureMipmap()`, \n @fn_gl_extension{GenerateTextureMipmap,EXT,direct_state_access} | @ref Texture::generateMipmap(), \n @ref TextureArray::generateMipmap(), \n @ref CubeMapTexture::generateMipmap(), \n @ref CubeMapTextureArray::generateMipmap()
+@fn_gl{Get} | see @ref opengl-mapping-state "table below"
@fn_gl2{GetActiveAtomicCounterBuffer,GetActiveAtomicCounterBufferiv} | not queryable
@fn_gl{GetActiveAttrib}, \n @fn_gl{GetActiveSubroutineName}, \n @fn_gl{GetActiveSubroutineUniform}, \n @fn_gl{GetActiveSubroutineUniformName}, \n @fn_gl{GetActiveUniform}, \n @fn_gl{GetActiveUniformBlock}, \n @fn_gl{GetActiveUniformBlockName}, \n @fn_gl{GetActiveUniformName}, \n @fn_gl{GetActiveUniforms} | not queryable
-@fn_gl{GetAttachedShaders} | not queryable, @ref AbstractShaderProgram::attachShader() setter only
-@fn_gl{GetAttribLocation} | not queryable, @ref AbstractShaderProgram::bindAttributeLocation() setter only
-@fn_gl{GetBufferParameter}, \n @fn_gl_extension{GetNamedBufferParameter,EXT,direct_state_access} | @ref Buffer::size()
-@fn_gl2{GetBufferPointer,GetBufferPointerv} | not queryable, @ref Buffer::map() setter only
-@fn_gl{GetBufferSubData}, \n @fn_gl_extension{GetNamedBufferSubData,EXT,direct_state_access} | @ref Buffer::data(), \n @ref Buffer::subData()
-@fn_gl{GetCompressedTexImage} | |
-@fn_gl{GetDebugMessageLog} | |
-@fn_gl{GetError} | @ref Renderer::error()
+@fn_gl{GetAttachedShaders} | not queryable, @ref AbstractShaderProgram::attachShader() setter only
+@fn_gl{GetAttribLocation} | not queryable, @ref AbstractShaderProgram::bindAttributeLocation() setter only
+@fn_gl{GetBufferParameter}, \n `glGetNamedBufferParameter()`, \n @fn_gl_extension{GetNamedBufferParameter,EXT,direct_state_access} | @ref Buffer::size()
+@fn_gl2{GetBufferPointer,GetBufferPointerv}, \n `glGetNamedBufferPointer()`, \n @fn_gl_extension{GetNamedBufferPointer,EXT,direct_state_access} | not queryable, @ref Buffer::map() setter only
+@fn_gl{GetBufferSubData}, \n `glGetNamedBufferSubData()`, \n @fn_gl_extension{GetNamedBufferSubData,EXT,direct_state_access} | @ref Buffer::data(), \n @ref Buffer::subData()
+@fn_gl{GetCompressedTexImage}, \n `glGetnCompressedTexImage()`, \n @fn_gl_extension{GetnCompressedTexImage,ARB,robustness}, \n `glGetCompressedTextureImage()`, \n @fn_gl_extension{GetCompressedTextureImage,EXT,direct_state_access} | |
+@fn_gl{GetCompressedTextureSubImage} | |
+@fn_gl{GetDebugMessageLog} | |
+@fn_gl{GetError} | @ref Renderer::error()
@fn_gl{GetFragDataIndex}, @fn_gl{GetFragDataLocation} | not queryable, @ref AbstractShaderProgram::bindFragmentDataLocation() and \n @ref AbstractShaderProgram::bindFragmentDataLocationIndexed() setters only
-@fn_gl{GetFramebufferAttachmentParameter} | not queryable, @ref Framebuffer setters only
-@fn_gl{GetFramebufferParameter} | not queryable, @ref DefaultFramebuffer and \n @ref Framebuffer setters only
-@fn_gl_extension{GetGraphicsResetStatus,ARB,robustness} | @ref Renderer::graphicsResetStatus()
-@fn_gl{GetInternalformat} | |
-@fn_gl{GetMultisample} | |
+@fn_gl{GetFramebufferAttachmentParameter}, \n `glGetNamedFramebufferAttachmentParameter()`, \n @fn_gl_extension{GetNamedFramebufferAttachmentParameter,EXT,direct_state_access} | not queryable, @ref Framebuffer setters only
+@fn_gl{GetFramebufferParameter}, \n `glGetNamedFramebufferParameter()`, \n @fn_gl_extension{GetNamedFramebufferParameter,EXT,direct_state_access} | not queryable, @ref DefaultFramebuffer and \n @ref Framebuffer setters only
+@fn_gl{GetGraphicsResetStatus}, \n @fn_gl_extension{GetGraphicsResetStatus,ARB,robustness} | @ref Renderer::graphicsResetStatus()
+@fn_gl{GetInternalformat} | |
+@fn_gl{GetMultisample} | |
@fn_gl{GetObjectLabel}, \n @fn_gl{GetObjectPtrLabel} | @ref AbstractShaderProgram::label(), \n @ref AbstractQuery::label(), \n @ref AbstractTexture::label(), \n @ref Buffer::label(), \n @ref Framebuffer::label(), \n @ref Mesh::label(), \n @ref Renderbuffer::label(), \n @ref Shader::label()
@fn_gl{GetProgram}, \n @fn_gl{GetProgramInfoLog} | @ref AbstractShaderProgram::link(), \n @ref AbstractShaderProgram::validate()
-@fn_gl{GetProgramBinary} | |
-@fn_gl{GetProgramInterface} | |
-@fn_gl{GetProgramPipeline} | |
-@fn_gl{GetProgramPipelineInfoLog} | |
-@fn_gl{GetProgramResource} | |
-@fn_gl{GetProgramResourceIndex} | |
-@fn_gl{GetProgramResourceLocation} | |
-@fn_gl{GetProgramResourceLocationIndex}| |
-@fn_gl{GetProgramResourceName} | |
-@fn_gl{GetProgramStage} | |
-@fn_gl{GetQueryIndexed} | |
-@fn_gl{GetQueryObject} | @ref AbstractQuery::result()
-@fn_gl2{GetQuery,GetQueryiv} | |
-@fn_gl{GetRenderbufferParameter} | not queryable, @ref Renderbuffer::setStorage() and \n @ref Renderbuffer::setStorageMultisample() setter only
-@fn_gl{GetSamplerParameter} | |
+@fn_gl{GetProgramBinary} | |
+@fn_gl{GetProgramInterface} | |
+@fn_gl{GetProgramPipeline} | |
+@fn_gl{GetProgramPipelineInfoLog} | |
+@fn_gl{GetProgramResource} | |
+@fn_gl{GetProgramResourceIndex} | |
+@fn_gl{GetProgramResourceLocation} | |
+@fn_gl{GetProgramResourceLocationIndex} | |
+@fn_gl{GetProgramResourceName} | |
+@fn_gl{GetProgramStage} | |
+@fn_gl{GetQueryIndexed} | |
+@fn_gl{GetQueryObject} | @ref AbstractQuery::result()
+@fn_gl{GetQueryBufferObject} | |
+@fn_gl2{GetQuery,GetQueryiv} | |
+@fn_gl{GetRenderbufferParameter}, \n `glGetNamedRenderbufferParameter()`, \n @fn_gl_extension{GetNamedRenderbufferParameter,EXT,direct_state_access} | not queryable, @ref Renderbuffer::setStorage() and \n @ref Renderbuffer::setStorageMultisample() setter only
+@fn_gl{GetSamplerParameter} | |
@fn_gl{GetShader}, \n @fn_gl{GetShaderInfoLog} | @ref Shader::compile()
-@fn_gl{GetShaderPrecisionFormat} | |
-@fn_gl{GetShaderSource} | not queryable but tracked in @ref Shader::sources()
-@fn_gl{GetString} | @ref Context::supportedExtensions(), \n @ref Context::rendererString(), \n @ref Context::shadingLanguageVersionString(), \n @ref Context::vendorString(), \n @ref Context::versionString()
-@fn_gl{GetSubroutineIndex} | |
-@fn_gl{GetSubroutineUniformLocation} | |
-@fn_gl{GetSync} | |
-@fn_gl{GetTexImage}, \n @fn_gl_extension{GetTextureImage,EXT,direct_state_access}, \n @fn_gl_extension{GetnTexImage,ARB,robustness} | @ref Texture::image(), \n @ref TextureArray::image(), \n @ref CubeMapTexture::image(), \n @ref CubeMapTextureArray::image(), \n @ref RectangleTexture::image()
-@fn_gl{GetTexLevelParameter}, \n @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access} | @ref Texture::imageSize(), \n @ref TextureArray::imageSize(), \n @ref CubeMapTexture::imageSize(), \n @ref CubeMapTextureArray::imageSize(), \n @ref RectangleTexture::imageSize()
-@fn_gl{GetTexParameter} | |
-@fn_gl{GetTransformFeedbackVarying} | |
-@fn_gl{GetUniform} | not queryable, @ref AbstractShaderProgram::setUniform() setter only
-@fn_gl{GetUniformBlockIndex} | |
-@fn_gl{GetUniformIndices} | |
-@fn_gl{GetUniformLocation} | @ref AbstractShaderProgram::uniformLocation()
-@fn_gl{GetUniformSubroutine} | |
-@fn_gl{GetVertexAttrib} | not queryable, @ref Mesh::addVertexBuffer() setter only
-@fn_gl{InvalidateBufferData} | @ref Buffer::invalidateData()
-@fn_gl{InvalidateBufferSubData} | @ref Buffer::invalidateSubData()
-@fn_gl{InvalidateFramebuffer}, \n @fn_gles_extension{DiscardFramebuffer,EXT,discard_framebuffer} | @ref DefaultFramebuffer::invalidate(), \n @ref Framebuffer::invalidate()
-@fn_gl{InvalidateSubFramebuffer} | @ref DefaultFramebuffer::invalidate(), \n @ref Framebuffer::invalidate()
-@fn_gl{InvalidateTexImage} | @ref Texture::invalidateImage(), \n @ref TextureArray::invalidateImage(), \n @ref CubeMapTexture::invalidateImage(), \n @ref CubeMapTextureArray::invalidateImage(), \n @ref RectangleTexture::invalidateImage(), \n @ref MultisampleTexture::invalidateImage()
-@fn_gl{InvalidateTexSubImage} | @ref Texture::invalidateSubImage(), \n @ref TextureArray::invalidateSubImage(), \n @ref CubeMapTexture::invalidateSubImage(), \n @ref CubeMapTextureArray::invalidateSubImage(), \n @ref RectangleTexture::invalidateSubImage(), \n @ref MultisampleTexture::invalidateSubImage()
+@fn_gl{GetShaderPrecisionFormat} | |
+@fn_gl{GetShaderSource} | not queryable but tracked in @ref Shader::sources()
+@fn_gl{GetString} | @ref Context::supportedExtensions(), \n @ref Context::rendererString(), \n @ref Context::shadingLanguageVersionString(), \n @ref Context::vendorString(), \n @ref Context::versionString()
+@fn_gl{GetSubroutineIndex} | |
+@fn_gl{GetSubroutineUniformLocation} | |
+@fn_gl{GetSync} | |
+@fn_gl{GetTexImage}, \n `glGetnTexImage()`, \n @fn_gl_extension{GetnTexImage,ARB,robustness}, \n `glGetTextureImage()`, \n @fn_gl_extension{GetTextureImage,EXT,direct_state_access} | @ref Texture::image(), \n @ref TextureArray::image(), \n @ref CubeMapTexture::image(), \n @ref CubeMapTextureArray::image(), \n @ref RectangleTexture::image()
+@fn_gl{GetTexLevelParameter}, \n `glGetTextureLevelParameter()`, \n @fn_gl_extension{GetTextureLevelParameter,EXT,direct_state_access} | @ref Texture::imageSize(), \n @ref TextureArray::imageSize(), \n @ref CubeMapTexture::imageSize(), \n @ref CubeMapTextureArray::imageSize(), \n @ref RectangleTexture::imageSize()
+@fn_gl{GetTexParameter}, \n `glGetTextureParameter()`, \n @fn_gl_extension{GetTextureParameter,EXT,direct_state_access} | |
+@fn_gl{GetTextureSubImage} | |
+@fn_gl{GetTransformFeedback} | |
+@fn_gl{GetTransformFeedbackVarying} | |
+@fn_gl{GetUniform}, \n `glGetnUniform()`, \n @fn_gl_extension{GetnUniform,ARB,robustness} | not queryable, @ref AbstractShaderProgram::setUniform() setter only
+@fn_gl{GetUniformBlockIndex} | |
+@fn_gl{GetUniformIndices} | |
+@fn_gl{GetUniformLocation} | @ref AbstractShaderProgram::uniformLocation()
+@fn_gl{GetUniformSubroutine} | |
+@fn_gl{GetVertexAttrib}, \n @fn_gl{GetVertexArray}, \n @fn_gl_extension{GetVertexArray,EXT,direct_state_access} | not queryable, @ref Mesh::addVertexBuffer() setter only
+
+@subsection opengl-mapping-functions-h H
+
+OpenGL function | Matching API
+--------------------------------------- | ------------
+@fn_gl{Hint} | @ref Renderer::setHint()
+
+@subsection opengl-mapping-functions-i I
+
+OpenGL function | Matching API
+--------------------------------------- | ------------
+@fn_gl{InvalidateBufferData} | @ref Buffer::invalidateData()
+@fn_gl{InvalidateBufferSubData} | @ref Buffer::invalidateSubData()
+@fn_gl{InvalidateFramebuffer}, \n `glInvalidateNamedFramebufferData()`, \n @fn_gles_extension{DiscardFramebuffer,EXT,discard_framebuffer} | @ref DefaultFramebuffer::invalidate(), \n @ref Framebuffer::invalidate()
+@fn_gl{InvalidateSubFramebuffer}, \n `glInvalidateNamedFramebufferSubData()` | @ref DefaultFramebuffer::invalidate(), \n @ref Framebuffer::invalidate()
+@fn_gl{InvalidateTexImage} | @ref Texture::invalidateImage(), \n @ref TextureArray::invalidateImage(), \n @ref CubeMapTexture::invalidateImage(), \n @ref CubeMapTextureArray::invalidateImage(), \n @ref RectangleTexture::invalidateImage(), \n @ref MultisampleTexture::invalidateImage()
+@fn_gl{InvalidateTexSubImage} | @ref Texture::invalidateSubImage(), \n @ref TextureArray::invalidateSubImage(), \n @ref CubeMapTexture::invalidateSubImage(), \n @ref CubeMapTextureArray::invalidateSubImage(), \n @ref RectangleTexture::invalidateSubImage(), \n @ref MultisampleTexture::invalidateSubImage()
@fn_gl{IsBuffer}, \n @fn_gl{IsFramebuffer}, \n @fn_gl{IsProgram}, \n @fn_gl{IsProgramPipeline}, \n @fn_gl{IsQuery}, \n @fn_gl{IsRenderbuffer}, \n @fn_gl{IsSampler}, \n @fn_gl{IsShader}, \n @fn_gl{IsSync}, \n @fn_gl{IsTexture}, \n @fn_gl{IsTransformFeedback}, \n @fn_gl{IsVertexArray} | not needed, objects are strongly typed
-@fn_gl{IsEnabled} | not queryable, @ref Renderer::setFeature() setter only
-@fn_gl{LineWidth} | @ref Renderer::setLineWidth()
-@fn_gl{LinkProgram} | @ref AbstractShaderProgram::link()
-@fn_gl{LogicOp} | @ref Renderer::setLogicOperation()
-@fn_gl{MapBuffer}, `glUnmapBuffer()`, \n @fn_gl_extension{MapNamedBuffer,EXT,direct_state_access}, @fn_gl_extension{UnmapNamedBuffer,EXT,direct_state_access}, \n @fn_gl{MapBufferRange}, \n @fn_gl_extension{MapNamedBufferRange,EXT,direct_state_access} | @ref Buffer::map(), @ref Buffer::unmap()
+@fn_gl{IsEnabled} | not queryable, @ref Renderer::setFeature() setter only
+
+@subsection opengl-mapping-functions-l L
+
+OpenGL function | Matching API
+--------------------------------------- | ------------
+@fn_gl{LineWidth} | @ref Renderer::setLineWidth()
+@fn_gl{LinkProgram} | @ref AbstractShaderProgram::link()
+@fn_gl{LogicOp} | @ref Renderer::setLogicOperation()
+
+@subsection opengl-mapping-functions-m M
+
+OpenGL function | Matching API
+--------------------------------------- | ------------
+@fn_gl{MapBuffer}, \n `glMapNamedBuffer()`, \n @fn_gl_extension{MapNamedBuffer,EXT,direct_state_access}, \n @fn_gl{MapBufferRange}, \n `glMapNamedBufferRange()`, \n @fn_gl_extension{MapNamedBufferRange,EXT,direct_state_access}, \n @fn_gl{UnmapBuffer}, \n `glUnmapNamedBuffer()`, \n @fn_gl_extension{UnmapNamedBuffer,EXT,direct_state_access} | @ref Buffer::map(), @ref Buffer::unmap()
@fn_gl_extension{MapBufferSubData,CHROMIUM,map_sub}, @fn_gl_extension{UnmapBufferSubData,CHROMIUM,map_sub} | @ref Buffer::mapSub(), @ref Buffer::unmapSub()
-@fn_gl{MemoryBarrier} | |
-@fn_gl{MinSampleShading} | |
+@fn_gl{MemoryBarrier}, \n `glMemoryBarrierByRegion()` | |
+@fn_gl{MinSampleShading} | |
@fn_gl{MultiDrawArrays}, \n @fn_gl{MultiDrawElements}, \n @fn_gl{MultiDrawElementsBaseVertex} | @ref MeshView::draw(AbstractShaderProgram&, std::initializer_list>)
+
+@subsection opengl-mapping-functions-o O
+
+OpenGL function | Matching API
+--------------------------------------- | ------------
@fn_gl{ObjectLabel}, \n @fn_gl{ObjectPtrLabel}, \n @fn_gl_extension2{LabelObject,EXT,debug_label} | @ref AbstractShaderProgram::setLabel(), \n @ref AbstractQuery::setLabel(), \n @ref AbstractTexture::setLabel(), \n @ref Buffer::setLabel(), \n @ref Framebuffer::setLabel(), \n @ref Mesh::setLabel(), \n @ref Renderbuffer::setLabel(), \n @ref Shader::setLabel()
-@fn_gl{PatchParameter} | |
+
+@subsection opengl-mapping-functions-p P
+
+OpenGL function | Matching API
+--------------------------------------- | ------------
+@fn_gl{PatchParameter} | |
@fn_gl{PauseTransformFeedback}, @fn_gl{ResumeTransformFeedback} | |
-@fn_gl{PixelStore} | |
-@fn_gl{PointParameter} | |
-@fn_gl{PointSize} | @ref Renderer::setPointSize()
-@fn_gl{PolygonMode} | @ref Renderer::setPolygonMode()
-@fn_gl{PolygonOffset} | @ref Renderer::setPolygonOffset()
-@fn_gl{PrimitiveRestartIndex} | |
-@fn_gl{ProgramBinary} | |
-@fn_gl{ProgramParameter} | @ref AbstractShaderProgram::setRetrievableBinary(), \n @ref AbstractShaderProgram::setSeparable()
-@fn_gl{ProvokingVertex} | @ref Renderer::setProvokingVertex()
+@fn_gl{PixelStore} | |
+@fn_gl{PointParameter} | |
+@fn_gl{PointSize} | @ref Renderer::setPointSize()
+@fn_gl{PolygonMode} | @ref Renderer::setPolygonMode()
+@fn_gl{PolygonOffset} | @ref Renderer::setPolygonOffset()
+@fn_gl{PrimitiveRestartIndex} | |
+@fn_gl{ProgramBinary} | |
+@fn_gl{ProgramParameter} | @ref AbstractShaderProgram::setRetrievableBinary(), \n @ref AbstractShaderProgram::setSeparable()
+@fn_gl{ProvokingVertex} | @ref Renderer::setProvokingVertex()
@fn_gl{PushDebugGroup}, @fn_gl{PopDebugGroup} | |
-@fn_gl{QueryCounter} | @ref TimeQuery::timestamp()
-@fn_gl{ReadBuffer}, \n @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access} | @ref DefaultFramebuffer::mapForRead(), \n @ref Framebuffer::mapForRead()
-@fn_gl{ReadPixels}, \n @fn_gl_extension{ReadnPixels,ARB,robustness} | @ref DefaultFramebuffer::read(), \n @ref Framebuffer::read()
-@fn_gl{ReleaseShaderCompiler} | |
-@fn_gl{RenderbufferStorage}, \n @fn_gl_extension{NamedRenderbufferStorage,EXT,direct_state_access} | @ref Renderbuffer::setStorage()
-@fn_gl{RenderbufferStorageMultisample}, \n @fn_gl_extension{NamedRenderbufferStorageMultisample,EXT,direct_state_access} | @ref Renderbuffer::setStorageMultisample()
-@fn_gl{SampleCoverage} | |
-@fn_gl{SampleMaski} | |
-@fn_gl{SamplerParameter} | |
-@fn_gl{Scissor} | @ref Renderer::setScissor()
-@fn_gl{ScissorArray} | |
-@fn_gl{ScissorIndexed} | |
-@fn_gl{ShaderBinary} | |
-@fn_gl{ShaderSource} | @ref Shader::addFile(), \n @ref Shader::addSource()
-@fn_gl{ShaderStorageBlockBinding} | |
+
+@subsection opengl-mapping-functions-q Q
+
+OpenGL function | Matching API
+--------------------------------------- | ------------
+@fn_gl{QueryCounter} | @ref TimeQuery::timestamp()
+
+@subsection opengl-mapping-functions-r R
+
+OpenGL function | Matching API
+--------------------------------------- | ------------
+@fn_gl{ReadBuffer}, \n `glNamedFramebufferReadBuffer()`, \n @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access} | @ref DefaultFramebuffer::mapForRead(), \n @ref Framebuffer::mapForRead()
+@fn_gl{ReadPixels}, \n `glReadnPixels()`, \n @fn_gl_extension{ReadnPixels,ARB,robustness} | @ref DefaultFramebuffer::read(), \n @ref Framebuffer::read()
+@fn_gl{ReleaseShaderCompiler} | |
+@fn_gl{RenderbufferStorage}, \n `glNamedRenderbufferStorage()`, \n @fn_gl_extension{NamedRenderbufferStorage,EXT,direct_state_access} | @ref Renderbuffer::setStorage()
+@fn_gl{RenderbufferStorageMultisample}, \n `glNamedRenderbufferStorageMultisample()`, \n @fn_gl_extension{NamedRenderbufferStorageMultisample,EXT,direct_state_access} | @ref Renderbuffer::setStorageMultisample()
+
+@subsection opengl-mapping-functions-s S
+
+OpenGL function | Matching API
+--------------------------------------- | ------------
+@fn_gl{SampleCoverage} | |
+@fn_gl{SampleMaski} | |
+@fn_gl{SamplerParameter} | |
+@fn_gl{Scissor} | @ref Renderer::setScissor()
+@fn_gl{ScissorArray} | |
+@fn_gl{ScissorIndexed} | |
+@fn_gl{ShaderBinary} | |
+@fn_gl{ShaderSource} | @ref Shader::addFile(), \n @ref Shader::addSource()
+@fn_gl{ShaderStorageBlockBinding} | |
@fn_gl{StencilFunc}, \n @fn_gl{StencilFuncSeparate} | @ref Renderer::setStencilFunction()
@fn_gl{StencilMask}, \n @fn_gl{StencilMaskSeparate} | @ref Renderer::setStencilMask()
@fn_gl{StencilOp}, \n @fn_gl{StencilOpSeparate} | @ref Renderer::setStencilOperation()
-@fn_gl{TexBuffer}, \n @fn_gl_extension{TextureBuffer,EXT,direct_state_access}, \n @fn_gl{TexBufferRange}, \n @fn_gl_extension{TextureBufferRange,EXT,direct_state_access} | @ref BufferTexture::setBuffer()
+
+@subsection opengl-mapping-functions-t T
+
+OpenGL function | Matching API
+--------------------------------------- | ------------
+@fn_gl{TexBuffer}, \n `glTextureBuffer()`, \n @fn_gl_extension{TextureBuffer,EXT,direct_state_access}, \n @fn_gl{TexBufferRange}, \n `glTextureBufferRange()`, \n @fn_gl_extension{TextureBufferRange,EXT,direct_state_access} | @ref BufferTexture::setBuffer()
@fn_gl{TexImage1D}, \n @fn_gl_extension{TextureImage1D,EXT,direct_state_access} \n @fn_gl{TexImage2D}, \n @fn_gl_extension{TextureImage2D,EXT,direct_state_access}, \n @fn_gl{TexImage3D}, \n @fn_gl_extension{TextureImage3D,EXT,direct_state_access} | @ref Texture::setImage(), \n @ref TextureArray::setImage(), \n @ref CubeMapTexture::setImage(), \n @ref CubeMapTextureArray::setImage(), \n @ref RectangleTexture::setImage()
@fn_gl{TexImage2DMultisample}, \n @fn_gl{TexImage3DMultisample} | @ref MultisampleTexture::setStorage()
-@fn_gl{TexParameter}, \n @fn_gl_extension{TextureParameter,EXT,direct_state_access} | @ref Texture::setBaseLevel() "*Texture::setBaseLevel()", \n @ref Texture::setMaxLevel() "*Texture::setMaxLevel()", \n @ref Texture::setMinificationFilter() "*Texture::setMinificationFilter()", \n @ref Texture::setMagnificationFilter() "*Texture::setMagnificationFilter()", \n @ref Texture::setMinLod() "*Texture::setMinLod()", \n @ref Texture::setMaxLod() "*Texture::setMaxLod()", \n @ref Texture::setLodBias() "*Texture::setLodBias()", \n @ref Texture::setWrapping() "*Texture::setWrapping()", \n @ref Texture::setBorderColor() "*Texture::setBorderColor()", \n @ref Texture::setMaxAnisotropy() "*Texture::setMaxAnisotropy()", \n @ref Texture::setSRGBDecode() "*Texture::setSRGBDecode()", \n @ref Texture::setSwizzle() "*Texture::setSwizzle()", \n @ref Texture::setCompareMode() "*Texture::setCompareMode()", \n @ref Texture::setCompareFunction() "*Texture::setCompareFunction()", \n @ref Texture::setDepthStencilMode() "*Texture::setDepthStencilMode()"
-@fn_gl{TexStorage1D}, \n @fn_gl_extension{TextureStorage1D,EXT,direct_state_access}, \n @fn_gl{TexStorage2D}, \n @fn_gl_extension{TextureStorage2D,EXT,direct_state_access}, \n @fn_gl{TexStorage3D}, \n @fn_gl_extension{TextureStorage3D,EXT,direct_state_access} | @ref Texture::setStorage(), \n @ref TextureArray::setStorage(), \n @ref CubeMapTexture::setStorage(), \n @ref CubeMapTextureArray::setStorage(), \n @ref RectangleTexture::setStorage()
-@fn_gl{TexStorage2DMultisample}, \n @fn_gl_extension{TextureStorage2DMultisample,EXT,direct_state_access}, \n @fn_gl{TexStorage3DMultisample}, \n @fn_gl_extension{TextureStorage3DMultisample,EXT,direct_state_access} | @ref MultisampleTexture::setStorage()
-@fn_gl{TexSubImage1D}, \n @fn_gl_extension{TextureSubImage1D,EXT,direct_state_access}, \n @fn_gl{TexSubImage2D}, \n @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}, \n @fn_gl{TexSubImage3D}, \n @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access} | @ref Texture::setSubImage(), \n @ref TextureArray::setSubImage(), \n @ref CubeMapTexture::setSubImage(), \n @ref CubeMapTextureArray::setSubImage(), \n @ref RectangleTexture::setSubImage()
-@fn_gl{TextureView} | |
-@fn_gl{TransformFeedbackVaryings} | |
+@fn_gl{TexParameter}, \n `glTextureParameter()`, \n @fn_gl_extension{TextureParameter,EXT,direct_state_access} | @ref Texture::setBaseLevel() "*Texture::setBaseLevel()", \n @ref Texture::setMaxLevel() "*Texture::setMaxLevel()", \n @ref Texture::setMinificationFilter() "*Texture::setMinificationFilter()", \n @ref Texture::setMagnificationFilter() "*Texture::setMagnificationFilter()", \n @ref Texture::setMinLod() "*Texture::setMinLod()", \n @ref Texture::setMaxLod() "*Texture::setMaxLod()", \n @ref Texture::setLodBias() "*Texture::setLodBias()", \n @ref Texture::setWrapping() "*Texture::setWrapping()", \n @ref Texture::setBorderColor() "*Texture::setBorderColor()", \n @ref Texture::setMaxAnisotropy() "*Texture::setMaxAnisotropy()", \n @ref Texture::setSRGBDecode() "*Texture::setSRGBDecode()", \n @ref Texture::setSwizzle() "*Texture::setSwizzle()", \n @ref Texture::setCompareMode() "*Texture::setCompareMode()", \n @ref Texture::setCompareFunction() "*Texture::setCompareFunction()", \n @ref Texture::setDepthStencilMode() "*Texture::setDepthStencilMode()"
+@fn_gl{TexStorage1D}, \n `glTextureStorage1D()`, \n @fn_gl_extension{TextureStorage1D,EXT,direct_state_access}, \n @fn_gl{TexStorage2D}, \n `glTextureStorage2D()`, \n @fn_gl_extension{TextureStorage2D,EXT,direct_state_access}, \n @fn_gl{TexStorage3D}, \n `glTextureStorage3D()`, \n @fn_gl_extension{TextureStorage3D,EXT,direct_state_access} | @ref Texture::setStorage(), \n @ref TextureArray::setStorage(), \n @ref CubeMapTexture::setStorage(), \n @ref CubeMapTextureArray::setStorage(), \n @ref RectangleTexture::setStorage()
+@fn_gl{TexStorage2DMultisample}, \n `glTextureStorage2DMultisample()`, \n @fn_gl_extension{TextureStorage2DMultisample,EXT,direct_state_access}, \n @fn_gl{TexStorage3DMultisample}, \n `glTextureStorage3DMultisample()`, \n @fn_gl_extension{TextureStorage3DMultisample,EXT,direct_state_access} | @ref MultisampleTexture::setStorage()
+@fn_gl{TexSubImage1D}, \n `glTextureSubImage1D()`, \n @fn_gl_extension{TextureSubImage1D,EXT,direct_state_access}, \n @fn_gl{TexSubImage2D}, \n `glTextureSubImage2D()`, \n @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}, \n @fn_gl{TexSubImage3D}, \n `glTextureSubImage3D()`, \n @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access} | @ref Texture::setSubImage(), \n @ref TextureArray::setSubImage(), \n @ref CubeMapTexture::setSubImage(), \n @ref CubeMapTextureArray::setSubImage(), \n @ref RectangleTexture::setSubImage()
+@fn_gl{TextureBarrier} | |
+@fn_gl{TextureView} | |
+@fn_gl{TransformFeedbackBufferBase}, \n @fn_gl{TransformFeedbackBufferRange} | |
+@fn_gl{TransformFeedbackVaryings} | |
+
+@subsection opengl-mapping-functions-u U
+
+OpenGL function | Matching API
+--------------------------------------- | ------------
@fn_gl{Uniform}, \n @fn_gl{ProgramUniform}, \n @fn_gl_extension{ProgramUniform,EXT,direct_state_access} | @ref AbstractShaderProgram::setUniform()
-@fn_gl{UniformBlockBinding} | |
-@fn_gl{UniformSubroutines} | |
-@fn_gl{UseProgram} | @ref Mesh::draw(), @ref MeshView::draw()
-@fn_gl{UseProgramStages} | |
-@fn_gl{ValidateProgram} | @ref AbstractShaderProgram::validate()
-@fn_gl{ValidateProgramPipeline} | |
-@fn_gl{VertexAttrib} | not supported (@ref opengl-unsupported "details")
-@fn_gl{VertexAttribBinding} | |
+@fn_gl{UniformBlockBinding} | |
+@fn_gl{UniformSubroutines} | |
+@fn_gl{UseProgram} | @ref Mesh::draw(), @ref MeshView::draw()
+@fn_gl{UseProgramStages} | |
+
+@subsection opengl-mapping-functions-v V
+
+OpenGL function | Matching API
+--------------------------------------- | ------------
+@fn_gl{ValidateProgram} | @ref AbstractShaderProgram::validate()
+@fn_gl{ValidateProgramPipeline} | |
+@fn_gl{VertexArrayElementBuffer} | |
+@fn_gl{VertexAttrib} | not supported (@ref opengl-unsupported "details")
+@fn_gl{VertexAttribBinding}, \n `glVertexArrayAttribBinding()`, \n @fn_gl_extension{VertexArrayVertexAttribBinding,EXT,direct_state_access} | |
@fn_gl{VertexAttribDivisor}, \n @fn_gl_extension{VertexArrayVertexAttribDivisor,EXT,direct_state_access} | @ref Mesh::addVertexBufferInstanced()
-@fn_gl{VertexAttribFormat} | |
+@fn_gl{VertexAttribFormat}, \n `glVertexArrayAttribFormat()`, \n @fn_gl_extension{VertexArrayVertexAttribFormat,EXT,direct_state_access} | |
@fn_gl{VertexAttribPointer}, \n @fn_gl_extension{VertexArrayVertexAttribOffset,EXT,direct_state_access} | @ref Mesh::addVertexBuffer()
-@fn_gl{VertexBindingDivisor} | |
-@fn_gl{Viewport} | @ref DefaultFramebuffer::setViewport(), \n @ref Framebuffer::setViewport()
-@fn_gl{ViewportArray} | |
-@fn_gl{ViewportIndexed} | |
-@fn_gl{WaitSync} | |
+@fn_gl{VertexBindingDivisor}, \n `glVertexArrayBindingDivisor()`, \n @fn_gl_extension{VertexArrayVertexBindingDivisor,EXT,direct_state_access} | |
+@fn_gl{Viewport} | @ref DefaultFramebuffer::setViewport(), \n @ref Framebuffer::setViewport()
+@fn_gl{ViewportArray} | |
+@fn_gl{ViewportIndexed} | |
+
+@subsection opengl-mapping-functions-w W
+
+OpenGL function | Matching API
+--------------------------------------- | ------------
+@fn_gl{WaitSync} | |
@section opengl-mapping-state Limit and state queries
@todo Things marked only as *not queryable* should have at least setter
-@fn_gl{Get} parameter | Matching API
--------------------------------------- | ------------
+@fn_gl{Get} parameter | Matching API
+--------------------------------------- | ------------
@def_gl{ACTIVE_TEXTURE}, \n @def_gl{TEXTURE_BINDING_1D_ARRAY}, \n @def_gl{TEXTURE_BINDING_1D}, \n @def_gl{TEXTURE_BINDING_2D_ARRAY}, \n @def_gl{TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY}, \n @def_gl{TEXTURE_BINDING_2D_MULTISAMPLE}, \n @def_gl{TEXTURE_BINDING_2D} , \n @def_gl{TEXTURE_BINDING_3D}, \n @def_gl{TEXTURE_BINDING_BUFFER}, \n @def_gl{TEXTURE_BINDING_BUFFER}, \n @def_gl{TEXTURE_BINDING_CUBE_MAP}, \n @def_gl{TEXTURE_BINDING_RECTANGLE} | not queryable but tracked internally
-@def_gl{ALIASED_LINE_WIDTH_RANGE} | |
+@def_gl{ALIASED_LINE_WIDTH_RANGE} | |
@def_gl{ARRAY_BUFFER_BINDING}, \n @def_gl{DISPATCH_INDIRECT_BUFFER_BINDING}, \n @def_gl{ELEMENT_ARRAY_BUFFER_BINDING}, \n @def_gl{PIXEL_PACK_BUFFER_BINDING}, \n @def_gl{PIXEL_UNPACK_BUFFER_BINDING} | not queryable but tracked internally
-@def_gl{BLEND_COLOR} | not queryable, @ref Renderer::setBlendColor() setter only
+@def_gl{BLEND_COLOR} | not queryable, @ref Renderer::setBlendColor() setter only
@def_gl{BLEND_DST_ALPHA}, \n @def_gl{BLEND_DST_RGB}, \n @def_gl{BLEND_SRC_ALPHA}, \n @def_gl{BLEND_SRC_RGB} | not queryable, @ref Renderer::setBlendFunction() setter only
@def_gl{BLEND_EQUATION_ALPHA}, \n @def_gl{BLEND_EQUATION_RGB} | not queryable, @ref Renderer::setBlendEquation() setter only
@def_gl{BLEND}, \n @def_gl{COLOR_LOGIC_OP}, \n @def_gl{CULL_FACE}, \n @def_gl{DEBUG_OUTPUT}, \n @def_gl{DEBUG_OUTPUT_SYNCHRONOUS}, \n @def_gl{DEPTH_CLAMP}, \n @def_gl{DEPTH_TEST}, \n @def_gl{DITHER}, \n @def_gl{MULTISAMPLE}, \n @def_gl{POLYGON_OFFSET_FILL}, \n @def_gl{POLYGON_OFFSET_LINE}, \n @def_gl{POLYGON_OFFSET_POINT}, \n @def_gl{PROGRAM_POINT_SIZE}, \n @def_gl{SCISSOR}, \n @def_gl{TEXTURE_CUBE_MAP_SEAMLESS}, \n @def_gl{STENCIL_TEST} | not queryable, @ref Renderer::setFeature() setter only
@def_gl{COLOR_CLEAR_VALUE}, \n @def_gl{DEPTH_CLEAR_VALUE}, \n @def_gl{STENCIL_CLEAR_VALUE} | not queryable, @ref Renderer::setClearColor(), \n @ref Renderer::setClearDepth() and \n @ref Renderer::setClearStencil() setters only
@def_gl{COLOR_WRITEMASK}, \n @def_gl{DEPTH_WRITEMASK}, \n @def_gl{STENCIL_BACK_WRITEMASK}, \n @def_gl{STENCIL_WRITEMASK} | not queryable, @ref Renderer::setColorMask(), \n @ref Renderer::setDepthMask() and \n @ref Renderer::setStencilMask() setters only
-@def_gl{COMPRESSED_TEXTURE_FORMATS} | |
-@def_gl{CONTEXT_FLAGS} | @ref Context::flags()
-@def_gl{CURRENT_PROGRAM} | not queryable but tracked internally
-@def_gl{DEBUG_GROUP_STACK_DEPTH} | |
-@def_gl{DEPTH_FUNC} | not queryable, @ref Renderer::setDepthFunction() setter only
-@def_gl{DEPTH_RANGE} | not queryable
+@def_gl{CONTEXT_FLAGS} | @ref Context::flags()
+@def_gl{CURRENT_PROGRAM} | not queryable but tracked internally
+@def_gl{DEBUG_GROUP_STACK_DEPTH} | |
+@def_gl{DEPTH_FUNC} | not queryable, @ref Renderer::setDepthFunction() setter only
+@def_gl{DEPTH_RANGE} | not queryable
@def_gl{DOUBLEBUFFER}, \n @def_gl{STEREO} | |
@def_gl{DRAW_BUFFERi}, \n @def_gl{DRAW_BUFFER}, \n @def_gl{READ_BUFFER} | not queryable, @ref DefaultFramebuffer::mapForDraw(), \n @ref DefaultFramebuffer::mapForRead(), \n @ref Framebuffer::mapForDraw() and \n @ref Framebuffer::mapForRead() setters only
@def_gl{DRAW_FRAMEBUFFER_BINDING}, \n @def_gl{READ_FRAMEBUFFER_BINDING} | not queryable but tracked internally
@def_gl{FRAGMENT_SHADER_DERIVATIVE_HINT}, \n @def_gl{LINE_SMOOTH_HINT}, \n @def_gl{POLYGON_SMOOTH_HINT}, \n @def_gl{TEXTURE_COMPRESSION_HINT} | not queryable
@def_gl{IMPLEMENTATION_COLOR_READ_FORMAT} | |
@def_gl{IMPLEMENTATION_COLOR_READ_TYPE} | |
-@def_gl{LAYER_PROVOKING_VERTEX} | |
+@def_gl{LAYER_PROVOKING_VERTEX} | |
@def_gl{LINE_SMOOTH}, \n @def_gl{POLYGON_SMOOTH} | not supported (@ref opengl-unsupported "details")
@def_gl{LINE_WIDTH_GRANULARITY}, \n @def_gl{LINE_WIDTH_RANGE} | |
-@def_gl{LINE_WIDTH} | not queryable, @ref Renderer::setLineWidth() setter only
-@def_gl{LOGIC_OP_MODE} | not queryable, @ref Renderer::setLogicOperation() setter only
+@def_gl{LINE_WIDTH} | not queryable, @ref Renderer::setLineWidth() setter only
+@def_gl{LOGIC_OP_MODE} | not queryable, @ref Renderer::setLogicOperation() setter only
@def_gl{MAJOR_VERSION}, \n @def_gl{MINOR_VERSION} | @ref Context::version()
`GL_MAX_*_ATOMIC_COUNTER_BUFFERS`, \n @def_gl{MAX_COMBINED_ATOMIC_COUNTER_BUFFERS} | @ref Shader::maxAtomicCounterBuffers(), \n @ref Shader::maxCombinedAtomicCounterBuffers()
`GL_MAX_*_ATOMIC_COUNTERS`, \n @def_gl{MAX_COMBINED_ATOMIC_COUNTERS} | @ref Shader::maxAtomicCounters(), \n @ref Shader::maxCombinedAtomicCounters()
@@ -295,88 +400,90 @@ OpenGL function | Matching API
`GL_MAX_*_TEXTURE_IMAGE_UNITS`, \n @def_gl{MAX_TEXTURE_IMAGE_UNITS}, \n @def_gl{MAX_COMBINED_TEXTURE_IMAGE_UNITS} | @ref Shader::maxTextureImageUnits(), \n @ref Shader::maxCombinedTextureImageUnits()
`GL_MAX_*_UNIFORM_BLOCKS`, \n @def_gl{MAX_COMBINED_UNIFORM_BLOCKS} | @ref Shader::maxUniformBlocks(), \n @ref Shader::maxCombinedUniformBlocks()
`GL_MAX_*_UNIFORM_COMPONENTS`, \n @def_gl{MAX_VERTEX_UNIFORM_VECTORS}, \n @def_gl{MAX_FRAGMENT_UNIFORM_VECTORS} | @ref Shader::maxUniformComponents()
-`GL_MAX_COMBINED_*_UNIFORM_COMPONENTS` | @ref Shader::maxCombinedUniformComponents()
+`GL_MAX_COMBINED_*_UNIFORM_COMPONENTS` | @ref Shader::maxCombinedUniformComponents()
@def_gl{MAX_3D_TEXTURE_SIZE}, \n @def_gl{MAX_ARRAY_TEXTURE_LAYERS}, \n @def_gl{MAX_CUBE_MAP_TEXTURE_SIZE}, \n @def_gl{MAX_RECTANGLE_TEXTURE_SIZE}, \n @def_gl{MAX_TEXTURE_SIZE} | @ref Texture::maxSize(), \n @ref TextureArray::maxSize(), \n @ref CubeMapTexture::maxSize(), \n @ref CubeMapTextureArray::maxSize(), \n @ref RectangleTexture::maxSize(), \n @ref BufferTexture::maxSize(), \n @ref MultisampleTexture::maxSize()
@def_gl{MAX_ATOMIC_COUNTER_BUFFER_SIZE} | @ref AbstractShaderProgram::maxAtomicCounterBufferSize()
@def_gl{MAX_ATOMIC_COUNTER_BUFFER_BINDINGS} | @ref Buffer::maxAtomicCounterBindings()
-@def_gl{MAX_COLOR_ATTACHMENTS} | @ref Framebuffer::maxColorAttachments()
+@def_gl{MAX_COLOR_ATTACHMENTS} | @ref Framebuffer::maxColorAttachments()
@def_gl{MAX_COMBINED_SHADER_OUTPUT_RESOURCES} | @ref AbstractShaderProgram::maxCombinedShaderOutputResources()
@def_gl{MAX_COMPUTE_SHARED_MEMORY_SIZE} | @ref AbstractShaderProgram::maxComputeSharedMemorySize()
-@def_gl{MAX_COMPUTE_WORK_GROUP_COUNT} | |
+@def_gl{MAX_COMPUTE_WORK_GROUP_COUNT} | |
@def_gl{MAX_COMPUTE_WORK_GROUP_INVOCATIONS} | @ref AbstractShaderProgram::maxComputeWorkGroupInvocations()
-@def_gl{MAX_COMPUTE_WORK_GROUP_SIZE} | |
-@def_gl{MAX_DEBUG_LOGGED_MESSAGES} | @ref DebugMessage::maxLoggedMessages()
-@def_gl{MAX_DEBUG_MESSAGE_LENGTH} | @ref DebugMessage::maxMessageLength()
-@def_gl{MAX_DEBUG_GROUP_STACK_DEPTH} | |
-@def_gl{MAX_CLIP_DISTANCES} | |
+@def_gl{MAX_COMPUTE_WORK_GROUP_SIZE} | |
+@def_gl{MAX_DEBUG_LOGGED_MESSAGES} | @ref DebugMessage::maxLoggedMessages()
+@def_gl{MAX_DEBUG_MESSAGE_LENGTH} | @ref DebugMessage::maxMessageLength()
+@def_gl{MAX_DEBUG_GROUP_STACK_DEPTH} | |
+@def_gl{MAX_CLIP_DISTANCES} | |
+@def_gl{MAX_CULL_DISTANCES} | |
+@def_gl{MAX_COMBINED_CLIP_AND_CULL_DISTANCES} | |
@def_gl{MAX_COLOR_TEXTURE_SAMPLES}, \n @def_gl{MAX_DEPTH_TEXTURE_SAMPLES}, \n @def_gl{MAX_INTEGER_SAMPLES} | @ref AbstractTexture::maxColorSamples(), \n @ref AbstractTexture::maxDepthSamples(), \n @ref AbstractTexture::maxIntegerSamples()
-@def_gl{MAX_DRAW_BUFFERS} | @ref AbstractFramebuffer::maxDrawBuffers()
-@def_gl{MAX_DUAL_SOURCE_DRAW_BUFFERS} | @ref AbstractFramebuffer::maxDualSourceDrawBuffers()
-@def_gl{MAX_ELEMENTS_INDICES} | @ref Mesh::maxElementsIndices()
-@def_gl{MAX_ELEMENTS_VERTICES} | @ref Mesh::maxElementsVertices()
-@def_gl{MAX_ELEMENT_INDEX} | |
-@def_gl{MAX_FRAMEBUFFER_HEIGHT} | |
-@def_gl{MAX_FRAMEBUFFER_LAYERS} | |
-@def_gl{MAX_FRAMEBUFFER_SAMPLES} | |
-@def_gl{MAX_FRAMEBUFFER_WIDTH} | |
-@def_gl{MAX_FRAGMENT_INPUT_COMPONENTS}, \n @def_gl{MAX_GEOMETRY_INPUT_COMPONENTS}, \n @def_gl{MAX_GEOMETRY_OUTPUT_COMPONENTS}, \n @def_gl{MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS}, \n @def_gl{MAX_TESS_CONTROL_INPUT_COMPONENTS}, \n @def_gl{MAX_TESS_CONTROL_OUTPUT_COMPONENTS}, \n @def_gl{MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS}, \n @def_gl{MAX_TESS_EVALUATION_INPUT_COMPONENTS}, \n @def_gl{MAX_TESS_EVALUATION_OUTPUT_COMPONENTS}, \n @def_gl{MAX_VERTEX_OUTPUT_COMPONENTS}, \n @def_gl{MAX_VARYING_COMPONENTS}, \n @def_gl{MAX_VARYING_FLOATS}, \n @def_gl{MAX_VARYING_VECTORS} | @ref Shader::maxFragmentInputComponents(), \n @ref Shader::maxGeometryInputComponents(), \n @ref Shader::maxGeometryOutputComponents(), \n @ref Shader::maxGeometryTotalOutputComponents(), \n @ref Shader::maxTessellationControlInputComponents(), \n @ref Shader::maxTessellationControlOutputComponents(), \n @ref Shader::maxTessellationControlTotalOutputComponents(), \n @ref Shader::maxTessellationEvaluationInputComponents(), \n @ref Shader::maxTessellationEvaluationOutputComponents(), \n @ref Shader::maxVertexOutputComponents()
-@def_gl{MAX_IMAGE_SAMPLES} | @ref AbstractShaderProgram::maxImageSamples()
-@def_gl{MAX_IMAGE_UNITS} | @ref AbstractShaderProgram::maxImageUnits()
-@def_gl{MAX_LABEL_LENGTH} | @ref AbstractObject::maxLabelLength()
-@def_gl{MAX_RENDERBUFFER_SIZE} | @ref Renderbuffer::maxSize()
-@def_gl{MAX_SAMPLE_MASK_WORDS} | |
-@def_gl{MAX_SERVER_WAIT_TIMEOUT} | |
-@def_gl{MAX_SHADER_STORAGE_BLOCK_SIZE} | @ref AbstractShaderProgram::maxShaderStorageBlockSize()
+@def_gl{MAX_DRAW_BUFFERS} | @ref AbstractFramebuffer::maxDrawBuffers()
+@def_gl{MAX_DUAL_SOURCE_DRAW_BUFFERS} | @ref AbstractFramebuffer::maxDualSourceDrawBuffers()
+@def_gl{MAX_ELEMENT_INDEX} | @ref Mesh::maxElementIndex()
+@def_gl{MAX_ELEMENTS_INDICES} | @ref Mesh::maxElementsIndices()
+@def_gl{MAX_ELEMENTS_VERTICES} | @ref Mesh::maxElementsVertices()
+@def_gl{MAX_FRAMEBUFFER_HEIGHT} | |
+@def_gl{MAX_FRAMEBUFFER_LAYERS} | |
+@def_gl{MAX_FRAMEBUFFER_SAMPLES} | |
+@def_gl{MAX_FRAMEBUFFER_WIDTH} | |
+@def_gl{MAX_FRAGMENT_INPUT_COMPONENTS}, \n @def_gl{MAX_GEOMETRY_INPUT_COMPONENTS}, \n @def_gl{MAX_GEOMETRY_OUTPUT_COMPONENTS}, \n @def_gl{MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS}, \n @def_gl{MAX_TESS_CONTROL_INPUT_COMPONENTS}, \n @def_gl{MAX_TESS_CONTROL_OUTPUT_COMPONENTS}, \n @def_gl{MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS}, \n @def_gl{MAX_TESS_EVALUATION_INPUT_COMPONENTS}, \n @def_gl{MAX_TESS_EVALUATION_OUTPUT_COMPONENTS}, \n @def_gl{MAX_VERTEX_OUTPUT_COMPONENTS}, \n @def_gl{MAX_VARYING_VECTORS} | @ref Shader::maxFragmentInputComponents(), \n @ref Shader::maxGeometryInputComponents(), \n @ref Shader::maxGeometryOutputComponents(), \n @ref Shader::maxGeometryTotalOutputComponents(), \n @ref Shader::maxTessellationControlInputComponents(), \n @ref Shader::maxTessellationControlOutputComponents(), \n @ref Shader::maxTessellationControlTotalOutputComponents(), \n @ref Shader::maxTessellationEvaluationInputComponents(), \n @ref Shader::maxTessellationEvaluationOutputComponents(), \n @ref Shader::maxVertexOutputComponents()
+@def_gl{MAX_IMAGE_SAMPLES} | @ref AbstractShaderProgram::maxImageSamples()
+@def_gl{MAX_IMAGE_UNITS} | @ref AbstractShaderProgram::maxImageUnits()
+@def_gl{MAX_LABEL_LENGTH} | @ref AbstractObject::maxLabelLength()
+@def_gl{MAX_RENDERBUFFER_SIZE} | @ref Renderbuffer::maxSize()
+@def_gl{MAX_SAMPLE_MASK_WORDS} | |
+@def_gl{MAX_SERVER_WAIT_TIMEOUT} | |
+@def_gl{MAX_SHADER_STORAGE_BLOCK_SIZE} | @ref AbstractShaderProgram::maxShaderStorageBlockSize()
@def_gl{MAX_SHADER_STORAGE_BUFFER_BINDINGS} | @ref Buffer::maxShaderStorageBindings()
-@def_gl{MAX_TEXTURE_BUFFER_SIZE} | |
+@def_gl{MAX_TEXTURE_BUFFER_SIZE} | @ref BufferTexture::maxSize()
@def_gl_extension{MAX_TEXTURE_MAX_ANISOTROPY,EXT,texture_filter_anisotropic} | @ref Sampler::maxMaxAnisotropy()
-@def_gl{MAX_TEXTURE_LOD_BIAS} | @ref AbstractTexture::maxLodBias()
-@def_gl{MAX_UNIFORM_BLOCK_SIZE} | @ref AbstractShaderProgram::maxUniformBlockSize()
-@def_gl{MAX_UNIFORM_BUFFER_BINDINGS} | @ref Buffer::maxUniformBindings()
-@def_gl{MAX_UNIFORM_LOCATIONS} | @ref AbstractShaderProgram::maxUniformLocations()
-@def_gl{MAX_VERTEX_ATTRIBS} | @ref AbstractShaderProgram::maxVertexAttributes()
-@def_gl{MAX_VERTEX_ATTRIB_BINDINGS} | |
+@def_gl{MAX_TEXTURE_LOD_BIAS} | @ref AbstractTexture::maxLodBias()
+@def_gl{MAX_UNIFORM_BLOCK_SIZE} | @ref AbstractShaderProgram::maxUniformBlockSize()
+@def_gl{MAX_UNIFORM_BUFFER_BINDINGS} | @ref Buffer::maxUniformBindings()
+@def_gl{MAX_UNIFORM_LOCATIONS} | @ref AbstractShaderProgram::maxUniformLocations()
+@def_gl{MAX_VERTEX_ATTRIBS} | @ref AbstractShaderProgram::maxVertexAttributes()
+@def_gl{MAX_VERTEX_ATTRIB_STRIDE} | |
+@def_gl{MAX_VERTEX_ATTRIB_BINDINGS} | |
@def_gl{MAX_VERTEX_ATTRIB_RELATIVE_OFFSET} | |
-@def_gl{MAX_VIEWPORTS} | |
-@def_gl{MAX_VIEWPORT_DIMS} | @ref AbstractFramebuffer::maxViewportSize()
-@def_gl{MIN_MAP_BUFFER_ALIGNMENT} | @ref Buffer::minMapAlignment()
+@def_gl{MAX_VIEWPORTS} | |
+@def_gl{MAX_VIEWPORT_DIMS} | @ref AbstractFramebuffer::maxViewportSize()
+@def_gl{MIN_MAP_BUFFER_ALIGNMENT} | @ref Buffer::minMapAlignment()
@def_gl{MIN_PROGRAM_TEXEL_OFFSET}, \n @def_gl{MAX_PROGRAM_TEXEL_OFFSET} | @ref AbstractShaderProgram::minTexelOffset(), \n @ref AbstractShaderProgram::maxTexelOffset()
-@def_gl{NUM_COMPRESSED_TEXTURE_FORMATS} | |
-@def_gl{NUM_EXTENSIONS} | @ref Context::supportedExtensions()
+@def_gl{NUM_EXTENSIONS} | @ref Context::supportedExtensions()
@def_gl{NUM_PROGRAM_BINARY_FORMATS}, \n @def_gl{PROGRAM_BINARY_FORMATS} | |
@def_gl{NUM_SHADER_BINARY_FORMATS}, \n @def_gl{SHADER_BINARY_FORMATS} | |
@def_gl{PACK_ALIGNMENT}, \n @def_gl{PACK_IMAGE_HEIGHT}, \n @def_gl{PACK_LSB_FIRST}, \n @def_gl{PACK_ROW_LENGTH}, \n @def_gl{PACK_SKIP_IMAGES}, \n @def_gl{PACK_SKIP_PIXELS}, \n @def_gl{PACK_SKIP_ROWS}, \n @def_gl{PACK_SWAP_BYTES}, \n @def_gl{UNPACK_ALIGNMENT}, \n @def_gl{UNPACK_IMAGE_HEIGHT}, \n @def_gl{UNPACK_LSB_FIRST}, \n @def_gl{UNPACK_ROW_LENGTH}, \n @def_gl{UNPACK_SKIP_IMAGES}, \n @def_gl{UNPACK_SKIP_PIXELS}, \n @def_gl{UNPACK_SKIP_ROWS}, \n @def_gl{UNPACK_SWAP_BYTES} | not queryable
-@def_gl{POINT_FADE_THRESHOLD_SIZE} | |
+@def_gl{POINT_FADE_THRESHOLD_SIZE} | |
@def_gl{POINT_SIZE_GRANULARITY}, \n @def_gl{POINT_SIZE_RANGE} | |
-@def_gl{POINT_SIZE} | not queryable, @ref Renderer::setPointSize() setter only
+@def_gl{POINT_SIZE} | not queryable, @ref Renderer::setPointSize() setter only
@def_gl{POLYGON_OFFSET_FACTOR}, \n @def_gl{POLYGON_OFFSET_UNITS} | not queryable, @ref Renderer::setPolygonOffset() setter only
-@def_gl{PRIMITIVE_RESTART_INDEX} | not queryable
-@def_gl{PROGRAM_PIPELINE_BINDING} | not queryable
-@def_gl{PROVOKING_VERTEX} | not queryable, @ref Renderer::setProvokingVertex() setter only
-@def_gl{RENDERBUFFER_BINDING} | not queryable but tracked internally
-@def_gl{SAMPLER_BINDING} | not queryable
-@def_gl{SAMPLES} | @ref Renderbuffer::maxSamples()
-@def_gl{SAMPLE_BUFFERS} | |
+@def_gl{PRIMITIVE_RESTART_INDEX} | not queryable
+@def_gl{PROGRAM_PIPELINE_BINDING} | not queryable
+@def_gl{PROVOKING_VERTEX} | not queryable, @ref Renderer::setProvokingVertex() setter only
+@def_gl{RENDERBUFFER_BINDING} | not queryable but tracked internally
+@def_gl{SAMPLER_BINDING} | not queryable
+@def_gl{SAMPLES} | @ref Renderbuffer::maxSamples()
+@def_gl{SAMPLE_BUFFERS} | |
@def_gl{SAMPLE_COVERAGE_INVERT}, \n @def_gl{SAMPLE_COVERAGE_VALUE} | |
-@def_gl{SCISSOR_BOX} | not queryable, @ref Renderer::setScissor() setter only
-@def_gl{SHADER_COMPILER} | not supported (@ref opengl-unsupported "details")
+@def_gl{SCISSOR_BOX} | not queryable, @ref Renderer::setScissor() setter only
+@def_gl{SHADER_COMPILER} | not supported (@ref opengl-unsupported "details")
@def_gl{SHADER_STORAGE_BUFFER_BINDING}, \n @def_gl{SHADER_STORAGE_BUFFER_SIZE}, \n @def_gl{SHADER_STORAGE_BUFFER_START} | not queryable
@def_gl{SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT} | @ref Buffer::shaderStorageOffsetAlignment()
@def_gl{SMOOTH_LINE_WIDTH_GRANULARITY}, \n @def_gl{SMOOTH_LINE_WIDTH_RANGE} | |
@def_gl{STENCIL_BACK_FUNC}, \n @def_gl{STENCIL_BACK_REF}, \n @def_gl{STENCIL_BACK_VALUE_MASK}, \n @def_gl{STENCIL_FUNC}, \n @def_gl{STENCIL_REF}, \n @def_gl{STENCIL_VALUE_MASK} | not queryable, @ref Renderer::setStencilFunction() setter only
@def_gl{STENCIL_BACK_FAIL}, \n @def_gl{STENCIL_BACK_PASS_DEPTH_FAIL}, \n @def_gl{STENCIL_BACK_PASS_DEPTH_PASS}, \n @def_gl{STENCIL_FAIL}, \n @def_gl{STENCIL_PASS_DEPTH_FAIL}, \n @def_gl{STENCIL_PASS_DEPTH_PASS} | not queryable, @ref Renderer::setStencilOperation() setter only
-@def_gl{SUBPIXEL_BITS} | |
+@def_gl{SUBPIXEL_BITS} | |
@def_gl{TEXTURE_BUFFER_OFFSET_ALIGNMENT} | @ref BufferTexture::offsetAlignment()
-@def_gl{TIMESTAMP} | |
+@def_gl{TIMESTAMP} | |
@def_gl{TRANSFORM_FEEDBACK_BUFFER_BINDING}, \n @def_gl{TRANSFORM_FEEDBACK_BUFFER_SIZE}, \n @def_gl{TRANSFORM_FEEDBACK_BUFFER_START} | not queryable
-@def_gl{UNIFORM_BUFFER_OFFSET_ALIGNMENT} | |
+@def_gl{UNIFORM_BUFFER_OFFSET_ALIGNMENT} | @ref Buffer::uniformOffsetAlignment()
@def_gl{UNIFORM_BUFFER_BINDING}, \n @def_gl{UNIFORM_BUFFER_SIZE}, \n @def_gl{UNIFORM_BUFFER_START} | not queryable
@def_gl{VERTEX_BINDING_DIVISOR}, \n @def_gl{VERTEX_BINDING_OFFSET}, \n @def_gl{VERTEX_BINDING_STRIDE} | not queryable
-@def_gl{VERTEX_PROGRAM_POINT_SIZE} | not queryable
-@def_gl{VIEWPORT_BOUNDS_RANGE} | |
+@def_gl{VERTEX_PROGRAM_POINT_SIZE} | not queryable
+@def_gl{VIEWPORT_BOUNDS_RANGE} | |
@def_gl{VIEWPORT_INDEX_PROVOKING_VERTEX} | |
-@def_gl{VIEWPORT_SUBPIXEL_BITS} | |
-@def_gl{VIEWPORT} | not queryable but tracked in @ref AbstractFramebuffer::viewport()
+@def_gl{VIEWPORT_SUBPIXEL_BITS} | |
+@def_gl{VIEWPORT} | not queryable but tracked in @ref AbstractFramebuffer::viewport()
*/
diff --git a/doc/opengl-support.dox b/doc/opengl-support.dox
index c1984a2d0..3b14aaf3d 100644
--- a/doc/opengl-support.dox
+++ b/doc/opengl-support.dox
@@ -47,248 +47,289 @@ following:
@subsection opengl-support-30 OpenGL 3.0
-@todo Replace @extension{APPLE,vertex_array_object} with ARB version (we use only ARB functions without APPLE fallback)
-@todo @extension{APPLE,flush_buffer_range} doesn't add anything to @extension{ARB,map_buffer_range} (remove it and leave only ARB one)
@todo @extension{EXT,texture_array} overlaps with @extension{ARB,framebuffer_object}
@todo Add @extension{ARB,depth_buffer_float} and implement the missing @fn_gl{DepthRange} function, but keep (and implement) @extension{NV,depth_buffer_float} for non-linear depth buffer
-@todo @extension{ARB,half_float_pixel}, @extension{ARB,half_float_vertex}?
-
-%Extension | Status
--------------------------------------------- | ------
-@extension{APPLE,flush_buffer_range} | done (GL 3.0 subset)
-@extension{APPLE,vertex_array_object} | done (GL 3.0 subset)
-@extension{ARB,map_buffer_range} | done
-@extension{ARB,color_buffer_float} | |
-@extension{ARB,half_float_pixel} | done
-@extension{ARB,texture_float} | done
-@extension{ARB,depth_buffer_float} | done
-@extension{ARB,texture_rg} | done
-@extension{ARB,framebuffer_object} | done
-@extension{EXT,gpu_shader4} | done
-@extension{EXT,packed_float} | done
-@extension{EXT,texture_array} | done
-@extension{EXT,texture_compression_rgtc} | done
-@extension{EXT,texture_shared_exponent} | done
-@extension{EXT,framebuffer_sRGB} | |
-@extension{EXT,draw_buffers2} | |
-@extension{EXT,texture_integer} | done (GL 3.0 subset)
-@extension{EXT,transform_feedback} | |
-@extension{NV,half_float} | done (GL 3.0 subset)
-@extension{NV,depth_buffer_float} | |
-@extension{NV,conditional_render} | done
+
+%Extension | Status
+------------------------------------------- | ------
+GLSL 1.30 | done
+@extension{ARB,map_buffer_range} | done
+@extension{ARB,color_buffer_float} | |
+@extension{ARB,half_float_pixel} | done
+@extension{ARB,texture_float} | done
+@extension{ARB,depth_buffer_float} | done
+@extension{ARB,texture_rg} | done
+@extension{ARB,vertex_array_object} | done
+@extension{ARB,framebuffer_object} | done
+@extension{ARB,framebuffer_sRGB} | done
+@extension{ARB,half_float_vertex} | done
+@extension{EXT,gpu_shader4} | done
+@extension{EXT,packed_float} | done
+@extension{EXT,texture_array} | done
+@extension{EXT,texture_compression_rgtc} | done
+@extension{EXT,texture_shared_exponent} | done
+@extension{EXT,draw_buffers2} | |
+@extension{EXT,texture_integer} | done (GL 3.0 subset)
+@extension{EXT,transform_feedback} | |
+@extension{NV,depth_buffer_float} | |
+@extension{NV,conditional_render} | done
@subsection opengl-support-31 OpenGL 3.1
-%Extension | Status
--------------------------------------------- | ------
-@extension{ARB,texture_rectangle} | done
-@extension{ARB,draw_instanced} | done
-@extension{ARB,texture_buffer_object} | done
-@extension{ARB,uniform_buffer_object} | |
-@extension{ARB,copy_buffer} | done
-@extension{EXT,texture_snorm} | done
-@extension{NV,primitive_restart} | |
+%Extension | Status
+------------------------------------------- | ------
+GLSL 1.40 | done
+@extension{ARB,texture_rectangle} | done
+@extension{ARB,draw_instanced} | done
+@extension{ARB,texture_buffer_object} | done
+@extension{ARB,uniform_buffer_object} | missing uniform block binding
+@extension{ARB,copy_buffer} | done
+@extension{EXT,texture_snorm} | done
+@extension{NV,primitive_restart} | |
@subsection opengl-support-32 OpenGL 3.2
-%Extension | Status
--------------------------------------------- | ------
-@extension{ARB,geometry_shader4} | missing layered attachments
-@extension{ARB,depth_clamp} | done
-@extension{ARB,draw_elements_base_vertex} | done
-@extension{ARB,fragment_coord_conventions} | done (shading language only)
-@extension{ARB,provoking_vertex} | done
-@extension{ARB,seamless_cube_map} | done
-@extension{ARB,sync} | |
-@extension{ARB,texture_multisample} | missing sample location queries and sample mask
-@extension{ARB,vertex_array_bgra} | done
+%Extension | Status
+------------------------------------------- | ------
+GLSL 1.50 | done
+@extension{ARB,geometry_shader4} | missing layered attachments
+@extension{ARB,depth_clamp} | done
+@extension{ARB,draw_elements_base_vertex} | done
+@extension{ARB,fragment_coord_conventions} | done (shading language only)
+@extension{ARB,provoking_vertex} | done
+@extension{ARB,seamless_cube_map} | done
+@extension{ARB,sync} | |
+@extension{ARB,texture_multisample} | missing sample location queries and sample mask
+@extension{ARB,vertex_array_bgra} | done
@subsection opengl-support-33 OpenGL 3.3
-%Extension | Status
--------------------------------------------- | ------
-@extension{ARB,instanced_arrays} | done
-@extension{ARB,blend_func_extended} | done
-@extension{ARB,explicit_attrib_location} | done (shading language only)
-@extension{ARB,occlusion_query2} | done
-@extension{ARB,sampler_objects} | |
-@extension{ARB,shader_bit_encoding} | done (shading language only)
-@extension{ARB,texture_rgb10_a2ui} | done
-@extension{ARB,texture_swizzle} | done
-@extension{ARB,timer_query} | missing direct query
-@extension{ARB,vertex_type_2_10_10_10_rev} | done
+%Extension | Status
+------------------------------------------- | ------
+GLSL 3.30 | done
+@extension{ARB,instanced_arrays} | done
+@extension{ARB,blend_func_extended} | done
+@extension{ARB,explicit_attrib_location} | done (shading language only)
+@extension{ARB,occlusion_query2} | done
+@extension{ARB,sampler_objects} | |
+@extension{ARB,shader_bit_encoding} | done (shading language only)
+@extension{ARB,texture_rgb10_a2ui} | done
+@extension{ARB,texture_swizzle} | done
+@extension{ARB,timer_query} | missing direct query
+@extension{ARB,vertex_type_2_10_10_10_rev} | done
@subsection opengl-support-40 OpenGL 4.0
-%Extension | Status
--------------------------------------------- | ------
-@extension{ARB,draw_buffers_blend} | |
-@extension{ARB,sample_shading} | |
-@extension{ARB,texture_cube_map_array} | done
-@extension{ARB,texture_gather} | missing limit queries
-@extension{ARB,texture_query_lod} | done (shading language only)
-@extension{ARB,draw_indirect} | |
-@extension{ARB,gpu_shader5} | missing limit queries
-@extension{ARB,gpu_shader_fp64} | done
-@extension{ARB,shader_subroutine} | |
-@extension{ARB,tessellation_shader} | missing some limit queries and patch parameter specification function
-@extension{ARB,texture_buffer_object_rgb32} | done
-@extension{ARB,transform_feedback2} | |
-@extension{ARB,transform_feedback3} | |
+%Extension | Status
+------------------------------------------- | ------
+GLSL 4.00 | done
+@extension{ARB,draw_buffers_blend} | |
+@extension{ARB,sample_shading} | |
+@extension{ARB,texture_cube_map_array} | done
+@extension{ARB,texture_gather} | missing limit queries
+@extension{ARB,texture_query_lod} | done (shading language only)
+@extension{ARB,draw_indirect} | |
+@extension{ARB,gpu_shader5} | missing limit queries
+@extension{ARB,gpu_shader_fp64} | done
+@extension{ARB,shader_subroutine} | |
+@extension{ARB,tessellation_shader} | missing some limit queries and patch parameter specification function
+@extension{ARB,texture_buffer_object_rgb32} | done
+@extension{ARB,transform_feedback2} | |
+@extension{ARB,transform_feedback3} | |
@subsection opengl-support-41 OpenGL 4.1
-%Extension | Status
--------------------------------------------- | ------
-@extension{ARB,ES2_compatibility} | only float depth clear
-@extension{ARB,get_program_binary} | |
-@extension{ARB,separate_shader_objects} | only direct uniform binding
-@extension{ARB,shader_precision} | done (shading language only)
-@extension{ARB,vertex_attrib_64bit} | done
-@extension{ARB,viewport_array} | |
+%Extension | Status
+------------------------------------------- | ------
+GLSL 4.10 | done
+@extension{ARB,ES2_compatibility} | only float depth clear
+@extension{ARB,get_program_binary} | |
+@extension{ARB,separate_shader_objects} | only direct uniform binding
+@extension{ARB,shader_precision} | done (shading language only)
+@extension{ARB,vertex_attrib_64bit} | done
+@extension{ARB,viewport_array} | |
@subsection opengl-support-42 OpenGL 4.2
-%Extension | Status
--------------------------------------------- | ------
-@extension{ARB,texture_compression_bptc} | done
-@extension{ARB,base_instance} | done
-@extension{ARB,shading_language_420pack} | done (shading language only)
+%Extension | Status
+------------------------------------------- | ------
+GLSL 4.20 | done
+@extension{ARB,texture_compression_bptc} | done
+@extension{ARB,base_instance} | done
+@extension{ARB,shading_language_420pack} | done (shading language only)
@extension{ARB,transform_feedback_instanced} | |
@extension{ARB,compressed_texture_pixel_storage} | |
-@extension{ARB,conservative_depth} | done (shading language only)
-@extension{ARB,internalformat_query} | |
-@extension{ARB,map_buffer_alignment} | done
-@extension{ARB,shader_atomic_counters} | |
-@extension{ARB,shader_image_load_store} | |
-@extension{ARB,shading_language_packing} | done (shading language only)
-@extension{ARB,texture_storage} | done
+@extension{ARB,conservative_depth} | done (shading language only)
+@extension{ARB,internalformat_query} | |
+@extension{ARB,map_buffer_alignment} | done
+@extension{ARB,shader_atomic_counters} | done
+@extension{ARB,shader_image_load_store} | |
+@extension{ARB,shading_language_packing} | done (shading language only)
+@extension{ARB,texture_storage} | done
@subsection opengl-support-43 OpenGL 4.3
-%Extension | Status
--------------------------------------------- | ------
-@extension{ARB,arrays_of_arrays} | done (shading language only)
-@extension{ARB,ES3_compatibility} | only conservative sample query
-@extension{ARB,clear_buffer_object} | |
-@extension{ARB,compute_shader} | |
-@extension{ARB,copy_image} | |
-@extension{KHR,debug} (also in ES) | missing log retrieval, sync, pipeline, transform feedback and sampler label and debug groups
-@extension{ARB,explicit_uniform_location} | done
-@extension{ARB,fragment_layer_viewport} | done (shading language only)
-@extension{ARB,framebuffer_no_attachments} | |
-@extension{ARB,internalformat_query2} | |
-@extension{ARB,invalidate_subdata} | done
-@extension{ARB,multi_draw_indirect} | |
-@extension{ARB,program_interface_query} | |
+%Extension | Status
+------------------------------------------- | ------
+GLSL 4.30 | done
+@extension{ARB,arrays_of_arrays} | done (shading language only)
+@extension{ARB,ES3_compatibility} | only conservative sample query
+@extension{ARB,clear_buffer_object} | |
+@extension{ARB,compute_shader} | |
+@extension{ARB,copy_image} | |
+@extension{KHR,debug} (also in ES) | missing log retrieval, sync, pipeline, transform feedback and sampler label and debug groups
+@extension{ARB,explicit_uniform_location} | done
+@extension{ARB,fragment_layer_viewport} | done (shading language only)
+@extension{ARB,framebuffer_no_attachments} | |
+@extension{ARB,internalformat_query2} | |
+@extension{ARB,invalidate_subdata} | done
+@extension{ARB,multi_draw_indirect} | |
+@extension{ARB,program_interface_query} | |
@extension{ARB,robust_buffer_access_behavior} | done (nothing to do)
-@extension{ARB,shader_image_size} | done (shading language only)
+@extension{ARB,shader_image_size} | done (shading language only)
@extension{ARB,shader_storage_buffer_object} | only limit queries
-@extension{ARB,stencil_texturing} | done
-@extension{ARB,texture_buffer_range} | done
-@extension{ARB,texture_query_levels} | done (shading language only)
-@extension{ARB,texture_storage_multisample} | done
-@extension{ARB,texture_view} | |
-@extension{ARB,vertex_attrib_binding} | |
+@extension{ARB,stencil_texturing} | done
+@extension{ARB,texture_buffer_range} | done
+@extension{ARB,texture_query_levels} | done (shading language only)
+@extension{ARB,texture_storage_multisample} | done
+@extension{ARB,texture_view} | |
+@extension{ARB,vertex_attrib_binding} | |
@subsection opengl-support-44 OpenGL 4.4
@todo Also fallback to @extension{AMD,query_buffer_object}
@todo @extension{AMD,pinned_memory} "fallback" for @extension{ARB,buffer_storage}
-%Extension | Status
--------------------------------------------- | ------
-@extension{ARB,buffer_storage} | |
-@extension{ARB,clear_texture} | |
-@extension{ARB,enhanced_layouts} | done (shading language only)
-@extension{ARB,multi_bind} | only texture binding
-@extension{ARB,query_buffer_object} | |
+%Extension | Status
+------------------------------------------- | ------
+GLSL 4.40 | done
+@def_gl{MAX_VERTEX_ATTRIB_STRIDE} | |
+@extension{ARB,buffer_storage} | |
+@extension{ARB,clear_texture} | |
+@extension{ARB,enhanced_layouts} | done (shading language only)
+@extension{ARB,multi_bind} | only texture and buffer binding
+@extension{ARB,query_buffer_object} | |
@extension{ARB,texture_mirror_clamp_to_edge} | done
-@extension{ARB,texture_stencil8} | done
-@extension{ARB,vertex_type_10f_11f_11f_rev} | done
-
-@subsection opengl-support-extensions OpenGL extensions
+@extension{ARB,texture_stencil8} | done
+@extension{ARB,vertex_type_10f_11f_11f_rev} | done
+
+@subsection opengl-support-45 OpenGL 4.5
+
+%Extension | Status
+------------------------------------------- | ------
+GLSL 4.50 | done
+@extension{ARB,ES3_1_compatibility} | |
+@extension{ARB,clip_control} | |
+@extension{ARB,conditional_render_inverted} | done
+@extension{ARB,cull_distance} | |
+@extension{ARB,derivative_control} | done (shading language only)
+@extension{ARB,direct_state_access} | object creation subset only
+@extension{ARB,get_texture_sub_image} | |
+@extension{ARB,shader_texture_image_samples} | done (shading language only)
+@extension{ARB,texture_barrier} | |
+@extension{KHR,context_flush_control} (also in ES) | |
+@extension{KHR,robustness} (also in ES) | |
+
+@subsection opengl-support-extensions ARB / Khronos OpenGL extensions
+
+%Extension | Status
+------------------------------------------- | ------
+@extension{ARB,robustness} | done
+@extension3{KHR,texture_compression_astc_ldr,texture_compression_astc_hdr} (also in ES) | |
+@extension{KHR,texture_compression_astc_hdr} (also in ES) | |
+@extension{ARB,robustness_isolation} | done
+@extension{ARB,bindless_texture} | |
+@extension{ARB,compute_variable_group_size} | |
+@extension{ARB,indirect_parameters} | |
+@extension{ARB,seamless_cubemap_per_texture} | |
+@extension{ARB,shader_draw_parameters} | done (shading language only)
+@extension{ARB,shader_group_vote} | done (shading language only)
+@extension{ARB,sparse_texture} | |
+@extension{ARB,pipeline_statistics_query} | |
+@extension{ARB,sparse_buffer} | |
+@extension{ARB,transform_feedback_overflow_query} | |
+
+@subsection opengl-support-extensions-vendor Vendor OpenGL extensions
@todo @extension{ARB,sparse_texture}, @extension{ARB,bindless_texture} + their vendor equivalents
@todo @extension{ATI,meminfo}, @extension{NVX,gpu_memory_info}, GPU temperature
@todo @extension{AMD,performance_monitor}, @extension{INTEL,performance_query}
-%Extension | Status
--------------------------------------------- | ------
-@extension{AMD,vertex_shader_layer} | done (shading language only)
-@extension{AMD,shader_trinary_minmax} | done (shading language only)
-@extension{ARB,robustness} | done
-@extension{ATI,texture_mirror_once} | done (GL 4.4 subset)
+%Extension | Status
+------------------------------------------- | ------
+@extension{AMD,vertex_shader_layer} | done (shading language only)
+@extension{AMD,shader_trinary_minmax} | done (shading language only)
+@extension{ATI,texture_mirror_once} | done (GL 4.4 subset)
@extension{EXT,texture_filter_anisotropic} (also in ES) | done
-@extension{EXT,texture_mirror_clamp} | only GL 4.4 subset
-@extension{EXT,direct_state_access} | done for implemented functionality
+@extension{EXT,texture_mirror_clamp} | only GL 4.4 subset
+@extension{EXT,direct_state_access} | done for implemented functionality
@extension{EXT,texture_sRGB_decode} (also in ES) | done
@extension{EXT,shader_integer_mix} (also in ES) | done (shading language only)
-@extension2{EXT,debug_label} (also in ES) | missing pipeline, transform feedback and sampler label
-@extension2{EXT,debug_marker} (also in ES) | missing marker groups
-@extension{GREMEDY,string_marker} | done
+@extension2{EXT,debug_label} (also in ES) | missing pipeline, transform feedback and sampler label
+@extension2{EXT,debug_marker} (also in ES) | missing marker groups
+@extension{GREMEDY,string_marker} | done
@subsection opengl-support-es20 OpenGL ES 2.0
Features that have their equivalents implemented in desktop version are
-supported.
+supported. ESSL 1.00 is supported.
@subsection opengl-support-es30 OpenGL ES 3.0
Features that have their equivalents implemented in desktop version are
-supported.
+supported. ESSL 3.00 is supported.
@subsection opengl-support-es31 OpenGL ES 3.1
Features that have their equivalents implemented in desktop version are
-supported.
+supported. ESSL 3.10 is supported.
@subsection opengl-support-es30-extensions OpenGL ES 2.0 extensions to match ES 3.0 functionality
-%Extension | Status
--------------------------------------------- | ------
-@es_extension{ANGLE,framebuffer_blit} | done
+%Extension | Status
+------------------------------------------- | ------
+@es_extension{ANGLE,framebuffer_blit} | done
@es_extension{ANGLE,framebuffer_multisample} | done
-@es_extension{ANGLE,instanced_arrays} | done
-@es_extension{ANGLE,depth_texture} | done
+@es_extension{ANGLE,instanced_arrays} | done
+@es_extension{ANGLE,depth_texture} | done
@es_extension{APPLE,framebuffer_multisample} | done (ES 3.0 subset)
-@es_extension{APPLE,texture_max_level} | done
-@es_extension{ARM,rgba8} | done
+@es_extension{APPLE,texture_max_level} | done
+@es_extension{ARM,rgba8} | done
@es_extension{EXT,texture_type_2_10_10_10_REV} | done
-@es_extension{EXT,discard_framebuffer} | done
+@es_extension{EXT,discard_framebuffer} | done
@es_extension2{EXT,blend_minmax,blend_minmax} | done
-@es_extension{EXT,shader_texture_lod} | done (shading language only)
-@es_extension{EXT,occlusion_query_boolean} | done
-@es_extension{EXT,shadow_samplers} | done
-@es_extension{EXT,texture_rg} | done
-@es_extension{EXT,texture_storage} | done
-@es_extension{EXT,map_buffer_range} | done
-@es_extension{EXT,instanced_arrays} | done
+@es_extension{EXT,shader_texture_lod} | done (shading language only)
+@es_extension{EXT,occlusion_query_boolean} | done
+@es_extension{EXT,shadow_samplers} | done
+@es_extension{EXT,texture_rg} | done
+@es_extension{EXT,texture_storage} | done
+@es_extension{EXT,map_buffer_range} | done
+@es_extension{EXT,instanced_arrays} | done
@es_extension2{EXT,draw_instanced,draw_instanced} | done
-@es_extension{NV,draw_buffers} | done
-@es_extension{NV,fbo_color_attachments} | done
-@es_extension{NV,read_buffer} | done
-@es_extension{NV,draw_instanced} | done
-@es_extension{NV,framebuffer_blit} | done
-@es_extension{NV,framebuffer_multisample} | done
-@es_extension{NV,instanced_arrays} | done
-@es_extension{NV,shadow_samplers_array} | done (shading language only)
-@es_extension{NV,shadow_samplers_cube} | done (shading language only)
-@es_extension{OES,depth24} | done
-@es_extension{OES,element_index_uint} | done
-@es_extension{OES,rgb8_rgba8} | done (desktop-compatible subset)
-@es_extension{OES,texture_3D} | done
+@es_extension{NV,draw_buffers} | done
+@es_extension{NV,fbo_color_attachments} | done
+@es_extension{NV,read_buffer} | done
+@es_extension{NV,draw_instanced} | done
+@es_extension{NV,framebuffer_blit} | done
+@es_extension{NV,framebuffer_multisample} | done
+@es_extension{NV,instanced_arrays} | done
+@es_extension{NV,shadow_samplers_array} | done (shading language only)
+@es_extension{NV,shadow_samplers_cube} | done (shading language only)
+@es_extension{OES,depth24} | done
+@es_extension{OES,element_index_uint} | done
+@es_extension{OES,rgb8_rgba8} | done (desktop-compatible subset)
+@es_extension{OES,texture_3D} | done
@es_extension2{OES,texture_half_float_linear,OES_texture_float_linear} | done
-@es_extension{OES,texture_float_linear} | done
+@es_extension{OES,texture_float_linear} | done
@es_extension2{OES,texture_half_float,OES_texture_float} | done
-@es_extension{OES,texture_float} | done
-@es_extension{OES,vertex_half_float} | done
-@es_extension{OES,packed_depth_stencil} | done
-@es_extension{OES,depth_texture} | done
-@es_extension{OES,standard_derivatives} | done
-@es_extension{OES,vertex_array_object} | done
-@es_extension{OES,required_internalformat} | done (desktop-compatible subset)
-@es_extension{OES,surfaceless_context} | done
+@es_extension{OES,texture_float} | done
+@es_extension{OES,vertex_half_float} | done
+@es_extension{OES,packed_depth_stencil} | done
+@es_extension{OES,depth_texture} | done
+@es_extension{OES,standard_derivatives} | done
+@es_extension{OES,vertex_array_object} | done
+@es_extension{OES,required_internalformat} | done (desktop-compatible subset)
+@es_extension{OES,surfaceless_context} | done
@subsection opengl-support-es-extensions OpenGL ES extensions to match desktop functionality
@@ -298,27 +339,28 @@ Only extensions not already listed in above tables are included here.
@todo Support also IMG_multisampled_render_to_texture? It has different enum
values (!)
-%Extension | Status
--------------------------------------------- | ------
+%Extension | Status
+------------------------------------------- | ------
@es_extension{APPLE,texture_format_BGRA8888} | done
-@es_extension{CHROMIUM,map_sub} | only buffer mapping
-@es_extension{EXT,texture_format_BGRA8888} | done
-@es_extension{EXT,read_format_bgra} | done
+@es_extension{CHROMIUM,map_sub} | only buffer mapping
+@es_extension{EXT,texture_format_BGRA8888} | done
+@es_extension{EXT,read_format_bgra} | done
@es_extension2{EXT,multi_draw_arrays,multi_draw_arrays} | done
-@es_extension{EXT,disjoint_timer_query} | only time elapsed query
-@es_extension{EXT,separate_shader_objects} | only direct uniform binding
-@es_extension{EXT,sRGB} | done
+@es_extension{EXT,disjoint_timer_query} | only time elapsed query
+@es_extension{EXT,separate_shader_objects} | only direct uniform binding
+@es_extension{EXT,sRGB} | done
@es_extension{EXT,multisampled_render_to_texture} | only renderbuffer storage
-@es_extension{EXT,robustness} | done
+@es_extension{EXT,robustness} | done
+@es_extension{KHR,robust_buffer_access_behavior} | done (nothing to do)
@es_extension2{NV,read_buffer_front,NV_read_buffer} | done
@es_extension2{NV,read_depth,NV_read_depth_stencil} | done
@es_extension2{NV,read_stencil,NV_read_depth_stencil} | done
-@es_extension{NV,read_depth_stencil} | done
-@es_extension{NV,texture_border_clamp} | done
-@es_extension{OES,depth32} | done
-@es_extension{OES,mapbuffer} | done
-@es_extension{OES,stencil1} | done
-@es_extension{OES,stencil4} | done
+@es_extension{NV,read_depth_stencil} | done
+@es_extension{NV,texture_border_clamp} | done
+@es_extension{OES,depth32} | done
+@es_extension{OES,mapbuffer} | done
+@es_extension{OES,stencil1} | done
+@es_extension{OES,stencil4} | done
@section opengl-unsupported Unsupported OpenGL features
@@ -328,6 +370,10 @@ add any performance gains, is not supported in %Magnum. See also
@subsection opengl-unsupported-features Unsupported features
+- API that is not part of core profile or is marked as deprecated (but still
+ supported in core profile) in the latest version of OpenGL specification is
+ not supported. The only exception are features that are needed for some
+ OpenGL ES 2.0 implementations (such as luminance texture formats).
- State queries (various `glIs*()`, `glGet*()` functions) are not supported.
%Magnum API is designed to prevent the need for majority of them, many of
them are tracked internally to avoid redundant state changes and in many
@@ -353,13 +399,21 @@ add any performance gains, is not supported in %Magnum. See also
- Direct vertex data specification (as opposed to using buffers) is not
supported, as it encourages bad practices.
-@subsection opengl-unsupported-extensions Unsupported extensions
+@subsection opengl-unsupported-extensions Unsupported ARB / Khronos extensions
+
+- @extension{ARB,shading_language_include} is overly complicated and
+ supported exclusively by NVidia
+- @extension{ARB,cl_event} seems to be not supported anywhere
+- @extension{ARB,shader_stencil_export} is supported exclusively by AMD
+
+@subsection opengl-unsupported-extensions-vendor Unsupported vendor extensions
-- @extension{INTEL,map_texture} negatively affects texture access performance.
- Combination of buffer mapping and pixel buffers might be of the same or
- better performance, without affecting texture access speed.
-- @extension{NV,draw_texture} can be done with framebuffer blitting and
- doesn't make any full-screen postprocessing easier, as shaders are excluded.
+- @extension{INTEL,map_texture} negatively affects texture access
+ performance. Combination of buffer mapping and pixel buffers might be of
+ the same or better performance, without affecting texture access speed.
+- @extension{NV,draw_texture} can be done with framebuffer blitting and
+ doesn't make any full-screen postprocessing easier, as shaders are
+ excluded.
*/
diff --git a/doc/opengl.dox b/doc/opengl.dox
index 582ad9213..babe2c6c6 100644
--- a/doc/opengl.dox
+++ b/doc/opengl.dox
@@ -43,7 +43,7 @@ The engine requires at least OpenGL 2.1 or OpenGL ES 2.0, but some specific
functionality has greater requirements. Following are lists of features
requiring specific OpenGL version. In most cases it is also specified which
extension is required, so if given hardware supports required extension, it
-doesn't need to have required OpenGL version too (e.g. `APPLE_vertex_array_object`
+doesn't need to have required OpenGL version too (e.g. `ARB_vertex_array_object`
is supported on older Intel GPUs even if they are capable of OpenGL 2.1 only).
- @subpage requires-gl30
@@ -55,6 +55,7 @@ is supported on older Intel GPUs even if they are capable of OpenGL 2.1 only).
- @subpage requires-gl42
- @subpage requires-gl43
- @subpage requires-gl44
+- @subpage requires-gl45
- @subpage requires-extension
- @subpage requires-gl
- @subpage requires-gles20
@@ -74,6 +75,7 @@ is supported on older Intel GPUs even if they are capable of OpenGL 2.1 only).
@page requires-gl42 Functionality requiring OpenGL 4.2
@page requires-gl43 Functionality requiring OpenGL 4.3
@page requires-gl44 Functionality requiring OpenGL 4.4
+@page requires-gl45 Functionality requiring OpenGL 4.5
@page requires-extension Functionality requiring specific OpenGL extension
diff --git a/package/gentoo/dev-libs/magnum/Manifest b/package/gentoo/dev-libs/magnum/Manifest
new file mode 100644
index 000000000..e6854f5fe
--- /dev/null
+++ b/package/gentoo/dev-libs/magnum/Manifest
@@ -0,0 +1 @@
+EBUILD magnum-9999.ebuild 1122 SHA256 c71b5825632f6161fdad24f221c875c926d20cad848c6312e6dea3fa448ab486 SHA512 e46cf2e44ea7b7ed316aea9e71604c0e5c2b05b40202bfc212d9b621e403d87d9355ae6ec1bfbe7cef749c1a7d767da4dfceacf29f69faed4f8f7b9d3442e971 WHIRLPOOL b08ee4efee6cab255e0fc38b6e4ccd9925300e4ec682b18401203e7152b42cd442f81ab588ddd9e1df85b484ed734119b8b23cde9146b4fd76544ba1b647b272
diff --git a/package/gentoo/dev-libs/magnum/magnum-9999.ebuild b/package/gentoo/dev-libs/magnum/magnum-9999.ebuild
new file mode 100644
index 000000000..1cd38ed5d
--- /dev/null
+++ b/package/gentoo/dev-libs/magnum/magnum-9999.ebuild
@@ -0,0 +1,52 @@
+# Copyright 1999-2014 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+EAPI=5
+
+EGIT_REPO_URI="git://github.com/mosra/magnum.git"
+
+inherit cmake-utils git-r3
+
+DESCRIPTION="C++11 and OpenGL 2D/3D graphics engine"
+HOMEPAGE="http://mosra.cz/blog/magnum.php"
+
+LICENSE="MIT"
+SLOT="0"
+KEYWORDS="~amd64 ~x86"
+IUSE=""
+
+RDEPEND="
+ dev-libs/corrade
+ media-libs/openal
+ media-libs/freeglut
+ media-libs/libsdl2
+"
+DEPEND="${RDEPEND}"
+
+src_configure() {
+ local mycmakeargs=(
+ -DCMAKE_INSTALL_PREFIX="${EPREFIX}/usr"
+ -DCMAKE_BUILD_TYPE=Debug \
+ -DWITH_AUDIO=ON \
+ -DWITH_GLUTAPPLICATION=ON \
+ -DWITH_GLXAPPLICATION=ON \
+ -DWITH_SDL2APPLICATION=ON \
+ -DWITH_WINDOWLESSGLXAPPLICATION=ON \
+ -DWITH_EGLCONTEXT=ON \
+ -DWITH_GLXCONTEXT=ON \
+ -DWITH_MAGNUMFONT=ON \
+ -DWITH_MAGNUMFONTCONVERTER=ON \
+ -DWITH_OBJIMPORTER=ON \
+ -DWITH_TGAIMAGECONVERTER=ON \
+ -DWITH_TGAIMPORTER=ON \
+ -DWITH_WAVAUDIOIMPORTER=ON \
+ -DWITH_DISTANCEFIELDCONVERTER=ON \
+ -DWITH_FONTCONVERTER=ON \
+ -DWITH_MAGNUMINFO=ON \
+ -DBUILD_TESTS=ON \
+ -DBUILD_GL_TESTS=ON
+ )
+ cmake-utils_src_configure
+}
+
diff --git a/src/Magnum/AbstractFramebuffer.cpp b/src/Magnum/AbstractFramebuffer.cpp
index f205c4f2d..80477b214 100644
--- a/src/Magnum/AbstractFramebuffer.cpp
+++ b/src/Magnum/AbstractFramebuffer.cpp
@@ -82,6 +82,17 @@ Int AbstractFramebuffer::maxDualSourceDrawBuffers() {
}
#endif
+void AbstractFramebuffer::createIfNotAlready() {
+ if(_created) return;
+
+ /* glGen*() does not create the object, just reserves the name. Some
+ commands (such as glObjectLabel()) operate with IDs directly and they
+ require the object to be created. Binding the framebuffer finally
+ creates it. Also all EXT DSA functions implicitly create it. */
+ bindInternal();
+ CORRADE_INTERNAL_ASSERT(_created);
+}
+
void AbstractFramebuffer::bind(FramebufferTarget target) {
bindInternal(target);
setViewportInternal();
@@ -102,6 +113,8 @@ void AbstractFramebuffer::bindInternal(FramebufferTarget target) {
state->readBinding = state->drawBinding = _id;
} else CORRADE_ASSERT_UNREACHABLE();
+ /* Binding the framebuffer finally creates it */
+ _created = true;
glBindFramebuffer(GLenum(target), _id);
}
@@ -119,6 +132,8 @@ FramebufferTarget AbstractFramebuffer::bindInternal() {
/* Or bind it, if not already */
state->readBinding = _id;
+ /* Binding the framebuffer finally creates it */
+ _created = true;
#ifndef MAGNUM_TARGET_GLES2
glBindFramebuffer(GLenum(FramebufferTarget::Read), _id);
return FramebufferTarget::Read;
@@ -222,7 +237,7 @@ void AbstractFramebuffer::read(const Vector2i& offset, const Vector2i& size, Buf
if(image.size() != size)
image.setData(image.format(), image.type(), size, nullptr, usage);
- image.buffer().bind(Buffer::Target::PixelPack);
+ image.buffer().bindInternal(Buffer::TargetHint::PixelPack);
(Context::current()->state().framebuffer->readImplementation)(offset, size, image.format(), image.type(), image.dataSize(size), nullptr);
}
#endif
@@ -255,7 +270,8 @@ GLenum AbstractFramebuffer::checkStatusImplementationDefault(const FramebufferTa
}
#ifndef MAGNUM_TARGET_GLES
-GLenum AbstractFramebuffer::checkStatusImplementationDSA(const FramebufferTarget target) {
+GLenum AbstractFramebuffer::checkStatusImplementationDSAEXT(const FramebufferTarget target) {
+ _created = true;
return glCheckNamedFramebufferStatusEXT(_id, GLenum(target));
}
#endif
@@ -279,7 +295,8 @@ void AbstractFramebuffer::drawBuffersImplementationDefault(GLsizei count, const
}
#ifndef MAGNUM_TARGET_GLES
-void AbstractFramebuffer::drawBuffersImplementationDSA(GLsizei count, const GLenum* buffers) {
+void AbstractFramebuffer::drawBuffersImplementationDSAEXT(GLsizei count, const GLenum* buffers) {
+ _created = true;
glFramebufferDrawBuffersEXT(_id, count, buffers);
}
#endif
@@ -304,7 +321,8 @@ void AbstractFramebuffer::drawBufferImplementationDefault(GLenum buffer) {
}
#ifndef MAGNUM_TARGET_GLES
-void AbstractFramebuffer::drawBufferImplementationDSA(GLenum buffer) {
+void AbstractFramebuffer::drawBufferImplementationDSAEXT(GLenum buffer) {
+ _created = true;
glFramebufferDrawBufferEXT(_id, buffer);
}
#endif
@@ -327,7 +345,8 @@ void AbstractFramebuffer::readBufferImplementationDefault(GLenum buffer) {
}
#ifndef MAGNUM_TARGET_GLES
-void AbstractFramebuffer::readBufferImplementationDSA(GLenum buffer) {
+void AbstractFramebuffer::readBufferImplementationDSAEXT(GLenum buffer) {
+ _created = true;
glFramebufferReadBufferEXT(_id, buffer);
}
#endif
diff --git a/src/Magnum/AbstractFramebuffer.h b/src/Magnum/AbstractFramebuffer.h
index c647b79d2..63da2b409 100644
--- a/src/Magnum/AbstractFramebuffer.h
+++ b/src/Magnum/AbstractFramebuffer.h
@@ -334,11 +334,14 @@ class MAGNUM_EXPORT AbstractFramebuffer {
explicit AbstractFramebuffer();
~AbstractFramebuffer();
+ void MAGNUM_LOCAL createIfNotAlready();
+
void MAGNUM_LOCAL bindInternal(FramebufferTarget target);
FramebufferTarget MAGNUM_LOCAL bindInternal();
void MAGNUM_LOCAL setViewportInternal();
GLuint _id;
+ bool _created; /* see createIfNotAlready() for details */
Range2Di _viewport;
private:
@@ -349,22 +352,22 @@ class MAGNUM_EXPORT AbstractFramebuffer {
GLenum MAGNUM_LOCAL checkStatusImplementationDefault(FramebufferTarget target);
#ifndef MAGNUM_TARGET_GLES
- GLenum MAGNUM_LOCAL checkStatusImplementationDSA(FramebufferTarget target);
+ GLenum MAGNUM_LOCAL checkStatusImplementationDSAEXT(FramebufferTarget target);
#endif
void MAGNUM_LOCAL drawBuffersImplementationDefault(GLsizei count, const GLenum* buffers);
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL drawBuffersImplementationDSA(GLsizei count, const GLenum* buffers);
+ void MAGNUM_LOCAL drawBuffersImplementationDSAEXT(GLsizei count, const GLenum* buffers);
#endif
void MAGNUM_LOCAL drawBufferImplementationDefault(GLenum buffer);
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL drawBufferImplementationDSA(GLenum buffer);
+ void MAGNUM_LOCAL drawBufferImplementationDSAEXT(GLenum buffer);
#endif
void MAGNUM_LOCAL readBufferImplementationDefault(GLenum buffer);
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL readBufferImplementationDSA(GLenum buffer);
+ void MAGNUM_LOCAL readBufferImplementationDSAEXT(GLenum buffer);
#endif
static void MAGNUM_LOCAL readImplementationDefault(const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
diff --git a/src/Magnum/Query.cpp b/src/Magnum/AbstractQuery.cpp
similarity index 82%
rename from src/Magnum/Query.cpp
rename to src/Magnum/AbstractQuery.cpp
index 3e01d4b8e..6221e3fad 100644
--- a/src/Magnum/Query.cpp
+++ b/src/Magnum/AbstractQuery.cpp
@@ -23,26 +23,27 @@
DEALINGS IN THE SOFTWARE.
*/
-#include "Query.h"
+#include "AbstractQuery.h"
#include
#include "Magnum/Context.h"
#include "Magnum/Implementation/DebugState.h"
+#include "Magnum/Implementation/QueryState.h"
#include "Magnum/Implementation/State.h"
namespace Magnum {
-AbstractQuery::AbstractQuery(): target() {
- #ifndef MAGNUM_TARGET_GLES2
- glGenQueries(1, &_id);
- #elif !defined(CORRADE_TARGET_EMSCRIPTEN)
- glGenQueriesEXT(1, &_id);
- #else
- CORRADE_ASSERT_UNREACHABLE();
- #endif
+AbstractQuery::AbstractQuery(GLenum target): _target{target} {
+ (this->*Context::current()->state().query->createImplementation)();
}
+#ifdef MAGNUM_BUILD_DEPRECATED
+AbstractQuery::AbstractQuery(): _target{} {
+ createImplementationDefault();
+}
+#endif
+
AbstractQuery::~AbstractQuery() {
/* Moved out, nothing to do */
if(!_id) return;
@@ -56,6 +57,22 @@ AbstractQuery::~AbstractQuery() {
#endif
}
+void AbstractQuery::createImplementationDefault() {
+ #ifndef MAGNUM_TARGET_GLES2
+ glGenQueries(1, &_id);
+ #elif !defined(CORRADE_TARGET_EMSCRIPTEN)
+ glGenQueriesEXT(1, &_id);
+ #else
+ CORRADE_ASSERT_UNREACHABLE();
+ #endif
+}
+
+#ifndef MAGNUM_TARGET_GLES
+void AbstractQuery::createImplementationDSA() {
+ glCreateQueries(_target, 1, &_id);
+}
+#endif
+
std::string AbstractQuery::label() const {
#ifndef MAGNUM_TARGET_GLES
return Context::current()->state().debug->getLabelImplementation(GL_QUERY, _id);
@@ -74,8 +91,6 @@ AbstractQuery& AbstractQuery::setLabelInternal(const Containers::ArrayReference<
}
bool AbstractQuery::resultAvailable() {
- CORRADE_ASSERT(!target, "AbstractQuery::resultAvailable(): the query is currently running", false);
-
GLuint result;
#ifndef MAGNUM_TARGET_GLES2
glGetQueryObjectuiv(_id, GL_QUERY_RESULT_AVAILABLE, &result);
@@ -89,8 +104,6 @@ bool AbstractQuery::resultAvailable() {
#ifndef DOXYGEN_GENERATING_OUTPUT
template<> UnsignedInt AbstractQuery::result() {
- CORRADE_ASSERT(!target, "AbstractQuery::result(): the query is currently running", {});
-
UnsignedInt result;
#ifndef MAGNUM_TARGET_GLES2
glGetQueryObjectuiv(_id, GL_QUERY_RESULT, &result);
@@ -105,8 +118,6 @@ template<> UnsignedInt AbstractQuery::result() {
template<> bool AbstractQuery::result() { return result() != 0; }
template<> Int AbstractQuery::result() {
- CORRADE_ASSERT(!target, "AbstractQuery::result(): the query is currently running", {});
-
Int result;
#ifndef MAGNUM_TARGET_GLES
glGetQueryObjectiv(_id, GL_QUERY_RESULT, &result);
@@ -120,8 +131,6 @@ template<> Int AbstractQuery::result() {
#ifndef MAGNUM_TARGET_WEBGL
template<> UnsignedLong AbstractQuery::result() {
- CORRADE_ASSERT(!target, "AbstractQuery::result(): the query is currently running", {});
-
UnsignedLong result;
#ifndef MAGNUM_TARGET_GLES
glGetQueryObjectui64v(_id, GL_QUERY_RESULT, &result);
@@ -134,8 +143,6 @@ template<> UnsignedLong AbstractQuery::result() {
}
template<> Long AbstractQuery::result() {
- CORRADE_ASSERT(!target, "AbstractQuery::result(): the query is currently running", {});
-
Long result;
#ifndef MAGNUM_TARGET_GLES
glGetQueryObjecti64v(_id, GL_QUERY_RESULT, &result);
@@ -149,30 +156,41 @@ template<> Long AbstractQuery::result() {
#endif
#endif
-void AbstractQuery::begin(GLenum target) {
- CORRADE_ASSERT(!this->target, "AbstractQuery::begin(): the query is already running", );
+void AbstractQuery::begin() {
+ #ifdef MAGNUM_BUILD_DEPRECATED
+ CORRADE_INTERNAL_ASSERT(_target);
+ #endif
#ifndef MAGNUM_TARGET_GLES2
- glBeginQuery(this->target = target, id());
+ glBeginQuery(_target, _id);
#elif !defined(CORRADE_TARGET_EMSCRIPTEN)
- glBeginQueryEXT(this->target = target, id());
+ glBeginQueryEXT(_target, _id);
#else
- static_cast(target);
CORRADE_ASSERT_UNREACHABLE();
#endif
}
+#ifdef MAGNUM_BUILD_DEPRECATED
+void AbstractQuery::begin(const GLenum target) {
+ CORRADE_INTERNAL_ASSERT(!_target || _target == target);
+
+ _target = target;
+ begin();
+}
+#endif
+
void AbstractQuery::end() {
- CORRADE_ASSERT(target, "AbstractQuery::end(): the query is not running", );
+ #ifdef MAGNUM_BUILD_DEPRECATED
+ CORRADE_INTERNAL_ASSERT(_target);
+ #endif
#ifndef MAGNUM_TARGET_GLES2
- glEndQuery(target);
+ glEndQuery(_target);
#elif !defined(CORRADE_TARGET_EMSCRIPTEN)
- glEndQueryEXT(target);
+ glEndQueryEXT(_target);
#else
CORRADE_ASSERT_UNREACHABLE();
#endif
- target = {};
}
}
diff --git a/src/Magnum/AbstractQuery.h b/src/Magnum/AbstractQuery.h
new file mode 100644
index 000000000..9077a635f
--- /dev/null
+++ b/src/Magnum/AbstractQuery.h
@@ -0,0 +1,196 @@
+#ifndef Magnum_AbstractQuery_h
+#define Magnum_AbstractQuery_h
+/*
+ This file is part of Magnum.
+
+ Copyright © 2010, 2011, 2012, 2013, 2014
+ Vladimír Vondruš
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+*/
+
+/** @file
+ * @brief Class @ref Magnum::AbstractQuery
+ */
+
+#include
+#include
+
+#include "Magnum/AbstractObject.h"
+#include "Magnum/configure.h"
+
+namespace Magnum {
+
+namespace Implementation { class QueryState; }
+
+/**
+@brief Base class for queries
+
+See @ref PrimitiveQuery, @ref SampleQuery and @ref TimeQuery documentation for
+more information.
+@todo `QUERY_COUNTER_BITS` (not sure since when this is supported)
+*/
+class MAGNUM_EXPORT AbstractQuery: public AbstractObject {
+ friend class Implementation::QueryState;
+
+ public:
+ /** @brief Copying is not allowed */
+ AbstractQuery(const AbstractQuery&) = delete;
+
+ /** @brief Move constructor */
+ AbstractQuery(AbstractQuery&& other) noexcept;
+
+ /** @brief Copying is not allowed */
+ AbstractQuery& operator=(const AbstractQuery&) = delete;
+
+ /** @brief Move assignment */
+ AbstractQuery& operator=(AbstractQuery&& other) noexcept;
+
+ /** @brief OpenGL query ID */
+ GLuint id() const { return _id; }
+
+ /**
+ * @brief %Query label
+ *
+ * The result is *not* cached, repeated queries will result in repeated
+ * OpenGL calls. If OpenGL 4.3 is not supported and neither
+ * @extension{KHR,debug} nor @extension2{EXT,debug_label} desktop or ES
+ * extension is available, this function returns empty string.
+ * @see @fn_gl{GetObjectLabel} with @def_gl{QUERY} or
+ * @fn_gl_extension2{GetObjectLabel,EXT,debug_label} with
+ * @def_gl{QUERY_OBJECT_EXT}
+ */
+ std::string label() const;
+
+ /**
+ * @brief Set query label
+ * @return Reference to self (for method chaining)
+ *
+ * Default is empty string. If OpenGL 4.3 is not supported and neither
+ * @extension{KHR,debug} nor @extension2{EXT,debug_label} desktop or ES
+ * extension is available, this function does nothing.
+ * @see @ref maxLabelLength(), @fn_gl{ObjectLabel} with
+ * @def_gl{QUERY} or @fn_gl_extension2{LabelObject,EXT,debug_label}
+ * with @def_gl{QUERY_OBJECT_EXT}
+ */
+ AbstractQuery& setLabel(const std::string& label) {
+ return setLabelInternal({label.data(), label.size()});
+ }
+
+ /** @overload */
+ template AbstractQuery& setLabel(const char(&label)[size]) {
+ return setLabelInternal(label);
+ }
+
+ /**
+ * @brief Whether the result is available
+ *
+ * @see @fn_gl{GetQueryObject} with @def_gl{QUERY_RESULT_AVAILABLE}
+ */
+ bool resultAvailable();
+
+ /**
+ * @brief Result
+ * @tparam T Result type. Can be either `bool`, @ref UnsignedInt,
+ * @ref Int, @ref UnsignedLong or @ref Long.
+ *
+ * Note that this function is blocking until the result is available.
+ * See resultAvailable().
+ * @attention @ref Magnum::UnsignedLong "UnsignedLong" and @ref Magnum::Long "Long"
+ * result type is not available in @ref MAGNUM_TARGET_WEBGL "WebGL".
+ * @see @fn_gl{GetQueryObject} with @def_gl{QUERY_RESULT}
+ * @requires_gl33 %Extension @extension{ARB,timer_query} for result
+ * type @ref Magnum::UnsignedInt "UnsignedInt" and @ref Magnum::Long
+ * "Long"
+ * @requires_es_extension %Extension @es_extension{EXT,disjoint_timer_query}
+ * for result types @ref Magnum::Int "Int", @ref Magnum::UnsignedLong "UnsignedLong"
+ * @ref Magnum::Long "Long".
+ */
+ template T result();
+
+ /**
+ * @brief Begin query
+ *
+ * Begins counting until @ref end() is called.
+ * @see @fn_gl{BeginQuery}
+ */
+ void begin();
+
+ /**
+ * @brief End query
+ *
+ * The result can be then retrieved by calling @ref result().
+ * @see @fn_gl{EndQuery}
+ */
+ void end();
+
+ protected:
+ /**
+ * @brief Destructor
+ *
+ * Deletes assigned OpenGL query.
+ * @see @fn_gl{DeleteQueries}
+ */
+ ~AbstractQuery();
+
+ #ifdef DOXYGEN_GENERATING_OUTPUT
+ private:
+ #endif
+ explicit AbstractQuery(GLenum target);
+
+ #ifdef MAGNUM_BUILD_DEPRECATED
+ explicit AbstractQuery();
+ void begin(GLenum target);
+ #endif
+
+ private:
+ AbstractQuery& setLabelInternal(Containers::ArrayReference label);
+
+ void MAGNUM_LOCAL createImplementationDefault();
+ #ifndef MAGNUM_TARGET_GLES
+ void MAGNUM_LOCAL createImplementationDSA();
+ #endif
+
+ GLuint _id;
+ GLenum _target;
+};
+
+#ifndef DOXYGEN_GENERATING_OUTPUT
+template<> bool MAGNUM_EXPORT AbstractQuery::result();
+template<> UnsignedInt MAGNUM_EXPORT AbstractQuery::result();
+template<> Int MAGNUM_EXPORT AbstractQuery::result();
+#ifndef MAGNUM_TARGET_WEBGL
+template<> UnsignedLong MAGNUM_EXPORT AbstractQuery::result();
+template<> Long MAGNUM_EXPORT AbstractQuery::result();
+#endif
+#endif
+
+inline AbstractQuery::AbstractQuery(AbstractQuery&& other) noexcept: _id(other._id), _target(other._target) {
+ other._id = 0;
+}
+
+inline AbstractQuery& AbstractQuery::operator=(AbstractQuery&& other) noexcept {
+ std::swap(_id, other._id);
+ std::swap(_target, other._target);
+ return *this;
+}
+
+}
+
+#endif
diff --git a/src/Magnum/AbstractShaderProgram.cpp b/src/Magnum/AbstractShaderProgram.cpp
index 7f36d74ac..9dee5629e 100644
--- a/src/Magnum/AbstractShaderProgram.cpp
+++ b/src/Magnum/AbstractShaderProgram.cpp
@@ -407,10 +407,14 @@ void AbstractShaderProgram::uniformImplementationDefault(const GLint location, c
glUniform1fv(location, count, values);
}
+#ifndef MAGNUM_TARGET_GLES2
void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const GLsizei count, const GLfloat* const values) {
- #ifndef MAGNUM_TARGET_GLES
glProgramUniform1fv(_id, location, count, values);
- #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
+}
+#endif
+
+void AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT(const GLint location, const GLsizei count, const GLfloat* const values) {
+ #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
glProgramUniform1fvEXT(_id, location, count, values);
#else
static_cast(location);
@@ -420,12 +424,6 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
#endif
}
-#ifndef MAGNUM_TARGET_GLES
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const GLfloat* const values) {
- glProgramUniform1fvEXT(_id, location, count, values);
-}
-#endif
-
void AbstractShaderProgram::setUniform(const Int location, const UnsignedInt count, const Math::Vector<2, Float>* const values) {
(this->*Context::current()->state().shaderProgram->uniform2fvImplementation)(location, count, values);
}
@@ -435,10 +433,14 @@ void AbstractShaderProgram::uniformImplementationDefault(const GLint location, c
glUniform2fv(location, count, values[0].data());
}
+#ifndef MAGNUM_TARGET_GLES2
void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const GLsizei count, const Math::Vector<2, GLfloat>* const values) {
- #ifndef MAGNUM_TARGET_GLES
glProgramUniform2fv(_id, location, count, values[0].data());
- #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
+}
+#endif
+
+void AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT(const GLint location, const GLsizei count, const Math::Vector<2, GLfloat>* const values) {
+ #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
glProgramUniform2fvEXT(_id, location, count, values[0].data());
#else
static_cast(location);
@@ -448,12 +450,6 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
#endif
}
-#ifndef MAGNUM_TARGET_GLES
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<2, GLfloat>* const values) {
- glProgramUniform2fvEXT(_id, location, count, values[0].data());
-}
-#endif
-
void AbstractShaderProgram::setUniform(const Int location, const UnsignedInt count, const Math::Vector<3, Float>* const values) {
(this->*Context::current()->state().shaderProgram->uniform3fvImplementation)(location, count, values);
}
@@ -463,10 +459,14 @@ void AbstractShaderProgram::uniformImplementationDefault(const GLint location, c
glUniform3fv(location, count, values[0].data());
}
+#ifndef MAGNUM_TARGET_GLES2
void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const GLsizei count, const Math::Vector<3, GLfloat>* const values) {
- #ifndef MAGNUM_TARGET_GLES
glProgramUniform3fv(_id, location, count, values[0].data());
- #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
+}
+#endif
+
+void AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT(const GLint location, const GLsizei count, const Math::Vector<3, GLfloat>* const values) {
+ #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
glProgramUniform3fvEXT(_id, location, count, values[0].data());
#else
static_cast(location);
@@ -476,12 +476,6 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
#endif
}
-#ifndef MAGNUM_TARGET_GLES
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<3, GLfloat>* const values) {
- glProgramUniform3fvEXT(_id, location, count, values[0].data());
-}
-#endif
-
void AbstractShaderProgram::setUniform(const Int location, const UnsignedInt count, const Math::Vector<4, Float>* const values) {
(this->*Context::current()->state().shaderProgram->uniform4fvImplementation)(location, count, values);
}
@@ -491,10 +485,14 @@ void AbstractShaderProgram::uniformImplementationDefault(const GLint location, c
glUniform4fv(location, count, values[0].data());
}
+#ifndef MAGNUM_TARGET_GLES2
void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const GLsizei count, const Math::Vector<4, GLfloat>* const values) {
- #ifndef MAGNUM_TARGET_GLES
glProgramUniform4fv(_id, location, count, values[0].data());
- #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
+}
+#endif
+
+void AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT(const GLint location, const GLsizei count, const Math::Vector<4, GLfloat>* const values) {
+ #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
glProgramUniform4fvEXT(_id, location, count, values[0].data());
#else
static_cast(location);
@@ -504,12 +502,6 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
#endif
}
-#ifndef MAGNUM_TARGET_GLES
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<4, GLfloat>* const values) {
- glProgramUniform4fvEXT(_id, location, count, values[0].data());
-}
-#endif
-
void AbstractShaderProgram::setUniform(const Int location, const UnsignedInt count, const Int* const values) {
(this->*Context::current()->state().shaderProgram->uniform1ivImplementation)(location, count, values);
}
@@ -519,10 +511,14 @@ void AbstractShaderProgram::uniformImplementationDefault(const GLint location, c
glUniform1iv(location, count, values);
}
+#ifndef MAGNUM_TARGET_GLES2
void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const GLsizei count, const GLint* const values) {
- #ifndef MAGNUM_TARGET_GLES
glProgramUniform1iv(_id, location, count, values);
- #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
+}
+#endif
+
+void AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT(const GLint location, const GLsizei count, const GLint* const values) {
+ #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
glProgramUniform1ivEXT(_id, location, count, values);
#else
static_cast(location);
@@ -532,12 +528,6 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
#endif
}
-#ifndef MAGNUM_TARGET_GLES
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const GLint* const values) {
- glProgramUniform1ivEXT(_id, location, count, values);
-}
-#endif
-
void AbstractShaderProgram::setUniform(const Int location, const UnsignedInt count, const Math::Vector<2, Int>* const values) {
(this->*Context::current()->state().shaderProgram->uniform2ivImplementation)(location, count, values);
}
@@ -547,10 +537,14 @@ void AbstractShaderProgram::uniformImplementationDefault(const GLint location, c
glUniform2iv(location, count, values[0].data());
}
+#ifndef MAGNUM_TARGET_GLES2
void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const GLsizei count, const Math::Vector<2, GLint>* const values) {
- #ifndef MAGNUM_TARGET_GLES
glProgramUniform2iv(_id, location, count, values[0].data());
- #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
+}
+#endif
+
+void AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT(const GLint location, const GLsizei count, const Math::Vector<2, GLint>* const values) {
+ #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
glProgramUniform2ivEXT(_id, location, count, values[0].data());
#else
static_cast(location);
@@ -560,12 +554,6 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
#endif
}
-#ifndef MAGNUM_TARGET_GLES
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<2, GLint>* const values) {
- glProgramUniform2ivEXT(_id, location, count, values[0].data());
-}
-#endif
-
void AbstractShaderProgram::setUniform(const Int location, const UnsignedInt count, const Math::Vector<3, Int>* const values) {
(this->*Context::current()->state().shaderProgram->uniform3ivImplementation)(location, count, values);
}
@@ -575,10 +563,14 @@ void AbstractShaderProgram::uniformImplementationDefault(const GLint location, c
glUniform3iv(location, count, values[0].data());
}
+#ifndef MAGNUM_TARGET_GLES2
void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const GLsizei count, const Math::Vector<3, GLint>* const values) {
- #ifndef MAGNUM_TARGET_GLES
glProgramUniform3iv(_id, location, count, values[0].data());
- #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
+}
+#endif
+
+void AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT(const GLint location, const GLsizei count, const Math::Vector<3, GLint>* const values) {
+ #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
glProgramUniform3ivEXT(_id, location, count, values[0].data());
#else
static_cast(location);
@@ -588,12 +580,6 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
#endif
}
-#ifndef MAGNUM_TARGET_GLES
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<3, GLint>* const values) {
- glProgramUniform3ivEXT(_id, location, count, values[0].data());
-}
-#endif
-
void AbstractShaderProgram::setUniform(const Int location, const UnsignedInt count, const Math::Vector<4, Int>* const values) {
(this->*Context::current()->state().shaderProgram->uniform4ivImplementation)(location, count, values);
}
@@ -603,10 +589,14 @@ void AbstractShaderProgram::uniformImplementationDefault(const GLint location, c
glUniform4iv(location, count, values[0].data());
}
+#ifndef MAGNUM_TARGET_GLES2
void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const GLsizei count, const Math::Vector<4, GLint>* const values) {
- #ifndef MAGNUM_TARGET_GLES
glProgramUniform4iv(_id, location, count, values[0].data());
- #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
+}
+#endif
+
+void AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT(const GLint location, const GLsizei count, const Math::Vector<4, GLint>* const values) {
+ #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
glProgramUniform4ivEXT(_id, location, count, values[0].data());
#else
static_cast(location);
@@ -616,12 +606,6 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
#endif
}
-#ifndef MAGNUM_TARGET_GLES
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<4, GLint>* const values) {
- glProgramUniform4ivEXT(_id, location, count, values[0].data());
-}
-#endif
-
#ifndef MAGNUM_TARGET_GLES2
void AbstractShaderProgram::setUniform(const Int location, const UnsignedInt count, const UnsignedInt* const values) {
(this->*Context::current()->state().shaderProgram->uniform1uivImplementation)(location, count, values);
@@ -633,23 +617,12 @@ void AbstractShaderProgram::uniformImplementationDefault(const GLint location, c
}
void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const GLsizei count, const GLuint* const values) {
- #ifndef MAGNUM_TARGET_GLES
glProgramUniform1uiv(_id, location, count, values);
- #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
- glProgramUniform1uivEXT(_id, location, count, values);
- #else
- static_cast(location);
- static_cast(count);
- static_cast(values);
- CORRADE_ASSERT_UNREACHABLE();
- #endif
}
-#ifndef MAGNUM_TARGET_GLES
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const GLuint* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT(const GLint location, const GLsizei count, const GLuint* const values) {
glProgramUniform1uivEXT(_id, location, count, values);
}
-#endif
void AbstractShaderProgram::setUniform(const Int location, const UnsignedInt count, const Math::Vector<2, UnsignedInt>* const values) {
(this->*Context::current()->state().shaderProgram->uniform2uivImplementation)(location, count, values);
@@ -661,23 +634,12 @@ void AbstractShaderProgram::uniformImplementationDefault(const GLint location, c
}
void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const GLsizei count, const Math::Vector<2, GLuint>* const values) {
- #ifndef MAGNUM_TARGET_GLES
glProgramUniform2uiv(_id, location, count, values[0].data());
- #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
- glProgramUniform2uivEXT(_id, location, count, values[0].data());
- #else
- static_cast(location);
- static_cast(count);
- static_cast(values);
- CORRADE_ASSERT_UNREACHABLE();
- #endif
}
-#ifndef MAGNUM_TARGET_GLES
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<2, GLuint>* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT(const GLint location, const GLsizei count, const Math::Vector<2, GLuint>* const values) {
glProgramUniform2uivEXT(_id, location, count, values[0].data());
}
-#endif
void AbstractShaderProgram::setUniform(const Int location, const UnsignedInt count, const Math::Vector<3, UnsignedInt>* const values) {
(this->*Context::current()->state().shaderProgram->uniform3uivImplementation)(location, count, values);
@@ -689,23 +651,12 @@ void AbstractShaderProgram::uniformImplementationDefault(const GLint location, c
}
void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const GLsizei count, const Math::Vector<3, GLuint>* const values) {
- #ifndef MAGNUM_TARGET_GLES
glProgramUniform3uiv(_id, location, count, values[0].data());
- #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
- glProgramUniform3uivEXT(_id, location, count, values[0].data());
- #else
- static_cast(location);
- static_cast(count);
- static_cast(values);
- CORRADE_ASSERT_UNREACHABLE();
- #endif
}
-#ifndef MAGNUM_TARGET_GLES
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<3, GLuint>* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT(const GLint location, const GLsizei count, const Math::Vector<3, GLuint>* const values) {
glProgramUniform3uivEXT(_id, location, count, values[0].data());
}
-#endif
void AbstractShaderProgram::setUniform(const Int location, const UnsignedInt count, const Math::Vector<4, UnsignedInt>* const values) {
(this->*Context::current()->state().shaderProgram->uniform4uivImplementation)(location, count, values);
@@ -717,24 +668,13 @@ void AbstractShaderProgram::uniformImplementationDefault(const GLint location, c
}
void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const GLsizei count, const Math::Vector<4, GLuint>* const values) {
- #ifndef MAGNUM_TARGET_GLES
glProgramUniform4uiv(_id, location, count, values[0].data());
- #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
- glProgramUniform4uivEXT(_id, location, count, values[0].data());
- #else
- static_cast(location);
- static_cast(count);
- static_cast(values);
- CORRADE_ASSERT_UNREACHABLE();
- #endif
}
-#ifndef MAGNUM_TARGET_GLES
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<4, GLuint>* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT(const GLint location, const GLsizei count, const Math::Vector<4, GLuint>* const values) {
glProgramUniform4uivEXT(_id, location, count, values[0].data());
}
#endif
-#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractShaderProgram::setUniform(const Int location, const UnsignedInt count, const Double* const values) {
@@ -750,7 +690,7 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
glProgramUniform1dv(_id, location, count, values);
}
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const GLdouble* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT(const GLint location, const GLsizei count, const GLdouble* const values) {
glProgramUniform1dvEXT(_id, location, count, values);
}
@@ -767,7 +707,7 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
glProgramUniform2dv(_id, location, count, values[0].data());
}
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<2, GLdouble>* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT(const GLint location, const GLsizei count, const Math::Vector<2, GLdouble>* const values) {
glProgramUniform2dvEXT(_id, location, count, values[0].data());
}
@@ -784,7 +724,7 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
glProgramUniform3dv(_id, location, count, values[0].data());
}
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<3, GLdouble>* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT(const GLint location, const GLsizei count, const Math::Vector<3, GLdouble>* const values) {
glProgramUniform3dvEXT(_id, location, count, values[0].data());
}
@@ -801,7 +741,7 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
glProgramUniform4dv(_id, location, count, values[0].data());
}
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::Vector<4, GLdouble>* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT(const GLint location, const GLsizei count, const Math::Vector<4, GLdouble>* const values) {
glProgramUniform4dvEXT(_id, location, count, values[0].data());
}
#endif
@@ -815,10 +755,14 @@ void AbstractShaderProgram::uniformImplementationDefault(const GLint location, c
glUniformMatrix2fv(location, count, GL_FALSE, values[0].data());
}
+#ifndef MAGNUM_TARGET_GLES2
void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 2, GLfloat>* const values) {
- #ifndef MAGNUM_TARGET_GLES
glProgramUniformMatrix2fv(_id, location, count, GL_FALSE, values[0].data());
- #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
+}
+#endif
+
+void AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 2, GLfloat>* const values) {
+ #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
glProgramUniformMatrix2fvEXT(_id, location, count, GL_FALSE, values[0].data());
#else
static_cast(location);
@@ -828,12 +772,6 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
#endif
}
-#ifndef MAGNUM_TARGET_GLES
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 2, GLfloat>* const values) {
- glProgramUniformMatrix2fvEXT(_id, location, count, GL_FALSE, values[0].data());
-}
-#endif
-
void AbstractShaderProgram::setUniform(const Int location, const UnsignedInt count, const Math::RectangularMatrix<3, 3, Float>* const values) {
(this->*Context::current()->state().shaderProgram->uniformMatrix3fvImplementation)(location, count, values);
}
@@ -843,10 +781,14 @@ void AbstractShaderProgram::uniformImplementationDefault(const GLint location, c
glUniformMatrix3fv(location, count, GL_FALSE, values[0].data());
}
+#ifndef MAGNUM_TARGET_GLES2
void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 3, GLfloat>* const values) {
- #ifndef MAGNUM_TARGET_GLES
glProgramUniformMatrix3fv(_id, location, count, GL_FALSE, values[0].data());
- #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
+}
+#endif
+
+void AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 3, GLfloat>* const values) {
+ #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
glProgramUniformMatrix3fvEXT(_id, location, count, GL_FALSE, values[0].data());
#else
static_cast(location);
@@ -856,12 +798,6 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
#endif
}
-#ifndef MAGNUM_TARGET_GLES
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 3, GLfloat>* const values) {
- glProgramUniformMatrix3fvEXT(_id, location, count, GL_FALSE, values[0].data());
-}
-#endif
-
void AbstractShaderProgram::setUniform(const Int location, const UnsignedInt count, const Math::RectangularMatrix<4, 4, Float>* const values) {
(this->*Context::current()->state().shaderProgram->uniformMatrix4fvImplementation)(location, count, values);
}
@@ -871,10 +807,14 @@ void AbstractShaderProgram::uniformImplementationDefault(const GLint location, c
glUniformMatrix4fv(location, count, GL_FALSE, values[0].data());
}
+#ifndef MAGNUM_TARGET_GLES2
void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 4, GLfloat>* const values) {
- #ifndef MAGNUM_TARGET_GLES
glProgramUniformMatrix4fv(_id, location, count, GL_FALSE, values[0].data());
- #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
+}
+#endif
+
+void AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 4, GLfloat>* const values) {
+ #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
glProgramUniformMatrix4fvEXT(_id, location, count, GL_FALSE, values[0].data());
#else
static_cast(location);
@@ -884,12 +824,6 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
#endif
}
-#ifndef MAGNUM_TARGET_GLES
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 4, GLfloat>* const values) {
- glProgramUniformMatrix4fvEXT(_id, location, count, GL_FALSE, values[0].data());
-}
-#endif
-
#ifndef MAGNUM_TARGET_GLES2
void AbstractShaderProgram::setUniform(const Int location, const UnsignedInt count, const Math::RectangularMatrix<2, 3, Float>* const values) {
(this->*Context::current()->state().shaderProgram->uniformMatrix2x3fvImplementation)(location, count, values);
@@ -901,23 +835,12 @@ void AbstractShaderProgram::uniformImplementationDefault(const GLint location, c
}
void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 3, GLfloat>* const values) {
- #ifndef MAGNUM_TARGET_GLES
glProgramUniformMatrix2x3fv(_id, location, count, GL_FALSE, values[0].data());
- #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
- glProgramUniformMatrix2x3fvEXT(_id, location, count, GL_FALSE, values[0].data());
- #else
- static_cast(location);
- static_cast(count);
- static_cast(values);
- CORRADE_ASSERT_UNREACHABLE();
- #endif
}
-#ifndef MAGNUM_TARGET_GLES
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 3, GLfloat>* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 3, GLfloat>* const values) {
glProgramUniformMatrix2x3fvEXT(_id, location, count, GL_FALSE, values[0].data());
}
-#endif
void AbstractShaderProgram::setUniform(const Int location, const UnsignedInt count, const Math::RectangularMatrix<3, 2, Float>* const values) {
(this->*Context::current()->state().shaderProgram->uniformMatrix3x2fvImplementation)(location, count, values);
@@ -929,23 +852,12 @@ void AbstractShaderProgram::uniformImplementationDefault(const GLint location, c
}
void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 2, GLfloat>* const values) {
- #ifndef MAGNUM_TARGET_GLES
- glProgramUniformMatrix3x2fv(_id, location, count, GL_FALSE, values[0].data());
- #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
glProgramUniformMatrix3x2fv(_id, location, count, GL_FALSE, values[0].data());
- #else
- static_cast(location);
- static_cast(count);
- static_cast(values);
- CORRADE_ASSERT_UNREACHABLE();
- #endif
}
-#ifndef MAGNUM_TARGET_GLES
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 2, GLfloat>* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 2, GLfloat>* const values) {
glProgramUniformMatrix3x2fvEXT(_id, location, count, GL_FALSE, values[0].data());
}
-#endif
void AbstractShaderProgram::setUniform(const Int location, const UnsignedInt count, const Math::RectangularMatrix<2, 4, Float>* const values) {
(this->*Context::current()->state().shaderProgram->uniformMatrix2x4fvImplementation)(location, count, values);
@@ -957,23 +869,12 @@ void AbstractShaderProgram::uniformImplementationDefault(const GLint location, c
}
void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 4, GLfloat>* const values) {
- #ifndef MAGNUM_TARGET_GLES
glProgramUniformMatrix2x4fv(_id, location, count, GL_FALSE, values[0].data());
- #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
- glProgramUniformMatrix2x4fvEXT(_id, location, count, GL_FALSE, values[0].data());
- #else
- static_cast(location);
- static_cast(count);
- static_cast(values);
- CORRADE_ASSERT_UNREACHABLE();
- #endif
}
-#ifndef MAGNUM_TARGET_GLES
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 4, GLfloat>* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 4, GLfloat>* const values) {
glProgramUniformMatrix2x4fvEXT(_id, location, count, GL_FALSE, values[0].data());
}
-#endif
void AbstractShaderProgram::setUniform(const Int location, const UnsignedInt count, const Math::RectangularMatrix<4, 2, Float>* const values) {
(this->*Context::current()->state().shaderProgram->uniformMatrix4x2fvImplementation)(location, count, values);
@@ -985,23 +886,12 @@ void AbstractShaderProgram::uniformImplementationDefault(const GLint location, c
}
void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 2, GLfloat>* const values) {
- #ifndef MAGNUM_TARGET_GLES
glProgramUniformMatrix4x2fv(_id, location, count, GL_FALSE, values[0].data());
- #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
- glProgramUniformMatrix4x2fvEXT(_id, location, count, GL_FALSE, values[0].data());
- #else
- static_cast(location);
- static_cast(count);
- static_cast(values);
- CORRADE_ASSERT_UNREACHABLE();
- #endif
}
-#ifndef MAGNUM_TARGET_GLES
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 2, GLfloat>* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 2, GLfloat>* const values) {
glProgramUniformMatrix4x2fvEXT(_id, location, count, GL_FALSE, values[0].data());
}
-#endif
void AbstractShaderProgram::setUniform(const Int location, const UnsignedInt count, const Math::RectangularMatrix<3, 4, Float>* const values) {
(this->*Context::current()->state().shaderProgram->uniformMatrix3x4fvImplementation)(location, count, values);
@@ -1013,23 +903,12 @@ void AbstractShaderProgram::uniformImplementationDefault(const GLint location, c
}
void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 4, GLfloat>* const values) {
- #ifndef MAGNUM_TARGET_GLES
glProgramUniformMatrix3x4fv(_id, location, count, GL_FALSE, values[0].data());
- #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
- glProgramUniformMatrix3x4fvEXT(_id, location, count, GL_FALSE, values[0].data());
- #else
- static_cast(location);
- static_cast(count);
- static_cast(values);
- CORRADE_ASSERT_UNREACHABLE();
- #endif
}
-#ifndef MAGNUM_TARGET_GLES
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 4, GLfloat>* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 4, GLfloat>* const values) {
glProgramUniformMatrix3x4fvEXT(_id, location, count, GL_FALSE, values[0].data());
}
-#endif
void AbstractShaderProgram::setUniform(const Int location, const UnsignedInt count, const Math::RectangularMatrix<4, 3, Float>* const values) {
(this->*Context::current()->state().shaderProgram->uniformMatrix4x3fvImplementation)(location, count, values);
@@ -1041,24 +920,13 @@ void AbstractShaderProgram::uniformImplementationDefault(const GLint location, c
}
void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 3, GLfloat>* const values) {
- #ifndef MAGNUM_TARGET_GLES
glProgramUniformMatrix4x3fv(_id, location, count, GL_FALSE, values[0].data());
- #elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
- glProgramUniformMatrix4x3fvEXT(_id, location, count, GL_FALSE, values[0].data());
- #else
- static_cast(location);
- static_cast(count);
- static_cast(values);
- CORRADE_ASSERT_UNREACHABLE();
- #endif
}
-#ifndef MAGNUM_TARGET_GLES
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 3, GLfloat>* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 3, GLfloat>* const values) {
glProgramUniformMatrix4x3fvEXT(_id, location, count, GL_FALSE, values[0].data());
}
#endif
-#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractShaderProgram::setUniform(const Int location, const UnsignedInt count, const Math::RectangularMatrix<2, 2, Double>* const values) {
@@ -1074,7 +942,7 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
glProgramUniformMatrix2dv(_id, location, count, GL_FALSE, values[0].data());
}
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 2, GLdouble>* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 2, GLdouble>* const values) {
glProgramUniformMatrix2dvEXT(_id, location, count, GL_FALSE, values[0].data());
}
@@ -1091,7 +959,7 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
glProgramUniformMatrix3dv(_id, location, count, GL_FALSE, values[0].data());
}
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 3, GLdouble>* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 3, GLdouble>* const values) {
glProgramUniformMatrix3dvEXT(_id, location, count, GL_FALSE, values[0].data());
}
@@ -1108,7 +976,7 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
glProgramUniformMatrix4dv(_id, location, count, GL_FALSE, values[0].data());
}
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 4, GLdouble>* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 4, GLdouble>* const values) {
glProgramUniformMatrix4dvEXT(_id, location, count, GL_FALSE, values[0].data());
}
@@ -1125,7 +993,7 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
glProgramUniformMatrix2x3dv(_id, location, count, GL_FALSE, values[0].data());
}
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 3, GLdouble>* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 3, GLdouble>* const values) {
glProgramUniformMatrix2x3dvEXT(_id, location, count, GL_FALSE, values[0].data());
}
@@ -1142,7 +1010,7 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
glProgramUniformMatrix3x2dv(_id, location, count, GL_FALSE, values[0].data());
}
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 2, GLdouble>* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 2, GLdouble>* const values) {
glProgramUniformMatrix3x2dvEXT(_id, location, count, GL_FALSE, values[0].data());
}
@@ -1159,7 +1027,7 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
glProgramUniformMatrix2x4dv(_id, location, count, GL_FALSE, values[0].data());
}
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 4, GLdouble>* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT(const GLint location, const GLsizei count, const Math::RectangularMatrix<2, 4, GLdouble>* const values) {
glProgramUniformMatrix2x4dvEXT(_id, location, count, GL_FALSE, values[0].data());
}
@@ -1176,7 +1044,7 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
glProgramUniformMatrix4x2dv(_id, location, count, GL_FALSE, values[0].data());
}
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 2, GLdouble>* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 2, GLdouble>* const values) {
glProgramUniformMatrix4x2dvEXT(_id, location, count, GL_FALSE, values[0].data());
}
@@ -1193,7 +1061,7 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
glProgramUniformMatrix3x4dv(_id, location, count, GL_FALSE, values[0].data());
}
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 4, GLdouble>* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT(const GLint location, const GLsizei count, const Math::RectangularMatrix<3, 4, GLdouble>* const values) {
glProgramUniformMatrix3x4dvEXT(_id, location, count, GL_FALSE, values[0].data());
}
@@ -1210,7 +1078,7 @@ void AbstractShaderProgram::uniformImplementationSSO(const GLint location, const
glProgramUniformMatrix4x3dv(_id, location, count, GL_FALSE, values[0].data());
}
-void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 3, GLdouble>* const values) {
+void AbstractShaderProgram::uniformImplementationDSAEXT(const GLint location, const GLsizei count, const Math::RectangularMatrix<4, 3, GLdouble>* const values) {
glProgramUniformMatrix4x3dvEXT(_id, location, count, GL_FALSE, values[0].data());
}
#endif
diff --git a/src/Magnum/AbstractShaderProgram.h b/src/Magnum/AbstractShaderProgram.h
index 74c8e31a1..4b9d8f3db 100644
--- a/src/Magnum/AbstractShaderProgram.h
+++ b/src/Magnum/AbstractShaderProgram.h
@@ -80,8 +80,7 @@ MyShader() {
CORRADE_INTERNAL_ASSERT_OUTPUT(Shader::compile({vert, frag}));
// Attach the shaders
- attachShader(vert);
- attachShader(frag);
+ attachShader({vert, frag});
// Link the program together
CORRADE_INTERNAL_ASSERT_OUTPUT(link());
@@ -236,7 +235,7 @@ layout(binding = 1) uniform sampler2D specularTexture;
@endcode
If you don't have the required extension, declare the uniforms without the
-`layout()` qualifier and set the texture binding unit using
+`binding` qualifier and set the texture binding unit using
@ref setUniform(Int, const T&) "setUniform(Int, Int)". Note that additional
syntax changes may be needed for GLSL 1.20 and GLSL ES 1.0.
@code
@@ -320,10 +319,10 @@ also @ref Attribute::DataType enum for additional type options.
queries don't result in repeated @fn_gl{Get} calls.
If extension @extension{ARB,separate_shader_objects} (part of OpenGL 4.1),
-@extension{EXT,direct_state_access} or @es_extension{EXT,separate_shader_objects}
-on OpenGL ES is available, uniform setting functions use DSA functions to avoid
-unnecessary calls to @fn_gl{UseProgram}. See @ref setUniform() documentation
-for more information.
+@extension{EXT,direct_state_access} desktop extension, @es_extension{EXT,separate_shader_objects}
+OpenGL ES extension or OpenGL ES 3.1 is available, uniform setting functions
+use DSA functions to avoid unnecessary calls to @fn_gl{UseProgram}. See
+@ref setUniform() documentation for more information.
To achieve least state changes, set all uniforms in one run -- method chaining
comes in handy.
@@ -688,6 +687,10 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
* The same as @ref bindFragmentDataLocationIndexed(), but with `index`
* set to `0`.
* @see @fn_gl{BindFragDataLocation}
+ * @deprecated_gl Preferred usage is to specify attribute location
+ * explicitly in the shader instead of using this function. See
+ * @ref AbstractShaderProgram-attribute-location "class documentation"
+ * for more information.
* @requires_gl30 %Extension @extension{EXT,gpu_shader4}
* @requires_gl Use explicit location specification in OpenGL ES 3.0
* and `gl_FragData[n]` provided by @es_extension2{NV,draw_buffers,GL_NV_draw_buffers}
@@ -779,9 +782,10 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
* @param values Values
*
* If neither @extension{ARB,separate_shader_objects} (part of OpenGL
- * 4.1) nor @extension{EXT,direct_state_access} nor
- * @es_extension{EXT,separate_shader_objects} (on OpenGL ES) is
- * available, the shader is marked for use before the operation.
+ * 4.1) nor @extension{EXT,direct_state_access} desktop extension nor
+ * @es_extension{EXT,separate_shader_objects} OpenGL ES extension nor
+ * OpenGL ES 3.1 is available, the shader is marked for use before the
+ * operation.
* @see @ref setUniform(Int, const T&), @fn_gl{UseProgram}, @fn_gl{Uniform}
* or @fn_gl{ProgramUniform}/@fn_gl_extension{ProgramUniform,EXT,direct_state_access}.
*/
@@ -866,6 +870,27 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
void use();
#endif
+ /*
+ Currently, there are four supported ways to call glProgramUniform():
+
+ - EXT_direct_state_access (desktop GL only, EXT suffix)
+ - EXT_separate_shader_objects (OpenGL ES extension, EXT suffix)
+ - ARB_separate_shader_objects (desktop GL only, no suffix)
+ - OpenGL ES 3.1, no suffix
+
+ To avoid copypasta and filesize bloat, this is merged to just two
+ variants of implementation functions:
+
+ - uniformImplementationSSO() - functions without suffix, used if
+ ARB_separate_shader_objects desktop extension or OpenGL ES 3.1
+ is available, completely disabled for ES2
+ - uniformImplementationDSAEXT_SSOEXT() / uniformImplementationDSAEXT() --
+ functions with EXT suffix, used if EXT_direct_state_access
+ desktop exttension or EXT_separate_shader_objects ES 2.0 / ES 3.0
+ extension is available, functions which don't have equivalents
+ on ES (double arguments) don't have the _SSOEXT suffix
+ */
+
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const GLfloat* values);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<2, GLfloat>* values);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<3, GLfloat>* values);
@@ -886,6 +911,7 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<3, GLdouble>* values);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::Vector<4, GLdouble>* values);
#endif
+ #ifndef MAGNUM_TARGET_GLES2
void MAGNUM_LOCAL uniformImplementationSSO(GLint location, GLsizei count, const GLfloat* values);
void MAGNUM_LOCAL uniformImplementationSSO(GLint location, GLsizei count, const Math::Vector<2, GLfloat>* values);
void MAGNUM_LOCAL uniformImplementationSSO(GLint location, GLsizei count, const Math::Vector<3, GLfloat>* values);
@@ -894,7 +920,6 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
void MAGNUM_LOCAL uniformImplementationSSO(GLint location, GLsizei count, const Math::Vector<2, GLint>* values);
void MAGNUM_LOCAL uniformImplementationSSO(GLint location, GLsizei count, const Math::Vector<3, GLint>* values);
void MAGNUM_LOCAL uniformImplementationSSO(GLint location, GLsizei count, const Math::Vector<4, GLint>* values);
- #ifndef MAGNUM_TARGET_GLES2
void MAGNUM_LOCAL uniformImplementationSSO(GLint location, GLsizei count, const GLuint* values);
void MAGNUM_LOCAL uniformImplementationSSO(GLint location, GLsizei count, const Math::Vector<2, GLuint>* values);
void MAGNUM_LOCAL uniformImplementationSSO(GLint location, GLsizei count, const Math::Vector<3, GLuint>* values);
@@ -906,23 +931,25 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
void MAGNUM_LOCAL uniformImplementationSSO(GLint location, GLsizei count, const Math::Vector<3, GLdouble>* values);
void MAGNUM_LOCAL uniformImplementationSSO(GLint location, GLsizei count, const Math::Vector<4, GLdouble>* values);
#endif
+ void MAGNUM_LOCAL uniformImplementationDSAEXT_SSOEXT(GLint location, GLsizei count, const GLfloat* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT_SSOEXT(GLint location, GLsizei count, const Math::Vector<2, GLfloat>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT_SSOEXT(GLint location, GLsizei count, const Math::Vector<3, GLfloat>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT_SSOEXT(GLint location, GLsizei count, const Math::Vector<4, GLfloat>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT_SSOEXT(GLint location, GLsizei count, const GLint* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT_SSOEXT(GLint location, GLsizei count, const Math::Vector<2, GLint>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT_SSOEXT(GLint location, GLsizei count, const Math::Vector<3, GLint>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT_SSOEXT(GLint location, GLsizei count, const Math::Vector<4, GLint>* values);
+ #ifndef MAGNUM_TARGET_GLES2
+ void MAGNUM_LOCAL uniformImplementationDSAEXT_SSOEXT(GLint location, GLsizei count, const GLuint* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT_SSOEXT(GLint location, GLsizei count, const Math::Vector<2, GLuint>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT_SSOEXT(GLint location, GLsizei count, const Math::Vector<3, GLuint>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT_SSOEXT(GLint location, GLsizei count, const Math::Vector<4, GLuint>* values);
+ #endif
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const GLfloat* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<2, GLfloat>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<3, GLfloat>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<4, GLfloat>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const GLint* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<2, GLint>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<3, GLint>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<4, GLint>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const GLuint* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<2, GLuint>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<3, GLuint>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<4, GLuint>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const GLdouble* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<2, GLdouble>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<3, GLdouble>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::Vector<4, GLdouble>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT(GLint location, GLsizei count, const GLdouble* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT(GLint location, GLsizei count, const Math::Vector<2, GLdouble>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT(GLint location, GLsizei count, const Math::Vector<3, GLdouble>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT(GLint location, GLsizei count, const Math::Vector<4, GLdouble>* values);
#endif
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<2, 2, GLfloat>* values);
@@ -947,10 +974,10 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<3, 4, GLdouble>* values);
void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLsizei count, const Math::RectangularMatrix<4, 3, GLdouble>* values);
#endif
+ #ifndef MAGNUM_TARGET_GLES2
void MAGNUM_LOCAL uniformImplementationSSO(GLint location, GLsizei count, const Math::RectangularMatrix<2, 2, GLfloat>* values);
void MAGNUM_LOCAL uniformImplementationSSO(GLint location, GLsizei count, const Math::RectangularMatrix<3, 3, GLfloat>* values);
void MAGNUM_LOCAL uniformImplementationSSO(GLint location, GLsizei count, const Math::RectangularMatrix<4, 4, GLfloat>* values);
- #ifndef MAGNUM_TARGET_GLES2
void MAGNUM_LOCAL uniformImplementationSSO(GLint location, GLsizei count, const Math::RectangularMatrix<2, 3, GLfloat>* values);
void MAGNUM_LOCAL uniformImplementationSSO(GLint location, GLsizei count, const Math::RectangularMatrix<3, 2, GLfloat>* values);
void MAGNUM_LOCAL uniformImplementationSSO(GLint location, GLsizei count, const Math::RectangularMatrix<2, 4, GLfloat>* values);
@@ -969,25 +996,27 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject {
void MAGNUM_LOCAL uniformImplementationSSO(GLint location, GLsizei count, const Math::RectangularMatrix<3, 4, GLdouble>* values);
void MAGNUM_LOCAL uniformImplementationSSO(GLint location, GLsizei count, const Math::RectangularMatrix<4, 3, GLdouble>* values);
#endif
+ void MAGNUM_LOCAL uniformImplementationDSAEXT_SSOEXT(GLint location, GLsizei count, const Math::RectangularMatrix<2, 2, GLfloat>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT_SSOEXT(GLint location, GLsizei count, const Math::RectangularMatrix<3, 3, GLfloat>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT_SSOEXT(GLint location, GLsizei count, const Math::RectangularMatrix<4, 4, GLfloat>* values);
+ #ifndef MAGNUM_TARGET_GLES2
+ void MAGNUM_LOCAL uniformImplementationDSAEXT_SSOEXT(GLint location, GLsizei count, const Math::RectangularMatrix<2, 3, GLfloat>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT_SSOEXT(GLint location, GLsizei count, const Math::RectangularMatrix<3, 2, GLfloat>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT_SSOEXT(GLint location, GLsizei count, const Math::RectangularMatrix<2, 4, GLfloat>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT_SSOEXT(GLint location, GLsizei count, const Math::RectangularMatrix<4, 2, GLfloat>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT_SSOEXT(GLint location, GLsizei count, const Math::RectangularMatrix<3, 4, GLfloat>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT_SSOEXT(GLint location, GLsizei count, const Math::RectangularMatrix<4, 3, GLfloat>* values);
+ #endif
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<2, 2, GLfloat>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<3, 3, GLfloat>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<4, 4, GLfloat>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<2, 3, GLfloat>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<3, 2, GLfloat>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<2, 4, GLfloat>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<4, 2, GLfloat>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<3, 4, GLfloat>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<4, 3, GLfloat>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<2, 2, GLdouble>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<3, 3, GLdouble>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<4, 4, GLdouble>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<2, 3, GLdouble>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<3, 2, GLdouble>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<2, 4, GLdouble>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<4, 2, GLdouble>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<3, 4, GLdouble>* values);
- void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLsizei count, const Math::RectangularMatrix<4, 3, GLdouble>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT(GLint location, GLsizei count, const Math::RectangularMatrix<2, 2, GLdouble>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT(GLint location, GLsizei count, const Math::RectangularMatrix<3, 3, GLdouble>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT(GLint location, GLsizei count, const Math::RectangularMatrix<4, 4, GLdouble>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT(GLint location, GLsizei count, const Math::RectangularMatrix<2, 3, GLdouble>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT(GLint location, GLsizei count, const Math::RectangularMatrix<3, 2, GLdouble>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT(GLint location, GLsizei count, const Math::RectangularMatrix<2, 4, GLdouble>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT(GLint location, GLsizei count, const Math::RectangularMatrix<4, 2, GLdouble>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT(GLint location, GLsizei count, const Math::RectangularMatrix<3, 4, GLdouble>* values);
+ void MAGNUM_LOCAL uniformImplementationDSAEXT(GLint location, GLsizei count, const Math::RectangularMatrix<4, 3, GLdouble>* values);
#endif
GLuint _id;
@@ -1111,7 +1140,7 @@ template class AbstractShaderProgram::Attribute {
/**
* Half float. Only for float attribute types.
- * @requires_gl30 %Extension @extension{NV,half_float}
+ * @requires_gl30 %Extension @extension{ARB,half_float_vertex}
* @requires_gles30 %Extension @es_extension{OES,vertex_half_float}
* in OpenGL ES 2.0
*/
diff --git a/src/Magnum/AbstractTexture.cpp b/src/Magnum/AbstractTexture.cpp
index 480dc7959..540e2cb1c 100644
--- a/src/Magnum/AbstractTexture.cpp
+++ b/src/Magnum/AbstractTexture.cpp
@@ -143,7 +143,7 @@ void AbstractTexture::unbindImplementationMulti(const GLint textureUnit) {
glBindTextures(textureUnit, 1, &zero);
}
-void AbstractTexture::unbindImplementationDSA(const GLint textureUnit) {
+void AbstractTexture::unbindImplementationDSAEXT(const GLint textureUnit) {
Implementation::TextureState* const textureState = Context::current()->state().texture;
CORRADE_INTERNAL_ASSERT(textureState->bindings[textureUnit].first != 0);
@@ -151,41 +151,65 @@ void AbstractTexture::unbindImplementationDSA(const GLint textureUnit) {
}
#endif
+void AbstractTexture::unbind(const Int firstTextureUnit, const std::size_t count) {
+ /* State tracker is updated in the implementations */
+ Context::current()->state().texture->bindMultiImplementation(firstTextureUnit, {nullptr, count});
+}
+
+/** @todoc const std::initializer_list makes Doxygen grumpy */
void AbstractTexture::bind(const Int firstTextureUnit, std::initializer_list textures) {
/* State tracker is updated in the implementations */
- Context::current()->state().texture->bindMultiImplementation(firstTextureUnit, textures);
+ Context::current()->state().texture->bindMultiImplementation(firstTextureUnit, {textures.begin(), textures.size()});
}
-void AbstractTexture::bindImplementationFallback(const GLint firstTextureUnit, std::initializer_list textures) {
- Int unit = firstTextureUnit;
- for(auto it = textures.begin(); it != textures.end(); ++it) {
- if(*it) (*it)->bind(unit);
- else unbind(unit);
- ++unit;
- }
+void AbstractTexture::bindImplementationFallback(const GLint firstTextureUnit, const Containers::ArrayReference textures) {
+ for(std::size_t i = 0; i != textures.size(); ++i)
+ textures && textures[i] ? textures[i]->bind(firstTextureUnit + i) : unbind(firstTextureUnit + i);
}
#ifndef MAGNUM_TARGET_GLES
-void AbstractTexture::bindImplementationMulti(const GLint firstTextureUnit, std::initializer_list textures) {
+void AbstractTexture::bindImplementationMulti(const GLint firstTextureUnit, const Containers::ArrayReference textures) {
Implementation::TextureState* const textureState = Context::current()->state().texture;
/* Create array of IDs and also update bindings in state tracker */
- Containers::Array ids{textures.size()};
- Int i{};
- for(auto it = textures.begin(); it != textures.end(); ++it) {
- textureState->bindings[firstTextureUnit + i].second = ids[i] = *it ? (*it)->id() : 0;
- ++i;
+ Containers::Array ids{textures ? textures.size() : 0};
+ bool different = false;
+ for(std::size_t i = 0; i != textures.size(); ++i) {
+ const GLuint id = textures && textures[i] ? textures[i]->_id : 0;
+
+ if(textures) {
+ if(textures[i]) textures[i]->createIfNotAlready();
+ ids[i] = id;
+ }
+
+ if(textureState->bindings[firstTextureUnit + i].second != id) {
+ different = true;
+ textureState->bindings[firstTextureUnit + i].second = id;
+ }
}
- glBindTextures(firstTextureUnit, ids.size(), ids);
+ /* Avoid doing the binding if there is nothing different */
+ if(different) glBindTextures(firstTextureUnit, textures.size(), ids);
}
#endif
-AbstractTexture::AbstractTexture(GLenum target): _target(target) {
- glGenTextures(1, &_id);
+AbstractTexture::AbstractTexture(GLenum target): _target{target} {
+ (this->*Context::current()->state().texture->createImplementation)();
CORRADE_INTERNAL_ASSERT(_id != Implementation::State::DisengagedBinding);
}
+void AbstractTexture::createImplementationDefault() {
+ glGenTextures(1, &_id);
+ _created = false;
+}
+
+#ifndef MAGNUM_TARGET_GLES
+void AbstractTexture::createImplementationDSA() {
+ glCreateTextures(_target, 1, &_id);
+ _created = true;
+}
+#endif
+
AbstractTexture::~AbstractTexture() {
/* Moved out, nothing to do */
if(!_id) return;
@@ -198,11 +222,25 @@ AbstractTexture::~AbstractTexture() {
glDeleteTextures(1, &_id);
}
-std::string AbstractTexture::label() const {
+inline void AbstractTexture::createIfNotAlready() {
+ if(_created) return;
+
+ /* glGen*() does not create the object, just reserves the name. Some
+ commands (such as glBindTextures() or glObjectLabel()) operate with IDs
+ directly and they require the object to be created. Binding the texture
+ to desired target finally creates it. Also all EXT DSA functions
+ implicitly create it. */
+ bindInternal();
+ CORRADE_INTERNAL_ASSERT(_created);
+}
+
+std::string AbstractTexture::label() {
+ createIfNotAlready();
return Context::current()->state().debug->getLabelImplementation(GL_TEXTURE, _id);
}
AbstractTexture& AbstractTexture::setLabelInternal(const Containers::ArrayReference label) {
+ createIfNotAlready();
Context::current()->state().debug->labelImplementation(GL_TEXTURE, _id, label);
return *this;
}
@@ -225,15 +263,19 @@ void AbstractTexture::bindImplementationDefault(GLint textureUnit) {
if(textureState->currentTextureUnit != textureUnit)
glActiveTexture(GL_TEXTURE0 + (textureState->currentTextureUnit = textureUnit));
+ /* Binding the texture finally creates it */
+ _created = true;
glBindTexture(_target, _id);
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::bindImplementationMulti(GLint textureUnit) {
+ createIfNotAlready();
glBindTextures(textureUnit, 1, &_id);
}
-void AbstractTexture::bindImplementationDSA(GLint textureUnit) {
+void AbstractTexture::bindImplementationDSAEXT(GLint textureUnit) {
+ _created = true;
glBindMultiTextureEXT(GL_TEXTURE0 + textureUnit, _target, _id);
}
#endif
@@ -359,7 +401,8 @@ void AbstractTexture::mipmapImplementationDefault() {
}
#ifndef MAGNUM_TARGET_GLES
-void AbstractTexture::mipmapImplementationDSA() {
+void AbstractTexture::mipmapImplementationDSAEXT() {
+ _created = true;
glGenerateTextureMipmapEXT(_id, _target);
}
#endif
@@ -384,6 +427,9 @@ void AbstractTexture::bindInternal() {
/* Bind the texture to internal unit if not already, update state tracker */
if(textureState->bindings[internalTextureUnit].second == _id) return;
textureState->bindings[internalTextureUnit] = {_target, _id};
+
+ /* Binding the texture finally creates it */
+ _created = true;
glBindTexture(_target, _id);
}
@@ -764,7 +810,8 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, GLint val
}
#ifndef MAGNUM_TARGET_GLES
-void AbstractTexture::parameterImplementationDSA(GLenum parameter, GLint value) {
+void AbstractTexture::parameterImplementationDSAEXT(GLenum parameter, GLint value) {
+ _created = true;
glTextureParameteriEXT(_id, _target, parameter, value);
}
#endif
@@ -775,7 +822,8 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, GLfloat v
}
#ifndef MAGNUM_TARGET_GLES
-void AbstractTexture::parameterImplementationDSA(GLenum parameter, GLfloat value) {
+void AbstractTexture::parameterImplementationDSAEXT(GLenum parameter, GLfloat value) {
+ _created = true;
glTextureParameterfEXT(_id, _target, parameter, value);
}
#endif
@@ -787,7 +835,8 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, const GLi
}
#ifndef MAGNUM_TARGET_GLES
-void AbstractTexture::parameterImplementationDSA(GLenum parameter, const GLint* values) {
+void AbstractTexture::parameterImplementationDSAEXT(GLenum parameter, const GLint* values) {
+ _created = true;
glTextureParameterivEXT(_id, _target, parameter, values);
}
#endif
@@ -799,7 +848,8 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, const GLf
}
#ifndef MAGNUM_TARGET_GLES
-void AbstractTexture::parameterImplementationDSA(GLenum parameter, const GLfloat* values) {
+void AbstractTexture::parameterImplementationDSAEXT(GLenum parameter, const GLfloat* values) {
+ _created = true;
glTextureParameterfvEXT(_id, _target, parameter, values);
}
#endif
@@ -810,7 +860,8 @@ void AbstractTexture::parameterIImplementationDefault(GLenum parameter, const GL
glTexParameterIuiv(_target, parameter, values);
}
-void AbstractTexture::parameterIImplementationDSA(GLenum parameter, const GLuint* values) {
+void AbstractTexture::parameterIImplementationDSAEXT(GLenum parameter, const GLuint* values) {
+ _created = true;
glTextureParameterIuivEXT(_id, _target, parameter, values);
}
@@ -819,7 +870,8 @@ void AbstractTexture::parameterIImplementationDefault(GLenum parameter, const GL
glTexParameterIiv(_target, parameter, values);
}
-void AbstractTexture::parameterIImplementationDSA(GLenum parameter, const GLint* values) {
+void AbstractTexture::parameterIImplementationDSAEXT(GLenum parameter, const GLint* values) {
+ _created = true;
glTextureParameterIivEXT(_id, _target, parameter, values);
}
#endif
@@ -837,7 +889,8 @@ void AbstractTexture::getLevelParameterImplementationDefault(GLenum target, GLin
}
#ifndef MAGNUM_TARGET_GLES
-void AbstractTexture::getLevelParameterImplementationDSA(GLenum target, GLint level, GLenum parameter, GLint* values) {
+void AbstractTexture::getLevelParameterImplementationDSAEXT(GLenum target, GLint level, GLenum parameter, GLint* values) {
+ _created = true;
glGetTextureLevelParameterivEXT(_id, target, level, parameter, values);
}
#endif
@@ -860,7 +913,8 @@ void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels
glTexStorage1D(target, levels, GLenum(internalFormat), size[0]);
}
-void AbstractTexture::storageImplementationDSA(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) {
+void AbstractTexture::storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) {
+ _created = true;
glTextureStorage1DEXT(_id, target, levels, GLenum(internalFormat), size[0]);
}
#endif
@@ -923,7 +977,8 @@ void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels
}
#ifndef MAGNUM_TARGET_GLES
-void AbstractTexture::storageImplementationDSA(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size) {
+void AbstractTexture::storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size) {
+ _created = true;
glTextureStorage2DEXT(_id, target, levels, GLenum(internalFormat), size.x(), size.y());
}
#endif
@@ -977,7 +1032,8 @@ void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels
}
#ifndef MAGNUM_TARGET_GLES
-void AbstractTexture::storageImplementationDSA(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size) {
+void AbstractTexture::storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size) {
+ _created = true;
glTextureStorage3DEXT(_id, target, levels, GLenum(internalFormat), size.x(), size.y(), size.z());
}
#endif
@@ -997,7 +1053,8 @@ void AbstractTexture::storageMultisampleImplementationDefault(const GLenum targe
#endif
#ifndef MAGNUM_TARGET_GLES
-void AbstractTexture::storageMultisampleImplementationDSA(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) {
+void AbstractTexture::storageMultisampleImplementationDSAEXT(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) {
+ _created = true;
glTextureStorage2DMultisampleEXT(_id, target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations);
}
@@ -1011,7 +1068,8 @@ void AbstractTexture::storageMultisampleImplementationDefault(const GLenum targe
glTexStorage3DMultisample(target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations);
}
-void AbstractTexture::storageMultisampleImplementationDSA(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) {
+void AbstractTexture::storageMultisampleImplementationDSAEXT(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) {
+ _created = true;
glTextureStorage3DMultisampleEXT(_id, target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations);
}
#endif
@@ -1022,7 +1080,8 @@ void AbstractTexture::getImageImplementationDefault(const GLenum target, const G
glGetTexImage(target, level, GLenum(format), GLenum(type), data);
}
-void AbstractTexture::getImageImplementationDSA(const GLenum target, const GLint level, const ColorFormat format, const ColorType type, const std::size_t, GLvoid* const data) {
+void AbstractTexture::getImageImplementationDSAEXT(const GLenum target, const GLint level, const ColorFormat format, const ColorType type, const std::size_t, GLvoid* const data) {
+ _created = true;
glGetTextureImageEXT(_id, target, level, GLenum(format), GLenum(type), data);
}
@@ -1038,7 +1097,8 @@ void AbstractTexture::imageImplementationDefault(GLenum target, GLint level, Tex
glTexImage1D(target, level, GLint(internalFormat), size[0], 0, GLenum(format), GLenum(type), data);
}
-void AbstractTexture::imageImplementationDSA(GLenum target, GLint level, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data) {
+void AbstractTexture::imageImplementationDSAEXT(GLenum target, GLint level, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data) {
+ _created = true;
glTextureImage1DEXT(_id, target, level, GLint(internalFormat), size[0], 0, GLenum(format), GLenum(type), data);
}
#endif
@@ -1049,7 +1109,8 @@ void AbstractTexture::imageImplementationDefault(GLenum target, GLint level, Tex
}
#ifndef MAGNUM_TARGET_GLES
-void AbstractTexture::imageImplementationDSA(GLenum target, GLint level, TextureFormat internalFormat, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data) {
+void AbstractTexture::imageImplementationDSAEXT(GLenum target, GLint level, TextureFormat internalFormat, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data) {
+ _created = true;
glTextureImage2DEXT(_id, target, level, GLint(internalFormat), size.x(), size.y(), 0, GLenum(format), GLenum(type), data);
}
#endif
@@ -1073,7 +1134,8 @@ void AbstractTexture::imageImplementationDefault(GLenum target, GLint level, Tex
}
#ifndef MAGNUM_TARGET_GLES
-void AbstractTexture::imageImplementationDSA(GLenum target, GLint level, TextureFormat internalFormat, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data) {
+void AbstractTexture::imageImplementationDSAEXT(GLenum target, GLint level, TextureFormat internalFormat, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data) {
+ _created = true;
glTextureImage3DEXT(_id, target, level, GLint(internalFormat), size.x(), size.y(), size.z(), 0, GLenum(format), GLenum(type), data);
}
#endif
@@ -1084,7 +1146,8 @@ void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level,
glTexSubImage1D(target, level, offset[0], size[0], GLenum(format), GLenum(type), data);
}
-void AbstractTexture::subImageImplementationDSA(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data) {
+void AbstractTexture::subImageImplementationDSAEXT(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data) {
+ _created = true;
glTextureSubImage1DEXT(_id, target, level, offset[0], size[0], GLenum(format), GLenum(type), data);
}
#endif
@@ -1095,7 +1158,8 @@ void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level,
}
#ifndef MAGNUM_TARGET_GLES
-void AbstractTexture::subImageImplementationDSA(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data) {
+void AbstractTexture::subImageImplementationDSAEXT(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data) {
+ _created = true;
glTextureSubImage2DEXT(_id, target, level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data);
}
#endif
@@ -1119,7 +1183,8 @@ void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level,
}
#ifndef MAGNUM_TARGET_GLES
-void AbstractTexture::subImageImplementationDSA(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data) {
+void AbstractTexture::subImageImplementationDSAEXT(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data) {
+ _created = true;
glTextureSubImage3DEXT(_id, target, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data);
}
#endif
@@ -1128,6 +1193,7 @@ void AbstractTexture::invalidateImageImplementationNoOp(GLint) {}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::invalidateImageImplementationARB(GLint level) {
+ createIfNotAlready();
glInvalidateTexImage(_id, level);
}
#endif
@@ -1136,6 +1202,7 @@ void AbstractTexture::invalidateSubImageImplementationNoOp(GLint, const Vector3i
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::invalidateSubImageImplementationARB(GLint level, const Vector3i& offset, const Vector3i& size) {
+ createIfNotAlready();
glInvalidateTexSubImage(_id, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z());
}
#endif
@@ -1160,7 +1227,7 @@ template void AbstractTexture::image(GLenum target, GLin
if(image.size() != size)
image.setData(image.format(), image.type(), size, nullptr, usage);
- image.buffer().bind(Buffer::Target::PixelPack);
+ image.buffer().bindInternal(Buffer::TargetHint::PixelPack);
(this->*Context::current()->state().texture->getImageImplementation)(target, level, image.format(), image.type(), dataSize, nullptr);
}
@@ -1228,78 +1295,78 @@ void AbstractTexture::DataHelper<3>::setStorageMultisample(AbstractTexture& text
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::DataHelper<1>::setImage(AbstractTexture& texture, const GLenum target, const GLint level, const TextureFormat internalFormat, const ImageReference1D& image) {
- Buffer::unbind(Buffer::Target::PixelUnpack);
+ Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
(texture.*Context::current()->state().texture->image1DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), image.data());
}
void AbstractTexture::DataHelper<1>::setImage(AbstractTexture& texture, const GLenum target, const GLint level, const TextureFormat internalFormat, BufferImage1D& image) {
- image.buffer().bind(Buffer::Target::PixelUnpack);
+ image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
(texture.*Context::current()->state().texture->image1DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), nullptr);
}
void AbstractTexture::DataHelper<1>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Math::Vector<1, GLint>& offset, const ImageReference1D& image) {
- Buffer::unbind(Buffer::Target::PixelUnpack);
+ Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
(texture.*Context::current()->state().texture->subImage1DImplementation)(target, level, offset, image.size(), image.format(), image.type(), image.data());
}
void AbstractTexture::DataHelper<1>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Math::Vector<1, GLint>& offset, BufferImage1D& image) {
- image.buffer().bind(Buffer::Target::PixelUnpack);
+ image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
(texture.*Context::current()->state().texture->subImage1DImplementation)(target, level, offset, image.size(), image.format(), image.type(), nullptr);
}
#endif
void AbstractTexture::DataHelper<2>::setImage(AbstractTexture& texture, const GLenum target, const GLint level, const TextureFormat internalFormat, const ImageReference2D& image) {
#ifndef MAGNUM_TARGET_GLES2
- Buffer::unbind(Buffer::Target::PixelUnpack);
+ Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
#endif
(texture.*Context::current()->state().texture->image2DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), image.data());
}
#ifndef MAGNUM_TARGET_GLES2
void AbstractTexture::DataHelper<2>::setImage(AbstractTexture& texture, const GLenum target, const GLint level, const TextureFormat internalFormat, BufferImage2D& image) {
- image.buffer().bind(Buffer::Target::PixelUnpack);
+ image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
(texture.*Context::current()->state().texture->image2DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), nullptr);
}
#endif
void AbstractTexture::DataHelper<2>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Vector2i& offset, const ImageReference2D& image) {
#ifndef MAGNUM_TARGET_GLES2
- Buffer::unbind(Buffer::Target::PixelUnpack);
+ Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
#endif
(texture.*Context::current()->state().texture->subImage2DImplementation)(target, level, offset, image.size(), image.format(), image.type(), image.data());
}
#ifndef MAGNUM_TARGET_GLES2
void AbstractTexture::DataHelper<2>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Vector2i& offset, BufferImage2D& image) {
- image.buffer().bind(Buffer::Target::PixelUnpack);
+ image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
(texture.*Context::current()->state().texture->subImage2DImplementation)(target, level, offset, image.size(), image.format(), image.type(), nullptr);
}
#endif
void AbstractTexture::DataHelper<3>::setImage(AbstractTexture& texture, const GLenum target, const GLint level, const TextureFormat internalFormat, const ImageReference3D& image) {
#ifndef MAGNUM_TARGET_GLES2
- Buffer::unbind(Buffer::Target::PixelUnpack);
+ Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
#endif
(texture.*Context::current()->state().texture->image3DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), image.data());
}
#ifndef MAGNUM_TARGET_GLES2
void AbstractTexture::DataHelper<3>::setImage(AbstractTexture& texture, const GLenum target, const GLint level, const TextureFormat internalFormat, BufferImage3D& image) {
- image.buffer().bind(Buffer::Target::PixelUnpack);
+ image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
(texture.*Context::current()->state().texture->image3DImplementation)(target, level, internalFormat, image.size(), image.format(), image.type(), nullptr);
}
#endif
void AbstractTexture::DataHelper<3>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Vector3i& offset, const ImageReference3D& image) {
#ifndef MAGNUM_TARGET_GLES2
- Buffer::unbind(Buffer::Target::PixelUnpack);
+ Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack);
#endif
(texture.*Context::current()->state().texture->subImage3DImplementation)(target, level, offset, image.size(), image.format(), image.type(), image.data());
}
#ifndef MAGNUM_TARGET_GLES2
void AbstractTexture::DataHelper<3>::setSubImage(AbstractTexture& texture, const GLenum target, const GLint level, const Vector3i& offset, BufferImage3D& image) {
- image.buffer().bind(Buffer::Target::PixelUnpack);
+ image.buffer().bindInternal(Buffer::TargetHint::PixelUnpack);
(texture.*Context::current()->state().texture->subImage3DImplementation)(target, level, offset, image.size(), image.format(), image.type(), nullptr);
}
#endif
diff --git a/src/Magnum/AbstractTexture.h b/src/Magnum/AbstractTexture.h
index 09c19c3e8..b8a2fab28 100644
--- a/src/Magnum/AbstractTexture.h
+++ b/src/Magnum/AbstractTexture.h
@@ -209,6 +209,21 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
*/
static void unbind(Int textureUnit);
+ /**
+ * @brief Unbind textures in given range of texture units
+ *
+ * Unbinds all texture in the range @f$ [ firstTextureUnit ; firstTextureUnit + count ) @f$.
+ * If @extension{ARB,multi_bind} (part of OpenGL 4.4) is not available,
+ * the feature is emulated with sequence of @ref unbind(Int) calls.
+ * @note This function is meant to be used only internally from
+ * @ref AbstractShaderProgram subclasses. See its documentation
+ * for more information.
+ * @see @ref Shader::maxCombinedTextureImageUnits(), @fn_gl{BindTextures},
+ * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} or
+ * @fn_gl_extension{BindMultiTexture,EXT,direct_state_access}
+ */
+ static void unbind(Int firstTextureUnit, std::size_t count);
+
/**
* @brief Bind textures to given range of texture units
*
@@ -216,9 +231,13 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
* `firstTextureUnit + 1` etc. If any texture is `nullptr`, given
* texture unit is unbound. If @extension{ARB,multi_bind} (part of
* OpenGL 4.4) is not available, the feature is emulated with sequence
- * of @ref bind(Int) / @ref unbind() calls.
- * @see @fn_gl{BindTextures}, eventually @fn_gl{ActiveTexture},
- * @fn_gl{BindTexture} or @fn_gl_extension{BindMultiTexture,EXT,direct_state_access}
+ * of @ref bind(Int) / @ref unbind(Int) calls.
+ * @note This function is meant to be used only internally from
+ * @ref AbstractShaderProgram subclasses. See its documentation
+ * for more information.
+ * @see @ref Shader::maxCombinedTextureImageUnits(), @fn_gl{BindTextures},
+ * eventually @fn_gl{ActiveTexture}, @fn_gl{BindTexture} or
+ * @fn_gl_extension{BindMultiTexture,EXT,direct_state_access}
*/
static void bind(Int firstTextureUnit, std::initializer_list textures);
@@ -253,7 +272,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
* @fn_gl_extension2{GetObjectLabel,EXT,debug_label} with
* @def_gl{TEXTURE}
*/
- std::string label() const;
+ std::string label();
/**
* @brief Set texture label
@@ -358,18 +377,25 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
static void MAGNUM_LOCAL unbindImplementationDefault(GLint textureUnit);
#ifndef MAGNUM_TARGET_GLES
static void MAGNUM_LOCAL unbindImplementationMulti(GLint textureUnit);
- static void MAGNUM_LOCAL unbindImplementationDSA(GLint textureUnit);
+ static void MAGNUM_LOCAL unbindImplementationDSAEXT(GLint textureUnit);
#endif
- static void MAGNUM_LOCAL bindImplementationFallback(GLint firstTextureUnit, std::initializer_list textures);
+ static void MAGNUM_LOCAL bindImplementationFallback(GLint firstTextureUnit, Containers::ArrayReference textures);
#ifndef MAGNUM_TARGET_GLES
- static void MAGNUM_LOCAL bindImplementationMulti(GLint firstTextureUnit, std::initializer_list textures);
+ static void MAGNUM_LOCAL bindImplementationMulti(GLint firstTextureUnit, Containers::ArrayReference textures);
#endif
+ void MAGNUM_LOCAL createImplementationDefault();
+ #ifndef MAGNUM_TARGET_GLES
+ void MAGNUM_LOCAL createImplementationDSA();
+ #endif
+
+ void MAGNUM_LOCAL createIfNotAlready();
+
void MAGNUM_LOCAL bindImplementationDefault(GLint textureUnit);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL bindImplementationMulti(GLint textureUnit);
- void MAGNUM_LOCAL bindImplementationDSA(GLint textureUnit);
+ void MAGNUM_LOCAL bindImplementationDSAEXT(GLint textureUnit);
#endif
void MAGNUM_LOCAL parameterImplementationDefault(GLenum parameter, GLint value);
@@ -383,12 +409,12 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
void MAGNUM_LOCAL parameterIImplementationDefault(GLenum parameter, const GLint* values);
#endif
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, GLint value);
- void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, GLfloat value);
- void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, const GLint* values);
- void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, const GLfloat* values);
- void MAGNUM_LOCAL parameterIImplementationDSA(GLenum parameter, const GLuint* values);
- void MAGNUM_LOCAL parameterIImplementationDSA(GLenum parameter, const GLint* values);
+ void MAGNUM_LOCAL parameterImplementationDSAEXT(GLenum parameter, GLint value);
+ void MAGNUM_LOCAL parameterImplementationDSAEXT(GLenum parameter, GLfloat value);
+ void MAGNUM_LOCAL parameterImplementationDSAEXT(GLenum parameter, const GLint* values);
+ void MAGNUM_LOCAL parameterImplementationDSAEXT(GLenum parameter, const GLfloat* values);
+ void MAGNUM_LOCAL parameterIImplementationDSAEXT(GLenum parameter, const GLuint* values);
+ void MAGNUM_LOCAL parameterIImplementationDSAEXT(GLenum parameter, const GLint* values);
#endif
void MAGNUM_LOCAL setMaxAnisotropyImplementationNoOp(GLfloat);
@@ -397,31 +423,31 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
#ifndef MAGNUM_TARGET_GLES2
void MAGNUM_LOCAL getLevelParameterImplementationDefault(GLenum target, GLint level, GLenum parameter, GLint* values);
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL getLevelParameterImplementationDSA(GLenum target, GLint level, GLenum parameter, GLint* values);
+ void MAGNUM_LOCAL getLevelParameterImplementationDSAEXT(GLenum target, GLint level, GLenum parameter, GLint* values);
#endif
#endif
void MAGNUM_LOCAL mipmapImplementationDefault();
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL mipmapImplementationDSA();
+ void MAGNUM_LOCAL mipmapImplementationDSAEXT();
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL storageImplementationFallback(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size);
void MAGNUM_LOCAL storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size);
- void MAGNUM_LOCAL storageImplementationDSA(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size);
+ void MAGNUM_LOCAL storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size);
#endif
void MAGNUM_LOCAL storageImplementationFallback(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size);
void MAGNUM_LOCAL storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size);
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL storageImplementationDSA(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size);
+ void MAGNUM_LOCAL storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size);
#endif
void MAGNUM_LOCAL storageImplementationFallback(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size);
void MAGNUM_LOCAL storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size);
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL storageImplementationDSA(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size);
+ void MAGNUM_LOCAL storageImplementationDSAEXT(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size);
#endif
#ifndef MAGNUM_TARGET_GLES
@@ -431,49 +457,49 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
void MAGNUM_LOCAL storageMultisampleImplementationDefault(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations);
#endif
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL storageMultisampleImplementationDSA(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations);
+ void MAGNUM_LOCAL storageMultisampleImplementationDSAEXT(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations);
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL storageMultisampleImplementationFallback(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations);
void MAGNUM_LOCAL storageMultisampleImplementationDefault(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations);
- void MAGNUM_LOCAL storageMultisampleImplementationDSA(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations);
+ void MAGNUM_LOCAL storageMultisampleImplementationDSAEXT(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations);
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL getImageImplementationDefault(GLenum target, GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
- void MAGNUM_LOCAL getImageImplementationDSA(GLenum target, GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
+ void MAGNUM_LOCAL getImageImplementationDSAEXT(GLenum target, GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
void MAGNUM_LOCAL getImageImplementationRobustness(GLenum target, GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL imageImplementationDefault(GLenum target, GLint level, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data);
- void MAGNUM_LOCAL imageImplementationDSA(GLenum target, GLint level, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data);
+ void MAGNUM_LOCAL imageImplementationDSAEXT(GLenum target, GLint level, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data);
#endif
void MAGNUM_LOCAL imageImplementationDefault(GLenum target, GLint level, TextureFormat internalFormat, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data);
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL imageImplementationDSA(GLenum target, GLint level, TextureFormat internalFormat, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data);
+ void MAGNUM_LOCAL imageImplementationDSAEXT(GLenum target, GLint level, TextureFormat internalFormat, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data);
#endif
void MAGNUM_LOCAL imageImplementationDefault(GLenum target, GLint level, TextureFormat internalFormat, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data);
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL imageImplementationDSA(GLenum target, GLint level, TextureFormat internalFormat, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data);
+ void MAGNUM_LOCAL imageImplementationDSAEXT(GLenum target, GLint level, TextureFormat internalFormat, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data);
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL subImageImplementationDefault(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data);
- void MAGNUM_LOCAL subImageImplementationDSA(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data);
+ void MAGNUM_LOCAL subImageImplementationDSAEXT(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data);
#endif
void MAGNUM_LOCAL subImageImplementationDefault(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data);
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL subImageImplementationDSA(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data);
+ void MAGNUM_LOCAL subImageImplementationDSAEXT(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data);
#endif
void MAGNUM_LOCAL subImageImplementationDefault(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data);
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL subImageImplementationDSA(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data);
+ void MAGNUM_LOCAL subImageImplementationDSAEXT(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data);
#endif
void MAGNUM_LOCAL invalidateImageImplementationNoOp(GLint level);
@@ -490,6 +516,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
ColorType MAGNUM_LOCAL imageTypeForInternalFormat(TextureFormat internalFormat);
GLuint _id;
+ bool _created; /* see createIfNotAlready() for details */
};
#ifndef DOXYGEN_GENERATING_OUTPUT
@@ -593,13 +620,14 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> {
};
#endif
-inline AbstractTexture::AbstractTexture(AbstractTexture&& other) noexcept: _target(other._target), _id(other._id) {
+inline AbstractTexture::AbstractTexture(AbstractTexture&& other) noexcept: _target{other._target}, _id{other._id}, _created{other._created} {
other._id = 0;
}
inline AbstractTexture& AbstractTexture::operator=(AbstractTexture&& other) noexcept {
std::swap(_target, other._target);
std::swap(_id, other._id);
+ std::swap(_created, other._created);
return *this;
}
diff --git a/src/Magnum/Buffer.cpp b/src/Magnum/Buffer.cpp
index e6c704ba5..c992b72b4 100644
--- a/src/Magnum/Buffer.cpp
+++ b/src/Magnum/Buffer.cpp
@@ -39,7 +39,7 @@ namespace Magnum {
#ifndef MAGNUM_TARGET_GLES
Int Buffer::minMapAlignment() {
if(!Context::current()->isExtensionSupported())
- return 0;
+ return 1;
GLint& value = Context::current()->state().buffer->minMapAlignment;
@@ -89,7 +89,7 @@ Int Buffer::shaderStorageOffsetAlignment() {
#else
if(!Context::current()->isVersionSupported(Version::GLES310))
#endif
- return 0;
+ return 1;
GLint& value = Context::current()->state().buffer->shaderStorageOffsetAlignment;
@@ -98,9 +98,21 @@ Int Buffer::shaderStorageOffsetAlignment() {
return value;
}
-#endif
-#ifndef MAGNUM_TARGET_GLES2
+Int Buffer::uniformOffsetAlignment() {
+ #ifndef MAGNUM_TARGET_GLES
+ if(!Context::current()->isExtensionSupported())
+ return 1;
+ #endif
+
+ GLint& value = Context::current()->state().buffer->uniformOffsetAlignment;
+
+ if(value == 0)
+ glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &value);
+
+ return value;
+}
+
Int Buffer::maxUniformBindings() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported())
@@ -114,23 +126,63 @@ Int Buffer::maxUniformBindings() {
return value;
}
-#endif
-#ifndef MAGNUM_TARGET_GLES2
+void Buffer::unbind(const Target target, const UnsignedInt index) {
+ #ifdef MAGNUM_BUILD_DEPRECATED
+ CORRADE_INTERNAL_ASSERT(target == Target::AtomicCounter || target == Target::ShaderStorage || target == Target::Uniform);
+ #endif
+ glBindBufferBase(GLenum(target), index, 0);
+}
+
+void Buffer::unbind(const Target target, const UnsignedInt firstIndex, const std::size_t count) {
+ #ifdef MAGNUM_BUILD_DEPRECATED
+ CORRADE_INTERNAL_ASSERT(target == Target::AtomicCounter || target == Target::ShaderStorage || target == Target::Uniform);
+ #endif
+ Context::current()->state().buffer->bindBasesImplementation(target, firstIndex, {nullptr, count});
+}
+
+/** @todoc const std::initializer_list makes Doxygen grumpy */
+void Buffer::bind(const Target target, const UnsignedInt firstIndex, std::initializer_list> buffers) {
+ #ifdef MAGNUM_BUILD_DEPRECATED
+ CORRADE_INTERNAL_ASSERT(target == Target::AtomicCounter || target == Target::ShaderStorage || target == Target::Uniform);
+ #endif
+ Context::current()->state().buffer->bindRangesImplementation(target, firstIndex, {buffers.begin(), buffers.size()});
+}
+
+/** @todoc const std::initializer_list makes Doxygen grumpy */
+void Buffer::bind(const Target target, const UnsignedInt firstIndex, std::initializer_list buffers) {
+ #ifdef MAGNUM_BUILD_DEPRECATED
+ CORRADE_INTERNAL_ASSERT(target == Target::AtomicCounter || target == Target::ShaderStorage || target == Target::Uniform);
+ #endif
+ Context::current()->state().buffer->bindBasesImplementation(target, firstIndex, {buffers.begin(), buffers.size()});
+}
+
void Buffer::copy(Buffer& read, Buffer& write, const GLintptr readOffset, const GLintptr writeOffset, const GLsizeiptr size) {
Context::current()->state().buffer->copyImplementation(read, write, readOffset, writeOffset, size);
}
#endif
-Buffer::Buffer(Buffer::Target targetHint): _targetHint(targetHint)
+Buffer::Buffer(const TargetHint targetHint): _targetHint{targetHint}
#ifdef CORRADE_TARGET_NACL
- , _mappedBuffer(nullptr)
+ , _mappedBuffer{nullptr}
#endif
{
- glGenBuffers(1, &_id);
+ (this->*Context::current()->state().buffer->createImplementation)();
CORRADE_INTERNAL_ASSERT(_id != Implementation::State::DisengagedBinding);
}
+void Buffer::createImplementationDefault() {
+ glGenBuffers(1, &_id);
+ _created = false;
+}
+
+#ifndef MAGNUM_TARGET_GLES
+void Buffer::createImplementationDSA() {
+ glCreateBuffers(1, &_id);
+ _created = true;
+}
+#endif
+
Buffer::~Buffer() {
/* Moved out, nothing to do */
if(!_id) return;
@@ -144,7 +196,20 @@ Buffer::~Buffer() {
glDeleteBuffers(1, &_id);
}
-std::string Buffer::label() const {
+inline void Buffer::createIfNotAlready() {
+ if(_created) return;
+
+ /* glGen*() does not create the object, just reserves the name. Some
+ commands (such as glInvalidateBufferData() or glObjectLabel()) operate
+ with IDs directly and they require the object to be created. Binding the
+ buffer finally creates it. Also all EXT DSA functions implicitly create
+ it. */
+ bindSomewhereInternal(_targetHint);
+ CORRADE_INTERNAL_ASSERT(_created);
+}
+
+std::string Buffer::label() {
+ createIfNotAlready();
#ifndef MAGNUM_TARGET_GLES
return Context::current()->state().debug->getLabelImplementation(GL_BUFFER, _id);
#else
@@ -153,6 +218,7 @@ std::string Buffer::label() const {
}
Buffer& Buffer::setLabelInternal(const Containers::ArrayReference label) {
+ createIfNotAlready();
#ifndef MAGNUM_TARGET_GLES
Context::current()->state().debug->labelImplementation(GL_BUFFER, _id, label);
#else
@@ -161,18 +227,20 @@ Buffer& Buffer::setLabelInternal(const Containers::ArrayReference la
return *this;
}
-void Buffer::bind(Target target, GLuint id) {
+void Buffer::bindInternal(const TargetHint target, Buffer* const buffer) {
+ const GLuint id = buffer ? buffer->_id : 0;
GLuint& bound = Context::current()->state().buffer->bindings[Implementation::BufferState::indexForTarget(target)];
/* Already bound, nothing to do */
if(bound == id) return;
- /* Bind the buffer otherwise */
+ /* Bind the buffer otherwise, which will also finally create it */
bound = id;
+ buffer->_created = true;
glBindBuffer(GLenum(target), id);
}
-Buffer::Target Buffer::bindInternal(Target hint) {
+auto Buffer::bindSomewhereInternal(const TargetHint hint) -> TargetHint {
GLuint* bindings = Context::current()->state().buffer->bindings;
GLuint& hintBinding = bindings[Implementation::BufferState::indexForTarget(hint)];
@@ -186,10 +254,29 @@ Buffer::Target Buffer::bindInternal(Target hint) {
/* Bind the buffer to hint target otherwise */
hintBinding = _id;
+ _created = true;
glBindBuffer(GLenum(hint), _id);
return hint;
}
+#ifndef MAGNUM_TARGET_GLES2
+Buffer& Buffer::bind(const Target target, const UnsignedInt index, const GLintptr offset, const GLsizeiptr size) {
+ #ifdef MAGNUM_BUILD_DEPRECATED
+ CORRADE_INTERNAL_ASSERT(target == Target::AtomicCounter || target == Target::ShaderStorage || target == Target::Uniform);
+ #endif
+ glBindBufferRange(GLenum(target), index, _id, offset, size);
+ return *this;
+}
+
+Buffer& Buffer::bind(const Target target, const UnsignedInt index) {
+ #ifdef MAGNUM_BUILD_DEPRECATED
+ CORRADE_INTERNAL_ASSERT(target == Target::AtomicCounter || target == Target::ShaderStorage || target == Target::Uniform);
+ #endif
+ glBindBufferBase(GLenum(target), index, _id);
+ return *this;
+}
+#endif
+
Int Buffer::size() {
/**
* @todo there is something like glGetBufferParameteri64v in 3.2 (I
@@ -268,53 +355,111 @@ void Buffer::subDataInternal(GLintptr offset, GLsizeiptr size, GLvoid* data) {
#endif
#ifndef MAGNUM_TARGET_GLES2
+void Buffer::bindImplementationFallback(const Target target, const GLuint firstIndex, Containers::ArrayReference buffers) {
+ for(std::size_t i = 0; i != buffers.size(); ++i) {
+ if(buffers && buffers[i]) buffers[i]->bind(target, firstIndex + i);
+ else unbind(target, firstIndex + i);
+ }
+}
+
+#ifndef MAGNUM_TARGET_GLES
+void Buffer::bindImplementationMulti(const Target target, const GLuint firstIndex, Containers::ArrayReference buffers) {
+ Containers::Array ids{buffers ? buffers.size() : 0};
+ if(buffers) for(std::size_t i = 0; i != buffers.size(); ++i) {
+ if(buffers[i]) {
+ buffers[i]->createIfNotAlready();
+ ids[i] = buffers[i]->_id;
+ } else {
+ ids[i] = 0;
+ }
+ }
+
+ glBindBuffersBase(GLenum(target), firstIndex, buffers.size(), ids);
+}
+#endif
+
+void Buffer::bindImplementationFallback(const Target target, const GLuint firstIndex, const Containers::ArrayReference> buffers) {
+ for(std::size_t i = 0; i != buffers.size(); ++i) {
+ if(buffers && std::get<0>(buffers[i]))
+ std::get<0>(buffers[i])->bind(target, firstIndex + i, std::get<1>(buffers[i]), std::get<2>(buffers[i]));
+ else unbind(target, firstIndex + i);
+ }
+}
+
+#ifndef MAGNUM_TARGET_GLES
+void Buffer::bindImplementationMulti(const Target target, const GLuint firstIndex, const Containers::ArrayReference> buffers) {
+ /** @todo use ArrayTuple */
+ Containers::Array ids{buffers ? buffers.size() : 0};
+ Containers::Array offsetsSizes{buffers ? buffers.size()*2 : 0};
+ if(buffers) for(std::size_t i = 0; i != buffers.size(); ++i) {
+ if(std::get<0>(buffers[i])) {
+ std::get<0>(buffers[i])->createIfNotAlready();
+ ids[i] = std::get<0>(buffers[i])->_id;
+ std::tie(std::ignore, offsetsSizes[i], offsetsSizes[buffers.size() + i]) = buffers[i];
+ } else {
+ ids[i] = 0;
+ offsetsSizes[i] = 0;
+ /** @todo fix workaround when NVidia 343.13 accepts zero sizes */
+ offsetsSizes[buffers.size() + i] = 1;
+ }
+ }
+
+ glBindBuffersRange(GLenum(target), firstIndex, buffers.size(), ids, offsetsSizes, offsetsSizes + buffers.size());
+}
+#endif
+
void Buffer::copyImplementationDefault(Buffer& read, Buffer& write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) {
- glCopyBufferSubData(GLenum(read.bindInternal(Target::CopyRead)), GLenum(write.bindInternal(Target::CopyWrite)), readOffset, writeOffset, size);
+ glCopyBufferSubData(GLenum(read.bindSomewhereInternal(TargetHint::CopyRead)), GLenum(write.bindSomewhereInternal(TargetHint::CopyWrite)), readOffset, writeOffset, size);
}
#ifndef MAGNUM_TARGET_GLES
-void Buffer::copyImplementationDSA(Buffer& read, Buffer& write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) {
+void Buffer::copyImplementationDSAEXT(Buffer& read, Buffer& write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) {
+ read._created = write._created = true;
glNamedCopyBufferSubDataEXT(read._id, write._id, readOffset, writeOffset, size);
}
#endif
#endif
void Buffer::getParameterImplementationDefault(const GLenum value, GLint* const data) {
- glGetBufferParameteriv(GLenum(bindInternal(_targetHint)), value, data);
+ glGetBufferParameteriv(GLenum(bindSomewhereInternal(_targetHint)), value, data);
}
#ifndef MAGNUM_TARGET_GLES
-void Buffer::getParameterImplementationDSA(const GLenum value, GLint* const data) {
+void Buffer::getParameterImplementationDSAEXT(const GLenum value, GLint* const data) {
+ _created = true;
glGetNamedBufferParameterivEXT(_id, value, data);
}
#endif
#ifndef MAGNUM_TARGET_GLES
void Buffer::getSubDataImplementationDefault(const GLintptr offset, const GLsizeiptr size, GLvoid* const data) {
- glGetBufferSubData(GLenum(bindInternal(_targetHint)), offset, size, data);
+ glGetBufferSubData(GLenum(bindSomewhereInternal(_targetHint)), offset, size, data);
}
-void Buffer::getSubDataImplementationDSA(const GLintptr offset, const GLsizeiptr size, GLvoid* const data) {
+void Buffer::getSubDataImplementationDSAEXT(const GLintptr offset, const GLsizeiptr size, GLvoid* const data) {
+ _created = true;
glGetNamedBufferSubDataEXT(_id, offset, size, data);
}
#endif
void Buffer::dataImplementationDefault(GLsizeiptr size, const GLvoid* data, BufferUsage usage) {
- glBufferData(GLenum(bindInternal(_targetHint)), size, data, GLenum(usage));
+ glBufferData(GLenum(bindSomewhereInternal(_targetHint)), size, data, GLenum(usage));
}
#ifndef MAGNUM_TARGET_GLES
-void Buffer::dataImplementationDSA(GLsizeiptr size, const GLvoid* data, BufferUsage usage) {
+void Buffer::dataImplementationDSAEXT(GLsizeiptr size, const GLvoid* data, BufferUsage usage) {
+ _created = true;
glNamedBufferDataEXT(_id, size, data, GLenum(usage));
}
#endif
void Buffer::subDataImplementationDefault(GLintptr offset, GLsizeiptr size, const GLvoid* data) {
- glBufferSubData(GLenum(bindInternal(_targetHint)), offset, size, data);
+ glBufferSubData(GLenum(bindSomewhereInternal(_targetHint)), offset, size, data);
}
#ifndef MAGNUM_TARGET_GLES
-void Buffer::subDataImplementationDSA(GLintptr offset, GLsizeiptr size, const GLvoid* data) {
+void Buffer::subDataImplementationDSAEXT(GLintptr offset, GLsizeiptr size, const GLvoid* data) {
+ _created = true;
glNamedBufferSubDataEXT(_id, offset, size, data);
}
#endif
@@ -323,6 +468,7 @@ void Buffer::invalidateImplementationNoOp() {}
#ifndef MAGNUM_TARGET_GLES
void Buffer::invalidateImplementationARB() {
+ createIfNotAlready();
glInvalidateBufferData(_id);
}
#endif
@@ -331,15 +477,16 @@ void Buffer::invalidateSubImplementationNoOp(GLintptr, GLsizeiptr) {}
#ifndef MAGNUM_TARGET_GLES
void Buffer::invalidateSubImplementationARB(GLintptr offset, GLsizeiptr length) {
+ createIfNotAlready();
glInvalidateBufferSubData(_id, offset, length);
}
#endif
void* Buffer::mapImplementationDefault(MapAccess access) {
#ifndef MAGNUM_TARGET_GLES
- return glMapBuffer(GLenum(bindInternal(_targetHint)), GLenum(access));
+ return glMapBuffer(GLenum(bindSomewhereInternal(_targetHint)), GLenum(access));
#elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
- return glMapBufferOES(GLenum(bindInternal(_targetHint)), GLenum(access));
+ return glMapBufferOES(GLenum(bindSomewhereInternal(_targetHint)), GLenum(access));
#else
static_cast(access);
CORRADE_ASSERT_UNREACHABLE();
@@ -347,16 +494,17 @@ void* Buffer::mapImplementationDefault(MapAccess access) {
}
#ifndef MAGNUM_TARGET_GLES
-void* Buffer::mapImplementationDSA(MapAccess access) {
+void* Buffer::mapImplementationDSAEXT(MapAccess access) {
+ _created = true;
return glMapNamedBufferEXT(_id, GLenum(access));
}
#endif
void* Buffer::mapRangeImplementationDefault(GLintptr offset, GLsizeiptr length, MapFlags access) {
#ifndef MAGNUM_TARGET_GLES2
- return glMapBufferRange(GLenum(bindInternal(_targetHint)), offset, length, GLenum(access));
+ return glMapBufferRange(GLenum(bindSomewhereInternal(_targetHint)), offset, length, GLenum(access));
#elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
- return glMapBufferRangeEXT(GLenum(bindInternal(_targetHint)), offset, length, GLenum(access));
+ return glMapBufferRangeEXT(GLenum(bindSomewhereInternal(_targetHint)), offset, length, GLenum(access));
#else
static_cast(offset);
static_cast(length);
@@ -366,16 +514,17 @@ void* Buffer::mapRangeImplementationDefault(GLintptr offset, GLsizeiptr length,
}
#ifndef MAGNUM_TARGET_GLES
-void* Buffer::mapRangeImplementationDSA(GLintptr offset, GLsizeiptr length, MapFlags access) {
+void* Buffer::mapRangeImplementationDSAEXT(GLintptr offset, GLsizeiptr length, MapFlags access) {
+ _created = true;
return glMapNamedBufferRangeEXT(_id, offset, length, GLenum(access));
}
#endif
void Buffer::flushMappedRangeImplementationDefault(GLintptr offset, GLsizeiptr length) {
#ifndef MAGNUM_TARGET_GLES2
- glFlushMappedBufferRange(GLenum(bindInternal(_targetHint)), offset, length);
+ glFlushMappedBufferRange(GLenum(bindSomewhereInternal(_targetHint)), offset, length);
#elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
- glFlushMappedBufferRangeEXT(GLenum(bindInternal(_targetHint)), offset, length);
+ glFlushMappedBufferRangeEXT(GLenum(bindSomewhereInternal(_targetHint)), offset, length);
#else
static_cast(offset);
static_cast(length);
@@ -384,31 +533,33 @@ void Buffer::flushMappedRangeImplementationDefault(GLintptr offset, GLsizeiptr l
}
#ifndef MAGNUM_TARGET_GLES
-void Buffer::flushMappedRangeImplementationDSA(GLintptr offset, GLsizeiptr length) {
+void Buffer::flushMappedRangeImplementationDSAEXT(GLintptr offset, GLsizeiptr length) {
+ _created = true;
glFlushMappedNamedBufferRangeEXT(_id, offset, length);
}
#endif
bool Buffer::unmapImplementationDefault() {
#ifndef MAGNUM_TARGET_GLES2
- return glUnmapBuffer(GLenum(bindInternal(_targetHint)));
+ return glUnmapBuffer(GLenum(bindSomewhereInternal(_targetHint)));
#elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
- return glUnmapBufferOES(GLenum(bindInternal(_targetHint)));
+ return glUnmapBufferOES(GLenum(bindSomewhereInternal(_targetHint)));
#else
CORRADE_ASSERT_UNREACHABLE();
#endif
}
#ifndef MAGNUM_TARGET_GLES
-bool Buffer::unmapImplementationDSA() {
+bool Buffer::unmapImplementationDSAEXT() {
+ _created = true;
return glUnmapNamedBufferEXT(_id);
}
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
-Debug operator<<(Debug debug, Buffer::Target value) {
+Debug operator<<(Debug debug, Buffer::TargetHint value) {
switch(value) {
- #define _c(value) case Buffer::Target::value: return debug << "Buffer::Target::" #value;
+ #define _c(value) case Buffer::TargetHint::value: return debug << "Buffer::TargetHint::" #value;
_c(Array)
#ifndef MAGNUM_TARGET_GLES2
_c(AtomicCounter)
@@ -433,8 +584,48 @@ Debug operator<<(Debug debug, Buffer::Target value) {
#undef _c
}
+ return debug << "Buffer::TargetHint::(invalid)";
+}
+#endif
+
+#if !defined(MAGNUM_TARGET_GLES2) || defined(MAGNUM_BUILD_DEPRECATED)
+#ifndef DOXYGEN_GENERATING_OUTPUT
+Debug operator<<(Debug debug, Buffer::Target value) {
+ switch(value) {
+ #ifndef MAGNUM_TARGET_GLES2
+ #define _c(value) case Buffer::Target::value: return debug << "Buffer::Target::" #value;
+ _c(AtomicCounter)
+ _c(ShaderStorage)
+ _c(Uniform)
+ #undef _c
+ #endif
+
+ #ifdef MAGNUM_BUILD_DEPRECATED
+ case Buffer::Target::Array:
+ #ifndef MAGNUM_TARGET_GLES2
+ case Buffer::Target::CopyRead:
+ case Buffer::Target::CopyWrite:
+ case Buffer::Target::DispatchIndirect:
+ case Buffer::Target::DrawIndirect:
+ #endif
+ case Buffer::Target::ElementArray:
+ #ifndef MAGNUM_TARGET_GLES2
+ case Buffer::Target::PixelPack:
+ case Buffer::Target::PixelUnpack:
+ #endif
+ #ifndef MAGNUM_TARGET_GLES
+ case Buffer::Target::Texture:
+ #endif
+ #ifndef MAGNUM_TARGET_GLES2
+ case Buffer::Target::TransformFeedback:
+ #endif
+ return debug << static_cast(value);
+ #endif
+ }
+
return debug << "Buffer::Target::(invalid)";
}
#endif
+#endif
}
diff --git a/src/Magnum/Buffer.h b/src/Magnum/Buffer.h
index a1aba4dfe..ed222b9e0 100644
--- a/src/Magnum/Buffer.h
+++ b/src/Magnum/Buffer.h
@@ -213,9 +213,9 @@ class MAGNUM_EXPORT Buffer: public AbstractObject {
/**
* @brief %Buffer target
*
- * @see @ref bind(Target), @ref unbind(Target)
+ * @see @ref Buffer(), @ref setTargetHint()
*/
- enum class Target: GLenum {
+ enum class TargetHint: GLenum {
/** Used for storing vertex attributes. */
Array = GL_ARRAY_BUFFER,
@@ -227,9 +227,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject {
* 3.0 and older.
*/
AtomicCounter = GL_ATOMIC_COUNTER_BUFFER,
- #endif
- #ifndef MAGNUM_TARGET_GLES2
/**
* Source for copies. See @ref copy().
* @requires_gl31 %Extension @extension{ARB,copy_buffer}
@@ -245,9 +243,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject {
* 2.0.
*/
CopyWrite = GL_COPY_WRITE_BUFFER,
- #endif
- #ifndef MAGNUM_TARGET_GLES2
/**
* Indirect compute dispatch commands.
* @requires_gl43 %Extension @extension{ARB,compute_shader}
@@ -266,11 +262,9 @@ class MAGNUM_EXPORT Buffer: public AbstractObject {
#endif
/** Used for storing vertex indices. */
- ElementArray = GL_ELEMENT_ARRAY_BUFFER
+ ElementArray = GL_ELEMENT_ARRAY_BUFFER,
#ifndef MAGNUM_TARGET_GLES2
- ,
-
/**
* Target for pixel pack operations.
* @requires_gles30 Pixel buffer objects are not available in
@@ -284,9 +278,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject {
* OpenGL ES 2.0.
*/
PixelUnpack = GL_PIXEL_UNPACK_BUFFER,
- #endif
- #ifndef MAGNUM_TARGET_GLES2
/**
* Used for shader storage.
* @requires_gl43 %Extension @extension{ARB,shader_storage_buffer_object}
@@ -324,6 +316,139 @@ class MAGNUM_EXPORT Buffer: public AbstractObject {
#endif
};
+ #if !defined(MAGNUM_TARGET_GLES2) || defined(MAGNUM_BUILD_DEPRECATED)
+ /**
+ * @brief %Buffer binding target
+ *
+ * @see @ref bind(), @ref unbind()
+ */
+ enum class Target: GLenum {
+ #ifdef MAGNUM_BUILD_DEPRECATED
+ /**
+ * @copydoc TargetHint::Array
+ * @deprecated For @ref Magnum::Buffer::setTargetHint() "setTargetHint()"
+ * only, use @ref Magnum::Buffer::TargetHint::Array "TargetHint::Array"
+ * instead.
+ */
+ Array = GL_ARRAY_BUFFER,
+ #endif
+
+ #ifndef MAGNUM_TARGET_GLES2
+ /**
+ * Atomic counter binding
+ * @requires_gl42 %Extension @extension{ARB,shader_atomic_counters}
+ * @requires_gles31 Atomic counters are not available in OpenGL ES
+ * 3.0 and older
+ */
+ AtomicCounter = GL_ATOMIC_COUNTER_BUFFER,
+ #endif
+
+ #ifdef MAGNUM_BUILD_DEPRECATED
+ #ifndef MAGNUM_TARGET_GLES2
+ /**
+ * @copydoc TargetHint::CopyRead
+ * @deprecated For @ref Magnum::Buffer::setTargetHint() "setTargetHint()"
+ * only, use @ref Magnum::Buffer::TargetHint::CopyRead "TargetHint::CopyRead"
+ * instead.
+ */
+ CopyRead = GL_COPY_READ_BUFFER,
+
+ /**
+ * @copydoc TargetHint::CopyWrite
+ * @deprecated For @ref Magnum::Buffer::setTargetHint() "setTargetHint()"
+ * only, use @ref Magnum::Buffer::TargetHint::CopyWrite "TargetHint::CopyWrite"
+ * instead.
+ */
+ CopyWrite = GL_COPY_WRITE_BUFFER,
+ #endif
+
+ #ifndef MAGNUM_TARGET_GLES2
+ /**
+ * @copydoc TargetHint::DispatchIndirect
+ * @deprecated For @ref Magnum::Buffer::setTargetHint() "setTargetHint()"
+ * only, use @ref Magnum::Buffer::TargetHint::DispatchIndirect "TargetHint::DispatchIndirect"
+ * instead.
+ */
+ DispatchIndirect = GL_DISPATCH_INDIRECT_BUFFER,
+
+ /**
+ * @copydoc TargetHint::DrawIndirect
+ * @deprecated For @ref Magnum::Buffer::setTargetHint() "setTargetHint()"
+ * only, use @ref Magnum::Buffer::TargetHint::DrawIndirect "TargetHint::DrawIndirect"
+ * instead.
+ */
+ DrawIndirect = GL_DRAW_INDIRECT_BUFFER,
+ #endif
+
+ /**
+ * @copydoc TargetHint::ElementArray
+ * @deprecated For @ref Magnum::Buffer::setTargetHint() "setTargetHint()"
+ * only, use @ref Magnum::Buffer::TargetHint::ElementArray "TargetHint::ElementArray"
+ * instead.
+ */
+ ElementArray = GL_ELEMENT_ARRAY_BUFFER,
+
+ #ifndef MAGNUM_TARGET_GLES2
+ /**
+ * @copydoc TargetHint::PixelPack
+ * @deprecated For @ref Magnum::Buffer::setTargetHint() "setTargetHint()"
+ * only, use @ref Magnum::Buffer::TargetHint::PixelPack "TargetHint::PixelPack"
+ * instead.
+ */
+ PixelPack = GL_PIXEL_PACK_BUFFER,
+
+ /**
+ * @copydoc TargetHint::PixelUnpack
+ * @deprecated For @ref Magnum::Buffer::setTargetHint() "setTargetHint()"
+ * only, use @ref Magnum::Buffer::TargetHint::PixelUnpack "TargetHint::PixelUnpack"
+ * instead.
+ */
+ PixelUnpack = GL_PIXEL_UNPACK_BUFFER,
+ #endif
+ #endif
+
+ #ifndef MAGNUM_TARGET_GLES2
+ /**
+ * Shader storage binding
+ * @requires_gl43 %Extension @extension{ARB,shader_storage_buffer_object}
+ * @requires_gles31 Shader storage is not available in OpenGL ES
+ * 3.0 and older
+ */
+ ShaderStorage = GL_SHADER_STORAGE_BUFFER,
+ #endif
+
+ #if defined(MAGNUM_BUILD_DEPRECATED) && !defined(MAGNUM_TARGET_GLES)
+ /**
+ * @copydoc TargetHint::Texture
+ * @deprecated For @ref Magnum::Buffer::setTargetHint() "setTargetHint()"
+ * only, use @ref Magnum::Buffer::TargetHint::Texture "TargetHint::Texture"
+ * instead.
+ */
+ Texture = GL_TEXTURE_BUFFER,
+ #endif
+
+ #if defined(MAGNUM_BUILD_DEPRECATED) && !defined(MAGNUM_TARGET_GLES2)
+ /**
+ * @copydoc TargetHint::TransformFeedback
+ * @deprecated For @ref Magnum::Buffer::setTargetHint() "setTargetHint()"
+ * only, use @ref Magnum::Buffer::TargetHint::TransformFeedback "TargetHint::TransformFeedback"
+ * instead.
+ */
+ TransformFeedback = GL_TRANSFORM_FEEDBACK_BUFFER,
+ #endif
+
+ #ifndef MAGNUM_TARGET_GLES2
+ /**
+ * Uniform binding
+ * @requires_gl31 %Extension @extension{ARB,uniform_buffer_object}
+ * @requires_gles30 Uniform buffers are not available in OpenGL ES
+ * 2.0
+ */
+ Uniform = GL_UNIFORM_BUFFER
+ #endif
+ };
+ #endif
+
#ifdef MAGNUM_BUILD_DEPRECATED
/**
* @copybrief BufferUsage
@@ -449,7 +574,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject {
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,map_buffer_alignment}
- * (part of OpenGL 4.2) is not available, returns `0`.
+ * (part of OpenGL 4.2) is not available, returns `1`.
* @see @ref map(), @fn_gl{Get} with @def_gl{MIN_MAP_BUFFER_ALIGNMENT}
* @requires_gl No minimal value is specified for OpenGL ES.
*/
@@ -463,7 +588,8 @@ class MAGNUM_EXPORT Buffer: public AbstractObject {
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If neither extension @extension{ARB,shader_atomic_counters}
* (part of OpenGL 4.2) nor OpenGL ES 3.1 is available, returns `0`.
- * @see @fn_gl{Get} with @def_gl{MAX_ATOMIC_COUNTER_BUFFER_BINDINGS}
+ * @see @ref bind(), @ref unbind(), @fn_gl{Get} with
+ * @def_gl{MAX_ATOMIC_COUNTER_BUFFER_BINDINGS}
* @requires_gles30 Not defined in OpenGL ES 2.0
*/
static Int maxAtomicCounterBindings();
@@ -474,45 +600,142 @@ class MAGNUM_EXPORT Buffer: public AbstractObject {
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If neither extension @extension{ARB,shader_storage_buffer_object}
* (part of OpenGL 4.3) nor OpenGL ES 3.1 is available, returns `0`.
- * @see @fn_gl{Get} with @def_gl{MAX_SHADER_STORAGE_BUFFER_BINDINGS}
+ * @see @ref bind(), @ref unbind(), @fn_gl{Get} with
+ * @def_gl{MAX_SHADER_STORAGE_BUFFER_BINDINGS}
* @requires_gles30 Not defined in OpenGL ES 2.0
*/
static Int maxShaderStorageBindings();
+ /**
+ * @brief Alignment of uniform buffer binding offset
+ *
+ * The result is cached, repeated queries don't result in repeated
+ * OpenGL calls. If extension @extension{ARB,uniform_buffer_object}
+ * (part of OpenGL 3.1) is not available, returns `1`.
+ * @see @ref bind(), @fn_gl{Get} with @def_gl{UNIFORM_BUFFER_OFFSET_ALIGNMENT}
+ * @requires_gles30 Uniform buffers are not available in OpenGL ES 2.0
+ */
+ static Int uniformOffsetAlignment();
+
/**
* @brief Alignment of shader storage buffer binding offset
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If neither extension @extension{ARB,shader_storage_buffer_object}
- * (part of OpenGL 4.3) nor OpenGL ES 3.1 is available, returns `0`.
- * @see @fn_gl{Get} with @def_gl{SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT}
+ * (part of OpenGL 4.3) nor OpenGL ES 3.1 is available, returns `1`.
+ * @see @ref bind(), @fn_gl{Get} with @def_gl{SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT}
* @requires_gles30 Not defined in OpenGL ES 2.0
*/
static Int shaderStorageOffsetAlignment();
- #endif
- #ifndef MAGNUM_TARGET_GLES2
/**
* @brief Max supported uniform buffer binding count
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,uniform_buffer_object}
* (part of OpenGL 3.1) is not available, returns `0`.
- * @see @fn_gl{Get} with @def_gl{MAX_UNIFORM_BUFFER_BINDINGS}
- * @requires_gles30 Uniform blocks are not available in OpenGL ES 2.0.
+ * @see @ref bind(), @ref unbind(), @fn_gl{Get} with
+ * @def_gl{MAX_UNIFORM_BUFFER_BINDINGS}
+ * @requires_gles30 Uniform buffers are not available in OpenGL ES 2.0
*/
static Int maxUniformBindings();
- #endif
/**
- * @brief Unbind any buffer from given target
- * @param target %Target
+ * @brief Unbind any buffer from given indexed target
*
- * @see @fn_gl{BindBuffer}
+ * The @p index parameter must respect limits for given @p target.
+ * @note This function is meant to be used only internally from
+ * @ref AbstractShaderProgram subclasses. See its documentation
+ * for more information.
+ * @see @ref bind(), @ref maxAtomicCounterBindings(),
+ * @ref maxShaderStorageBindings(), @ref maxUniformBindings(),
+ * @fn_gl{BindBufferBase}
+ * @requires_gl30 No form of indexed buffer binding is available in
+ * OpenGL 2.1, see particular @ref Magnum::Buffer::Target "Target"
+ * values for version requirements.
+ * @requires_gles30 No form of indexed buffer binding is available in
+ * OpenGL ES 2.0, see particular @ref Magnum::Buffer::Target "Target"
+ * values for version requirements.
*/
- static void unbind(Target target) { bind(target, 0); }
+ static void unbind(Target target, UnsignedInt index);
+
+ /**
+ * @brief Unbind given range of indexed targets
+ *
+ * Unbinds all buffers in given target in range @f$ [ firstIndex ; firstIndex + count ] @f$.
+ * The range of indices must respect limits for given @p target. If
+ * @extension{ARB,multi_bind} (part of OpenGL 4.4) is not available,
+ * the feature is emulated with sequence of @ref unbind(Target, UnsignedInt)
+ * calls.
+ * @note This function is meant to be used only internally from
+ * @ref AbstractShaderProgram subclasses. See its documentation
+ * for more information.
+ * @see @ref unbind(Target, UnsignedInt), @ref maxAtomicCounterBindings(),
+ * @ref maxShaderStorageBindings(), @ref maxUniformBindings(),
+ * @fn_gl{BindBuffersBase} or @fn_gl{BindBufferBase}
+ * @requires_gl30 No form of indexed buffer binding is available in
+ * OpenGL 2.1, see particular @ref Magnum::Buffer::Target "Target"
+ * values for version requirements.
+ * @requires_gles30 No form of indexed buffer binding is available in
+ * OpenGL ES 2.0, see particular @ref Magnum::Buffer::Target "Target"
+ * values for version requirements.
+ */
+ static void unbind(Target target, UnsignedInt firstIndex, std::size_t count);
+
+ /**
+ * @brief Bind ranges of buffers to given range of indexed targets
+ *
+ * Binds first buffer in the list to @p firstIndex, second to
+ * `firstIndex + 1` etc. Second parameter is offset, third is size. If
+ * any buffer is `nullptr`, given indexed target is unbound. The range
+ * of indices must respect limits for given @p target. The offsets must
+ * respect alignment, which is 4 bytes for @ref Target::AtomicCounter
+ * and implementation-defined for other targets. If @extension{ARB,multi_bind}
+ * (part of OpenGL 4.4) is not available, the feature is emulated with
+ * sequence of @ref bind(Target, UnsignedInt, GLintptr, GLsizeiptr) /
+ * @ref unbind(Target, UnsignedInt) calls.
+ * @note This function is meant to be used only internally from
+ * @ref AbstractShaderProgram subclasses. See its documentation
+ * for more information.
+ * @see @ref bind(Target, UnsignedInt, GLintptr, GLsizeiptr),
+ * @ref maxAtomicCounterBindings(), @ref maxShaderStorageBindings(),
+ * @ref maxUniformBindings(), @ref shaderStorageOffsetAlignment(),
+ * @ref uniformOffsetAlignment(), @fn_gl{BindBuffersRange} or
+ * @fn_gl{BindBufferRange}
+ * @requires_gl30 No form of indexed buffer binding is available in
+ * OpenGL 2.1, see particular @ref Magnum::Buffer::Target "Target"
+ * values for version requirements.
+ * @requires_gles30 No form of indexed buffer binding is available in
+ * OpenGL ES 2.0, see particular @ref Magnum::Buffer::Target "Target"
+ * values for version requirements.
+ */
+ static void bind(Target target, UnsignedInt firstIndex, std::initializer_list> buffers);
+
+ /**
+ * @brief Bind buffers to given range of indexed targets
+ *
+ * Binds first buffer in the list to @p firstIndex, second to
+ * `firstIndex + 1` etc. If any buffer is `nullptr`, given indexed
+ * target is unbound. The range of indices must respect limits for
+ * given @p target. If @extension{ARB,multi_bind} (part of OpenGL 4.4)
+ * is not available, the feature is emulated with sequence of
+ * @ref bind(Target, UnsignedInt) / @ref unbind(Target, UnsignedInt)
+ * calls.
+ * @note This function is meant to be used only internally from
+ * @ref AbstractShaderProgram subclasses. See its documentation
+ * for more information.
+ * @see @ref bind(Target, UnsignedInt), @ref maxAtomicCounterBindings(),
+ * @ref maxShaderStorageBindings(), @ref maxUniformBindings(),
+ * @fn_gl{BindBuffersBase} or @fn_gl{BindBufferBase}
+ * @requires_gl30 No form of indexed buffer binding is available in
+ * OpenGL 2.1, see particular @ref Magnum::Buffer::Target "Target"
+ * values for version requirements.
+ * @requires_gles30 No form of indexed buffer binding is available in
+ * OpenGL ES 2.0, see particular @ref Magnum::Buffer::Target "Target"
+ * values for version requirements.
+ */
+ static void bind(Target target, UnsignedInt firstIndex, std::initializer_list buffers);
- #ifndef MAGNUM_TARGET_GLES2
/**
* @brief Copy one buffer to another
* @param read %Buffer from which to read
@@ -538,10 +761,21 @@ class MAGNUM_EXPORT Buffer: public AbstractObject {
* @param targetHint Target hint, see @ref setTargetHint() for more
* information
*
- * Creates new OpenGL buffer.
- * @see @fn_gl{GenBuffers}
+ * Creates new OpenGL buffer object. If @extension{ARB,direct_state_access}
+ * (part of OpenGL 4.5) is not supported, the buffer is created on
+ * first use.
+ * @see @fn_gl{CreateBuffers}, eventually @fn_gl{GenBuffers}
+ */
+ explicit Buffer(TargetHint targetHint = TargetHint::Array);
+
+ #ifdef MAGNUM_BUILD_DEPRECATED
+ /**
+ * @copybrief Buffer(TargetHint)
+ * @deprecated Use @ref Magnum::Buffer::Buffer(Magnum::Buffer::TargetHint) "Buffer(TargetHint)"
+ * instead.
*/
- explicit Buffer(Target targetHint = Target::Array);
+ CORRADE_DEPRECATED("use Buffer(TargetHint) instead") explicit Buffer(Target targetHint): Buffer{static_cast(targetHint)} {}
+ #endif
/** @brief Copying is not allowed */
Buffer(const Buffer&) = delete;
@@ -552,7 +786,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject {
/**
* @brief Destructor
*
- * Deletes associated OpenGL buffer.
+ * Deletes associated OpenGL buffer object.
* @see @fn_gl{DeleteBuffers}
*/
~Buffer();
@@ -577,7 +811,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject {
* @fn_gl_extension2{GetObjectLabel,EXT,debug_label} with
* @def_gl{BUFFER_OBJECT_EXT}
*/
- std::string label() const;
+ std::string label();
/**
* @brief Set buffer label
@@ -600,7 +834,7 @@ class MAGNUM_EXPORT Buffer: public AbstractObject {
}
/** @brief Target hint */
- Target targetHint() const { return _targetHint; }
+ TargetHint targetHint() const { return _targetHint; }
/**
* @brief Set target hint
@@ -617,22 +851,66 @@ class MAGNUM_EXPORT Buffer: public AbstractObject {
* http://www.opengl.org/wiki/Vertex_Specification#Index_buffers
* ... damned GL state
*/
- Buffer& setTargetHint(Target hint) {
+ Buffer& setTargetHint(TargetHint hint) {
_targetHint = hint;
return *this;
}
+ #ifdef MAGNUM_BUILD_DEPRECATED
/**
- * @brief Bind buffer
- * @param target %Target
+ * @copybrief setTargetHint(TargetHint)
+ * @deprecated Use @ref Magnum::Buffer::setTargetHint(Magnum::Buffer::TargetHint) "setTargetHint(TargetHint)"
+ * instead.
+ */
+ CORRADE_DEPRECATED("use setTargetHint(TargetHint) instead") Buffer& setTargetHint(Target hint) {
+ return setTargetHint(static_cast(hint));
+ }
+ #endif
+
+ #ifndef MAGNUM_TARGET_GLES2
+ /**
+ * @brief Bind buffer range to given binding index
*
- * @see @fn_gl{BindBuffer}
- * @todo Allow binding to Target::ElementArray only if VAO is bound
- * to avoid potential issues?
- * @todo Don't allow user to bind buffers?
- * @bug Binding to ElementArray if any VAO is active will corrupt the mesh
+ * The @p index parameter must respect limits for given @p target. The
+ * @p offset parameter must respect alignment, which is 4 bytes for
+ * @ref Target::AtomicCounter and implementation-defined for other
+ * targets.
+ * @note This function is meant to be used only internally from
+ * @ref AbstractShaderProgram subclasses. See its documentation
+ * for more information.
+ * @see @ref bind(Target, UnsignedInt, std::initializer_list>),
+ * @ref maxAtomicCounterBindings(), @ref maxShaderStorageBindings(),
+ * @ref maxUniformBindings(), @ref shaderStorageOffsetAlignment(),
+ * @ref uniformOffsetAlignment(), @fn_gl{BindBufferRange}
+ * @requires_gl30 No form of indexed buffer binding is available in
+ * OpenGL 2.1, see particular @ref Magnum::Buffer::Target "Target"
+ * values for version requirements.
+ * @requires_gles30 No form of indexed buffer binding is available in
+ * OpenGL ES 2.0, see particular @ref Magnum::Buffer::Target "Target"
+ * values for version requirements.
+ * @todo State tracking for indexed binding
*/
- void bind(Target target) { bind(target, _id); }
+ Buffer& bind(Target target, UnsignedInt index, GLintptr offset, GLsizeiptr size);
+
+ /**
+ * @brief Bind buffer to given binding index
+ *
+ * The @p index parameter must respect limits for given @p target.
+ * @note This function is meant to be used only internally from
+ * @ref AbstractShaderProgram subclasses. See its documentation
+ * for more information.
+ * @see @ref bind(Target, UnsignedInt, std::initializer_list),
+ * @ref maxAtomicCounterBindings(), @ref maxShaderStorageBindings(),
+ * @ref maxUniformBindings(), @fn_gl{BindBufferBase}
+ * @requires_gl30 No form of indexed buffer binding is available in
+ * OpenGL 2.1, see particular @ref Magnum::Buffer::Target "Target"
+ * values for version requirements.
+ * @requires_gles30 No form of indexed buffer binding is available in
+ * OpenGL ES 2.0, see particular @ref Magnum::Buffer::Target "Target"
+ * values for version requirements.
+ */
+ Buffer& bind(Target target, UnsignedInt index);
+ #endif
/**
* @brief %Buffer size
@@ -868,41 +1146,68 @@ class MAGNUM_EXPORT Buffer: public AbstractObject {
void unmapSub();
#endif
+ #ifdef DOXYGEN_GENERATING_OUTPUT
private:
- Buffer& setLabelInternal(Containers::ArrayReference label);
+ #endif
+ /* There should be no need to use these from user code. Also it's a bit
+ unfortunate to have the parameter typed as TargetHint while in this
+ case it is no hint at all, but it allows to have cleaner public
+ binding API (just with short Target name) */
+ static void unbindInternal(TargetHint target) { bindInternal(target, nullptr); }
+ void bindInternal(TargetHint target) { bindInternal(target, this); }
- static void bind(Target hint, GLuint id);
- Target MAGNUM_LOCAL bindInternal(Target hint);
+ private:
+ static void bindInternal(TargetHint hint, Buffer* buffer);
+ TargetHint MAGNUM_LOCAL bindSomewhereInternal(TargetHint hint);
#ifndef MAGNUM_TARGET_GLES2
+ static void MAGNUM_LOCAL bindImplementationFallback(Target target, GLuint first, Containers::ArrayReference buffers);
+ #ifndef MAGNUM_TARGET_GLES
+ static void MAGNUM_LOCAL bindImplementationMulti(Target target, GLuint first, Containers::ArrayReference buffers);
+ #endif
+
+ static void MAGNUM_LOCAL bindImplementationFallback(Target target, GLuint first, Containers::ArrayReference> buffers);
+ #ifndef MAGNUM_TARGET_GLES
+ static void MAGNUM_LOCAL bindImplementationMulti(Target target, GLuint first, Containers::ArrayReference> buffers);
+ #endif
+
static void MAGNUM_LOCAL copyImplementationDefault(Buffer& read, Buffer& write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
#ifndef MAGNUM_TARGET_GLES
- static void MAGNUM_LOCAL copyImplementationDSA(Buffer& read, Buffer& write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+ static void MAGNUM_LOCAL copyImplementationDSAEXT(Buffer& read, Buffer& write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
#endif
#endif
+ void MAGNUM_LOCAL createImplementationDefault();
+ #ifndef MAGNUM_TARGET_GLES
+ void MAGNUM_LOCAL createImplementationDSA();
+ #endif
+
+ void MAGNUM_LOCAL createIfNotAlready();
+
+ Buffer& setLabelInternal(Containers::ArrayReference label);
+
#ifndef MAGNUM_TARGET_GLES
void subDataInternal(GLintptr offset, GLsizeiptr size, GLvoid* data);
#endif
void MAGNUM_LOCAL getParameterImplementationDefault(GLenum value, GLint* data);
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL getParameterImplementationDSA(GLenum value, GLint* data);
+ void MAGNUM_LOCAL getParameterImplementationDSAEXT(GLenum value, GLint* data);
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL getSubDataImplementationDefault(GLintptr offset, GLsizeiptr size, GLvoid* data);
- void MAGNUM_LOCAL getSubDataImplementationDSA(GLintptr offset, GLsizeiptr size, GLvoid* data);
+ void MAGNUM_LOCAL getSubDataImplementationDSAEXT(GLintptr offset, GLsizeiptr size, GLvoid* data);
#endif
void MAGNUM_LOCAL dataImplementationDefault(GLsizeiptr size, const GLvoid* data, BufferUsage usage);
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL dataImplementationDSA(GLsizeiptr size, const GLvoid* data, BufferUsage usage);
+ void MAGNUM_LOCAL dataImplementationDSAEXT(GLsizeiptr size, const GLvoid* data, BufferUsage usage);
#endif
void MAGNUM_LOCAL subDataImplementationDefault(GLintptr offset, GLsizeiptr size, const GLvoid* data);
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL subDataImplementationDSA(GLintptr offset, GLsizeiptr size, const GLvoid* data);
+ void MAGNUM_LOCAL subDataImplementationDSAEXT(GLintptr offset, GLsizeiptr size, const GLvoid* data);
#endif
void MAGNUM_LOCAL invalidateImplementationNoOp();
@@ -917,43 +1222,61 @@ class MAGNUM_EXPORT Buffer: public AbstractObject {
void MAGNUM_LOCAL * mapImplementationDefault(MapAccess access);
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL * mapImplementationDSA(MapAccess access);
+ void MAGNUM_LOCAL * mapImplementationDSAEXT(MapAccess access);
#endif
void MAGNUM_LOCAL * mapRangeImplementationDefault(GLintptr offset, GLsizeiptr length, MapFlags access);
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL * mapRangeImplementationDSA(GLintptr offset, GLsizeiptr length, MapFlags access);
+ void MAGNUM_LOCAL * mapRangeImplementationDSAEXT(GLintptr offset, GLsizeiptr length, MapFlags access);
#endif
void MAGNUM_LOCAL flushMappedRangeImplementationDefault(GLintptr offset, GLsizeiptr length);
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL flushMappedRangeImplementationDSA(GLintptr offset, GLsizeiptr length);
+ void MAGNUM_LOCAL flushMappedRangeImplementationDSAEXT(GLintptr offset, GLsizeiptr length);
#endif
bool MAGNUM_LOCAL unmapImplementationDefault();
#ifndef MAGNUM_TARGET_GLES
- bool MAGNUM_LOCAL unmapImplementationDSA();
+ bool MAGNUM_LOCAL unmapImplementationDSAEXT();
#endif
GLuint _id;
- Target _targetHint;
+ TargetHint _targetHint;
#ifdef CORRADE_TARGET_NACL
void* _mappedBuffer;
#endif
+ bool _created; /* see createIfNotAlready() for details */
};
CORRADE_ENUMSET_OPERATORS(Buffer::MapFlags)
+/** @debugoperatorclassenum{Magnum::Buffer,Magnum::Buffer::TargetHint} */
+Debug MAGNUM_EXPORT operator<<(Debug debug, Buffer::TargetHint value);
+
+#if !defined(MAGNUM_TARGET_GLES2) || defined(MAGNUM_BUILD_DEPRECATED)
/** @debugoperatorclassenum{Magnum::Buffer,Magnum::Buffer::Target} */
Debug MAGNUM_EXPORT operator<<(Debug debug, Buffer::Target value);
+#endif
-inline Buffer::Buffer(Buffer&& other) noexcept: _id(other._id), _targetHint(other._targetHint) {
+inline Buffer::Buffer(Buffer&& other) noexcept: _id{other._id}, _targetHint{other._targetHint},
+ #ifdef CORRADE_TARGET_NACL
+ _mappedBuffer{other._mappedBuffer},
+ #endif
+ _created{other._created}
+{
other._id = 0;
+ #ifdef CORRADE_TARGET_NACL
+ other._mappedBuffer = nullptr;
+ #endif
}
inline Buffer& Buffer::operator=(Buffer&& other) noexcept {
std::swap(_id, other._id);
std::swap(_targetHint, other._targetHint);
+ #ifdef CORRADE_TARGET_NACL
+ std::swap(_mappedBuffer, other._mappedBuffer);
+ #endif
+ std::swap(_created, other._created);
return *this;
}
diff --git a/src/Magnum/BufferImage.cpp b/src/Magnum/BufferImage.cpp
index 08c6fb1ae..440a69ce9 100644
--- a/src/Magnum/BufferImage.cpp
+++ b/src/Magnum/BufferImage.cpp
@@ -28,11 +28,11 @@
namespace Magnum {
#ifndef MAGNUM_TARGET_GLES2
-template BufferImage::BufferImage(ColorFormat format, ColorType type, const typename DimensionTraits< Dimensions, Int >::VectorType& size, const void* data, BufferUsage usage): AbstractImage(format, type), _size(size), _buffer(Buffer::Target::PixelPack) {
+template BufferImage::BufferImage(ColorFormat format, ColorType type, const typename DimensionTraits< Dimensions, Int >::VectorType& size, const void* data, BufferUsage usage): AbstractImage(format, type), _size(size), _buffer(Buffer::TargetHint::PixelPack) {
_buffer.setData({data, dataSize(size)}, usage);
}
-template BufferImage::BufferImage(ColorFormat format, ColorType type): AbstractImage(format, type), _buffer(Buffer::Target::PixelPack) {}
+template BufferImage::BufferImage(ColorFormat format, ColorType type): AbstractImage(format, type), _buffer(Buffer::TargetHint::PixelPack) {}
template void BufferImage::setData(ColorFormat format, ColorType type, const typename DimensionTraits::VectorType& size, const void* data, BufferUsage usage) {
_format = format;
diff --git a/src/Magnum/BufferTexture.cpp b/src/Magnum/BufferTexture.cpp
index 84b5ad87b..0c45eb264 100644
--- a/src/Magnum/BufferTexture.cpp
+++ b/src/Magnum/BufferTexture.cpp
@@ -49,7 +49,7 @@ Int BufferTexture::maxSize() {
Int BufferTexture::offsetAlignment() {
if(!Context::current()->isExtensionSupported())
- return 0;
+ return 1;
GLint& value = Context::current()->state().texture->bufferOffsetAlignment;
@@ -75,7 +75,7 @@ void BufferTexture::setBufferImplementationDefault(BufferTextureFormat internalF
glTexBuffer(GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id());
}
-void BufferTexture::setBufferImplementationDSA(BufferTextureFormat internalFormat, Buffer& buffer) {
+void BufferTexture::setBufferImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer) {
glTextureBufferEXT(id(), GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id());
}
@@ -84,7 +84,7 @@ void BufferTexture::setBufferRangeImplementationDefault(BufferTextureFormat inte
glTexBufferRange(GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id(), offset, size);
}
-void BufferTexture::setBufferRangeImplementationDSA(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size) {
+void BufferTexture::setBufferRangeImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size) {
glTextureBufferRangeEXT(id(), GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer.id(), offset, size);
}
diff --git a/src/Magnum/BufferTexture.h b/src/Magnum/BufferTexture.h
index 9954b6f4b..8aa468974 100644
--- a/src/Magnum/BufferTexture.h
+++ b/src/Magnum/BufferTexture.h
@@ -217,7 +217,7 @@ class MAGNUM_EXPORT BufferTexture: public AbstractTexture {
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,texture_buffer_range}
- * (part of OpenGL 4.3) is not available, returns `0`.
+ * (part of OpenGL 4.3) is not available, returns `1`.
* @see @fn_gl{Get} with @def_gl{TEXTURE_BUFFER_OFFSET_ALIGNMENT}
*/
static Int offsetAlignment();
@@ -225,8 +225,11 @@ class MAGNUM_EXPORT BufferTexture: public AbstractTexture {
/**
* @brief Constructor
*
- * Creates new OpenGL texture object.
- * @see @fn_gl{GenTextures} with @def_gl{TEXTURE_BUFFER}
+ * Creates new OpenGL texture object. If @extension{ARB,direct_state_access}
+ * (part of OpenGL 4.5) is not supported, the texture is created on
+ * first use.
+ * @see @fn_gl{CreateTextures} with @def_gl{TEXTURE_BUFFER}, eventually
+ * @fn_gl{GenTextures}
*/
explicit BufferTexture(): AbstractTexture(GL_TEXTURE_BUFFER) {}
@@ -287,10 +290,10 @@ class MAGNUM_EXPORT BufferTexture: public AbstractTexture {
private:
void MAGNUM_LOCAL setBufferImplementationDefault(BufferTextureFormat internalFormat, Buffer& buffer);
- void MAGNUM_LOCAL setBufferImplementationDSA(BufferTextureFormat internalFormat, Buffer& buffer);
+ void MAGNUM_LOCAL setBufferImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer);
void MAGNUM_LOCAL setBufferRangeImplementationDefault(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size);
- void MAGNUM_LOCAL setBufferRangeImplementationDSA(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size);
+ void MAGNUM_LOCAL setBufferRangeImplementationDSAEXT(BufferTextureFormat internalFormat, Buffer& buffer, GLintptr offset, GLsizeiptr size);
};
}
diff --git a/src/Magnum/CMakeLists.txt b/src/Magnum/CMakeLists.txt
index d6db799e4..588bc6d3e 100644
--- a/src/Magnum/CMakeLists.txt
+++ b/src/Magnum/CMakeLists.txt
@@ -31,6 +31,7 @@ set(Magnum_SRCS
AbstractFramebuffer.cpp
AbstractImage.cpp
AbstractObject.cpp
+ AbstractQuery.cpp
AbstractTexture.cpp
AbstractShaderProgram.cpp
Buffer.cpp
@@ -44,7 +45,6 @@ set(Magnum_SRCS
Mesh.cpp
MeshView.cpp
OpenGL.cpp
- Query.cpp
Renderbuffer.cpp
Renderer.cpp
Resource.cpp
@@ -58,6 +58,7 @@ set(Magnum_SRCS
Implementation/DebugState.cpp
Implementation/FramebufferState.cpp
Implementation/MeshState.cpp
+ Implementation/QueryState.cpp
Implementation/RendererState.cpp
Implementation/ShaderProgramState.cpp
Implementation/State.cpp
@@ -83,6 +84,7 @@ set(Magnum_HEADERS
AbstractFramebuffer.h
AbstractImage.h
AbstractObject.h
+ AbstractQuery.h
AbstractResourceLoader.h
AbstractShaderProgram.h
AbstractTexture.h
@@ -103,17 +105,18 @@ set(Magnum_HEADERS
Mesh.h
MeshView.h
OpenGL.h
- Query.h
Renderbuffer.h
RenderbufferFormat.h
Renderer.h
Resource.h
ResourceManager.h
+ SampleQuery.h
Sampler.h
Shader.h
Texture.h
TextureFormat.h
Timeline.h
+ TimeQuery.h
Types.h
Version.h
@@ -126,6 +129,7 @@ set(Magnum_PRIVATE_HEADERS
Implementation/FramebufferState.h
Implementation/maxTextureSize.h
Implementation/MeshState.h
+ Implementation/QueryState.h
Implementation/RendererState.h
Implementation/ShaderProgramState.h
Implementation/ShaderState.h
@@ -135,7 +139,8 @@ set(Magnum_PRIVATE_HEADERS
# Deprecated headers
if(BUILD_DEPRECATED)
set(Magnum_HEADERS ${Magnum_HEADERS}
- DebugMarker.h)
+ DebugMarker.h
+ Query.h)
endif()
# Desktop-only stuff
@@ -155,6 +160,7 @@ if(NOT TARGET_GLES2)
set(Magnum_HEADERS ${Magnum_HEADERS}
BufferImage.h
MultisampleTexture.h
+ PrimitiveQuery.h
TextureArray.h)
set(Magnum_SRCS ${Magnum_SRCS}
BufferImage.cpp
diff --git a/src/Magnum/ColorFormat.h b/src/Magnum/ColorFormat.h
index ecfc6ee6e..f7d2f52a4 100644
--- a/src/Magnum/ColorFormat.h
+++ b/src/Magnum/ColorFormat.h
@@ -331,7 +331,7 @@ enum class ColorType: GLenum {
/**
* Each component half float.
- * @requires_gl30 %Extension @extension{NV,half_float} / @extension{ARB,half_float_pixel}
+ * @requires_gl30 %Extension @extension{ARB,half_float_pixel}
* @requires_gles30 For texture data only, extension
* @es_extension2{OES,texture_half_float,OES_texture_float} in OpenGL
* ES 2.0
diff --git a/src/Magnum/Context.cpp b/src/Magnum/Context.cpp
index dc3c24611..f2906b984 100644
--- a/src/Magnum/Context.cpp
+++ b/src/Magnum/Context.cpp
@@ -62,6 +62,19 @@ const std::vector& Extension::extensions(Version version) {
_extension(GL,AMD,vertex_shader_layer),
_extension(GL,AMD,shader_trinary_minmax),
_extension(GL,ARB,robustness),
+ _extension(GL,ARB,robustness_isolation),
+ _extension(GL,ARB,robustness_application_isolation),
+ _extension(GL,ARB,robustness_share_group_isolation),
+ _extension(GL,ARB,bindless_texture),
+ _extension(GL,ARB,compute_variable_group_size),
+ _extension(GL,ARB,indirect_parameters),
+ _extension(GL,ARB,seamless_cubemap_per_texture),
+ _extension(GL,ARB,shader_draw_parameters),
+ _extension(GL,ARB,shader_group_vote),
+ _extension(GL,ARB,sparse_texture),
+ _extension(GL,ARB,pipeline_statistics_query),
+ _extension(GL,ARB,sparse_buffer),
+ _extension(GL,ARB,transform_feedback_overflow_query),
_extension(GL,ATI,texture_mirror_once),
_extension(GL,EXT,texture_filter_anisotropic),
_extension(GL,EXT,texture_mirror_clamp),
@@ -70,27 +83,28 @@ const std::vector& Extension::extensions(Version version) {
_extension(GL,EXT,shader_integer_mix),
_extension(GL,EXT,debug_label),
_extension(GL,EXT,debug_marker),
- _extension(GL,GREMEDY,string_marker)};
+ _extension(GL,GREMEDY,string_marker),
+ _extension(GL,KHR,texture_compression_astc_ldr),
+ _extension(GL,KHR,texture_compression_astc_hdr)};
static const std::vector extensions300{
- _extension(GL,APPLE,flush_buffer_range),
- _extension(GL,APPLE,vertex_array_object),
_extension(GL,ARB,map_buffer_range),
_extension(GL,ARB,color_buffer_float),
_extension(GL,ARB,half_float_pixel),
_extension(GL,ARB,texture_float),
_extension(GL,ARB,depth_buffer_float),
_extension(GL,ARB,texture_rg),
+ _extension(GL,ARB,vertex_array_object),
_extension(GL,ARB,framebuffer_object),
+ _extension(GL,ARB,framebuffer_sRGB),
+ _extension(GL,ARB,half_float_vertex),
_extension(GL,EXT,gpu_shader4),
_extension(GL,EXT,packed_float),
_extension(GL,EXT,texture_array),
_extension(GL,EXT,texture_compression_rgtc),
_extension(GL,EXT,texture_shared_exponent),
- _extension(GL,EXT,framebuffer_sRGB),
_extension(GL,EXT,draw_buffers2),
_extension(GL,EXT,texture_integer),
_extension(GL,EXT,transform_feedback),
- _extension(GL,NV,half_float),
_extension(GL,NV,depth_buffer_float),
_extension(GL,NV,conditional_render)};
static const std::vector extensions310{
@@ -189,6 +203,18 @@ const std::vector& Extension::extensions(Version version) {
_extension(GL,ARB,texture_mirror_clamp_to_edge),
_extension(GL,ARB,texture_stencil8),
_extension(GL,ARB,vertex_type_10f_11f_11f_rev)};
+ static const std::vector extensions450{
+ _extension(GL,ARB,ES3_1_compatibility),
+ _extension(GL,ARB,clip_control),
+ _extension(GL,ARB,conditional_render_inverted),
+ _extension(GL,ARB,cull_distance),
+ _extension(GL,ARB,derivative_control),
+ _extension(GL,ARB,direct_state_access),
+ _extension(GL,ARB,get_texture_sub_image),
+ _extension(GL,ARB,shader_texture_image_samples),
+ _extension(GL,ARB,texture_barrier),
+ _extension(GL,KHR,context_flush_control),
+ _extension(GL,KHR,robustness)};
#undef _extension
#else
static const std::vector extensions{
@@ -206,7 +232,12 @@ const std::vector& Extension::extensions(Version version) {
_extension(GL,EXT,sRGB),
_extension(GL,EXT,multisampled_render_to_texture),
_extension(GL,EXT,robustness),
+ _extension(GL,KHR,texture_compression_astc_ldr),
+ _extension(GL,KHR,texture_compression_astc_hdr),
_extension(GL,KHR,debug),
+ _extension(GL,KHR,robustness),
+ _extension(GL,KHR,robust_buffer_access_behavior),
+ _extension(GL,KHR,context_flush_control),
_extension(GL,NV,read_buffer_front),
_extension(GL,NV,read_depth),
_extension(GL,NV,read_stencil),
@@ -278,6 +309,7 @@ const std::vector& Extension::extensions(Version version) {
/* case Version::GLES300: */
case Version::GL430: return extensions430;
case Version::GL440: return extensions440;
+ case Version::GL450: return extensions450;
#else
case Version::GLES200: return empty;
case Version::GLES300:
@@ -394,6 +426,7 @@ Context::Context(void functionLoader()) {
Version::GL420,
Version::GL430,
Version::GL440,
+ Version::GL450,
#else
Version::GLES200,
Version::GLES300,
@@ -453,7 +486,10 @@ Context::Context(void functionLoader()) {
CORRADE_ASSERT(!_current, "Context: Another context currently active", );
_current = this;
- /* Initialize state tracker */
+ /* Print some info and initialize state tracker (which also prints some
+ more info) */
+ Debug() << "Renderer:" << rendererString() << "by" << vendorString();
+ Debug() << "OpenGL version:" << versionString();
_state = new Implementation::State(*this);
/* Initialize functionality based on current OpenGL version and extensions */
diff --git a/src/Magnum/CubeMapTexture.h b/src/Magnum/CubeMapTexture.h
index 93ba1ffc7..5dc73c20b 100644
--- a/src/Magnum/CubeMapTexture.h
+++ b/src/Magnum/CubeMapTexture.h
@@ -103,8 +103,11 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture {
/**
* @brief Constructor
*
- * Creates new OpenGL texture object.
- * @see @fn_gl{GenTextures} with @def_gl{TEXTURE_CUBE_MAP}
+ * Creates new OpenGL texture object. If @extension{ARB,direct_state_access}
+ * (part of OpenGL 4.5) is not supported, the texture is created on
+ * first use.
+ * @see @fn_gl{CreateTextures} with @def_gl{TEXTURE_CUBE_MAP},
+ * eventually @fn_gl{GenTextures}
*/
explicit CubeMapTexture(): AbstractTexture(GL_TEXTURE_CUBE_MAP) {}
diff --git a/src/Magnum/CubeMapTextureArray.h b/src/Magnum/CubeMapTextureArray.h
index 58c4abf3e..486a03928 100644
--- a/src/Magnum/CubeMapTextureArray.h
+++ b/src/Magnum/CubeMapTextureArray.h
@@ -87,8 +87,11 @@ class CubeMapTextureArray: public AbstractTexture {
/**
* @brief Constructor
*
- * Creates new OpenGL texture object.
- * @see @fn_gl{GenTextures} with @def_gl{TEXTURE_CUBE_MAP_ARRAY}
+ * Creates new OpenGL texture object. If @extension{ARB,direct_state_access}
+ * (part of OpenGL 4.5) is not supported, the texture is created on
+ * first use.
+ * @see @fn_gl{CreateTextures} with @def_gl{TEXTURE_CUBE_MAP_ARRAY},
+ * eventually @fn_gl{GenTextures}
*/
explicit CubeMapTextureArray(): AbstractTexture(GL_TEXTURE_CUBE_MAP_ARRAY) {}
diff --git a/src/Magnum/DebugTools/ForceRenderer.cpp b/src/Magnum/DebugTools/ForceRenderer.cpp
index 620d1ba12..5f5349ea8 100644
--- a/src/Magnum/DebugTools/ForceRenderer.cpp
+++ b/src/Magnum/DebugTools/ForceRenderer.cpp
@@ -77,8 +77,8 @@ template ForceRenderer::ForceRenderer(SceneG
if(mesh) return;
/* Create the mesh */
- Buffer* vertexBuffer = new Buffer(Buffer::Target::Array);
- Buffer* indexBuffer = new Buffer(Buffer::Target::ElementArray);
+ Buffer* vertexBuffer = new Buffer{Buffer::TargetHint::Array};
+ Buffer* indexBuffer = new Buffer{Buffer::TargetHint::ElementArray};
vertexBuffer->setData(positions, BufferUsage::StaticDraw);
ResourceManager::instance().set(this->vertexBuffer.key(), vertexBuffer, ResourceDataState::Final, ResourcePolicy::Manual);
diff --git a/src/Magnum/DebugTools/Implementation/AbstractShapeRenderer.cpp b/src/Magnum/DebugTools/Implementation/AbstractShapeRenderer.cpp
index 0258e6609..ce3eb0316 100644
--- a/src/Magnum/DebugTools/Implementation/AbstractShapeRenderer.cpp
+++ b/src/Magnum/DebugTools/Implementation/AbstractShapeRenderer.cpp
@@ -46,7 +46,7 @@ template void create(typename MeshData::Type
template<> void create<2>(Trade::MeshData2D& data, Resource& meshResource, Resource& vertexBufferResource, Resource& indexBufferResource) {
/* Vertex buffer */
- Buffer* buffer = new Buffer(Buffer::Target::Array);
+ Buffer* buffer = new Buffer{Buffer::TargetHint::Array};
buffer->setData(data.positions(0), BufferUsage::StaticDraw);
ResourceManager::instance().set(vertexBufferResource.key(), buffer, ResourceDataState::Final, ResourcePolicy::Manual);
@@ -65,7 +65,7 @@ template<> void create<2>(Trade::MeshData2D& data, Resource& meshResource,
UnsignedInt indexStart, indexEnd;
std::tie(indexData, indexType, indexStart, indexEnd) = MeshTools::compressIndices(data.indices());
- Buffer* indexBuffer = new Buffer(Buffer::Target::ElementArray);
+ Buffer* indexBuffer = new Buffer{Buffer::TargetHint::ElementArray};
indexBuffer->setData(indexData, BufferUsage::StaticDraw);
mesh->setCount(data.indices().size())
.setIndexBuffer(*indexBuffer, 0, indexType, indexStart, indexEnd);
@@ -78,7 +78,7 @@ template<> void create<2>(Trade::MeshData2D& data, Resource& meshResource,
template<> void create<3>(Trade::MeshData3D& data, Resource& meshResource, Resource& vertexBufferResource, Resource& indexBufferResource) {
/* Vertex buffer */
- Buffer* vertexBuffer = new Buffer(Buffer::Target::Array);
+ Buffer* vertexBuffer = new Buffer{Buffer::TargetHint::Array};
vertexBuffer->setData(data.positions(0), BufferUsage::StaticDraw);
ResourceManager::instance().set(vertexBufferResource.key(), vertexBuffer, ResourceDataState::Final, ResourcePolicy::Manual);
@@ -97,7 +97,7 @@ template<> void create<3>(Trade::MeshData3D& data, Resource& meshResource,
UnsignedInt indexStart, indexEnd;
std::tie(indexData, indexType, indexStart, indexEnd) = MeshTools::compressIndices(data.indices());
- Buffer* indexBuffer = new Buffer(Buffer::Target::ElementArray);
+ Buffer* indexBuffer = new Buffer{Buffer::TargetHint::ElementArray};
indexBuffer->setData(indexData, BufferUsage::StaticDraw);
mesh->setCount(data.indices().size())
.setIndexBuffer(*indexBuffer, 0, indexType, indexStart, indexEnd);
diff --git a/src/Magnum/DebugTools/ObjectRenderer.cpp b/src/Magnum/DebugTools/ObjectRenderer.cpp
index 3bbd3c5c4..e3bc05146 100644
--- a/src/Magnum/DebugTools/ObjectRenderer.cpp
+++ b/src/Magnum/DebugTools/ObjectRenderer.cpp
@@ -156,8 +156,8 @@ template ObjectRenderer::ObjectRenderer(Scen
if(mesh) return;
/* Create the mesh */
- Buffer* vertexBuffer = new Buffer(Buffer::Target::Array);
- Buffer* indexBuffer = new Buffer(Buffer::Target::ElementArray);
+ Buffer* vertexBuffer = new Buffer{Buffer::TargetHint::Array};
+ Buffer* indexBuffer = new Buffer{Buffer::TargetHint::ElementArray};
Mesh* mesh = new Mesh;
vertexBuffer->setData(MeshTools::interleave(Renderer::positions, Renderer::colors), BufferUsage::StaticDraw);
diff --git a/src/Magnum/DefaultFramebuffer.cpp b/src/Magnum/DefaultFramebuffer.cpp
index fefaa37b1..e4c86c319 100644
--- a/src/Magnum/DefaultFramebuffer.cpp
+++ b/src/Magnum/DefaultFramebuffer.cpp
@@ -36,7 +36,10 @@ namespace Magnum {
DefaultFramebuffer defaultFramebuffer;
-DefaultFramebuffer::DefaultFramebuffer() { _id = 0; }
+DefaultFramebuffer::DefaultFramebuffer() {
+ _id = 0;
+ _created = true;
+}
DefaultFramebuffer::Status DefaultFramebuffer::checkStatus(const FramebufferTarget target) {
return Status((this->*Context::current()->state().framebuffer->checkStatusImplementation)(target));
diff --git a/src/Magnum/Extensions.h b/src/Magnum/Extensions.h
index 55f02dfcc..7e8312138 100644
--- a/src/Magnum/Extensions.h
+++ b/src/Magnum/Extensions.h
@@ -73,9 +73,6 @@ namespace GL {
namespace AMD {
_extension(GL,AMD,vertex_shader_layer, GL210, None) // #417
_extension(GL,AMD,shader_trinary_minmax, GL210, None) // #428
- } namespace APPLE {
- _extension(GL,APPLE,flush_buffer_range, GL210, GL300) // #321
- _extension(GL,APPLE,vertex_array_object, GL210, GL300) // #273
} namespace ARB {
_extension(GL,ARB,texture_rectangle, GL210, GL310) // #38
_extension(GL,ARB,color_buffer_float, GL210, GL300) // #39
@@ -84,11 +81,14 @@ namespace GL {
_extension(GL,ARB,depth_buffer_float, GL210, GL300) // #43
_extension(GL,ARB,draw_instanced, GL210, GL310) // #44
_extension(GL,ARB,framebuffer_object, GL210, GL300) // #45
+ _extension(GL,ARB,framebuffer_sRGB, GL210, GL300) // #46
_extension(GL,ARB,geometry_shader4, GL210, GL320) // #47
+ _extension(GL,ARB,half_float_vertex, GL210, GL300) // #48
_extension(GL,ARB,instanced_arrays, GL210, GL330) // #49
_extension(GL,ARB,map_buffer_range, GL210, GL300) // #50
_extension(GL,ARB,texture_buffer_object, GL210, GL310) // #51
_extension(GL,ARB,texture_rg, GL210, GL300) // #53
+ _extension(GL,ARB,vertex_array_object, GL210, GL300) // #54
_extension(GL,ARB,uniform_buffer_object, GL210, GL310) // #57
_extension(GL,ARB,copy_buffer, /*?*/ GL210, GL310) // #59
_extension(GL,ARB,depth_clamp, /*?*/ GL210, GL320) // #61
@@ -146,6 +146,9 @@ namespace GL {
_extension(GL,ARB,copy_image, GL210, GL430) // #123
_extension(GL,ARB,texture_view, GL210, GL430) // #124
_extension(GL,ARB,vertex_attrib_binding, GL210, GL430) // #125
+ _extension(GL,ARB,robustness_isolation, GL210, None) // #126
+ _extension(GL,ARB,robustness_application_isolation, GL210, None) // #126
+ _extension(GL,ARB,robustness_share_group_isolation, GL210, None) // #126
_extension(GL,ARB,ES3_compatibility, GL330, GL430) // #127
_extension(GL,ARB,explicit_uniform_location, GL210, GL430) // #128
_extension(GL,ARB,fragment_layer_viewport, GL300, GL430) // #129
@@ -169,6 +172,25 @@ namespace GL {
_extension(GL,ARB,texture_mirror_clamp_to_edge, GL210, GL440) // #149
_extension(GL,ARB,texture_stencil8, GL210, GL440) // #150
_extension(GL,ARB,vertex_type_10f_11f_11f_rev, GL300, GL440) // #151
+ _extension(GL,ARB,bindless_texture, GL400, None) // #152
+ _extension(GL,ARB,compute_variable_group_size, GL420, None) // #153
+ _extension(GL,ARB,indirect_parameters, GL420, None) // #154
+ _extension(GL,ARB,seamless_cubemap_per_texture, GL320, None) // #155
+ _extension(GL,ARB,shader_draw_parameters, GL310, None) // #156
+ _extension(GL,ARB,shader_group_vote, GL420, None) // #157
+ _extension(GL,ARB,sparse_texture, GL210, None) // #158
+ _extension(GL,ARB,ES3_1_compatibility, GL440, GL450) // #159
+ _extension(GL,ARB,clip_control, GL210, GL450) // #160
+ _extension(GL,ARB,conditional_render_inverted, GL300, GL450) // #161
+ _extension(GL,ARB,cull_distance, GL300, GL450) // #162
+ _extension(GL,ARB,derivative_control, GL400, GL450) // #163
+ _extension(GL,ARB,direct_state_access, GL210, GL450) // #164
+ _extension(GL,ARB,get_texture_sub_image, GL210, GL450) // #165
+ _extension(GL,ARB,shader_texture_image_samples, GL430, GL450) // #166
+ _extension(GL,ARB,texture_barrier, GL210, GL450) // #167
+ _extension(GL,ARB,pipeline_statistics_query, GL300, None) // #171
+ _extension(GL,ARB,sparse_buffer, GL210, None) // #172
+ _extension(GL,ARB,transform_feedback_overflow_query, GL300, None) // #173
} namespace ATI {
_extension(GL,ATI,texture_mirror_once, GL210, None) // #221
} namespace EXT {
@@ -181,7 +203,6 @@ namespace GL {
_extension(GL,EXT,texture_array, GL210, GL300) // #329
_extension(GL,EXT,texture_compression_rgtc, GL210, GL300) // #332
_extension(GL,EXT,texture_shared_exponent, GL210, GL300) // #333
- _extension(GL,EXT,framebuffer_sRGB, GL210, GL300) // #337
_extension(GL,EXT,draw_buffers2, GL210, GL300) // #340
_extension(GL,EXT,texture_integer, GL210, GL300) // #343
_extension(GL,EXT,transform_feedback, GL210, GL300) // #352
@@ -193,18 +214,19 @@ namespace GL {
_extension(GL,EXT,debug_marker, GL210, None) // #440
} namespace GREMEDY {
_extension(GL,GREMEDY,string_marker, GL210, None) // #311
- } namespace INTEL {
- /* INTEL_map_texture not supported */ // #429
} namespace KHR {
+ _extension(GL,KHR,texture_compression_astc_ldr, GL210, None) // #118
+ _extension(GL,KHR,texture_compression_astc_hdr, GL210, None) // #118
_extension(GL,KHR,debug, GL210, GL430) // #119
+ _extension(GL,KHR,context_flush_control, GL210, GL450) // #168
+ _extension(GL,KHR,robustness, GL320, GL450) // #170
} namespace NV {
- _extension(GL,NV,half_float, GL210, GL300) // #283
_extension(GL,NV,primitive_restart, GL210, GL310) // #285
_extension(GL,NV,depth_buffer_float, GL210, GL300) // #334
_extension(GL,NV,conditional_render, GL210, GL300) // #346
/* NV_draw_texture not supported */ // #430
}
- /* IMPORTANT: if this line is > 226 (66 + size), don't forget to update array size in Context.h */
+ /* IMPORTANT: if this line is > 233 (73 + size), don't forget to update array size in Context.h */
#else
#line 1
namespace ANGLE {
@@ -270,7 +292,12 @@ namespace GL {
_extension(GL,EXT,shader_integer_mix, GLES300, None) // #161
#endif
} namespace KHR {
+ _extension(GL,KHR,texture_compression_astc_ldr, GLES200, None) // #117
+ _extension(GL,KHR,texture_compression_astc_hdr, GLES200, None) // #117
_extension(GL,KHR,debug, GLES200, None) // #118
+ _extension(GL,KHR,robustness, GLES200, None) // #170
+ _extension(GL,KHR,robust_buffer_access_behavior, GLES200, None) // #189
+ _extension(GL,KHR,context_flush_control, GLES200, None) // #191
} namespace NV {
#ifdef MAGNUM_TARGET_GLES2
_extension(GL,NV,draw_buffers, GLES200, GLES300) // #91
diff --git a/src/Magnum/Framebuffer.cpp b/src/Magnum/Framebuffer.cpp
index d09a23e14..5aec61e0e 100644
--- a/src/Magnum/Framebuffer.cpp
+++ b/src/Magnum/Framebuffer.cpp
@@ -81,11 +81,22 @@ Int Framebuffer::maxColorAttachments() {
Framebuffer::Framebuffer(const Range2Di& viewport) {
_viewport = viewport;
+ (this->*Context::current()->state().framebuffer->createImplementation)();
+ CORRADE_INTERNAL_ASSERT(_id != Implementation::State::DisengagedBinding);
+}
+void Framebuffer::createImplementationDefault() {
glGenFramebuffers(1, &_id);
- CORRADE_INTERNAL_ASSERT(_id != Implementation::State::DisengagedBinding);
+ _created = false;
}
+#ifndef MAGNUM_TARGET_GLES
+void Framebuffer::createImplementationDSA() {
+ glCreateFramebuffers(1, &_id);
+ _created = true;
+}
+#endif
+
Framebuffer::~Framebuffer() {
/* Moved out, nothing to do */
if(!_id) return;
@@ -108,11 +119,13 @@ Framebuffer::~Framebuffer() {
glDeleteFramebuffers(1, &_id);
}
-std::string Framebuffer::label() const {
+std::string Framebuffer::label() {
+ createIfNotAlready();
return Context::current()->state().debug->getLabelImplementation(GL_FRAMEBUFFER, _id);
}
Framebuffer& Framebuffer::setLabelInternal(const Containers::ArrayReference label) {
+ createIfNotAlready();
Context::current()->state().debug->labelImplementation(GL_FRAMEBUFFER, _id, label);
return *this;
}
@@ -254,7 +267,8 @@ void Framebuffer::renderbufferImplementationDefault(BufferAttachment attachment,
}
#ifndef MAGNUM_TARGET_GLES
-void Framebuffer::renderbufferImplementationDSA(BufferAttachment attachment, Renderbuffer& renderbuffer) {
+void Framebuffer::renderbufferImplementationDSAEXT(BufferAttachment attachment, Renderbuffer& renderbuffer) {
+ _created = true;
glNamedFramebufferRenderbufferEXT(_id, GLenum(attachment), GL_RENDERBUFFER, renderbuffer.id());
}
@@ -262,7 +276,8 @@ void Framebuffer::texture1DImplementationDefault(BufferAttachment attachment, GL
glFramebufferTexture1D(GLenum(bindInternal()), GLenum(attachment), GL_TEXTURE_1D, textureId, mipLevel);
}
-void Framebuffer::texture1DImplementationDSA(BufferAttachment attachment, GLuint textureId, GLint mipLevel) {
+void Framebuffer::texture1DImplementationDSAEXT(BufferAttachment attachment, GLuint textureId, GLint mipLevel) {
+ _created = true;
glNamedFramebufferTexture1DEXT(_id, GLenum(attachment), GL_TEXTURE_1D, textureId, mipLevel);
}
#endif
@@ -272,7 +287,8 @@ void Framebuffer::texture2DImplementationDefault(BufferAttachment attachment, GL
}
#ifndef MAGNUM_TARGET_GLES
-void Framebuffer::texture2DImplementationDSA(BufferAttachment attachment, GLenum textureTarget, GLuint textureId, GLint mipLevel) {
+void Framebuffer::texture2DImplementationDSAEXT(BufferAttachment attachment, GLenum textureTarget, GLuint textureId, GLint mipLevel) {
+ _created = true;
glNamedFramebufferTexture2DEXT(_id, GLenum(attachment), textureTarget, textureId, mipLevel);
}
#endif
@@ -292,7 +308,8 @@ void Framebuffer::textureLayerImplementationDefault(BufferAttachment attachment,
}
#ifndef MAGNUM_TARGET_GLES
-void Framebuffer::textureLayerImplementationDSA(BufferAttachment attachment, GLuint textureId, GLint mipLevel, GLint layer) {
+void Framebuffer::textureLayerImplementationDSAEXT(BufferAttachment attachment, GLuint textureId, GLint mipLevel, GLint layer) {
+ _created = true;
glNamedFramebufferTextureLayerEXT(_id, GLenum(attachment), textureId, mipLevel, layer);
}
#endif
diff --git a/src/Magnum/Framebuffer.h b/src/Magnum/Framebuffer.h
index 0759f611e..ebc6310e9 100644
--- a/src/Magnum/Framebuffer.h
+++ b/src/Magnum/Framebuffer.h
@@ -318,8 +318,11 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
/**
* @brief Constructor
*
- * Generates new OpenGL framebuffer.
- * @see @ref setViewport(), @fn_gl{GenFramebuffers}
+ * Generates new OpenGL framebuffer object. If @extension{ARB,direct_state_access}
+ * (part of OpenGL 4.5) is not supported, the framebuffer is created on
+ * first use.
+ * @see @ref setViewport(), @fn_gl{CreateFramebuffers}, eventually
+ * @fn_gl{GenFramebuffers}
*/
explicit Framebuffer(const Range2Di& viewport);
@@ -332,7 +335,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
/**
* @brief Destructor
*
- * Deletes associated OpenGL framebuffer.
+ * Deletes associated OpenGL framebuffer object.
* @see @fn_gl{DeleteFramebuffers}
*/
~Framebuffer();
@@ -357,7 +360,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* @fn_gl_extension2{GetObjectLabel,EXT,debug_label} with
* @def_gl{FRAMEBUFFER}
*/
- std::string label() const;
+ std::string label();
/**
* @brief Set framebuffer label
@@ -651,26 +654,31 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
#endif
private:
+ void MAGNUM_LOCAL createImplementationDefault();
+ #ifndef MAGNUM_TARGET_GLES
+ void MAGNUM_LOCAL createImplementationDSA();
+ #endif
+
Framebuffer& setLabelInternal(Containers::ArrayReference label);
void MAGNUM_LOCAL renderbufferImplementationDefault(BufferAttachment attachment, Renderbuffer& renderbuffer);
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL renderbufferImplementationDSA(BufferAttachment attachment, Renderbuffer& renderbuffer);
+ void MAGNUM_LOCAL renderbufferImplementationDSAEXT(BufferAttachment attachment, Renderbuffer& renderbuffer);
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL texture1DImplementationDefault(BufferAttachment attachment, GLuint textureId, GLint level);
- void MAGNUM_LOCAL texture1DImplementationDSA(BufferAttachment attachment, GLuint textureId, GLint level);
+ void MAGNUM_LOCAL texture1DImplementationDSAEXT(BufferAttachment attachment, GLuint textureId, GLint level);
#endif
void MAGNUM_LOCAL texture2DImplementationDefault(BufferAttachment attachment, GLenum textureTarget, GLuint textureId, GLint level);
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL texture2DImplementationDSA(BufferAttachment attachment, GLenum textureTarget, GLuint textureId, GLint level);
+ void MAGNUM_LOCAL texture2DImplementationDSAEXT(BufferAttachment attachment, GLenum textureTarget, GLuint textureId, GLint level);
#endif
void MAGNUM_LOCAL textureLayerImplementationDefault(BufferAttachment attachment, GLuint textureId, GLint level, GLint layer);
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL textureLayerImplementationDSA(BufferAttachment attachment, GLuint textureId, GLint level, GLint layer);
+ void MAGNUM_LOCAL textureLayerImplementationDSAEXT(BufferAttachment attachment, GLuint textureId, GLint level, GLint layer);
#endif
};
@@ -680,6 +688,7 @@ Debug MAGNUM_EXPORT operator<<(Debug debug, Framebuffer::Status value);
inline Framebuffer::Framebuffer(Framebuffer&& other) noexcept {
_id = other._id;
_viewport = other._viewport;
+ _created = other._created;
other._id = 0;
other._viewport = {};
}
@@ -687,6 +696,7 @@ inline Framebuffer::Framebuffer(Framebuffer&& other) noexcept {
inline Framebuffer& Framebuffer::operator=(Framebuffer&& other) noexcept {
std::swap(_id, other._id);
std::swap(_viewport, other._viewport);
+ std::swap(_created, other._created);
return *this;
}
diff --git a/src/Magnum/Implementation/BufferState.cpp b/src/Magnum/Implementation/BufferState.cpp
index dda1acb73..e8c2de2a0 100644
--- a/src/Magnum/Implementation/BufferState.cpp
+++ b/src/Magnum/Implementation/BufferState.cpp
@@ -34,43 +34,43 @@
namespace Magnum { namespace Implementation {
-const Buffer::Target BufferState::targetForIndex[] = {
- Buffer::Target::Array,
- Buffer::Target::ElementArray,
+const Buffer::TargetHint BufferState::targetForIndex[] = {
+ Buffer::TargetHint::Array,
+ Buffer::TargetHint::ElementArray,
#ifndef MAGNUM_TARGET_GLES2
- Buffer::Target::CopyRead,
- Buffer::Target::CopyWrite,
- Buffer::Target::PixelPack,
- Buffer::Target::PixelUnpack,
- Buffer::Target::TransformFeedback,
- Buffer::Target::Uniform,
- Buffer::Target::AtomicCounter,
- Buffer::Target::DispatchIndirect,
- Buffer::Target::DrawIndirect,
- Buffer::Target::ShaderStorage,
+ Buffer::TargetHint::CopyRead,
+ Buffer::TargetHint::CopyWrite,
+ Buffer::TargetHint::PixelPack,
+ Buffer::TargetHint::PixelUnpack,
+ Buffer::TargetHint::TransformFeedback,
+ Buffer::TargetHint::Uniform,
+ Buffer::TargetHint::AtomicCounter,
+ Buffer::TargetHint::DispatchIndirect,
+ Buffer::TargetHint::DrawIndirect,
+ Buffer::TargetHint::ShaderStorage,
#ifndef MAGNUM_TARGET_GLES
- Buffer::Target::Texture
+ Buffer::TargetHint::Texture
#endif
#endif
};
-std::size_t BufferState::indexForTarget(Buffer::Target target) {
+std::size_t BufferState::indexForTarget(Buffer::TargetHint target) {
switch(target) {
- case Buffer::Target::Array: return 1;
- case Buffer::Target::ElementArray: return 2;
+ case Buffer::TargetHint::Array: return 1;
+ case Buffer::TargetHint::ElementArray: return 2;
#ifndef MAGNUM_TARGET_GLES2
- case Buffer::Target::CopyRead: return 3;
- case Buffer::Target::CopyWrite: return 4;
- case Buffer::Target::PixelPack: return 5;
- case Buffer::Target::PixelUnpack: return 6;
- case Buffer::Target::TransformFeedback: return 7;
- case Buffer::Target::Uniform: return 8;
- case Buffer::Target::AtomicCounter: return 9;
- case Buffer::Target::DispatchIndirect: return 10;
- case Buffer::Target::DrawIndirect: return 11;
- case Buffer::Target::ShaderStorage: return 12;
+ case Buffer::TargetHint::CopyRead: return 3;
+ case Buffer::TargetHint::CopyWrite: return 4;
+ case Buffer::TargetHint::PixelPack: return 5;
+ case Buffer::TargetHint::PixelUnpack: return 6;
+ case Buffer::TargetHint::TransformFeedback: return 7;
+ case Buffer::TargetHint::Uniform: return 8;
+ case Buffer::TargetHint::AtomicCounter: return 9;
+ case Buffer::TargetHint::DispatchIndirect: return 10;
+ case Buffer::TargetHint::DrawIndirect: return 11;
+ case Buffer::TargetHint::ShaderStorage: return 12;
#ifndef MAGNUM_TARGET_GLES
- case Buffer::Target::Texture: return 13;
+ case Buffer::TargetHint::Texture: return 13;
#endif
#endif
}
@@ -83,22 +83,34 @@ BufferState::BufferState(Context& context, std::vector& extensions)
#ifndef MAGNUM_TARGET_GLES
, minMapAlignment(0)
#endif
- , maxAtomicCounterBindings(0), maxShaderStorageBindings(0), shaderStorageOffsetAlignment(0), maxUniformBindings(0)
+ , maxAtomicCounterBindings{0}, maxShaderStorageBindings{0}, shaderStorageOffsetAlignment{0}, uniformOffsetAlignment{0}, maxUniformBindings{0}
#endif
{
+ /* Create implementation */
+ #ifndef MAGNUM_TARGET_GLES
+ if(context.isExtensionSupported()) {
+ extensions.push_back(Extensions::GL::ARB::direct_state_access::string());
+ createImplementation = &Buffer::createImplementationDSA;
+
+ } else
+ #endif
+ {
+ createImplementation = &Buffer::createImplementationDefault;
+ }
+
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported()) {
extensions.push_back(Extensions::GL::EXT::direct_state_access::string());
- copyImplementation = &Buffer::copyImplementationDSA;
- getParameterImplementation = &Buffer::getParameterImplementationDSA;
- getSubDataImplementation = &Buffer::getSubDataImplementationDSA;
- dataImplementation = &Buffer::dataImplementationDSA;
- subDataImplementation = &Buffer::subDataImplementationDSA;
- mapImplementation = &Buffer::mapImplementationDSA;
- mapRangeImplementation = &Buffer::mapRangeImplementationDSA;
- flushMappedRangeImplementation = &Buffer::flushMappedRangeImplementationDSA;
- unmapImplementation = &Buffer::unmapImplementationDSA;
+ copyImplementation = &Buffer::copyImplementationDSAEXT;
+ getParameterImplementation = &Buffer::getParameterImplementationDSAEXT;
+ getSubDataImplementation = &Buffer::getSubDataImplementationDSAEXT;
+ dataImplementation = &Buffer::dataImplementationDSAEXT;
+ subDataImplementation = &Buffer::subDataImplementationDSAEXT;
+ mapImplementation = &Buffer::mapImplementationDSAEXT;
+ mapRangeImplementation = &Buffer::mapRangeImplementationDSAEXT;
+ flushMappedRangeImplementation = &Buffer::flushMappedRangeImplementationDSAEXT;
+ unmapImplementation = &Buffer::unmapImplementationDSAEXT;
} else
#endif
{
@@ -130,6 +142,21 @@ BufferState::BufferState(Context& context, std::vector& extensions)
invalidateSubImplementation = &Buffer::invalidateSubImplementationNoOp;
}
+ #ifndef MAGNUM_TARGET_GLES2
+ #ifndef MAGNUM_TARGET_GLES
+ if(context.isExtensionSupported()) {
+ extensions.push_back(Extensions::GL::ARB::multi_bind::string());
+
+ bindBasesImplementation = &Buffer::bindImplementationMulti;
+ bindRangesImplementation = &Buffer::bindImplementationMulti;
+ } else
+ #endif
+ {
+ bindBasesImplementation = &Buffer::bindImplementationFallback;
+ bindRangesImplementation = &Buffer::bindImplementationFallback;
+ }
+ #endif
+
#ifdef MAGNUM_TARGET_GLES
static_cast(context);
static_cast(extensions);
diff --git a/src/Magnum/Implementation/BufferState.h b/src/Magnum/Implementation/BufferState.h
index 48ccba415..29eaabec0 100644
--- a/src/Magnum/Implementation/BufferState.h
+++ b/src/Magnum/Implementation/BufferState.h
@@ -39,16 +39,19 @@ struct BufferState {
#endif
/* Target <-> index mapping */
- static std::size_t indexForTarget(Buffer::Target target);
- static const Buffer::Target targetForIndex[TargetCount-1];
+ static std::size_t indexForTarget(Buffer::TargetHint target);
+ static const Buffer::TargetHint targetForIndex[TargetCount-1];
explicit BufferState(Context& context, std::vector& extensions);
void reset();
#ifndef MAGNUM_TARGET_GLES2
+ void(*bindBasesImplementation)(Buffer::Target, UnsignedInt, Containers::ArrayReference);
+ void(*bindRangesImplementation)(Buffer::Target, UnsignedInt, Containers::ArrayReference>);
void(*copyImplementation)(Buffer&, Buffer&, GLintptr, GLintptr, GLsizeiptr);
#endif
+ void(Buffer::*createImplementation)();
void(Buffer::*getParameterImplementation)(GLenum, GLint*);
#ifndef MAGNUM_TARGET_GLES2
void(Buffer::*getSubDataImplementation)(GLintptr, GLsizeiptr, GLvoid*);
@@ -74,6 +77,7 @@ struct BufferState {
maxAtomicCounterBindings,
maxShaderStorageBindings,
shaderStorageOffsetAlignment,
+ uniformOffsetAlignment,
maxUniformBindings;
#endif
};
diff --git a/src/Magnum/Implementation/FramebufferState.cpp b/src/Magnum/Implementation/FramebufferState.cpp
index 0d49ab50a..f7fe3540b 100644
--- a/src/Magnum/Implementation/FramebufferState.cpp
+++ b/src/Magnum/Implementation/FramebufferState.cpp
@@ -38,22 +38,36 @@ FramebufferState::FramebufferState(Context& context, std::vector& e
, maxDualSourceDrawBuffers(0)
#endif
{
+ /* Create implementation */
+ #ifndef MAGNUM_TARGET_GLES
+ if(context.isExtensionSupported()) {
+ extensions.push_back(Extensions::GL::ARB::direct_state_access::string());
+ createImplementation = &Framebuffer::createImplementationDSA;
+ createRenderbufferImplementation = &Renderbuffer::createImplementationDSA;
+
+ } else
+ #endif
+ {
+ createImplementation = &Framebuffer::createImplementationDefault;
+ createRenderbufferImplementation = &Renderbuffer::createImplementationDefault;
+ }
+
/* DSA/non-DSA implementation */
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported()) {
extensions.push_back(Extensions::GL::EXT::direct_state_access::string());
- checkStatusImplementation = &AbstractFramebuffer::checkStatusImplementationDSA;
- drawBuffersImplementation = &AbstractFramebuffer::drawBuffersImplementationDSA;
- drawBufferImplementation = &AbstractFramebuffer::drawBufferImplementationDSA;
- readBufferImplementation = &AbstractFramebuffer::readBufferImplementationDSA;
+ checkStatusImplementation = &AbstractFramebuffer::checkStatusImplementationDSAEXT;
+ drawBuffersImplementation = &AbstractFramebuffer::drawBuffersImplementationDSAEXT;
+ drawBufferImplementation = &AbstractFramebuffer::drawBufferImplementationDSAEXT;
+ readBufferImplementation = &AbstractFramebuffer::readBufferImplementationDSAEXT;
- renderbufferImplementation = &Framebuffer::renderbufferImplementationDSA;
- texture1DImplementation = &Framebuffer::texture1DImplementationDSA;
- texture2DImplementation = &Framebuffer::texture2DImplementationDSA;
- textureLayerImplementation = &Framebuffer::textureLayerImplementationDSA;
+ renderbufferImplementation = &Framebuffer::renderbufferImplementationDSAEXT;
+ texture1DImplementation = &Framebuffer::texture1DImplementationDSAEXT;
+ texture2DImplementation = &Framebuffer::texture2DImplementationDSAEXT;
+ textureLayerImplementation = &Framebuffer::textureLayerImplementationDSAEXT;
- renderbufferStorageImplementation = &Renderbuffer::storageImplementationDSA;
+ renderbufferStorageImplementation = &Renderbuffer::storageImplementationDSAEXT;
} else
#endif
{
@@ -120,7 +134,7 @@ FramebufferState::FramebufferState(Context& context, std::vector& e
if(context.isExtensionSupported()) {
/* Extension added above */
- renderbufferStorageMultisampleImplementation = &Renderbuffer::storageMultisampleImplementationDSA;
+ renderbufferStorageMultisampleImplementation = &Renderbuffer::storageMultisampleImplementationDSAEXT;
} else
#endif
{
diff --git a/src/Magnum/Implementation/FramebufferState.h b/src/Magnum/Implementation/FramebufferState.h
index c66fdf96d..426b497e4 100644
--- a/src/Magnum/Implementation/FramebufferState.h
+++ b/src/Magnum/Implementation/FramebufferState.h
@@ -59,6 +59,7 @@ struct FramebufferState {
void(AbstractFramebuffer::*invalidateSubImplementation)(GLsizei, const GLenum*, const Range2Di&);
#endif
+ void(Framebuffer::*createImplementation)();
void(Framebuffer::*renderbufferImplementation)(Framebuffer::BufferAttachment, Renderbuffer&);
#ifndef MAGNUM_TARGET_GLES
void(Framebuffer::*texture1DImplementation)(Framebuffer::BufferAttachment, GLuint, GLint);
@@ -66,6 +67,7 @@ struct FramebufferState {
void(Framebuffer::*texture2DImplementation)(Framebuffer::BufferAttachment, GLenum, GLuint, GLint);
void(Framebuffer::*textureLayerImplementation)(Framebuffer::BufferAttachment, GLuint, GLint, GLint);
+ void(Renderbuffer::*createRenderbufferImplementation)();
void(Renderbuffer::*renderbufferStorageImplementation)(RenderbufferFormat, const Vector2i&);
void(Renderbuffer::*renderbufferStorageMultisampleImplementation)(GLsizei, RenderbufferFormat, const Vector2i&);
diff --git a/src/Magnum/Implementation/MeshState.cpp b/src/Magnum/Implementation/MeshState.cpp
index eed3a9763..e2e595c91 100644
--- a/src/Magnum/Implementation/MeshState.cpp
+++ b/src/Magnum/Implementation/MeshState.cpp
@@ -35,11 +35,11 @@ namespace Magnum { namespace Implementation {
MeshState::MeshState(Context& context, std::vector& extensions): currentVAO(0)
#ifndef MAGNUM_TARGET_GLES2
- , maxElementsIndices(0), maxElementsVertices(0)
+ , maxElementIndex{0}, maxElementsIndices{0}, maxElementsVertices{0}
#endif
{
#ifndef MAGNUM_TARGET_GLES
- if(context.isExtensionSupported())
+ if(context.isExtensionSupported())
#elif defined(MAGNUM_TARGET_GLES2)
if(context.isExtensionSupported())
#else
@@ -48,7 +48,7 @@ MeshState::MeshState(Context& context, std::vector& extensions): cu
#endif
{
#ifndef MAGNUM_TARGET_GLES
- extensions.push_back(Extensions::GL::APPLE::vertex_array_object::string());
+ extensions.push_back(Extensions::GL::ARB::vertex_array_object::string());
#elif defined(MAGNUM_TARGET_GLES2)
extensions.push_back(Extensions::GL::OES::vertex_array_object::string());
#endif
@@ -60,9 +60,9 @@ MeshState::MeshState(Context& context, std::vector& extensions): cu
if(context.isExtensionSupported()) {
extensions.push_back(Extensions::GL::EXT::direct_state_access::string());
- attributePointerImplementation = &Mesh::attributePointerImplementationDSA;
- attributeIPointerImplementation = &Mesh::attributePointerImplementationDSA;
- attributeLPointerImplementation = &Mesh::attributePointerImplementationDSA;
+ attributePointerImplementation = &Mesh::attributePointerImplementationDSAEXT;
+ attributeIPointerImplementation = &Mesh::attributePointerImplementationDSAEXT;
+ attributeLPointerImplementation = &Mesh::attributePointerImplementationDSAEXT;
} else
#endif
{
@@ -96,6 +96,14 @@ MeshState::MeshState(Context& context, std::vector& extensions): cu
}
#endif
+ #ifndef MAGNUM_TARGET_GLES
+ /* DSA create implementation (other cases handled above) */
+ if(context.isExtensionSupported()) {
+ extensions.push_back(Extensions::GL::ARB::direct_state_access::string());
+ createImplementation = &Mesh::createImplementationVAODSA;
+ }
+ #endif
+
#ifdef MAGNUM_TARGET_GLES
/* Multi draw implementation on ES */
if(context.isExtensionSupported()) {
diff --git a/src/Magnum/Implementation/MeshState.h b/src/Magnum/Implementation/MeshState.h
index 0b0349cec..9095a6ff0 100644
--- a/src/Magnum/Implementation/MeshState.h
+++ b/src/Magnum/Implementation/MeshState.h
@@ -64,6 +64,7 @@ struct MeshState {
GLuint currentVAO;
#ifndef MAGNUM_TARGET_GLES2
+ GLint64 maxElementIndex;
GLint maxElementsIndices, maxElementsVertices;
#endif
};
diff --git a/src/Magnum/Implementation/QueryState.cpp b/src/Magnum/Implementation/QueryState.cpp
new file mode 100644
index 000000000..bec5f3d00
--- /dev/null
+++ b/src/Magnum/Implementation/QueryState.cpp
@@ -0,0 +1,52 @@
+/*
+ This file is part of Magnum.
+
+ Copyright © 2010, 2011, 2012, 2013, 2014
+ Vladimír Vondruš
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+*/
+
+#include "QueryState.h"
+
+#include "Magnum/Context.h"
+#include "Magnum/Extensions.h"
+
+namespace Magnum { namespace Implementation {
+
+QueryState::QueryState(Context& context, std::vector& extensions) {
+ /* Create implementation */
+ #ifndef MAGNUM_TARGET_GLES
+ if(context.isExtensionSupported()) {
+ extensions.push_back(Extensions::GL::ARB::direct_state_access::string());
+ createImplementation = &AbstractQuery::createImplementationDSA;
+
+ } else
+ #endif
+ {
+ createImplementation = &AbstractQuery::createImplementationDefault;
+ }
+
+ #ifdef MAGNUM_TARGET_GLES
+ static_cast(context);
+ static_cast(extensions);
+ #endif
+}
+
+}}
diff --git a/src/Magnum/Implementation/QueryState.h b/src/Magnum/Implementation/QueryState.h
new file mode 100644
index 000000000..75d0f3d45
--- /dev/null
+++ b/src/Magnum/Implementation/QueryState.h
@@ -0,0 +1,44 @@
+#ifndef Magnum_Implementation_QueryState_h
+#define Magnum_Implementation_QueryState_h
+/*
+ This file is part of Magnum.
+
+ Copyright © 2010, 2011, 2012, 2013, 2014
+ Vladimír Vondruš
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+*/
+
+#include
+
+#include "Magnum/AbstractQuery.h"
+
+namespace Magnum { namespace Implementation {
+
+struct QueryState {
+ explicit QueryState(Context& context, std::vector& extensions);
+
+ void reset();
+
+ void(AbstractQuery::*createImplementation)();
+};
+
+}}
+
+#endif
diff --git a/src/Magnum/Implementation/ShaderProgramState.cpp b/src/Magnum/Implementation/ShaderProgramState.cpp
index 37fc7aa32..e55a22313 100644
--- a/src/Magnum/Implementation/ShaderProgramState.cpp
+++ b/src/Magnum/Implementation/ShaderProgramState.cpp
@@ -41,16 +41,15 @@ ShaderProgramState::ShaderProgramState(Context& context, std::vector())
#else
- if(context.isExtensionSupported())
+ if(context.isVersionSupported(Version::GLES310))
#endif
{
#ifndef MAGNUM_TARGET_GLES
extensions.push_back(Extensions::GL::ARB::separate_shader_objects::string());
- #else
- extensions.push_back(Extensions::GL::EXT::separate_shader_objects::string());
#endif
uniform1fvImplementation = &AbstractShaderProgram::uniformImplementationSSO;
@@ -61,12 +60,10 @@ ShaderProgramState::ShaderProgramState(Context& context, std::vector()) {
+ if(context.isExtensionSupported())
+ #else
+ if(context.isExtensionSupported())
+ #endif
+ {
+ #ifndef MAGNUM_TARGET_GLES
extensions.push_back(Extensions::GL::EXT::direct_state_access::string());
+ #else
+ extensions.push_back(Extensions::GL::EXT::separate_shader_objects::string());
+ #endif
- uniform1fvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniform2fvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniform3fvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniform4fvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniform1ivImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniform2ivImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniform3ivImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniform4ivImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniform1uivImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniform2uivImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniform3uivImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniform4uivImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniform1dvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniform2dvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniform3dvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniform4dvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
-
- uniformMatrix2fvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniformMatrix3fvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniformMatrix4fvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniformMatrix2x3fvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniformMatrix3x2fvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniformMatrix2x4fvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniformMatrix4x2fvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniformMatrix3x4fvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniformMatrix4x3fvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniformMatrix2dvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniformMatrix3dvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniformMatrix4dvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniformMatrix2x3dvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniformMatrix3x2dvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniformMatrix2x4dvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniformMatrix4x2dvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniformMatrix3x4dvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- uniformMatrix4x3dvImplementation = &AbstractShaderProgram::uniformImplementationDSA;
- }
- #endif
+ uniform1fvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT;
+ uniform2fvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT;
+ uniform3fvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT;
+ uniform4fvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT;
+ uniform1ivImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT;
+ uniform2ivImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT;
+ uniform3ivImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT;
+ uniform4ivImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT;
+ #ifndef MAGNUM_TARGET_GLES2
+ uniform1uivImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT;
+ uniform2uivImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT;
+ uniform3uivImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT;
+ uniform4uivImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT;
+ #endif
+ #ifndef MAGNUM_TARGET_GLES
+ uniform1dvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT;
+ uniform2dvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT;
+ uniform3dvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT;
+ uniform4dvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT;
+ #endif
- else {
+ uniformMatrix2fvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT;
+ uniformMatrix3fvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT;
+ uniformMatrix4fvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT;
+ #ifndef MAGNUM_TARGET_GLES2
+ uniformMatrix2x3fvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT;
+ uniformMatrix3x2fvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT;
+ uniformMatrix2x4fvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT;
+ uniformMatrix4x2fvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT;
+ uniformMatrix3x4fvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT;
+ uniformMatrix4x3fvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT_SSOEXT;
+ #endif
+ #ifndef MAGNUM_TARGET_GLES
+ uniformMatrix2dvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT;
+ uniformMatrix3dvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT;
+ uniformMatrix4dvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT;
+ uniformMatrix2x3dvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT;
+ uniformMatrix3x2dvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT;
+ uniformMatrix2x4dvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT;
+ uniformMatrix4x2dvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT;
+ uniformMatrix3x4dvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT;
+ uniformMatrix4x3dvImplementation = &AbstractShaderProgram::uniformImplementationDSAEXT;
+ #endif
+ } else {
uniform1fvImplementation = &AbstractShaderProgram::uniformImplementationDefault;
uniform2fvImplementation = &AbstractShaderProgram::uniformImplementationDefault;
uniform3fvImplementation = &AbstractShaderProgram::uniformImplementationDefault;
diff --git a/src/Magnum/Implementation/State.cpp b/src/Magnum/Implementation/State.cpp
index 133eddccc..987e68055 100644
--- a/src/Magnum/Implementation/State.cpp
+++ b/src/Magnum/Implementation/State.cpp
@@ -34,6 +34,7 @@
#include "DebugState.h"
#include "FramebufferState.h"
#include "MeshState.h"
+#include "QueryState.h"
#include "RendererState.h"
#include "ShaderState.h"
#include "ShaderProgramState.h"
@@ -55,6 +56,7 @@ State::State(Context& context) {
debug = new DebugState(context, extensions);
framebuffer = new FramebufferState(context, extensions);
mesh = new MeshState(context, extensions);
+ query = new QueryState(context, extensions);
renderer = new RendererState(context, extensions);
shader = new ShaderState;
shaderProgram = new ShaderProgramState(context, extensions);
diff --git a/src/Magnum/Implementation/State.h b/src/Magnum/Implementation/State.h
index f8e9c6a7f..481e6ad73 100644
--- a/src/Magnum/Implementation/State.h
+++ b/src/Magnum/Implementation/State.h
@@ -34,6 +34,7 @@ struct BufferState;
struct DebugState;
struct FramebufferState;
struct MeshState;
+struct QueryState;
struct RendererState;
struct ShaderState;
struct ShaderProgramState;
@@ -51,6 +52,7 @@ struct State {
DebugState* debug;
FramebufferState* framebuffer;
MeshState* mesh;
+ QueryState* query;
RendererState* renderer;
ShaderState* shader;
ShaderProgramState* shaderProgram;
diff --git a/src/Magnum/Implementation/TextureState.cpp b/src/Magnum/Implementation/TextureState.cpp
index 9badb9faa..e53f4a27e 100644
--- a/src/Magnum/Implementation/TextureState.cpp
+++ b/src/Magnum/Implementation/TextureState.cpp
@@ -57,6 +57,18 @@ TextureState::TextureState(Context& context, std::vector& extension
, bufferOffsetAlignment(0)
#endif
{
+ /* Create implementation */
+ #ifndef MAGNUM_TARGET_GLES
+ if(context.isExtensionSupported()) {
+ extensions.push_back(Extensions::GL::ARB::direct_state_access::string());
+ createImplementation = &AbstractTexture::createImplementationDSA;
+
+ } else
+ #endif
+ {
+ createImplementation = &AbstractTexture::createImplementationDefault;
+ }
+
/* Bind implementation */
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported()) {
@@ -69,9 +81,9 @@ TextureState::TextureState(Context& context, std::vector& extension
} else if(context.isExtensionSupported()) {
/* Extension name added below */
- unbindImplementation = &AbstractTexture::unbindImplementationDSA;
+ unbindImplementation = &AbstractTexture::unbindImplementationDSAEXT;
bindMultiImplementation = &AbstractTexture::bindImplementationFallback;
- bindImplementation = &AbstractTexture::bindImplementationDSA;
+ bindImplementation = &AbstractTexture::bindImplementationDSAEXT;
} else
#endif
@@ -86,24 +98,24 @@ TextureState::TextureState(Context& context, std::vector& extension
if(context.isExtensionSupported()) {
extensions.push_back(Extensions::GL::EXT::direct_state_access::string());
- parameteriImplementation = &AbstractTexture::parameterImplementationDSA;
- parameterfImplementation = &AbstractTexture::parameterImplementationDSA;
- parameterivImplementation = &AbstractTexture::parameterImplementationDSA;
- parameterfvImplementation = &AbstractTexture::parameterImplementationDSA;
- parameterIuivImplementation = &AbstractTexture::parameterIImplementationDSA;
- parameterIivImplementation = &AbstractTexture::parameterIImplementationDSA;
- getLevelParameterivImplementation = &AbstractTexture::getLevelParameterImplementationDSA;
- mipmapImplementation = &AbstractTexture::mipmapImplementationDSA;
- getImageImplementation = &AbstractTexture::getImageImplementationDSA;
- image1DImplementation = &AbstractTexture::imageImplementationDSA;
- image2DImplementation = &AbstractTexture::imageImplementationDSA;
- image3DImplementation = &AbstractTexture::imageImplementationDSA;
- subImage1DImplementation = &AbstractTexture::subImageImplementationDSA;
- subImage2DImplementation = &AbstractTexture::subImageImplementationDSA;
- subImage3DImplementation = &AbstractTexture::subImageImplementationDSA;
-
- setBufferImplementation = &BufferTexture::setBufferImplementationDSA;
- setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDSA;
+ parameteriImplementation = &AbstractTexture::parameterImplementationDSAEXT;
+ parameterfImplementation = &AbstractTexture::parameterImplementationDSAEXT;
+ parameterivImplementation = &AbstractTexture::parameterImplementationDSAEXT;
+ parameterfvImplementation = &AbstractTexture::parameterImplementationDSAEXT;
+ parameterIuivImplementation = &AbstractTexture::parameterIImplementationDSAEXT;
+ parameterIivImplementation = &AbstractTexture::parameterIImplementationDSAEXT;
+ getLevelParameterivImplementation = &AbstractTexture::getLevelParameterImplementationDSAEXT;
+ mipmapImplementation = &AbstractTexture::mipmapImplementationDSAEXT;
+ getImageImplementation = &AbstractTexture::getImageImplementationDSAEXT;
+ image1DImplementation = &AbstractTexture::imageImplementationDSAEXT;
+ image2DImplementation = &AbstractTexture::imageImplementationDSAEXT;
+ image3DImplementation = &AbstractTexture::imageImplementationDSAEXT;
+ subImage1DImplementation = &AbstractTexture::subImageImplementationDSAEXT;
+ subImage2DImplementation = &AbstractTexture::subImageImplementationDSAEXT;
+ subImage3DImplementation = &AbstractTexture::subImageImplementationDSAEXT;
+
+ setBufferImplementation = &BufferTexture::setBufferImplementationDSAEXT;
+ setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDSAEXT;
} else
#endif
{
@@ -178,9 +190,9 @@ TextureState::TextureState(Context& context, std::vector& extension
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported()) {
- storage1DImplementation = &AbstractTexture::storageImplementationDSA;
- storage2DImplementation = &AbstractTexture::storageImplementationDSA;
- storage3DImplementation = &AbstractTexture::storageImplementationDSA;
+ storage1DImplementation = &AbstractTexture::storageImplementationDSAEXT;
+ storage2DImplementation = &AbstractTexture::storageImplementationDSAEXT;
+ storage3DImplementation = &AbstractTexture::storageImplementationDSAEXT;
} else
#endif
{
@@ -208,8 +220,8 @@ TextureState::TextureState(Context& context, std::vector& extension
extensions.push_back(Extensions::GL::ARB::texture_storage_multisample::string());
if(context.isExtensionSupported()) {
- storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSA;
- storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSA;
+ storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSAEXT;
+ storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSAEXT;
} else {
storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDefault;
storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDefault;
diff --git a/src/Magnum/Implementation/TextureState.h b/src/Magnum/Implementation/TextureState.h
index b51a2af9a..df3ac72b1 100644
--- a/src/Magnum/Implementation/TextureState.h
+++ b/src/Magnum/Implementation/TextureState.h
@@ -58,7 +58,8 @@ struct TextureState {
void reset();
void(*unbindImplementation)(GLint);
- void(*bindMultiImplementation)(GLint, std::initializer_list);
+ void(*bindMultiImplementation)(GLint, Containers::ArrayReference);
+ void(AbstractTexture::*createImplementation)();
void(AbstractTexture::*bindImplementation)(GLint);
void(AbstractTexture::*parameteriImplementation)(GLenum, GLint);
void(AbstractTexture::*parameterfImplementation)(GLenum, GLfloat);
diff --git a/src/Magnum/Implementation/detectedDriver.cpp b/src/Magnum/Implementation/detectedDriver.cpp
index 60ada7803..ca52c6620 100644
--- a/src/Magnum/Implementation/detectedDriver.cpp
+++ b/src/Magnum/Implementation/detectedDriver.cpp
@@ -28,7 +28,7 @@
namespace Magnum {
-auto Context::detectedDriver() -> Context::DetectedDrivers {
+auto Context::detectedDriver() -> DetectedDrivers {
if(_detectedDrivers) return *_detectedDrivers;
_detectedDrivers = DetectedDrivers{};
diff --git a/src/Magnum/Math/Geometry/Rectangle.h b/src/Magnum/Math/Geometry/Rectangle.h
index a4154272f..0f0c99f67 100644
--- a/src/Magnum/Math/Geometry/Rectangle.h
+++ b/src/Magnum/Math/Geometry/Rectangle.h
@@ -27,7 +27,7 @@
/** @file
* @brief Class @ref Magnum::Math::Geometry::Rectangle
- * @deprecated Use @ref Math/Range.h instead.
+ * @deprecated Use @ref Magnum/Math/Range.h instead.
*/
#include "Magnum/Math/Range.h"
diff --git a/src/Magnum/Mesh.cpp b/src/Magnum/Mesh.cpp
index 6789cef00..202ad4411 100644
--- a/src/Magnum/Mesh.cpp
+++ b/src/Magnum/Mesh.cpp
@@ -41,6 +41,21 @@ namespace Magnum {
Int Mesh::maxVertexAttributes() { return AbstractShaderProgram::maxVertexAttributes(); }
#ifndef MAGNUM_TARGET_GLES2
+Long Mesh::maxElementIndex() {
+ #ifndef MAGNUM_TARGET_GLES
+ if(!Context::current()->isExtensionSupported())
+ return 0xFFFFFFFFl;
+ #endif
+
+ GLint64& value = Context::current()->state().mesh->maxElementIndex;
+
+ /* Get the value, if not already cached */
+ if(value == 0)
+ glGetInteger64v(GL_MAX_ELEMENT_INDEX, &value);
+
+ return value;
+}
+
Int Mesh::maxElementsIndices() {
GLint& value = Context::current()->state().mesh->maxElementsIndices;
@@ -72,7 +87,7 @@ std::size_t Mesh::indexSize(IndexType type) {
CORRADE_ASSERT_UNREACHABLE();
}
-Mesh::Mesh(MeshPrimitive primitive): _primitive(primitive), _count(0), _baseVertex(0), _instanceCount{1},
+Mesh::Mesh(const MeshPrimitive primitive): _primitive{primitive}, _count{0}, _baseVertex{0}, _instanceCount{1},
#ifndef MAGNUM_TARGET_GLES
_baseInstance{0},
#endif
@@ -95,7 +110,7 @@ Mesh::~Mesh() {
(this->*Context::current()->state().mesh->destroyImplementation)();
}
-Mesh::Mesh(Mesh&& other) noexcept: _id(other._id), _primitive(other._primitive), _count(other._count), _baseVertex{other._baseVertex}, _instanceCount{other._instanceCount},
+Mesh::Mesh(Mesh&& other) noexcept: _id(other._id), _created{other._created}, _primitive(other._primitive), _count(other._count), _baseVertex{other._baseVertex}, _instanceCount{other._instanceCount},
#ifndef MAGNUM_TARGET_GLES
_baseInstance{other._baseInstance},
#endif
@@ -115,6 +130,7 @@ Mesh::Mesh(Mesh&& other) noexcept: _id(other._id), _primitive(other._primitive),
Mesh& Mesh::operator=(Mesh&& other) noexcept {
std::swap(_id, other._id);
+ std::swap(_created, other._created);
std::swap(_primitive, other._primitive);
std::swap(_count, other._count);
std::swap(_baseVertex, other._baseVertex);
@@ -140,7 +156,20 @@ Mesh& Mesh::operator=(Mesh&& other) noexcept {
return *this;
}
-std::string Mesh::label() const {
+inline void Mesh::createIfNotAlready() {
+ /* If VAO extension is not available, _created is always true */
+ if(_created) return;
+
+ /* glGen*() does not create the object, just reserves the name. Some
+ commands (such as glObjectLabel()) operate with IDs directly and they
+ require the object to be created. Binding the VAO finally creates it.
+ Also all EXT DSA functions implicitly create it. */
+ bindVAO();
+ CORRADE_INTERNAL_ASSERT(_created);
+}
+
+std::string Mesh::label() {
+ createIfNotAlready();
#ifndef MAGNUM_TARGET_GLES
return Context::current()->state().debug->getLabelImplementation(GL_VERTEX_ARRAY, _id);
#else
@@ -149,6 +178,7 @@ std::string Mesh::label() const {
}
Mesh& Mesh::setLabelInternal(const Containers::ArrayReference label) {
+ createIfNotAlready();
#ifndef MAGNUM_TARGET_GLES
Context::current()->state().debug->labelImplementation(GL_VERTEX_ARRAY, _id, label);
#else
@@ -159,8 +189,8 @@ Mesh& Mesh::setLabelInternal(const Containers::ArrayReference label)
Mesh& Mesh::setIndexBuffer(Buffer& buffer, GLintptr offset, IndexType type, UnsignedInt start, UnsignedInt end) {
#if defined(CORRADE_TARGET_NACL) || defined(MAGNUM_TARGET_WEBGL)
- CORRADE_ASSERT(buffer.targetHint() == Buffer::Target::ElementArray,
- "Mesh::setIndexBuffer(): the buffer has unexpected target hint, expected" << Buffer::Target::ElementArray << "but got" << buffer.targetHint(), *this);
+ CORRADE_ASSERT(buffer.targetHint() == Buffer::TargetHint::ElementArray,
+ "Mesh::setIndexBuffer(): the buffer has unexpected target hint, expected" << Buffer::TargetHint::ElementArray << "but got" << buffer.targetHint(), *this);
#endif
_indexBuffer = &buffer;
@@ -284,20 +314,25 @@ void Mesh::drawInternal(Int count, Int baseVertex, Int instanceCount, GLintptr i
(this->*state.unbindImplementation)();
}
-void Mesh::bindVAO(GLuint vao) {
+void Mesh::bindVAO() {
GLuint& current = Context::current()->state().mesh->currentVAO;
- if(current != vao) {
+ if(current != _id) {
+ /* Binding the VAO finally creates it */
+ _created = true;
#ifndef MAGNUM_TARGET_GLES2
- glBindVertexArray(current = vao);
+ glBindVertexArray(current = _id);
#elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
- glBindVertexArrayOES(current = vao);
+ glBindVertexArrayOES(current = _id);
#else
CORRADE_ASSERT_UNREACHABLE();
#endif
}
}
-void Mesh::createImplementationDefault() { _id = 0; }
+void Mesh::createImplementationDefault() {
+ _id = 0;
+ _created = true;
+}
void Mesh::createImplementationVAO() {
#ifndef MAGNUM_TARGET_GLES2
@@ -307,9 +342,17 @@ void Mesh::createImplementationVAO() {
#else
CORRADE_ASSERT_UNREACHABLE();
#endif
+ _created = false;
CORRADE_INTERNAL_ASSERT(_id != Implementation::State::DisengagedBinding);
}
+#ifndef MAGNUM_TARGET_GLES
+void Mesh::createImplementationVAODSA() {
+ glCreateVertexArrays(1, &_id);
+ _created = true;
+}
+#endif
+
void Mesh::destroyImplementationDefault() {}
void Mesh::destroyImplementationVAO() {
@@ -328,8 +371,8 @@ void Mesh::attributePointerInternal(const Attribute& attribute) {
void Mesh::attributePointerImplementationDefault(const Attribute& attribute) {
#if defined(CORRADE_TARGET_NACL) || defined(MAGNUM_TARGET_WEBGL)
- CORRADE_ASSERT(attribute.buffer->targetHint() == Buffer::Target::Array,
- "Mesh::addVertexBuffer(): the buffer has unexpected target hint, expected" << Buffer::Target::Array << "but got" << attribute.buffer->targetHint(), );
+ CORRADE_ASSERT(attribute.buffer->targetHint() == Buffer::TargetHint::Array,
+ "Mesh::addVertexBuffer(): the buffer has unexpected target hint, expected" << Buffer::TargetHint::Array << "but got" << attribute.buffer->targetHint(), );
#endif
_attributes.push_back(attribute);
@@ -337,16 +380,17 @@ void Mesh::attributePointerImplementationDefault(const Attribute& attribute) {
void Mesh::attributePointerImplementationVAO(const Attribute& attribute) {
#if defined(CORRADE_TARGET_NACL) || defined(MAGNUM_TARGET_WEBGL)
- CORRADE_ASSERT(attribute.buffer->targetHint() == Buffer::Target::Array,
- "Mesh::addVertexBuffer(): the buffer has unexpected target hint, expected" << Buffer::Target::Array << "but got" << attribute.buffer->targetHint(), );
+ CORRADE_ASSERT(attribute.buffer->targetHint() == Buffer::TargetHint::Array,
+ "Mesh::addVertexBuffer(): the buffer has unexpected target hint, expected" << Buffer::TargetHint::Array << "but got" << attribute.buffer->targetHint(), );
#endif
- bindVAO(_id);
+ bindVAO();
vertexAttribPointer(attribute);
}
#ifndef MAGNUM_TARGET_GLES
-void Mesh::attributePointerImplementationDSA(const Attribute& attribute) {
+void Mesh::attributePointerImplementationDSAEXT(const Attribute& attribute) {
+ _created = true;
glEnableVertexArrayAttribEXT(_id, attribute.location);
glVertexArrayVertexAttribOffsetEXT(_id, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.normalized, attribute.stride, attribute.offset);
if(attribute.divisor) glVertexArrayVertexAttribDivisorEXT(_id, attribute.location, attribute.divisor);
@@ -355,7 +399,7 @@ void Mesh::attributePointerImplementationDSA(const Attribute& attribute) {
void Mesh::vertexAttribPointer(const Attribute& attribute) {
glEnableVertexAttribArray(attribute.location);
- attribute.buffer->bind(Buffer::Target::Array);
+ attribute.buffer->bindInternal(Buffer::TargetHint::Array);
glVertexAttribPointer(attribute.location, attribute.size, attribute.type, attribute.normalized, attribute.stride, reinterpret_cast(attribute.offset));
if(attribute.divisor) {
#ifndef MAGNUM_TARGET_GLES2
@@ -376,12 +420,13 @@ void Mesh::attributePointerImplementationDefault(const IntegerAttribute& attribu
}
void Mesh::attributePointerImplementationVAO(const IntegerAttribute& attribute) {
- bindVAO(_id);
+ bindVAO();
vertexAttribPointer(attribute);
}
#ifndef MAGNUM_TARGET_GLES
-void Mesh::attributePointerImplementationDSA(const IntegerAttribute& attribute) {
+void Mesh::attributePointerImplementationDSAEXT(const IntegerAttribute& attribute) {
+ _created = true;
glEnableVertexArrayAttribEXT(_id, attribute.location);
glVertexArrayVertexAttribIOffsetEXT(_id, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.stride, attribute.offset);
if(attribute.divisor) glVertexArrayVertexAttribDivisorEXT(_id, attribute.location, attribute.divisor);
@@ -390,7 +435,7 @@ void Mesh::attributePointerImplementationDSA(const IntegerAttribute& attribute)
void Mesh::vertexAttribPointer(const IntegerAttribute& attribute) {
glEnableVertexAttribArray(attribute.location);
- attribute.buffer->bind(Buffer::Target::Array);
+ attribute.buffer->bindInternal(Buffer::TargetHint::Array);
glVertexAttribIPointer(attribute.location, attribute.size, attribute.type, attribute.stride, reinterpret_cast(attribute.offset));
if(attribute.divisor) glVertexAttribDivisor(attribute.location, attribute.divisor);
}
@@ -406,11 +451,12 @@ void Mesh::attributePointerImplementationDefault(const LongAttribute& attribute)
}
void Mesh::attributePointerImplementationVAO(const LongAttribute& attribute) {
- bindVAO(_id);
+ bindVAO();
vertexAttribPointer(attribute);
}
-void Mesh::attributePointerImplementationDSA(const LongAttribute& attribute) {
+void Mesh::attributePointerImplementationDSAEXT(const LongAttribute& attribute) {
+ _created = true;
glEnableVertexArrayAttribEXT(_id, attribute.location);
glVertexArrayVertexAttribLOffsetEXT(_id, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.stride, attribute.offset);
if(attribute.divisor) glVertexArrayVertexAttribDivisorEXT(_id, attribute.location, attribute.divisor);
@@ -418,7 +464,7 @@ void Mesh::attributePointerImplementationDSA(const LongAttribute& attribute) {
void Mesh::vertexAttribPointer(const LongAttribute& attribute) {
glEnableVertexAttribArray(attribute.location);
- attribute.buffer->bind(Buffer::Target::Array);
+ attribute.buffer->bindInternal(Buffer::TargetHint::Array);
glVertexAttribLPointer(attribute.location, attribute.size, attribute.type, attribute.stride, reinterpret_cast(attribute.offset));
if(attribute.divisor) glVertexAttribDivisor(attribute.location, attribute.divisor);
}
@@ -459,13 +505,13 @@ void Mesh::vertexAttribDivisorImplementationNV(const GLuint index, const GLuint
void Mesh::bindIndexBufferImplementationDefault(Buffer&) {}
void Mesh::bindIndexBufferImplementationVAO(Buffer& buffer) {
- bindVAO(_id);
+ bindVAO();
/* Reset ElementArray binding to force explicit glBindBuffer call later */
/** @todo Do this cleaner way */
- Context::current()->state().buffer->bindings[Implementation::BufferState::indexForTarget(Buffer::Target::ElementArray)] = 0;
+ Context::current()->state().buffer->bindings[Implementation::BufferState::indexForTarget(Buffer::TargetHint::ElementArray)] = 0;
- buffer.bind(Buffer::Target::ElementArray);
+ buffer.bindInternal(Buffer::TargetHint::ElementArray);
}
void Mesh::bindImplementationDefault() {
@@ -484,11 +530,11 @@ void Mesh::bindImplementationDefault() {
#endif
/* Bind index buffer, if the mesh is indexed */
- if(_indexBuffer) _indexBuffer->bind(Buffer::Target::ElementArray);
+ if(_indexBuffer) _indexBuffer->bindInternal(Buffer::TargetHint::ElementArray);
}
void Mesh::bindImplementationVAO() {
- bindVAO(_id);
+ bindVAO();
}
void Mesh::unbindImplementationDefault() {
diff --git a/src/Magnum/Mesh.h b/src/Magnum/Mesh.h
index 4e3cdf063..fbae5fe19 100644
--- a/src/Magnum/Mesh.h
+++ b/src/Magnum/Mesh.h
@@ -316,7 +316,7 @@ layout, see @ref addVertexBuffer() documentation for details.
@anchor Mesh-performance-optimization
## Performance optimizations
-If @extension{APPLE,vertex_array_object} (part of OpenGL 3.0), OpenGL ES 3.0 or
+If @extension{ARB,vertex_array_object} (part of OpenGL 3.0), OpenGL ES 3.0 or
@es_extension{OES,vertex_array_object} on OpenGL ES 2.0 is supported, VAOs are
used instead of binding the buffers and specifying vertex attribute pointers
in each @ref draw() call. The engine tracks currently bound VAO and currently
@@ -375,6 +375,19 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
static Int maxVertexAttributes();
#ifndef MAGNUM_TARGET_GLES2
+ /**
+ * @brief Max supported index value
+ *
+ * The result is cached, repeated queries don't result in repeated
+ * OpenGL calls. If extension @extension{ARB,ES3_compatibility} (part
+ * of OpenGL 4.3) is not available, returns max representable 32-bit
+ * value (@f$ 2^32 - 1 @f$).
+ * @see @ref setIndexBuffer(), @fn_gl{Get} with @def_gl{MAX_ELEMENT_INDEX}
+ * @requires_gles30 No upper limit is specified for index values in
+ * OpenGL ES 2.0
+ */
+ static Long maxElementIndex();
+
/**
* @brief Max recommended index count
*
@@ -409,9 +422,13 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
* @brief Constructor
* @param primitive Primitive type
*
- * Creates mesh with no vertex buffers and zero vertex count.
- * @see @ref setPrimitive(), @ref setCount(), @fn_gl{GenVertexArrays}
- * (if @extension{APPLE,vertex_array_object} is available)
+ * If @extension{ARB,vertex_array_object} (part of OpenGL 3.0), OpenGL
+ * ES 3.0 or @es_extension{OES,vertex_array_object} in OpenGL ES 2.0 is
+ * available, vertex array object is created. If @extension{ARB,direct_state_access}
+ * (part of OpenGL 4.5) is not supported, the vertex array object is
+ * created on first use.
+ * @see @ref setPrimitive(), @ref setCount(), @fn_gl{CreateVertexArrays},
+ * eventually @fn_gl{GenVertexArrays}
*/
explicit Mesh(MeshPrimitive primitive = MeshPrimitive::Triangles);
@@ -424,8 +441,10 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
/**
* @brief Destructor
*
- * @see @fn_gl{DeleteVertexArrays} (if
- * @extension{APPLE,vertex_array_object} is available)
+ * If @extension{ARB,vertex_array_object} (part of OpenGL 3.0), OpenGL
+ * ES 3.0 or @es_extension{OES,vertex_array_object} in OpenGL ES 2.0 is
+ * available, associated vertex array object is deleted.
+ * @see @fn_gl{DeleteVertexArrays}
*/
~Mesh();
@@ -438,8 +457,9 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
/**
* @brief OpenGL mesh ID
*
- * If @extension{APPLE,vertex_array_object} (part of OpenGL 3.0) is not
- * available, returns `0`.
+ * If neither @extension{ARB,vertex_array_object} (part of OpenGL 3.0)
+ * nor OpenGL ES 3.0 nor @es_extension{OES,vertex_array_object} in
+ * OpenGL ES 2.0 is available, returns `0`.
*/
GLuint id() const { return _id; }
@@ -454,7 +474,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
* @fn_gl_extension2{GetObjectLabel,EXT,debug_label} with
* @def_gl{VERTEX_ARRAY_OBJECT_EXT}
*/
- std::string label() const;
+ std::string label();
/**
* @brief Set mesh label
@@ -662,6 +682,10 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
* .addVertexBuffer(buffer, 76 + 24*vertexCount, Shaders::Phong::Normal());
* @endcode
*
+ * If @extension{ARB,vertex_array_object} (part of OpenGL 3.0), OpenGL
+ * ES 3.0 or @es_extension{OES,vertex_array_object} in OpenGL ES 2.0 is
+ * available, the vertex array object is used to hold the parameters.
+ *
* @attention The buffer passed as parameter is not managed by the
* mesh, you must ensure it will exist for whole lifetime of the
* mesh and delete it afterwards.
@@ -678,7 +702,6 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
* @fn_gl{VertexAttribPointer} or
* @fn_gl_extension{EnableVertexArrayAttrib,EXT,direct_state_access},
* @fn_gl_extension{VertexArrayVertexAttribOffset,EXT,direct_state_access}
- * if @extension{APPLE,vertex_array_object} is available
*/
template inline Mesh& addVertexBuffer(Buffer& buffer, GLintptr offset, const T&... attributes) {
addVertexBufferInternal(buffer, offset, strideOfInterleaved(attributes...), 0, attributes...);
@@ -693,6 +716,11 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
* number of instances that will pass until new data are fetched from
* the buffer. Setting it to `0` is equivalent to calling
* @ref addVertexBuffer().
+ *
+ * If @extension{ARB,vertex_array_object} (part of OpenGL 3.0), OpenGL
+ * ES 3.0 or @es_extension{OES,vertex_array_object} in OpenGL ES 2.0 is
+ * available, the vertex array object is used to hold the parameters.
+ *
* @see @ref maxVertexAttributes(), @ref setPrimitive(),
* @ref setCount(), @ref setInstanceCount(), @ref setBaseInstance(),
* @fn_gl{BindVertexArray}, @fn_gl{EnableVertexAttribArray},
@@ -701,7 +729,6 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
* @fn_gl_extension{EnableVertexArrayAttrib,EXT,direct_state_access},
* @fn_gl_extension{VertexArrayVertexAttribOffset,EXT,direct_state_access},
* @fn_gl_extension{VertexArrayVertexAttribDivisor,EXT,direct_state_access}
- * if @extension{APPLE,vertex_array_object} is available
* @requires_gl33 %Extension @extension{ARB,instanced_arrays}
* @requires_gles30 %Extension @es_extension{ANGLE,instanced_arrays},
* @es_extension{EXT,instanced_arrays} or
@@ -728,10 +755,14 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
* On OpenGL ES 2.0 this function behaves always as
* @ref setIndexBuffer(Buffer&, GLintptr, IndexType), as this
* functionality is not available there.
- * @see @ref maxElementsIndices(), @ref maxElementsVertices(),
- * @ref setCount(), @ref isIndexed(), @fn_gl{BindVertexArray},
- * @fn_gl{BindBuffer} (if @extension{APPLE,vertex_array_object} is
- * available)
+ *
+ * If @extension{ARB,vertex_array_object} (part of OpenGL 3.0), OpenGL
+ * ES 3.0 or @es_extension{OES,vertex_array_object} in OpenGL ES 2.0 is
+ * available, the vertex array object is used to hold the parameters.
+ *
+ * @see @ref maxElementIndex(), @ref maxElementsIndices(),
+ * @ref maxElementsVertices(), @ref setCount(), @ref isIndexed(),
+ * @fn_gl{BindVertexArray}, @fn_gl{BindBuffer}
*/
Mesh& setIndexBuffer(Buffer& buffer, GLintptr offset, IndexType type, UnsignedInt start, UnsignedInt end);
@@ -758,14 +789,16 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
* set up. If vertex/index count or instance count is `0`, no draw
* commands are issued. See also
* @ref AbstractShaderProgram-rendering-workflow "AbstractShaderProgram documentation"
- * for more information.
+ * for more information. If @extension{ARB,vertex_array_object} (part
+ * of OpenGL 3.0), OpenGL ES 3.0 or @es_extension{OES,vertex_array_object}
+ * in OpenGL ES 2.0 is available, the associated vertex array object is
+ * bound instead of setting up the mesh from scratch.
* @see @ref setCount(), @ref setInstanceCount(),
* @ref MeshView::draw(AbstractShaderProgram&),
* @ref MeshView::draw(AbstractShaderProgram&, std::initializer_list>),
* @fn_gl{UseProgram}, @fn_gl{EnableVertexAttribArray},
* @fn_gl{BindBuffer}, @fn_gl{VertexAttribPointer},
- * @fn_gl{DisableVertexAttribArray} or @fn_gl{BindVertexArray} (if
- * @extension{APPLE,vertex_array_object} is available),
+ * @fn_gl{DisableVertexAttribArray} or @fn_gl{BindVertexArray},
* @fn_gl{DrawArrays}/@fn_gl{DrawArraysInstanced}/
* @fn_gl{DrawArraysInstancedBaseInstance} or @fn_gl{DrawElements}/
* @fn_gl{DrawRangeElements}/@fn_gl{DrawElementsBaseVertex}/
@@ -843,6 +876,8 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
#endif
#endif
+ void MAGNUM_LOCAL createIfNotAlready();
+
Mesh& setLabelInternal(Containers::ArrayReference label);
/* Computing stride of interleaved vertex attributes */
@@ -910,7 +945,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
#endif
#endif
- static void MAGNUM_LOCAL bindVAO(GLuint vao);
+ void MAGNUM_LOCAL bindVAO();
#ifndef MAGNUM_TARGET_GLES
void drawInternal(Int count, Int baseVertex, Int instanceCount, UnsignedInt baseInstance, GLintptr indexOffset, Int indexStart, Int indexEnd);
@@ -922,6 +957,9 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
void MAGNUM_LOCAL createImplementationDefault();
void MAGNUM_LOCAL createImplementationVAO();
+ #ifndef MAGNUM_TARGET_GLES
+ void MAGNUM_LOCAL createImplementationVAODSA();
+ #endif
void MAGNUM_LOCAL destroyImplementationDefault();
void MAGNUM_LOCAL destroyImplementationVAO();
@@ -930,7 +968,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
void MAGNUM_LOCAL attributePointerImplementationDefault(const Attribute& attribute);
void MAGNUM_LOCAL attributePointerImplementationVAO(const Attribute& attribute);
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL attributePointerImplementationDSA(const Attribute& attribute);
+ void MAGNUM_LOCAL attributePointerImplementationDSAEXT(const Attribute& attribute);
#endif
void MAGNUM_LOCAL vertexAttribPointer(const Attribute& attribute);
@@ -939,7 +977,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
void MAGNUM_LOCAL attributePointerImplementationDefault(const IntegerAttribute& attribute);
void MAGNUM_LOCAL attributePointerImplementationVAO(const IntegerAttribute& attribute);
#ifndef MAGNUM_TARGET_GLES
- void MAGNUM_LOCAL attributePointerImplementationDSA(const IntegerAttribute& attribute);
+ void MAGNUM_LOCAL attributePointerImplementationDSAEXT(const IntegerAttribute& attribute);
#endif
void MAGNUM_LOCAL vertexAttribPointer(const IntegerAttribute& attribute);
#endif
@@ -948,7 +986,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
void attributePointerInternal(const LongAttribute& attribute);
void MAGNUM_LOCAL attributePointerImplementationDefault(const LongAttribute& attribute);
void MAGNUM_LOCAL attributePointerImplementationVAO(const LongAttribute& attribute);
- void MAGNUM_LOCAL attributePointerImplementationDSA(const LongAttribute& attribute);
+ void MAGNUM_LOCAL attributePointerImplementationDSAEXT(const LongAttribute& attribute);
void MAGNUM_LOCAL vertexAttribPointer(const LongAttribute& attribute);
#endif
@@ -978,6 +1016,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
#endif
GLuint _id;
+ bool _created; /* see createIfNotAlready() for details */
MeshPrimitive _primitive;
Int _count, _baseVertex, _instanceCount;
#ifndef MAGNUM_TARGET_GLES
diff --git a/src/Magnum/MeshTools/Compile.cpp b/src/Magnum/MeshTools/Compile.cpp
index 4f0c979d4..adc585a6d 100644
--- a/src/Magnum/MeshTools/Compile.cpp
+++ b/src/Magnum/MeshTools/Compile.cpp
@@ -49,7 +49,7 @@ std::tuple, std::unique_ptr> compile(const
stride += sizeof(Shaders::Generic2D::TextureCoordinates::Type);
/* Create vertex buffer */
- std::unique_ptr vertexBuffer{new Buffer{Buffer::Target::Array}};
+ std::unique_ptr vertexBuffer{new Buffer{Buffer::TargetHint::Array}};
/* Interleave positions */
Containers::Array data = MeshTools::interleave(
@@ -82,7 +82,7 @@ std::tuple, std::unique_ptr> compile(const
UnsignedInt indexStart, indexEnd;
std::tie(indexData, indexType, indexStart, indexEnd) = MeshTools::compressIndices(meshData.indices());
- indexBuffer.reset(new Buffer{Buffer::Target::ElementArray});
+ indexBuffer.reset(new Buffer{Buffer::TargetHint::ElementArray});
indexBuffer->setData(indexData, usage);
mesh.setCount(meshData.indices().size())
.setIndexBuffer(*indexBuffer, 0, indexType, indexStart, indexEnd);
@@ -109,7 +109,7 @@ std::tuple, std::unique_ptr> compile(const
stride += sizeof(Shaders::Generic3D::TextureCoordinates::Type);
/* Create vertex buffer */
- std::unique_ptr vertexBuffer{new Buffer{Buffer::Target::Array}};
+ std::unique_ptr vertexBuffer{new Buffer{Buffer::TargetHint::Array}};
/* Interleave positions */
Containers::Array data = MeshTools::interleave(
@@ -154,7 +154,7 @@ std::tuple, std::unique_ptr> compile(const
UnsignedInt indexStart, indexEnd;
std::tie(indexData, indexType, indexStart, indexEnd) = MeshTools::compressIndices(meshData.indices());
- indexBuffer.reset(new Buffer{Buffer::Target::ElementArray});
+ indexBuffer.reset(new Buffer{Buffer::TargetHint::ElementArray});
indexBuffer->setData(indexData, usage);
mesh.setCount(meshData.indices().size())
.setIndexBuffer(*indexBuffer, 0, indexType, indexStart, indexEnd);
diff --git a/src/Magnum/MeshView.h b/src/Magnum/MeshView.h
index 7a7e0ee48..2585579ea 100644
--- a/src/Magnum/MeshView.h
+++ b/src/Magnum/MeshView.h
@@ -70,13 +70,17 @@ class MAGNUM_EXPORT MeshView {
* In OpenGL ES, if @es_extension2{EXT,multi_draw_arrays,multi_draw_arrays}
* is not present, the functionality is emulated using sequence of
* @ref draw(AbstractShaderProgram&) calls.
+ *
+ * If @extension{ARB,vertex_array_object} (part of OpenGL 3.0), OpenGL
+ * ES 3.0 or @es_extension{OES,vertex_array_object} in OpenGL ES 2.0 is
+ * available, the associated vertex array object is bound instead of
+ * setting up the mesh from scratch.
* @attention All meshes must be views of the same original mesh and
* must not be instanced.
* @see @ref draw(AbstractShaderProgram&), @fn_gl{UseProgram},
* @fn_gl{EnableVertexAttribArray}, @fn_gl{BindBuffer},
* @fn_gl{VertexAttribPointer}, @fn_gl{DisableVertexAttribArray}
- * or @fn_gl{BindVertexArray} (if @extension{APPLE,vertex_array_object}
- * is available), @fn_gl{MultiDrawArrays} or
+ * or @fn_gl{BindVertexArray}, @fn_gl{MultiDrawArrays} or
* @fn_gl{MultiDrawElements}/@fn_gl{MultiDrawElementsBaseVertex}
*/
static void draw(AbstractShaderProgram& shader, std::initializer_list> meshes);
diff --git a/src/Magnum/MultisampleTexture.h b/src/Magnum/MultisampleTexture.h
index 7133a1447..e82bef600 100644
--- a/src/Magnum/MultisampleTexture.h
+++ b/src/Magnum/MultisampleTexture.h
@@ -113,9 +113,12 @@ template class MultisampleTexture: public AbstractTextur
/**
* @brief Constructor
*
- * Creates new OpenGL texture object.
- * @see @fn_gl{GenTextures} with @def_gl{TEXTURE_2D_MULTISAMPLE} or
- * @def_gl{TEXTURE_2D_MULTISAMPLE_ARRAY}
+ * Creates new OpenGL texture object. If @extension{ARB,direct_state_access}
+ * (part of OpenGL 4.5) is not supported, the texture is created on
+ * first use.
+ * @see @fn_gl{CreateTextures} with @def_gl{TEXTURE_2D_MULTISAMPLE} or
+ * @def_gl{TEXTURE_2D_MULTISAMPLE_ARRAY}, eventually
+ * @fn_gl{GenTextures}
*/
explicit MultisampleTexture(): AbstractTexture(Implementation::multisampleTextureTarget()) {}
diff --git a/src/Magnum/Platform/AndroidApplication.h b/src/Magnum/Platform/AndroidApplication.h
index c278133f1..f11ca46ac 100644
--- a/src/Magnum/Platform/AndroidApplication.h
+++ b/src/Magnum/Platform/AndroidApplication.h
@@ -98,6 +98,8 @@ properly set **absolute** path to `toolchains/modules/` directory containing
-DCMAKE_TOOLCHAIN_FILE="../toolchains/generic/Android-x86.cmake"
cmake --build .
+See @ref cmake for more information.
+
The compiled binaries will be put into `lib/armeabi-v7a` and `lib/x86`. You can
then build the APK package simply by running `ant`. The resulting APK package
can be then installed directly on the device or emulator using `adb install`.
@@ -114,7 +116,7 @@ Request `%AndroidApplication` component, add
`${MAGNUM_ANDROIDAPPLICATION_INCLUDE_DIRS}` to include path and link to
`${MAGNUM_ANDROIDAPPLICATION_LIBRARIES}`. If no other application is requested,
you can also use generic `${MAGNUM_APPLICATION_INCLUDE_DIRS}` and
-`${MAGNUM_APPLICATION_LIBRARIES}` aliases to simplify porting. See
+`${MAGNUM_APPLICATION_LIBRARIES}` aliases to simplify porting. Again, see
@ref building and @ref cmake for more information. Note that unlike on other
platforms you need to create *shared library* instead of executable. The
resulting binary then needs to be copied to `lib/armeabi-v7a` and `lib/x86`,
diff --git a/src/Magnum/Platform/GlutApplication.h b/src/Magnum/Platform/GlutApplication.h
index 92da40f21..877d4b4b5 100644
--- a/src/Magnum/Platform/GlutApplication.h
+++ b/src/Magnum/Platform/GlutApplication.h
@@ -74,13 +74,15 @@ with these four commands:
cmake --build .
./src/MyApplication # or ./src/Debug/MyApplication
+See @ref cmake for more information.
+
## General usage
In CMake you need to request `%GlutApplication` component, add
`${MAGNUM_GLUTAPPLICATION_INCLUDE_DIRS}` to include path and link to
`${MAGNUM_GLUTAPPLICATION_LIBRARIES}`. If no other application is requested,
you can also use generic `${MAGNUM_APPLICATION_INCLUDE_DIRS}` and
-`${MAGNUM_APPLICATION_LIBRARIES}` aliases to simplify porting. See
+`${MAGNUM_APPLICATION_LIBRARIES}` aliases to simplify porting. Again, see
@ref building and @ref cmake for more information.
In C++ code you need to implement at least @ref drawEvent() to be able to draw
diff --git a/src/Magnum/Platform/NaClApplication.h b/src/Magnum/Platform/NaClApplication.h
index 2d9341681..88a718c2c 100644
--- a/src/Magnum/Platform/NaClApplication.h
+++ b/src/Magnum/Platform/NaClApplication.h
@@ -114,6 +114,8 @@ location of your webserver to have the files installed in proper location (e.g.
cmake --build .
cmake --build . --target install
+See @ref cmake for more information.
+
You can then open `MyApplication` through your webserver in Chrome (e.g.
`http://localhost/nacl/MyApplication.html`).
@@ -125,7 +127,7 @@ ES). Request `%NaClApplication` component, add
`${MAGNUM_NACLAPPLICATION_INCLUDE_DIRS}` to include path and link to
`${MAGNUM_NACLAPPLICATION_LIBRARIES}`. If no other application is requested,
you can also use generic `${MAGNUM_APPLICATION_INCLUDE_DIRS}` and
-`${MAGNUM_APPLICATION_LIBRARIES}` aliases to simplify porting. See
+`${MAGNUM_APPLICATION_LIBRARIES}` aliases to simplify porting. Again, see
@ref building and @ref cmake for more information.
In C++ code you need to implement at least @ref drawEvent() to be able to draw
diff --git a/src/Magnum/Platform/Sdl2Application.cpp b/src/Magnum/Platform/Sdl2Application.cpp
index 8c1f140ae..71f3854ed 100644
--- a/src/Magnum/Platform/Sdl2Application.cpp
+++ b/src/Magnum/Platform/Sdl2Application.cpp
@@ -287,7 +287,7 @@ void Sdl2Application::mainLoop() {
case SDL_MOUSEWHEEL:
if(event.wheel.y != 0) {
- MouseEvent e(event.wheel.y < 0 ? MouseEvent::Button::WheelUp : MouseEvent::Button::WheelDown, {event.wheel.x, event.wheel.y});
+ MouseEvent e(event.wheel.y > 0 ? MouseEvent::Button::WheelUp : MouseEvent::Button::WheelDown, {event.wheel.x, event.wheel.y});
mousePressEvent(e);
} break;
diff --git a/src/Magnum/Platform/Sdl2Application.h b/src/Magnum/Platform/Sdl2Application.h
index 612055301..59584f54b 100644
--- a/src/Magnum/Platform/Sdl2Application.h
+++ b/src/Magnum/Platform/Sdl2Application.h
@@ -80,6 +80,8 @@ with these four commands:
cmake --build .
./src/MyApplication # or ./src/Debug/MyApplication
+See @ref cmake for more information.
+
## Bootstrap application for Emscripten
Fully contained base application using @ref Sdl2Application for both desktop
@@ -119,7 +121,7 @@ In case of Emscripten you need also `FindOpenGLES2.cmake`. Request
`%Sdl2Application` component, add `${MAGNUM_SDL2APPLICATION_INCLUDE_DIRS}`
to include path and link to `${MAGNUM_SDL2APPLICATION_LIBRARIES}`. If no other
application is requested, you can also use generic `${MAGNUM_APPLICATION_INCLUDE_DIRS}`
-and `${MAGNUM_APPLICATION_LIBRARIES}` aliases to simplify porting. See
+and `${MAGNUM_APPLICATION_LIBRARIES}` aliases to simplify porting. Again, see
@ref building and @ref cmake for more information.
In C++ code you need to implement at least @ref drawEvent() to be able to draw on the
@@ -443,7 +445,10 @@ class Sdl2Application::Configuration {
Debug = SDL_GL_CONTEXT_DEBUG_FLAG, /**< Create debug context */
/** Create context with robust access */
- RobustAccess = SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG
+ RobustAccess = SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG,
+
+ /** Create context with reset isolation */
+ ResetIsolation = SDL_GL_CONTEXT_RESET_ISOLATION_FLAG
};
/**
@@ -454,7 +459,7 @@ class Sdl2Application::Configuration {
*/
#ifndef DOXYGEN_GENERATING_OUTPUT
typedef Containers::EnumSet Flags;
+ SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG|SDL_GL_CONTEXT_RESET_ISOLATION_FLAG> Flags;
#else
typedef Containers::EnumSet Flags;
#endif
diff --git a/src/Magnum/Platform/WindowlessCglApplication.h b/src/Magnum/Platform/WindowlessCglApplication.h
index 225ed3a53..0f751b16c 100644
--- a/src/Magnum/Platform/WindowlessCglApplication.h
+++ b/src/Magnum/Platform/WindowlessCglApplication.h
@@ -63,6 +63,8 @@ application with these four commands:
cmake --build .
./src/MyApplication # or ./src/Debug/MyApplication
+See @ref cmake for more information.
+
## General usage
In CMake you need to request `%WindowlessCglApplication` component, add
@@ -70,8 +72,8 @@ In CMake you need to request `%WindowlessCglApplication` component, add
`${MAGNUM_WINDOWLESSCGLAPPLICATION_LIBRARIES}`. If no other windowless
application is requested, you can also use generic
`${MAGNUM_WINDOWLESSAPPLICATION_INCLUDE_DIRS}` and
-`${MAGNUM_WINDOWLESSAPPLICATION_LIBRARIES}` aliases to simplify porting. See
-@ref building and @ref cmake for more information.
+`${MAGNUM_WINDOWLESSAPPLICATION_LIBRARIES}` aliases to simplify porting. Again,
+see @ref building and @ref cmake for more information.
Place your code into @ref exec(). The subclass can be then used directly in
`main()` -- see convenience macro @ref MAGNUM_WINDOWLESSCGLAPPLICATION_MAIN().
diff --git a/src/Magnum/Platform/WindowlessGlxApplication.h b/src/Magnum/Platform/WindowlessGlxApplication.h
index c099de18e..d7d2ccac6 100644
--- a/src/Magnum/Platform/WindowlessGlxApplication.h
+++ b/src/Magnum/Platform/WindowlessGlxApplication.h
@@ -69,6 +69,8 @@ application with these four commands:
cmake --build .
./src/MyApplication # or ./src/Debug/MyApplication
+See @ref cmake for more information.
+
## General usage
In CMake you need to request `%WindowlessGlxApplication` component, add
@@ -76,8 +78,8 @@ In CMake you need to request `%WindowlessGlxApplication` component, add
`${MAGNUM_WINDOWLESSGLXAPPLICATION_LIBRARIES}`. If no other windowless
application is requested, you can also use generic
`${MAGNUM_WINDOWLESSAPPLICATION_INCLUDE_DIRS}` and
-`${MAGNUM_WINDOWLESSAPPLICATION_LIBRARIES}` aliases to simplify porting. See
-@ref building and @ref cmake for more information.
+`${MAGNUM_WINDOWLESSAPPLICATION_LIBRARIES}` aliases to simplify porting. Again,
+see @ref building and @ref cmake for more information.
Place your code into @ref exec(). The subclass can be then used directly in
`main()` -- see convenience macro @ref MAGNUM_WINDOWLESSGLXAPPLICATION_MAIN().
diff --git a/src/Magnum/Platform/WindowlessWglApplication.h b/src/Magnum/Platform/WindowlessWglApplication.h
index a21cf341d..3f1ecb623 100644
--- a/src/Magnum/Platform/WindowlessWglApplication.h
+++ b/src/Magnum/Platform/WindowlessWglApplication.h
@@ -64,6 +64,8 @@ application with these four commands:
cmake --build .
./src/MyApplication # or ./src/Debug/MyApplication
+See @ref cmake for more information.
+
## General usage
In CMake you need to request `%WindowlessWglApplication` component, add
@@ -71,8 +73,8 @@ In CMake you need to request `%WindowlessWglApplication` component, add
`${MAGNUM_WINDOWLESSWGLAPPLICATION_LIBRARIES}`. If no other windowless
application is requested, you can also use generic
`${MAGNUM_WINDOWLESSAPPLICATION_INCLUDE_DIRS}` and
-`${MAGNUM_WINDOWLESSAPPLICATION_LIBRARIES}` aliases to simplify porting. See
-@ref building and @ref cmake for more information.
+`${MAGNUM_WINDOWLESSAPPLICATION_LIBRARIES}` aliases to simplify porting. Again,
+see @ref building and @ref cmake for more information.
Place your code into @ref exec(). The subclass can be then used in main
function using @ref MAGNUM_WINDOWLESSWGLAPPLICATION_MAIN() macro. See
diff --git a/src/Magnum/Platform/magnum-info.cpp b/src/Magnum/Platform/magnum-info.cpp
index 6b046a693..9b6e035d9 100644
--- a/src/Magnum/Platform/magnum-info.cpp
+++ b/src/Magnum/Platform/magnum-info.cpp
@@ -224,9 +224,6 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat
place */
createContext();
Context* c = Context::current();
- Debug() << "Vendor:" << c->vendorString();
- Debug() << "Renderer:" << c->rendererString();
- Debug() << "OpenGL version:" << c->version() << '(' + c->versionString() + ')';
Debug() << "Context flags:";
#ifndef MAGNUM_TARGET_GLES
@@ -256,8 +253,10 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat
Version::GL420,
Version::GL430,
Version::GL440,
+ Version::GL450,
#else
Version::GLES300,
+ Version::GLES310,
#endif
Version::None
};
@@ -305,6 +304,7 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat
_l(AbstractFramebuffer::maxDrawBuffers())
_l(Framebuffer::maxColorAttachments())
#ifndef MAGNUM_TARGET_GLES2
+ _l(Mesh::maxElementIndex())
_l(Mesh::maxElementsIndices())
_l(Mesh::maxElementsVertices())
#endif
@@ -527,6 +527,7 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat
_h(ARB::uniform_buffer_object)
#endif
+ _l(Buffer::uniformOffsetAlignment())
_l(Shader::maxUniformBlocks(Shader::Type::Vertex))
#ifndef MAGNUM_TARGET_GLES
_l(Shader::maxUniformBlocks(Shader::Type::TessellationControl))
diff --git a/src/Magnum/PrimitiveQuery.h b/src/Magnum/PrimitiveQuery.h
new file mode 100644
index 000000000..ad7649f19
--- /dev/null
+++ b/src/Magnum/PrimitiveQuery.h
@@ -0,0 +1,130 @@
+#ifndef Magnum_PrimitiveQuery_h
+#define Magnum_PrimitiveQuery_h
+/*
+ This file is part of Magnum.
+
+ Copyright © 2010, 2011, 2012, 2013, 2014
+ Vladimír Vondruš
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MAGNUM_TARGET_GLES2
+/** @file
+ * @brief Class @ref Magnum::PrimitiveQuery
+ */
+#endif
+
+#include "Magnum/AbstractQuery.h"
+
+#ifndef MAGNUM_TARGET_GLES2
+namespace Magnum {
+
+/**
+@brief Query for primitives
+
+Queries count of generated primitives from vertex shader, geometry shader or
+transform feedback. Example usage:
+@code
+PrimitiveQuery q;
+
+q.begin(PrimitiveQuery::Target::PrimitivesGenerated);
+// rendering...
+q.end();
+
+if(!q.resultAvailable()) {
+ // do some work until to give OpenGL some time...
+}
+
+// ...or block until the result is available
+UnsignedInt primitiveCount = q.result();
+@endcode
+@requires_gl30 %Extension @extension{EXT,transform_feedback}
+@requires_gles30 Only sample queries are available on OpenGL ES 2.0.
+
+@see @ref SampleQuery, @ref TimeQuery
+@todo glBeginQueryIndexed
+*/
+class PrimitiveQuery: public AbstractQuery {
+ public:
+ /** @brief Query target */
+ enum class Target: GLenum {
+ #ifndef MAGNUM_TARGET_GLES
+ /**
+ * Count of primitives generated from vertex shader or geometry
+ * shader.
+ * @requires_gl Only transform feedback query is available in
+ * OpenGL ES.
+ */
+ PrimitivesGenerated = GL_PRIMITIVES_GENERATED,
+ #endif
+
+ /** Count of primitives written to transform feedback buffer. */
+ TransformFeedbackPrimitivesWritten = GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
+ };
+
+ #ifdef MAGNUM_BUILD_DEPRECATED
+ /**
+ * @copybrief PrimitiveQuery(Target)
+ * @deprecated Use @ref Magnum::PrimitiveQuery::PrimitiveQuery(Target) "PrimitiveQuery(Target)"
+ * instead.
+ */
+ CORRADE_DEPRECATED("use PrimitiveQuery(Target) instead") explicit PrimitiveQuery() {}
+ #endif
+
+ /**
+ * @brief Constructor
+ *
+ * Creates new OpenGL query object. If @extension{ARB,direct_state_access}
+ * (part of OpenGL 4.5) is not supported, the query is created on first
+ * use.
+ * @see @fn_gl{CreateQueries}, eventually @fn_gl{GenQueries}
+ */
+ explicit PrimitiveQuery(Target target): AbstractQuery(GLenum(target)) {}
+
+ #ifdef MAGNUM_BUILD_DEPRECATED
+ /**
+ * @copybrief AbstractQuery::begin()
+ * @deprecated Use @ref Magnum::AbstractQuery::begin() "begin()"
+ * instead.
+ */
+ CORRADE_DEPRECATED("use begin() instead") void begin(Target target) {
+ AbstractQuery::begin(GLenum(target));
+ }
+
+ using AbstractQuery::begin;
+ #endif
+
+ /* Overloads to remove WTF-factor from method chaining order */
+ #ifndef DOXYGEN_GENERATING_OUTPUT
+ PrimitiveQuery& setLabel(const std::string& label) {
+ AbstractQuery::setLabel(label);
+ return *this;
+ }
+ template PrimitiveQuery& setLabel(const char(&label)[size]) {
+ AbstractQuery::setLabel(label);
+ return *this;
+ }
+ #endif
+};
+
+}
+#endif
+
+#endif
diff --git a/src/Magnum/Query.h b/src/Magnum/Query.h
index ebb713926..5bde8162e 100644
--- a/src/Magnum/Query.h
+++ b/src/Magnum/Query.h
@@ -27,493 +27,17 @@
/** @file
* @brief Class @ref Magnum::AbstractQuery, @ref Magnum::PrimitiveQuery, @ref Magnum::SampleQuery, @ref Magnum::TimeQuery
+ * @deprecated Use @ref Magnum/PrimitiveQuery.h, @ref Magnum/SampleQuery.h or @ref Magnum/TimeQuery.h instead.
*/
-#include
-#include
-
-#include "Magnum/AbstractObject.h"
#include "Magnum/configure.h"
-namespace Magnum {
-
-/**
-@brief Base class for queries
-
-See @ref PrimitiveQuery, @ref SampleQuery and @ref TimeQuery documentation for
-more information.
-@todo `QUERY_COUNTER_BITS` (not sure since when this is supported)
-*/
-class MAGNUM_EXPORT AbstractQuery: public AbstractObject {
- public:
- /** @brief Copying is not allowed */
- AbstractQuery(const AbstractQuery&) = delete;
-
- /** @brief Move constructor */
- AbstractQuery(AbstractQuery&& other) noexcept;
-
- /** @brief Copying is not allowed */
- AbstractQuery& operator=(const AbstractQuery&) = delete;
-
- /** @brief Move assignment */
- AbstractQuery& operator=(AbstractQuery&& other) noexcept;
-
- /** @brief OpenGL query ID */
- GLuint id() const { return _id; }
-
- /**
- * @brief %Query label
- *
- * The result is *not* cached, repeated queries will result in repeated
- * OpenGL calls. If OpenGL 4.3 is not supported and neither
- * @extension{KHR,debug} nor @extension2{EXT,debug_label} desktop or ES
- * extension is available, this function returns empty string.
- * @see @fn_gl{GetObjectLabel} with @def_gl{QUERY} or
- * @fn_gl_extension2{GetObjectLabel,EXT,debug_label} with
- * @def_gl{QUERY_OBJECT_EXT}
- */
- std::string label() const;
-
- /**
- * @brief Set query label
- * @return Reference to self (for method chaining)
- *
- * Default is empty string. If OpenGL 4.3 is not supported and neither
- * @extension{KHR,debug} nor @extension2{EXT,debug_label} desktop or ES
- * extension is available, this function does nothing.
- * @see @ref maxLabelLength(), @fn_gl{ObjectLabel} with
- * @def_gl{QUERY} or @fn_gl_extension2{LabelObject,EXT,debug_label}
- * with @def_gl{QUERY_OBJECT_EXT}
- */
- AbstractQuery& setLabel(const std::string& label) {
- return setLabelInternal({label.data(), label.size()});
- }
-
- /** @overload */
- template AbstractQuery& setLabel(const char(&label)[size]) {
- return setLabelInternal(label);
- }
-
- /**
- * @brief Whether the result is available
- *
- * @see @fn_gl{GetQueryObject} with @def_gl{QUERY_RESULT_AVAILABLE}
- */
- bool resultAvailable();
-
- /**
- * @brief Result
- * @tparam T Result type. Can be either `bool`, @ref UnsignedInt,
- * @ref Int, @ref UnsignedLong or @ref Long.
- *
- * Note that this function is blocking until the result is available.
- * See resultAvailable().
- * @attention @ref Magnum::UnsignedLong "UnsignedLong" and @ref Magnum::Long "Long"
- * result type is not available in @ref MAGNUM_TARGET_WEBGL "WebGL".
- * @see @fn_gl{GetQueryObject} with @def_gl{QUERY_RESULT}
- * @requires_gl33 %Extension @extension{ARB,timer_query} for result
- * type @ref Magnum::UnsignedInt "UnsignedInt" and @ref Magnum::Long
- * "Long"
- * @requires_es_extension %Extension @es_extension{EXT,disjoint_timer_query}
- * for result types @ref Magnum::Int "Int", @ref Magnum::UnsignedLong "UnsignedLong"
- * @ref Magnum::Long "Long".
- */
- template T result();
-
- /**
- * @brief End query
- *
- * The result can be then retrieved by calling @ref result().
- * @see @fn_gl{EndQuery}
- */
- void end();
-
- protected:
- /**
- * @brief Constructor
- *
- * Generates one OpenGL query.
- * @see @fn_gl{GenQueries}
- */
- explicit AbstractQuery();
-
- /**
- * @brief Destructor
- *
- * Deletes assigned OpenGL query.
- * @see @fn_gl{DeleteQueries}
- */
- ~AbstractQuery();
-
- #ifdef DOXYGEN_GENERATING_OUTPUT
- private:
- #endif
- void begin(GLenum target);
-
- private:
- AbstractQuery& setLabelInternal(Containers::ArrayReference label);
-
- GLuint _id;
- GLenum target;
-};
-
-
-#ifndef DOXYGEN_GENERATING_OUTPUT
-template<> bool MAGNUM_EXPORT AbstractQuery::result();
-template<> UnsignedInt MAGNUM_EXPORT AbstractQuery::result();
-template<> Int MAGNUM_EXPORT AbstractQuery::result();
-#ifndef MAGNUM_TARGET_WEBGL
-template<> UnsignedLong MAGNUM_EXPORT AbstractQuery::result();
-template<> Long MAGNUM_EXPORT AbstractQuery::result();
-#endif
+#ifdef MAGNUM_BUILD_DEPRECATED
+#include "Magnum/PrimitiveQuery.h"
+#include "Magnum/SampleQuery.h"
+#include "Magnum/TimeQuery.h"
+#else
+#error use Magnum/PrimitiveQuery.h, Magnum/SampleQuery.h or Magnum/TimeQuery.h instead.
#endif
-#ifndef MAGNUM_TARGET_GLES2
-/**
-@brief Query for primitives
-
-Queries count of generated primitives from vertex shader, geometry shader or
-transform feedback. Example usage:
-@code
-PrimitiveQuery q;
-
-q.begin(PrimitiveQuery::Target::PrimitivesGenerated);
-// rendering...
-q.end();
-
-if(!q.resultAvailable()) {
- // do some work until to give OpenGL some time...
-}
-
-// ...or block until the result is available
-UnsignedInt primitiveCount = q.result();
-@endcode
-@requires_gl30 %Extension @extension{EXT,transform_feedback}
-@requires_gles30 Only sample queries are available on OpenGL ES 2.0.
-
-@see @ref SampleQuery, @ref TimeQuery
-@todo glBeginQueryIndexed
-*/
-class PrimitiveQuery: public AbstractQuery {
- public:
- /** @brief Query target */
- enum class Target: GLenum {
- #ifndef MAGNUM_TARGET_GLES
- /**
- * Count of primitives generated from vertex shader or geometry
- * shader.
- * @requires_gl Only transform feedback query is available in
- * OpenGL ES.
- */
- PrimitivesGenerated = GL_PRIMITIVES_GENERATED,
- #endif
-
- /** Count of primitives written to transform feedback buffer. */
- TransformFeedbackPrimitivesWritten = GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
- };
-
- explicit PrimitiveQuery() {}
-
- #ifdef CORRADE_GCC45_COMPATIBILITY
- PrimitiveQuery(const PrimitiveQuery&) = delete;
- PrimitiveQuery(PrimitiveQuery&& other): AbstractQuery(std::move(other)) {}
- PrimitiveQuery& operator=(const PrimitiveQuery&) = delete;
- PrimitiveQuery& operator=(PrimitiveQuery&& other) {
- AbstractQuery::operator=(std::move(other));
- return *this;
- }
- #endif
-
- /**
- * @brief Begin query
- *
- * Begins counting of given @p target until @ref end() is called.
- * @see @fn_gl{BeginQuery}
- */
- void begin(Target target) {
- AbstractQuery::begin(GLenum(target));
- }
-
- /* Overloads to remove WTF-factor from method chaining order */
- #ifndef DOXYGEN_GENERATING_OUTPUT
- PrimitiveQuery& setLabel(const std::string& label) {
- AbstractQuery::setLabel(label);
- return *this;
- }
- template PrimitiveQuery& setLabel(const char(&label)[size]) {
- AbstractQuery::setLabel(label);
- return *this;
- }
- #endif
-};
-#endif
-
-/**
-@brief Query for samples
-
-Queries count of samples passed from fragment shader or boolean value
-indicating whether any samples passed. Can be used for example for conditional
-rendering:
-@code
-SampleQuery q;
-
-q.begin(SampleQuery::Target::AnySamplesPassed);
-// render simplified object to test whether it is visible at all...
-q.end();
-
-// render full version of the object only if it is visible
-if(q.result()) {
- // ...
-}
-@endcode
-This approach has some drawbacks, as the rendering is blocked until result is
-available for the CPU to decide. This can be improved by using conditional
-rendering on GPU itself. The drawing commands will be sent to the GPU and
-processed or discarded later, so CPU can continue executing the code without
-waiting for the result.
-@code
-SampleQuery q;
-
-q.begin(SampleQuery::Target::AnySamplesPassed);
-// render simplified object to test whether it is visible at all...
-q.end();
-
-q.beginConditionalRender(SampleQuery::ConditionalRenderMode::Wait);
-// render full version of the object only if the query returns nonzero result
-q.endConditionalRender();
-@endcode
-
-@see @ref PrimitiveQuery, @ref TimeQuery
-@requires_gles30 %Extension @es_extension{EXT,occlusion_query_boolean} in
- OpenGL ES 2.0
-*/
-class SampleQuery: public AbstractQuery {
- public:
- /** @brief Query target */
- enum class Target: GLenum {
- #ifndef MAGNUM_TARGET_GLES
- /**
- * Count of samples passed from fragment shader
- * @requires_gl Only boolean query is available in OpenGL ES.
- */
- SamplesPassed = GL_SAMPLES_PASSED,
- #endif
-
- /**
- * Whether any samples passed from fragment shader
- * @requires_gl33 %Extension @extension{ARB,occlusion_query2}
- */
- #ifndef MAGNUM_TARGET_GLES2
- AnySamplesPassed = GL_ANY_SAMPLES_PASSED,
- #else
- AnySamplesPassed = GL_ANY_SAMPLES_PASSED_EXT,
- #endif
-
- /**
- * Whether any samples passed from fragment shader (conservative)
- *
- * An implementation may choose a less precise version of the
- * test at the expense of some false positives.
- * @requires_gl43 %Extension @extension{ARB,ES3_compatibility}
- */
- #ifndef MAGNUM_TARGET_GLES2
- AnySamplesPassedConservative = GL_ANY_SAMPLES_PASSED_CONSERVATIVE
- #else
- AnySamplesPassedConservative = GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
- #endif
- };
-
- #ifndef MAGNUM_TARGET_GLES
- /**
- * @brief Conditional render mode
- *
- * @requires_gl30 %Extension @extension{NV,conditional_render}
- * @requires_gl Conditional rendering is not available in OpenGL ES.
- */
- enum class ConditionalRenderMode: GLenum {
- /**
- * If query result is not yet available, waits for it and
- * then begins conditional rendering based on result value.
- */
- Wait = GL_QUERY_WAIT,
-
- /**
- * If query result is not yet available, OpenGL may begin
- * rendering like if the result value was nonzero.
- */
- NoWait = GL_QUERY_NO_WAIT,
-
- /**
- * The same as Wait, but regions untouched by the sample query may
- * not be rendered at all.
- */
- ByRegionWait = GL_QUERY_BY_REGION_WAIT,
-
- /**
- * The same as NoWait, but regions untouched by the sample query
- * may not be rendered at all.
- */
- ByRegionNoWait = GL_QUERY_BY_REGION_NO_WAIT
- };
- #endif
-
- explicit SampleQuery() {}
-
- #ifdef CORRADE_GCC45_COMPATIBILITY
- SampleQuery(const SampleQuery&) = delete;
- SampleQuery(SampleQuery&& other): AbstractQuery(std::move(other)) {}
- SampleQuery& operator=(const SampleQuery&) = delete;
- SampleQuery& operator=(SampleQuery&& other) {
- AbstractQuery::operator=(std::move(other));
- return *this;
- }
- #endif
-
- /** @copydoc PrimitiveQuery::begin() */
- void begin(Target target) {
- AbstractQuery::begin(GLenum(target));
- }
-
- #ifndef MAGNUM_TARGET_GLES
- /**
- * @brief Begin conditional rendering based on result value
- *
- * @see @fn_gl{BeginConditionalRender}
- * @requires_gl30 %Extension @extension{NV,conditional_render}
- * @requires_gl Conditional rendering is not available in OpenGL ES.
- */
- void beginConditionalRender(ConditionalRenderMode mode) {
- glBeginConditionalRender(id(), GLenum(mode));
- }
-
- /**
- * @brief End conditional render
- *
- * @see @fn_gl{EndConditionalRender}
- * @requires_gl30 %Extension @extension{NV,conditional_render}
- * @requires_gl Conditional rendering is not available in OpenGL ES.
- */
- void endConditionalRender() {
- glEndConditionalRender();
- }
- #endif
-
- /* Overloads to remove WTF-factor from method chaining order */
- #ifndef DOXYGEN_GENERATING_OUTPUT
- SampleQuery& setLabel(const std::string& label) {
- AbstractQuery::setLabel(label);
- return *this;
- }
- template SampleQuery& setLabel(const char(&label)[size]) {
- AbstractQuery::setLabel(label);
- return *this;
- }
- #endif
-};
-
-/**
-@brief Query for elapsed time
-
-Queries timestamp after all previous OpenGL calls have been processed. It can
-query either duration of sequence of commands or absolute timestamp. Example
-usage of both methods:
-@code
-TimeQuery q1, q2;
-q1.begin(TimeQuery::Target::TimeElapsed);
-// rendering...
-q1.end();
-q2.begin(TimeQuery::Target::TimeElapsed);
-// another rendering...
-q2.end();
-UnsignedInt timeElapsed1 = q1.result();
-UnsignedInt timeElapsed2 = q2.result();
-@endcode
-@code
-TimeQuery q1, q2, q3;
-q1.timestamp();
-// rendering...
-q2.timestamp();
-// another rendering...
-q3.timestamp();
-UnsignedInt tmp = q2.result