Browse Source

Merge branch 'master' into compatibility

Conflicts:
	src/Magnum/AbstractTexture.cpp
	src/Magnum/BufferImage.cpp
	src/Magnum/Platform/Sdl2Application.h
	src/Magnum/Query.h
Vladimír Vondruš 12 years ago
parent
commit
e4454ace8d
  1. 11
      CREDITS.md
  2. 2
      Doxyfile
  3. 40
      README.md
  4. 24
      doc/building.dox
  5. 5
      doc/cmake.dox
  6. 4
      doc/getting-started.dox
  7. 2
      doc/mainpage.dox
  8. 605
      doc/opengl-mapping.dox
  9. 452
      doc/opengl-support.dox
  10. 4
      doc/opengl.dox
  11. 1
      package/gentoo/dev-libs/magnum/Manifest
  12. 52
      package/gentoo/dev-libs/magnum/magnum-9999.ebuild
  13. 29
      src/Magnum/AbstractFramebuffer.cpp
  14. 11
      src/Magnum/AbstractFramebuffer.h
  15. 74
      src/Magnum/AbstractQuery.cpp
  16. 196
      src/Magnum/AbstractQuery.h
  17. 310
      src/Magnum/AbstractShaderProgram.cpp
  18. 123
      src/Magnum/AbstractShaderProgram.h
  19. 173
      src/Magnum/AbstractTexture.cpp
  20. 86
      src/Magnum/AbstractTexture.h
  21. 265
      src/Magnum/Buffer.cpp
  22. 433
      src/Magnum/Buffer.h
  23. 4
      src/Magnum/BufferImage.cpp
  24. 6
      src/Magnum/BufferTexture.cpp
  25. 13
      src/Magnum/BufferTexture.h
  26. 12
      src/Magnum/CMakeLists.txt
  27. 2
      src/Magnum/ColorFormat.h
  28. 48
      src/Magnum/Context.cpp
  29. 7
      src/Magnum/CubeMapTexture.h
  30. 7
      src/Magnum/CubeMapTextureArray.h
  31. 4
      src/Magnum/DebugTools/ForceRenderer.cpp
  32. 8
      src/Magnum/DebugTools/Implementation/AbstractShapeRenderer.cpp
  33. 4
      src/Magnum/DebugTools/ObjectRenderer.cpp
  34. 5
      src/Magnum/DefaultFramebuffer.cpp
  35. 43
      src/Magnum/Extensions.h
  36. 29
      src/Magnum/Framebuffer.cpp
  37. 26
      src/Magnum/Framebuffer.h
  38. 103
      src/Magnum/Implementation/BufferState.cpp
  39. 8
      src/Magnum/Implementation/BufferState.h
  40. 34
      src/Magnum/Implementation/FramebufferState.cpp
  41. 2
      src/Magnum/Implementation/FramebufferState.h
  42. 20
      src/Magnum/Implementation/MeshState.cpp
  43. 1
      src/Magnum/Implementation/MeshState.h
  44. 52
      src/Magnum/Implementation/QueryState.cpp
  45. 44
      src/Magnum/Implementation/QueryState.h
  46. 103
      src/Magnum/Implementation/ShaderProgramState.cpp
  47. 2
      src/Magnum/Implementation/State.cpp
  48. 2
      src/Magnum/Implementation/State.h
  49. 62
      src/Magnum/Implementation/TextureState.cpp
  50. 3
      src/Magnum/Implementation/TextureState.h
  51. 2
      src/Magnum/Implementation/detectedDriver.cpp
  52. 2
      src/Magnum/Math/Geometry/Rectangle.h
  53. 102
      src/Magnum/Mesh.cpp
  54. 83
      src/Magnum/Mesh.h
  55. 8
      src/Magnum/MeshTools/Compile.cpp
  56. 8
      src/Magnum/MeshView.h
  57. 9
      src/Magnum/MultisampleTexture.h
  58. 4
      src/Magnum/Platform/AndroidApplication.h
  59. 4
      src/Magnum/Platform/GlutApplication.h
  60. 4
      src/Magnum/Platform/NaClApplication.h
  61. 2
      src/Magnum/Platform/Sdl2Application.cpp
  62. 11
      src/Magnum/Platform/Sdl2Application.h
  63. 6
      src/Magnum/Platform/WindowlessCglApplication.h
  64. 6
      src/Magnum/Platform/WindowlessGlxApplication.h
  65. 6
      src/Magnum/Platform/WindowlessWglApplication.h
  66. 7
      src/Magnum/Platform/magnum-info.cpp
  67. 130
      src/Magnum/PrimitiveQuery.h
  68. 490
      src/Magnum/Query.h
  69. 7
      src/Magnum/RectangleTexture.h
  70. 39
      src/Magnum/Renderbuffer.cpp
  71. 25
      src/Magnum/Renderbuffer.h
  72. 41
      src/Magnum/Renderer.h
  73. 247
      src/Magnum/SampleQuery.h
  74. 1
      src/Magnum/Shader.cpp
  75. 4
      src/Magnum/Shaders/DistanceFieldVector.cpp
  76. 4
      src/Magnum/Shaders/Flat.cpp
  77. 4
      src/Magnum/Shaders/Implementation/CreateCompatibilityShader.h
  78. 6
      src/Magnum/Shaders/MeshVisualizer.cpp
  79. 4
      src/Magnum/Shaders/Phong.cpp
  80. 4
      src/Magnum/Shaders/Vector.cpp
  81. 4
      src/Magnum/Shaders/VertexColor.cpp
  82. 37
      src/Magnum/Test/AbstractQueryGLTest.cpp
  83. 11
      src/Magnum/Test/AbstractTextureGLTest.cpp
  84. 73
      src/Magnum/Test/BufferGLTest.cpp
  85. 25
      src/Magnum/Test/BufferTextureGLTest.cpp
  86. 6
      src/Magnum/Test/ContextGLTest.cpp
  87. 13
      src/Magnum/Test/CubeMapTextureArrayGLTest.cpp
  88. 13
      src/Magnum/Test/CubeMapTextureGLTest.cpp
  89. 12
      src/Magnum/Test/FramebufferGLTest.cpp
  90. 42
      src/Magnum/Test/MeshGLTest.cpp
  91. 24
      src/Magnum/Test/MultisampleTextureGLTest.cpp
  92. 6
      src/Magnum/Test/PrimitiveQueryGLTest.cpp
  93. 13
      src/Magnum/Test/RectangleTextureGLTest.cpp
  94. 20
      src/Magnum/Test/RenderbufferGLTest.cpp
  95. 20
      src/Magnum/Test/SampleQueryGLTest.cpp
  96. 24
      src/Magnum/Test/TextureArrayGLTest.cpp
  97. 37
      src/Magnum/Test/TextureGLTest.cpp
  98. 24
      src/Magnum/Test/TimeQueryGLTest.cpp
  99. 2
      src/Magnum/Text/DistanceFieldGlyphCache.h
  100. 2
      src/Magnum/Text/GlyphCache.h
  101. Some files were not shown because too many files have changed in this diff Show More

11
CONTRIBUTORS.md → 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!

2
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}=<a href=\"http://www.opengl.org/registry/specs/\1/\2.txt\"><tt>\1_\2</tt></a>" \
"extension2{2}=<a href=\"http://www.opengl.org/registry/specs/\1/\1_\2.txt\"><tt>\1_\2</tt></a>" \
"extension3{3}=<a href=\"http://www.opengl.org/registry/specs/\1/\3.txt\"><tt>\1_\2</tt></a>" \
"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)\"" \

40
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
=======

24
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/<file>
@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

5
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)

4
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

2
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

605
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<std::reference_wrapper<MeshView>>)
@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()
*/

452
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.
*/

4
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

1
package/gentoo/dev-libs/magnum/Manifest

@ -0,0 +1 @@
EBUILD magnum-9999.ebuild 1122 SHA256 c71b5825632f6161fdad24f221c875c926d20cad848c6312e6dea3fa448ab486 SHA512 e46cf2e44ea7b7ed316aea9e71604c0e5c2b05b40202bfc212d9b621e403d87d9355ae6ec1bfbe7cef749c1a7d767da4dfceacf29f69faed4f8f7b9d3442e971 WHIRLPOOL b08ee4efee6cab255e0fc38b6e4ccd9925300e4ec682b18401203e7152b42cd442f81ab588ddd9e1df85b484ed734119b8b23cde9146b4fd76544ba1b647b272

52
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
}

29
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

11
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);

74
src/Magnum/Query.cpp → src/Magnum/AbstractQuery.cpp

@ -23,26 +23,27 @@
DEALINGS IN THE SOFTWARE.
*/
#include "Query.h"
#include "AbstractQuery.h"
#include <Corrade/Utility/Assert.h>
#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<UnsignedInt>() {
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<UnsignedInt>() {
template<> bool AbstractQuery::result<bool>() { return result<UnsignedInt>() != 0; }
template<> Int AbstractQuery::result<Int>() {
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<Int>() {
#ifndef MAGNUM_TARGET_WEBGL
template<> UnsignedLong AbstractQuery::result<UnsignedLong>() {
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<UnsignedLong>() {
}
template<> Long AbstractQuery::result<Long>() {
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<Long>() {
#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<void>(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 = {};
}
}

196
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š <mosra@centrum.cz>
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 <Corrade/Containers/Array.h>
#include <Corrade/Utility/Assert.h>
#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<std::size_t size> 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<class T> 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<const char> 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<bool>();
template<> UnsignedInt MAGNUM_EXPORT AbstractQuery::result<UnsignedInt>();
template<> Int MAGNUM_EXPORT AbstractQuery::result<Int>();
#ifndef MAGNUM_TARGET_WEBGL
template<> UnsignedLong MAGNUM_EXPORT AbstractQuery::result<UnsignedLong>();
template<> Long MAGNUM_EXPORT AbstractQuery::result<Long>();
#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

310
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<void>(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<void>(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<void>(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<void>(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<void>(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<void>(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<void>(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<void>(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<void>(location);
static_cast<void>(count);
static_cast<void>(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<void>(location);
static_cast<void>(count);
static_cast<void>(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<void>(location);
static_cast<void>(count);
static_cast<void>(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<void>(location);
static_cast<void>(count);
static_cast<void>(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<void>(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<void>(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<void>(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<void>(location);
static_cast<void>(count);
static_cast<void>(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<void>(location);
static_cast<void>(count);
static_cast<void>(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<void>(location);
static_cast<void>(count);
static_cast<void>(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<void>(location);
static_cast<void>(count);
static_cast<void>(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<void>(location);
static_cast<void>(count);
static_cast<void>(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<void>(location);
static_cast<void>(count);
static_cast<void>(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

123
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<UnsignedInt location, class T> 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
*/

173
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<AbstractTexture*> 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<AbstractTexture*> 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<AbstractTexture* const> 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<AbstractTexture*> textures) {
void AbstractTexture::bindImplementationMulti(const GLint firstTextureUnit, const Containers::ArrayReference<AbstractTexture* const> textures) {
Implementation::TextureState* const textureState = Context::current()->state().texture;
/* Create array of IDs and also update bindings in state tracker */
Containers::Array<GLuint> 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<GLuint> 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<const char> 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<UnsignedInt dimensions> 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

86
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<AbstractTexture*> 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<AbstractTexture*> textures);
static void MAGNUM_LOCAL bindImplementationFallback(GLint firstTextureUnit, Containers::ArrayReference<AbstractTexture* const> textures);
#ifndef MAGNUM_TARGET_GLES
static void MAGNUM_LOCAL bindImplementationMulti(GLint firstTextureUnit, std::initializer_list<AbstractTexture*> textures);
static void MAGNUM_LOCAL bindImplementationMulti(GLint firstTextureUnit, Containers::ArrayReference<AbstractTexture* const> 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;
}

265
src/Magnum/Buffer.cpp

@ -39,7 +39,7 @@ namespace Magnum {
#ifndef MAGNUM_TARGET_GLES
Int Buffer::minMapAlignment() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::map_buffer_alignment>())
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<Extensions::GL::ARB::uniform_buffer_object>())
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<Extensions::GL::ARB::uniform_buffer_object>())
@ -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<std::tuple<Buffer*, GLintptr, GLsizeiptr>> 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<Buffer*> 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<const char> 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<const char> 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<Buffer* const> 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<Buffer* const> buffers) {
Containers::Array<GLuint> 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<const std::tuple<Buffer*, GLintptr, GLsizeiptr>> 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<const std::tuple<Buffer*, GLintptr, GLsizeiptr>> buffers) {
/** @todo use ArrayTuple */
Containers::Array<GLuint> ids{buffers ? buffers.size() : 0};
Containers::Array<GLintptr> 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<void>(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<void>(offset);
static_cast<void>(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<void>(offset);
static_cast<void>(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<Buffer::TargetHint>(value);
#endif
}
return debug << "Buffer::Target::(invalid)";
}
#endif
#endif
}

433
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<std::tuple<Buffer*, GLintptr, GLsizeiptr>> 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<Buffer*> 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>(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<TargetHint>(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<std::tuple<Buffer*, GLintptr, GLsizeiptr>>),
* @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<Buffer*>),
* @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<const char> 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<Buffer* const> buffers);
#ifndef MAGNUM_TARGET_GLES
static void MAGNUM_LOCAL bindImplementationMulti(Target target, GLuint first, Containers::ArrayReference<Buffer* const> buffers);
#endif
static void MAGNUM_LOCAL bindImplementationFallback(Target target, GLuint first, Containers::ArrayReference<const std::tuple<Buffer*, GLintptr, GLsizeiptr>> buffers);
#ifndef MAGNUM_TARGET_GLES
static void MAGNUM_LOCAL bindImplementationMulti(Target target, GLuint first, Containers::ArrayReference<const std::tuple<Buffer*, GLintptr, GLsizeiptr>> 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<const char> 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;
}

4
src/Magnum/BufferImage.cpp

@ -28,11 +28,11 @@
namespace Magnum {
#ifndef MAGNUM_TARGET_GLES2
template<UnsignedInt dimensions> BufferImage<dimensions>::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<UnsignedInt dimensions> BufferImage<dimensions>::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<UnsignedInt dimensions> BufferImage<dimensions>::BufferImage(ColorFormat format, ColorType type): AbstractImage(format, type), _buffer(Buffer::Target::PixelPack) {}
template<UnsignedInt dimensions> BufferImage<dimensions>::BufferImage(ColorFormat format, ColorType type): AbstractImage(format, type), _buffer(Buffer::TargetHint::PixelPack) {}
template<UnsignedInt dimensions> void BufferImage<dimensions>::setData(ColorFormat format, ColorType type, const typename DimensionTraits<Dimensions, Int>::VectorType& size, const void* data, BufferUsage usage) {
_format = format;

6
src/Magnum/BufferTexture.cpp

@ -49,7 +49,7 @@ Int BufferTexture::maxSize() {
Int BufferTexture::offsetAlignment() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_buffer_range>())
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);
}

13
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);
};
}

12
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

2
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

48
src/Magnum/Context.cpp

@ -62,6 +62,19 @@ const std::vector<Extension>& 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>& 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<Extension> 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<Extension> extensions310{
@ -189,6 +203,18 @@ const std::vector<Extension>& 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<Extension> 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<Extension> extensions{
@ -206,7 +232,12 @@ const std::vector<Extension>& 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>& 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 */

7
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) {}

7
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) {}

4
src/Magnum/DebugTools/ForceRenderer.cpp

@ -77,8 +77,8 @@ template<UnsignedInt dimensions> ForceRenderer<dimensions>::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);

8
src/Magnum/DebugTools/Implementation/AbstractShapeRenderer.cpp

@ -46,7 +46,7 @@ template<UnsignedInt dimensions> void create(typename MeshData<dimensions>::Type
template<> void create<2>(Trade::MeshData2D& data, Resource<Mesh>& meshResource, Resource<Buffer>& vertexBufferResource, Resource<Buffer>& 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<Mesh>& 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<Mesh>& meshResource,
template<> void create<3>(Trade::MeshData3D& data, Resource<Mesh>& meshResource, Resource<Buffer>& vertexBufferResource, Resource<Buffer>& 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<Mesh>& 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);

4
src/Magnum/DebugTools/ObjectRenderer.cpp

@ -156,8 +156,8 @@ template<UnsignedInt dimensions> ObjectRenderer<dimensions>::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<dimensions>::positions, Renderer<dimensions>::colors), BufferUsage::StaticDraw);

5
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));

43
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

29
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<const char> 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

26
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<const char> 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;
}

103
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<std::string>& 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::GL::ARB::direct_state_access>()) {
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::GL::EXT::direct_state_access>()) {
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<std::string>& extensions)
invalidateSubImplementation = &Buffer::invalidateSubImplementationNoOp;
}
#ifndef MAGNUM_TARGET_GLES2
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::ARB::multi_bind>()) {
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<void>(context);
static_cast<void>(extensions);

8
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<std::string>& extensions);
void reset();
#ifndef MAGNUM_TARGET_GLES2
void(*bindBasesImplementation)(Buffer::Target, UnsignedInt, Containers::ArrayReference<Buffer* const>);
void(*bindRangesImplementation)(Buffer::Target, UnsignedInt, Containers::ArrayReference<const std::tuple<Buffer*, GLintptr, GLsizeiptr>>);
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
};

34
src/Magnum/Implementation/FramebufferState.cpp

@ -38,22 +38,36 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
, maxDualSourceDrawBuffers(0)
#endif
{
/* Create implementation */
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::ARB::direct_state_access>()) {
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::GL::EXT::direct_state_access>()) {
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<std::string>& e
if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
/* Extension added above */
renderbufferStorageMultisampleImplementation = &Renderbuffer::storageMultisampleImplementationDSA;
renderbufferStorageMultisampleImplementation = &Renderbuffer::storageMultisampleImplementationDSAEXT;
} else
#endif
{

2
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&);

20
src/Magnum/Implementation/MeshState.cpp

@ -35,11 +35,11 @@ namespace Magnum { namespace Implementation {
MeshState::MeshState(Context& context, std::vector<std::string>& 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<Extensions::GL::APPLE::vertex_array_object>())
if(context.isExtensionSupported<Extensions::GL::ARB::vertex_array_object>())
#elif defined(MAGNUM_TARGET_GLES2)
if(context.isExtensionSupported<Extensions::GL::OES::vertex_array_object>())
#else
@ -48,7 +48,7 @@ MeshState::MeshState(Context& context, std::vector<std::string>& 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<std::string>& extensions): cu
if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
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<std::string>& extensions): cu
}
#endif
#ifndef MAGNUM_TARGET_GLES
/* DSA create implementation (other cases handled above) */
if(context.isExtensionSupported<Extensions::GL::ARB::direct_state_access>()) {
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<Extensions::GL::EXT::multi_draw_arrays>()) {

1
src/Magnum/Implementation/MeshState.h

@ -64,6 +64,7 @@ struct MeshState {
GLuint currentVAO;
#ifndef MAGNUM_TARGET_GLES2
GLint64 maxElementIndex;
GLint maxElementsIndices, maxElementsVertices;
#endif
};

52
src/Magnum/Implementation/QueryState.cpp

@ -0,0 +1,52 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014
Vladimír Vondruš <mosra@centrum.cz>
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<std::string>& extensions) {
/* Create implementation */
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::ARB::direct_state_access>()) {
extensions.push_back(Extensions::GL::ARB::direct_state_access::string());
createImplementation = &AbstractQuery::createImplementationDSA;
} else
#endif
{
createImplementation = &AbstractQuery::createImplementationDefault;
}
#ifdef MAGNUM_TARGET_GLES
static_cast<void>(context);
static_cast<void>(extensions);
#endif
}
}}

44
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š <mosra@centrum.cz>
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 <vector>
#include "Magnum/AbstractQuery.h"
namespace Magnum { namespace Implementation {
struct QueryState {
explicit QueryState(Context& context, std::vector<std::string>& extensions);
void reset();
void(AbstractQuery::*createImplementation)();
};
}}
#endif

103
src/Magnum/Implementation/ShaderProgramState.cpp

@ -41,16 +41,15 @@ ShaderProgramState::ShaderProgramState(Context& context, std::vector<std::string
, maxImageSamples(0)
#endif
{
#ifndef MAGNUM_TARGET_GLES2
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::ARB::separate_shader_objects>())
#else
if(context.isExtensionSupported<Extensions::GL::EXT::separate_shader_objects>())
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<std::string
uniform2ivImplementation = &AbstractShaderProgram::uniformImplementationSSO;
uniform3ivImplementation = &AbstractShaderProgram::uniformImplementationSSO;
uniform4ivImplementation = &AbstractShaderProgram::uniformImplementationSSO;
#ifndef MAGNUM_TARGET_GLES2
uniform1uivImplementation = &AbstractShaderProgram::uniformImplementationSSO;
uniform2uivImplementation = &AbstractShaderProgram::uniformImplementationSSO;
uniform3uivImplementation = &AbstractShaderProgram::uniformImplementationSSO;
uniform4uivImplementation = &AbstractShaderProgram::uniformImplementationSSO;
#endif
#ifndef MAGNUM_TARGET_GLES
uniform1dvImplementation = &AbstractShaderProgram::uniformImplementationSSO;
uniform2dvImplementation = &AbstractShaderProgram::uniformImplementationSSO;
@ -77,14 +74,12 @@ ShaderProgramState::ShaderProgramState(Context& context, std::vector<std::string
uniformMatrix2fvImplementation = &AbstractShaderProgram::uniformImplementationSSO;
uniformMatrix3fvImplementation = &AbstractShaderProgram::uniformImplementationSSO;
uniformMatrix4fvImplementation = &AbstractShaderProgram::uniformImplementationSSO;
#ifndef MAGNUM_TARGET_GLES2
uniformMatrix2x3fvImplementation = &AbstractShaderProgram::uniformImplementationSSO;
uniformMatrix3x2fvImplementation = &AbstractShaderProgram::uniformImplementationSSO;
uniformMatrix2x4fvImplementation = &AbstractShaderProgram::uniformImplementationSSO;
uniformMatrix4x2fvImplementation = &AbstractShaderProgram::uniformImplementationSSO;
uniformMatrix3x4fvImplementation = &AbstractShaderProgram::uniformImplementationSSO;
uniformMatrix4x3fvImplementation = &AbstractShaderProgram::uniformImplementationSSO;
#endif
#ifndef MAGNUM_TARGET_GLES
uniformMatrix2dvImplementation = &AbstractShaderProgram::uniformImplementationSSO;
uniformMatrix3dvImplementation = &AbstractShaderProgram::uniformImplementationSSO;
@ -96,51 +91,65 @@ ShaderProgramState::ShaderProgramState(Context& context, std::vector<std::string
uniformMatrix3x4dvImplementation = &AbstractShaderProgram::uniformImplementationSSO;
uniformMatrix4x3dvImplementation = &AbstractShaderProgram::uniformImplementationSSO;
#endif
}
} else
#endif
#ifndef MAGNUM_TARGET_GLES
else if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>())
#else
if(context.isExtensionSupported<Extensions::GL::EXT::separate_shader_objects>())
#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;

2
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);

2
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;

62
src/Magnum/Implementation/TextureState.cpp

@ -57,6 +57,18 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
, bufferOffsetAlignment(0)
#endif
{
/* Create implementation */
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::ARB::direct_state_access>()) {
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<Extensions::GL::ARB::multi_bind>()) {
@ -69,9 +81,9 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
} else if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
/* 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<std::string>& extension
if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
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<std::string>& extension
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
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<std::string>& extension
extensions.push_back(Extensions::GL::ARB::texture_storage_multisample::string());
if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSA;
storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSA;
storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSAEXT;
storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSAEXT;
} else {
storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDefault;
storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDefault;

3
src/Magnum/Implementation/TextureState.h

@ -58,7 +58,8 @@ struct TextureState {
void reset();
void(*unbindImplementation)(GLint);
void(*bindMultiImplementation)(GLint, std::initializer_list<AbstractTexture*>);
void(*bindMultiImplementation)(GLint, Containers::ArrayReference<AbstractTexture* const>);
void(AbstractTexture::*createImplementation)();
void(AbstractTexture::*bindImplementation)(GLint);
void(AbstractTexture::*parameteriImplementation)(GLenum, GLint);
void(AbstractTexture::*parameterfImplementation)(GLenum, GLfloat);

2
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{};

2
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"

102
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<Extensions::GL::ARB::ES3_compatibility>())
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<const char> 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<const char> 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<const GLvoid*>(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<const GLvoid*>(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<const GLvoid*>(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() {

83
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<class ...T> 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<std::reference_wrapper<MeshView>>),
* @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<const char> 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

8
src/Magnum/MeshTools/Compile.cpp

@ -49,7 +49,7 @@ std::tuple<Mesh, std::unique_ptr<Buffer>, std::unique_ptr<Buffer>> compile(const
stride += sizeof(Shaders::Generic2D::TextureCoordinates::Type);
/* Create vertex buffer */
std::unique_ptr<Buffer> vertexBuffer{new Buffer{Buffer::Target::Array}};
std::unique_ptr<Buffer> vertexBuffer{new Buffer{Buffer::TargetHint::Array}};
/* Interleave positions */
Containers::Array<char> data = MeshTools::interleave(
@ -82,7 +82,7 @@ std::tuple<Mesh, std::unique_ptr<Buffer>, std::unique_ptr<Buffer>> 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<Mesh, std::unique_ptr<Buffer>, std::unique_ptr<Buffer>> compile(const
stride += sizeof(Shaders::Generic3D::TextureCoordinates::Type);
/* Create vertex buffer */
std::unique_ptr<Buffer> vertexBuffer{new Buffer{Buffer::Target::Array}};
std::unique_ptr<Buffer> vertexBuffer{new Buffer{Buffer::TargetHint::Array}};
/* Interleave positions */
Containers::Array<char> data = MeshTools::interleave(
@ -154,7 +154,7 @@ std::tuple<Mesh, std::unique_ptr<Buffer>, std::unique_ptr<Buffer>> 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);

8
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<std::reference_wrapper<MeshView>> meshes);

9
src/Magnum/MultisampleTexture.h

@ -113,9 +113,12 @@ template<UnsignedInt dimensions> 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<dimensions>()) {}

4
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`,

4
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

4
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

2
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;

11
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<Flag, int, SDL_GL_CONTEXT_DEBUG_FLAG|
SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG> Flags;
SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG|SDL_GL_CONTEXT_RESET_ISOLATION_FLAG> Flags;
#else
typedef Containers::EnumSet<Flag, int> Flags;
#endif

6
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().

6
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().

6
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

7
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))

130
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š <mosra@centrum.cz>
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<UnsignedInt>();
@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<std::size_t size> PrimitiveQuery& setLabel(const char(&label)[size]) {
AbstractQuery::setLabel<size>(label);
return *this;
}
#endif
};
}
#endif
#endif

490
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 <Corrade/Containers/Array.h>
#include <Corrade/Utility/Assert.h>
#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<std::size_t size> 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<class T> 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<const char> label);
GLuint _id;
GLenum target;
};
#ifndef DOXYGEN_GENERATING_OUTPUT
template<> bool MAGNUM_EXPORT AbstractQuery::result<bool>();
template<> UnsignedInt MAGNUM_EXPORT AbstractQuery::result<UnsignedInt>();
template<> Int MAGNUM_EXPORT AbstractQuery::result<Int>();
#ifndef MAGNUM_TARGET_WEBGL
template<> UnsignedLong MAGNUM_EXPORT AbstractQuery::result<UnsignedLong>();
template<> Long MAGNUM_EXPORT AbstractQuery::result<Long>();
#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<UnsignedInt>();
@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<std::size_t size> PrimitiveQuery& setLabel(const char(&label)[size]) {
AbstractQuery::setLabel<size>(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<bool>()) {
// ...
}
@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<std::size_t size> SampleQuery& setLabel(const char(&label)[size]) {
AbstractQuery::setLabel<size>(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>();
UnsignedInt timeElapsed2 = q2.result<UnsignedInt>();
@endcode
@code
TimeQuery q1, q2, q3;
q1.timestamp();
// rendering...
q2.timestamp();
// another rendering...
q3.timestamp();
UnsignedInt tmp = q2.result<UnsignedInt>();
UnsignedInt timeElapsed1 = tmp-q1.result<UnsignedInt>();
UnsignedInt timeElapsed2 = q3.result<UnsignedInt>()-tmp;
@endcode
Using the latter results in fewer OpenGL calls when doing more measures.
@requires_gl33 %Extension @extension{ARB,timer_query}
@requires_es_extension %Extension @es_extension{EXT,disjoint_timer_query}
@see @ref PrimitiveQuery, @ref SampleQuery
@todo timestamp with glGet + example usage
@todo @es_extension{EXT,disjoint_timer_query} -- GL_GPU_DISJOINT_EXT support? where?
*/
class TimeQuery: public AbstractQuery {
public:
/** @brief Query target */
enum class Target: GLenum {
/** Elapsed time */
#ifndef MAGNUM_TARGET_GLES
TimeElapsed = GL_TIME_ELAPSED
#else
TimeElapsed = GL_TIME_ELAPSED_EXT
#endif
};
explicit TimeQuery() {}
#ifdef CORRADE_GCC45_COMPATIBILITY
TimeQuery(const TimeQuery&) = delete;
TimeQuery(TimeQuery&& other): AbstractQuery(std::move(other)) {}
TimeQuery& operator=(const TimeQuery&) = delete;
TimeQuery& operator=(TimeQuery&& other) {
AbstractQuery::operator=(std::move(other));
return *this;
}
#endif
/**
* @brief Query timestamp
*
* @see @fn_gl{QueryCounter} with @def_gl{TIMESTAMP}
*/
void timestamp() {
#ifndef MAGNUM_TARGET_GLES
glQueryCounter(id(), GL_TIMESTAMP);
#elif !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
glQueryCounterEXT(id(), GL_TIMESTAMP_EXT);
#else
CORRADE_ASSERT_UNREACHABLE();
#endif
}
/** @copydoc PrimitiveQuery::begin() */
void begin(Target target) {
AbstractQuery::begin(GLenum(target));
}
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
TimeQuery& setLabel(const std::string& label) {
AbstractQuery::setLabel(label);
return *this;
}
template<std::size_t size> TimeQuery& setLabel(const char(&label)[size]) {
AbstractQuery::setLabel<size>(label);
return *this;
}
#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

7
src/Magnum/RectangleTexture.h

@ -83,8 +83,11 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture {
/**
* @brief Constructor
*
* Creates new OpenGL texture object.
* @see @fn_gl{GenTextures} with @def_gl{TEXTURE_RECTANGLE}
* 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_RECTANGLE},
* eventually @fn_gl{GenTextures}
*/
explicit RectangleTexture(): AbstractTexture(GL_TEXTURE_RECTANGLE) {}

39
src/Magnum/Renderbuffer.cpp

@ -64,7 +64,21 @@ Int Renderbuffer::maxSamples() {
return value;
}
Renderbuffer::Renderbuffer() { glGenRenderbuffers(1, &_id); }
Renderbuffer::Renderbuffer() {
(this->*Context::current()->state().framebuffer->createRenderbufferImplementation)();
}
void Renderbuffer::createImplementationDefault() {
glGenRenderbuffers(1, &_id);
_created = false;
}
#ifndef MAGNUM_TARGET_GLES
void Renderbuffer::createImplementationDSA() {
glCreateRenderbuffers(1, &_id);
_created = true;
}
#endif
Renderbuffer::~Renderbuffer() {
/* Moved out, nothing to do */
@ -77,11 +91,24 @@ Renderbuffer::~Renderbuffer() {
glDeleteRenderbuffers(1, &_id);
}
std::string Renderbuffer::label() const {
inline void Renderbuffer::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 renderbuffer finally
creates it. Also all EXT DSA functions implicitly create it. */
bind();
CORRADE_INTERNAL_ASSERT(_created);
}
std::string Renderbuffer::label() {
createIfNotAlready();
return Context::current()->state().debug->getLabelImplementation(GL_RENDERBUFFER, _id);
}
Renderbuffer& Renderbuffer::setLabelInternal(const Containers::ArrayReference<const char> label) {
createIfNotAlready();
Context::current()->state().debug->labelImplementation(GL_RENDERBUFFER, _id, label);
return *this;
}
@ -99,7 +126,9 @@ void Renderbuffer::bind() {
if(binding == _id) return;
/* Binding the renderbuffer finally creates it */
binding = _id;
_created = true;
glBindRenderbuffer(GL_RENDERBUFFER, _id);
}
@ -109,7 +138,8 @@ void Renderbuffer::storageImplementationDefault(RenderbufferFormat internalForma
}
#ifndef MAGNUM_TARGET_GLES
void Renderbuffer::storageImplementationDSA(RenderbufferFormat internalFormat, const Vector2i& size) {
void Renderbuffer::storageImplementationDSAEXT(RenderbufferFormat internalFormat, const Vector2i& size) {
_created = true;
glNamedRenderbufferStorageEXT(_id, GLenum(internalFormat), size.x(), size.y());
}
#endif
@ -146,7 +176,8 @@ void Renderbuffer::storageMultisampleImplementationNV(const GLsizei samples, con
#endif
#ifndef MAGNUM_TARGET_GLES
void Renderbuffer::storageMultisampleImplementationDSA(GLsizei samples, RenderbufferFormat internalFormat, const Vector2i& size) {
void Renderbuffer::storageMultisampleImplementationDSAEXT(GLsizei samples, RenderbufferFormat internalFormat, const Vector2i& size) {
_created = true;
glNamedRenderbufferStorageMultisampleEXT(_id, samples, GLenum(internalFormat), size.x(), size.y());
}
#endif

25
src/Magnum/Renderbuffer.h

@ -89,8 +89,10 @@ class MAGNUM_EXPORT Renderbuffer: public AbstractObject {
/**
* @brief Constructor
*
* Generates new OpenGL renderbuffer.
* @see @fn_gl{GenRenderbuffers}
* Generates new OpenGL renderbuffer object. If @extension{ARB,direct_state_access}
* (part of OpenGL 4.5) is not supported, the renderbuffer is created
* on first use.
* @see @fn_gl{CreateRenderbuffers}, eventually @fn_gl{GenRenderbuffers}
*/
explicit Renderbuffer();
@ -103,7 +105,7 @@ class MAGNUM_EXPORT Renderbuffer: public AbstractObject {
/**
* @brief Destructor
*
* Deletes associated OpenGL renderbuffer.
* Deletes associated OpenGL renderbuffer object.
* @see @fn_gl{DeleteRenderbuffers}
*/
~Renderbuffer();
@ -128,7 +130,7 @@ class MAGNUM_EXPORT Renderbuffer: public AbstractObject {
* @fn_gl_extension2{GetObjectLabel,EXT,debug_label} with
* @def_gl{RENDERBUFFER}
*/
std::string label() const;
std::string label();
/**
* @brief Set renderbuffer label
@ -182,17 +184,24 @@ class MAGNUM_EXPORT Renderbuffer: public AbstractObject {
void setStorageMultisample(Int samples, RenderbufferFormat internalFormat, const Vector2i& size);
private:
void MAGNUM_LOCAL createImplementationDefault();
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL createImplementationDSA();
#endif
void MAGNUM_LOCAL createIfNotAlready();
Renderbuffer& setLabelInternal(Containers::ArrayReference<const char> label);
void MAGNUM_LOCAL storageImplementationDefault(RenderbufferFormat internalFormat, const Vector2i& size);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL storageImplementationDSA(RenderbufferFormat internalFormat, const Vector2i& size);
void MAGNUM_LOCAL storageImplementationDSAEXT(RenderbufferFormat internalFormat, const Vector2i& size);
#endif
#ifndef MAGNUM_TARGET_GLES2
void MAGNUM_LOCAL storageMultisampleImplementationDefault(GLsizei samples, RenderbufferFormat internalFormat, const Vector2i& size);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL storageMultisampleImplementationDSA(GLsizei samples, RenderbufferFormat internalFormat, const Vector2i& size);
void MAGNUM_LOCAL storageMultisampleImplementationDSAEXT(GLsizei samples, RenderbufferFormat internalFormat, const Vector2i& size);
#endif
#else
void MAGNUM_LOCAL storageMultisampleImplementationANGLE(GLsizei samples, RenderbufferFormat internalFormat, const Vector2i& size);
@ -202,14 +211,16 @@ class MAGNUM_EXPORT Renderbuffer: public AbstractObject {
void MAGNUM_LOCAL bind();
GLuint _id;
bool _created; /* see createIfNotAlready() for details */
};
inline Renderbuffer::Renderbuffer(Renderbuffer&& other) noexcept: _id(other._id) {
inline Renderbuffer::Renderbuffer(Renderbuffer&& other) noexcept: _id{other._id}, _created{other._created} {
other._id = 0;
}
inline Renderbuffer& Renderbuffer::operator=(Renderbuffer&& other) noexcept {
std::swap(_id, other._id);
std::swap(_created, other._created);
return *this;
}

41
src/Magnum/Renderer.h

@ -135,6 +135,14 @@ class MAGNUM_EXPORT Renderer {
FaceCulling = GL_CULL_FACE,
#ifndef MAGNUM_TARGET_GLES
/**
* sRGB encoding of the default framebuffer
* @requires_gl30 %Extension @extension{ARB,framebuffer_sRGB}
* @requires_gl sRGB encoding of the default framebuffer is
* implementation-defined in OpenGL ES.
*/
FramebufferSRGB = GL_FRAMEBUFFER_SRGB,
/**
* Logical operation
* @see @ref setLogicOperation()
@ -194,6 +202,16 @@ class MAGNUM_EXPORT Renderer {
ProgramPointSize = GL_PROGRAM_POINT_SIZE,
#endif
#ifndef MAGNUM_TARGET_GLES2
/**
* Discard primitives before rasterization.
* @requires_gl30 %Extension @extension{EXT,transform_feedback}
* @requires_gles30 Transform feedback is not available in OpenGL
* ES 2.0.
*/
RasterizerDiscard = GL_RASTERIZER_DISCARD,
#endif
/**
* Scissor test
* @see @ref setScissor()
@ -1030,6 +1048,12 @@ class MAGNUM_EXPORT Renderer {
* OpenGL calls. If OpenGL extension @extension{ARB,robustness} or ES
* extension @es_extension{EXT,robustness} is not available, this
* function always returns @ref ResetNotificationStrategy::NoResetNotification.
*
* For the reset notification to work, additionally to the extension
* support the context must be created with
* @ref Platform::Sdl2Application::Configuration::Flag::RobustAccess "Platform::*Application::Configuration::Flag::RobustAccess"
* flag.
*
* @see @ref graphicsResetStatus(), @fn_gl{Get} with
* @def_gl{RESET_NOTIFICATION_STRATEGY_ARB}
*/
@ -1074,7 +1098,22 @@ class MAGNUM_EXPORT Renderer {
* Reset causes all context state to be lost. If OpenGL extension
* @extension{ARB,robustness} or ES extension @es_extension{EXT,robustness}
* is not available, this function always returns @ref GraphicsResetStatus::NoError.
* @see @ref resetNotificationStrategy(), @fn_gl_extension{GetGraphicsResetStatus,ARB,robustness}
*
* For the reset notification to work, additionally to the extension
* support the context must be created with
* @ref Platform::Sdl2Application::Configuration::Flag::RobustAccess "Platform::*Application::Configuration::Flag::RobustAccess"
* flag.
*
* If the reset occurs, @extension{ARB,robustness_isolation}
* extension is supported and context is created with
* @ref Platform::Sdl2Application::Configuration::Flag::ResetIsolation "Platform::*Application::Configuration::Flag::ResetIsolation",
* advertised support for @extension{ARB,robustness_application_isolation}
* indicates that no other application on the system will be affected
* by the graphics reset. Advertised support for
* @extension{ARB,robustness_share_group_isolation} indicates that no
* other share group will be affected by the graphics reset.
* @see @ref resetNotificationStrategy(),
* @fn_gl_extension{GetGraphicsResetStatus,ARB,robustness}
*/
static GraphicsResetStatus graphicsResetStatus();

247
src/Magnum/SampleQuery.h

@ -0,0 +1,247 @@
#ifndef Magnum_SampleQuery_h
#define Magnum_SampleQuery_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014
Vladimír Vondruš <mosra@centrum.cz>
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::SampleQuery
*/
#include "Magnum/AbstractQuery.h"
namespace Magnum {
/**
@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<bool>()) {
// ...
}
@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 rendering only if result is nonzero.
*/
Wait = GL_QUERY_WAIT,
/**
* If query result is not yet available, waits for it and then
* begins rendering only if result is zero.
* @requires_gl45 %Extension @extension{ARB,conditional_render_inverted}
*/
WaitInverted = GL_QUERY_WAIT_INVERTED,
/**
* If query result is not yet available, begins rendering like if
* the result was nonzero.
*/
NoWait = GL_QUERY_NO_WAIT,
/**
* If query result is not yet available, begins rendering like if
* the result was zero.
* @requires_gl45 %Extension @extension{ARB,conditional_render_inverted}
*/
NoWaitInverted = GL_QUERY_NO_WAIT_INVERTED,
/**
* The same as @ref ConditionalRenderMode::Wait, but regions
* untouched by the sample query may not be rendered at all.
*/
ByRegionWait = GL_QUERY_BY_REGION_WAIT,
/**
* The same as @ref ConditionalRenderMode::WaitInverted, but
* regions untouched by the sample query may not be rendered at
* all.
* @requires_gl45 %Extension @extension{ARB,conditional_render_inverted}
*/
ByRegionWaitInverted = GL_QUERY_BY_REGION_WAIT_INVERTED,
/**
* The same as @ref ConditionalRenderMode::NoWait, but regions
* untouched by the sample query may not be rendered at all.
*/
ByRegionNoWait = GL_QUERY_BY_REGION_NO_WAIT,
/**
* The same as @ref ConditionalRenderMode::NoWaitInverted, but
* regions untouched by the sample query may not be rendered at
* all.
* @requires_gl45 %Extension @extension{ARB,conditional_render_inverted}
*/
ByRegionNoWaitInverted = GL_QUERY_BY_REGION_NO_WAIT_INVERTED
};
#endif
#ifdef MAGNUM_BUILD_DEPRECATED
/**
* @copybrief SampleQuery(Target)
* @deprecated Use @ref Magnum::SampleQuery::SampleQuery(Target) "SampleQuery(Target)"
* instead.
*/
CORRADE_DEPRECATED("use SampleQuery(Target) instead") explicit SampleQuery() {}
#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 SampleQuery(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
#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<std::size_t size> SampleQuery& setLabel(const char(&label)[size]) {
AbstractQuery::setLabel<size>(label);
return *this;
}
#endif
};
}
#endif

1
src/Magnum/Shader.cpp

@ -626,6 +626,7 @@ Shader::Shader(const Version version, const Type type): _type(type), _id(0) {
case Version::GL420: _sources.push_back("#version 420\n"); return;
case Version::GL430: _sources.push_back("#version 430\n"); return;
case Version::GL440: _sources.push_back("#version 440\n"); return;
case Version::GL450: _sources.push_back("#version 450\n"); return;
#else
case Version::GLES200: _sources.push_back("#version 100\n"); return;
case Version::GLES300: _sources.push_back("#version 300 es\n"); return;

4
src/Magnum/Shaders/DistanceFieldVector.cpp

@ -53,8 +53,8 @@ template<UnsignedInt dimensions> DistanceFieldVector<dimensions>::DistanceFieldV
#endif
Version version = Context::current()->supportedVersion(vs);
Shader frag = Implementation::createCompatibilityShader(version, Shader::Type::Vertex);
Shader vert = Implementation::createCompatibilityShader(version, Shader::Type::Fragment);
Shader frag = Implementation::createCompatibilityShader(rs, version, Shader::Type::Vertex);
Shader vert = Implementation::createCompatibilityShader(rs, version, Shader::Type::Fragment);
frag.addSource(rs.get("generic.glsl"))
.addSource(rs.get(vertexShaderName<dimensions>()));

4
src/Magnum/Shaders/Flat.cpp

@ -56,8 +56,8 @@ template<UnsignedInt dimensions> Flat<dimensions>::Flat(const Flags flags): tran
#endif
Version version = Context::current()->supportedVersion(vs);
Shader vert = Implementation::createCompatibilityShader(version, Shader::Type::Vertex);
Shader frag = Implementation::createCompatibilityShader(version, Shader::Type::Fragment);
Shader vert = Implementation::createCompatibilityShader(rs, version, Shader::Type::Vertex);
Shader frag = Implementation::createCompatibilityShader(rs, version, Shader::Type::Fragment);
vert.addSource(flags & Flag::Textured ? "#define TEXTURED\n" : "")
.addSource(rs.get("generic.glsl"))

4
src/Magnum/Shaders/Implementation/CreateCompatibilityShader.h

@ -33,7 +33,7 @@
namespace Magnum { namespace Shaders { namespace Implementation {
inline Shader createCompatibilityShader(Version version, Shader::Type type) {
inline Shader createCompatibilityShader(const Utility::Resource& rs, Version version, Shader::Type type) {
Shader shader(version, type);
#ifndef MAGNUM_TARGET_GLES
@ -52,7 +52,7 @@ inline Shader createCompatibilityShader(Version version, Shader::Type type) {
shader.addSource("#ifndef GL_ES\n#define GL_ES 1\n#endif\n");
#endif
shader.addSource(Utility::Resource("MagnumShaders").get("compatibility.glsl"));
shader.addSource(rs.get("compatibility.glsl"));
return shader;
}

6
src/Magnum/Shaders/MeshVisualizer.cpp

@ -56,8 +56,8 @@ MeshVisualizer::MeshVisualizer(const Flags flags): flags(flags), transformationP
const Version version = Context::current()->supportedVersion({Version::GLES300, Version::GLES200});
#endif
Shader vert = Implementation::createCompatibilityShader(version, Shader::Type::Vertex);
Shader frag = Implementation::createCompatibilityShader(version, Shader::Type::Fragment);
Shader vert = Implementation::createCompatibilityShader(rs, version, Shader::Type::Vertex);
Shader frag = Implementation::createCompatibilityShader(rs, version, Shader::Type::Fragment);
vert.addSource(flags & Flag::Wireframe ? "#define WIREFRAME_RENDERING\n" : "")
.addSource(flags & Flag::NoGeometryShader ? "#define NO_GEOMETRY_SHADER\n" : "")
@ -76,7 +76,7 @@ MeshVisualizer::MeshVisualizer(const Flags flags): flags(flags), transformationP
#ifndef MAGNUM_TARGET_GLES
std::optional<Shader> geom;
if(flags & Flag::Wireframe && !(flags & Flag::NoGeometryShader)) {
geom = Implementation::createCompatibilityShader(version, Shader::Type::Geometry);
geom = Implementation::createCompatibilityShader(rs, version, Shader::Type::Geometry);
geom->addSource(rs.get("MeshVisualizer.geom"));
}
#endif

4
src/Magnum/Shaders/Phong.cpp

@ -53,8 +53,8 @@ Phong::Phong(const Flags flags): transformationMatrixUniform(0), projectionMatri
const Version version = Context::current()->supportedVersion({Version::GLES300, Version::GLES200});
#endif
Shader vert = Implementation::createCompatibilityShader(version, Shader::Type::Vertex);
Shader frag = Implementation::createCompatibilityShader(version, Shader::Type::Fragment);
Shader vert = Implementation::createCompatibilityShader(rs, version, Shader::Type::Vertex);
Shader frag = Implementation::createCompatibilityShader(rs, version, Shader::Type::Fragment);
vert.addSource(flags ? "#define TEXTURED\n" : "")
.addSource(rs.get("generic.glsl"))

4
src/Magnum/Shaders/Vector.cpp

@ -53,8 +53,8 @@ template<UnsignedInt dimensions> Vector<dimensions>::Vector(): transformationPro
#endif
Version version = Context::current()->supportedVersion(vs);
Shader vert = Implementation::createCompatibilityShader(version, Shader::Type::Vertex);
Shader frag = Implementation::createCompatibilityShader(version, Shader::Type::Fragment);
Shader vert = Implementation::createCompatibilityShader(rs, version, Shader::Type::Vertex);
Shader frag = Implementation::createCompatibilityShader(rs, version, Shader::Type::Fragment);
vert.addSource(rs.get("generic.glsl"))
.addSource(rs.get(vertexShaderName<dimensions>()));

4
src/Magnum/Shaders/VertexColor.cpp

@ -61,8 +61,8 @@ template<UnsignedInt dimensions> VertexColor<dimensions>::VertexColor(): transfo
Version version = Context::current()->supportedVersion(vs);
#endif
Shader vert = Implementation::createCompatibilityShader(version, Shader::Type::Vertex);
Shader frag = Implementation::createCompatibilityShader(version, Shader::Type::Fragment);
Shader vert = Implementation::createCompatibilityShader(rs, version, Shader::Type::Vertex);
Shader frag = Implementation::createCompatibilityShader(rs, version, Shader::Type::Fragment);
vert.addSource(rs.get("generic.glsl"))
.addSource(rs.get(vertexShaderName<dimensions>()));

37
src/Magnum/Test/AbstractQueryGLTest.cpp

@ -23,7 +23,7 @@
DEALINGS IN THE SOFTWARE.
*/
#include "Magnum/Query.h"
#include "Magnum/SampleQuery.h"
#include "Magnum/Test/AbstractOpenGLTester.h"
namespace Magnum { namespace Test {
@ -54,7 +54,11 @@ void AbstractQueryGLTest::construct() {
#endif
{
const SampleQuery query;
#ifndef MAGNUM_TARGET_GLES
const SampleQuery query{SampleQuery::Target::SamplesPassed};
#else
const SampleQuery query{SampleQuery::Target::AnySamplesPassed};
#endif
MAGNUM_VERIFY_NO_ERROR();
CORRADE_VERIFY(query.id() > 0);
@ -81,7 +85,11 @@ void AbstractQueryGLTest::constructMove() {
CORRADE_SKIP(Extensions::GL::EXT::occlusion_query_boolean::string() + std::string(" is not supported."));
#endif
SampleQuery a;
#ifndef MAGNUM_TARGET_GLES
SampleQuery a{SampleQuery::Target::SamplesPassed};
#else
SampleQuery a{SampleQuery::Target::AnySamplesPassed};
#endif
const Int id = a.id();
MAGNUM_VERIFY_NO_ERROR();
@ -92,7 +100,11 @@ void AbstractQueryGLTest::constructMove() {
CORRADE_COMPARE(a.id(), 0);
CORRADE_COMPARE(b.id(), id);
SampleQuery c;
#ifndef MAGNUM_TARGET_GLES
SampleQuery c{SampleQuery::Target::SamplesPassed};
#else
SampleQuery c{SampleQuery::Target::AnySamplesPassed};
#endif
const Int cId = c.id();
c = std::move(b);
@ -113,14 +125,21 @@ void AbstractQueryGLTest::label() {
!Context::current()->isExtensionSupported<Extensions::GL::EXT::debug_label>())
CORRADE_SKIP("Required extension is not available");
#ifndef MAGNUM_TARGET_GLES
SampleQuery query{SampleQuery::Target::SamplesPassed};
#else
SampleQuery query{SampleQuery::Target::AnySamplesPassed};
#endif
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::direct_state_access>())
#endif
{
/** @todo Is this even legal optimization? */
CORRADE_EXPECT_FAIL("The object must be used at least once before setting/querying label.");
query.begin(); query.end();
CORRADE_EXPECT_FAIL("Without ARB_direct_state_access, the object must be used at least once before setting/querying label.");
CORRADE_VERIFY(false);
}
SampleQuery query;
query.begin(SampleQuery::Target::AnySamplesPassed);
query.end();
CORRADE_COMPARE(query.label(), "");

11
src/Magnum/Test/AbstractTextureGLTest.cpp

@ -100,20 +100,15 @@ void AbstractTextureGLTest::label() {
!Context::current()->isExtensionSupported<Extensions::GL::EXT::debug_label>())
CORRADE_SKIP("Required extension is not available");
{
/** @todo Is this even legal optimization? */
CORRADE_EXPECT_FAIL("The object must be used at least once before setting/querying label.");
CORRADE_VERIFY(false);
}
Texture2D texture;
texture.setMinificationFilter(Sampler::Filter::Linear);
CORRADE_COMPARE(texture.label(), "");
MAGNUM_VERIFY_NO_ERROR();
texture.setLabel("MyTexture");
CORRADE_COMPARE(texture.label(), "MyTexture");
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(texture.label(), "MyTexture");
}
}}

73
src/Magnum/Test/BufferGLTest.cpp

@ -43,6 +43,12 @@ class BufferGLTest: public AbstractOpenGLTester {
void constructMove();
void label();
#ifndef MAGNUM_TARGET_GLES2
void bindBase();
void bindRange();
#endif
void data();
void map();
#ifdef MAGNUM_TARGET_GLES2
@ -58,7 +64,16 @@ class BufferGLTest: public AbstractOpenGLTester {
BufferGLTest::BufferGLTest() {
addTests({&BufferGLTest::construct,
&BufferGLTest::constructCopy,
&BufferGLTest::constructMove,
&BufferGLTest::label,
#ifndef MAGNUM_TARGET_GLES2
&BufferGLTest::bindBase,
&BufferGLTest::bindRange,
#endif
&BufferGLTest::data,
&BufferGLTest::map,
#ifdef MAGNUM_TARGET_GLES2
@ -78,7 +93,7 @@ void BufferGLTest::construct() {
MAGNUM_VERIFY_NO_ERROR();
CORRADE_VERIFY(buffer.id() > 0);
CORRADE_COMPARE(buffer.targetHint(), Buffer::Target::Array);
CORRADE_COMPARE(buffer.targetHint(), Buffer::TargetHint::Array);
CORRADE_COMPARE(buffer.size(), 0);
}
@ -125,22 +140,66 @@ void BufferGLTest::label() {
!Context::current()->isExtensionSupported<Extensions::GL::EXT::debug_label>())
CORRADE_SKIP("Required extension is not available");
{
/** @todo Is this even legal optimization? */
CORRADE_EXPECT_FAIL("The object must be used at least once before setting/querying label.");
CORRADE_VERIFY(false);
}
Buffer buffer;
buffer.setData({nullptr, 3}, BufferUsage::StaticDraw);
CORRADE_COMPARE(buffer.label(), "");
MAGNUM_VERIFY_NO_ERROR();
buffer.setLabel("MyBuffer");
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(buffer.label(), "MyBuffer");
}
#ifndef MAGNUM_TARGET_GLES2
void BufferGLTest::bindBase() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::uniform_buffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::uniform_buffer_object::string() + std::string{" is not supported."});
#endif
Buffer buffer;
buffer.bind(Buffer::Target::Uniform, 15);
MAGNUM_VERIFY_NO_ERROR();
Buffer::unbind(Buffer::Target::Uniform, 15);
MAGNUM_VERIFY_NO_ERROR();
Buffer::bind(Buffer::Target::Uniform, 7, {&buffer, nullptr, &buffer});
MAGNUM_VERIFY_NO_ERROR();
Buffer::unbind(Buffer::Target::Uniform, 7, 3);
MAGNUM_VERIFY_NO_ERROR();
}
void BufferGLTest::bindRange() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::uniform_buffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::uniform_buffer_object::string() + std::string{" is not supported."});
#endif
/* Check that we have correct offset alignment */
CORRADE_INTERNAL_ASSERT(256 % Buffer::uniformOffsetAlignment() == 0);
Buffer buffer;
buffer.setData({nullptr, 1024}, BufferUsage::StaticDraw)
.bind(Buffer::Target::Uniform, 15, 256, 13);
MAGNUM_VERIFY_NO_ERROR();
/** @todo C++14: get rid of std::make_tuple */
Buffer::bind(Buffer::Target::Uniform, 7, {
std::make_tuple(&buffer, 256, 13), {},
std::make_tuple(&buffer, 768, 64)});
MAGNUM_VERIFY_NO_ERROR();
}
#endif
void BufferGLTest::data() {
Buffer buffer;

25
src/Magnum/Test/BufferTextureGLTest.cpp

@ -67,19 +67,6 @@ void BufferTextureGLTest::bind() {
CORRADE_SKIP(Extensions::GL::ARB::texture_buffer_object::string() + std::string(" is not supported."));
BufferTexture texture;
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::multi_bind>()) {
CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it");
Buffer buffer;
constexpr UnsignedByte data[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};
buffer.setData(data, BufferUsage::StaticDraw);
texture.setBuffer(BufferTextureFormat::R8UI, buffer);
CORRADE_VERIFY(false);
}
texture.bind(15);
MAGNUM_VERIFY_NO_ERROR();
@ -91,6 +78,10 @@ void BufferTextureGLTest::bind() {
AbstractTexture::bind(7, {&texture, nullptr, &texture});
MAGNUM_VERIFY_NO_ERROR();
AbstractTexture::unbind(7, 3);
MAGNUM_VERIFY_NO_ERROR();
}
void BufferTextureGLTest::setBuffer() {
@ -113,6 +104,9 @@ void BufferTextureGLTest::setBufferOffset() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_buffer_object>())
CORRADE_SKIP(Extensions::GL::ARB::texture_buffer_object::string() + std::string(" is not supported."));
/* Check that we have correct offset alignment */
CORRADE_INTERNAL_ASSERT(256 % BufferTexture::offsetAlignment() == 0);
BufferTexture texture;
Buffer buffer;
constexpr UnsignedByte data[] = {
@ -121,8 +115,9 @@ void BufferTextureGLTest::setBufferOffset() {
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
};
buffer.setData(data, BufferUsage::StaticDraw);
texture.setBuffer(BufferTextureFormat::R8UI, buffer, 16, 8);
buffer.setData({nullptr, 1024}, BufferUsage::StaticDraw);
buffer.setSubData(256 - 16, data);
texture.setBuffer(BufferTextureFormat::R8UI, buffer, 256, 8);
MAGNUM_VERIFY_NO_ERROR();
}

6
src/Magnum/Test/ContextGLTest.cpp

@ -91,14 +91,14 @@ void ContextGLTest::isExtensionSupported() {
void ContextGLTest::isExtensionDisabled() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::APPLE::vertex_array_object>())
CORRADE_SKIP(Extensions::GL::APPLE::vertex_array_object::string() + std::string(" extension should be supported, can't test"));
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::vertex_array_object>())
CORRADE_SKIP(Extensions::GL::ARB::vertex_array_object::string() + std::string(" extension should be supported, can't test"));
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::explicit_attrib_location>())
CORRADE_SKIP(Extensions::GL::ARB::explicit_attrib_location::string() + std::string(" extension should be supported, can't test"));
/* This is not disabled anywhere */
CORRADE_VERIFY(!Context::current()->isExtensionDisabled<Extensions::GL::APPLE::vertex_array_object>());
CORRADE_VERIFY(!Context::current()->isExtensionDisabled<Extensions::GL::ARB::vertex_array_object>());
/* This is disabled in GL < 3.2 to work around GLSL compiler bugs */
CORRADE_VERIFY(Context::current()->isExtensionDisabled<Extensions::GL::ARB::explicit_attrib_location>(Version::GL310));

13
src/Magnum/Test/CubeMapTextureArrayGLTest.cpp

@ -103,15 +103,6 @@ void CubeMapTextureArrayGLTest::bind() {
CORRADE_SKIP(Extensions::GL::ARB::texture_cube_map_array::string() + std::string(" is not supported."));
CubeMapTextureArray texture;
#ifndef MAGNUM_TARGET_GLES
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::multi_bind>()) {
CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it.");
texture.setBaseLevel(0);
CORRADE_VERIFY(false);
}
#endif
texture.bind(15);
MAGNUM_VERIFY_NO_ERROR();
@ -123,6 +114,10 @@ void CubeMapTextureArrayGLTest::bind() {
AbstractTexture::bind(7, {&texture, nullptr, &texture});
MAGNUM_VERIFY_NO_ERROR();
AbstractTexture::unbind(7, 3);
MAGNUM_VERIFY_NO_ERROR();
}
void CubeMapTextureArrayGLTest::sampling() {

13
src/Magnum/Test/CubeMapTextureGLTest.cpp

@ -128,15 +128,6 @@ void CubeMapTextureGLTest::construct() {
void CubeMapTextureGLTest::bind() {
CubeMapTexture texture;
#ifndef MAGNUM_TARGET_GLES
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::multi_bind>()) {
CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it.");
texture.setBaseLevel(0);
CORRADE_VERIFY(false);
}
#endif
texture.bind(15);
MAGNUM_VERIFY_NO_ERROR();
@ -148,6 +139,10 @@ void CubeMapTextureGLTest::bind() {
AbstractTexture::bind(7, {&texture, nullptr, &texture});
MAGNUM_VERIFY_NO_ERROR();
AbstractTexture::unbind(7, 3);
MAGNUM_VERIFY_NO_ERROR();
}
void CubeMapTextureGLTest::sampling() {

12
src/Magnum/Test/FramebufferGLTest.cpp

@ -222,19 +222,7 @@ void FramebufferGLTest::label() {
!Context::current()->isExtensionSupported<Extensions::GL::EXT::debug_label>())
CORRADE_SKIP("Required extension is not available");
{
/** @todo Is this even legal optimization? */
CORRADE_EXPECT_FAIL("The object must be used at least once before setting/querying label.");
CORRADE_VERIFY(false);
}
Renderbuffer renderbuffer;
#ifndef MAGNUM_TARGET_GLES2
renderbuffer.setStorage(RenderbufferFormat::RGBA8, {128, 128});
#else
renderbuffer.setStorage(RenderbufferFormat::RGBA4, {128, 128});
#endif
Framebuffer framebuffer({{}, Vector2i(32)});
framebuffer.attachRenderbuffer(Framebuffer::BufferAttachment(Framebuffer::BufferAttachment::Depth), renderbuffer);
CORRADE_COMPARE(framebuffer.label(), "");
MAGNUM_VERIFY_NO_ERROR();

42
src/Magnum/Test/MeshGLTest.cpp

@ -233,7 +233,7 @@ void MeshGLTest::construct() {
MAGNUM_VERIFY_NO_ERROR();
#ifndef MAGNUM_TARGET_GLES
if(Context::current()->isExtensionSupported<Extensions::GL::APPLE::vertex_array_object>())
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::vertex_array_object>())
#elif defined(MAGNUM_TARGET_GLES2)
if(Context::current()->isExtensionSupported<Extensions::GL::OES::vertex_array_object>())
#endif
@ -264,7 +264,7 @@ void MeshGLTest::constructMove() {
MAGNUM_VERIFY_NO_ERROR();
#ifndef MAGNUM_TARGET_GLES
if(Context::current()->isExtensionSupported<Extensions::GL::APPLE::vertex_array_object>())
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::vertex_array_object>())
#elif defined(MAGNUM_TARGET_GLES2)
if(Context::current()->isExtensionSupported<Extensions::GL::OES::vertex_array_object>())
#endif
@ -284,7 +284,7 @@ void MeshGLTest::constructMove() {
MAGNUM_VERIFY_NO_ERROR();
#ifndef MAGNUM_TARGET_GLES
if(Context::current()->isExtensionSupported<Extensions::GL::APPLE::vertex_array_object>())
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::vertex_array_object>())
#elif defined(MAGNUM_TARGET_GLES2)
if(Context::current()->isExtensionSupported<Extensions::GL::OES::vertex_array_object>())
#endif
@ -302,21 +302,15 @@ void MeshGLTest::label() {
!Context::current()->isExtensionSupported<Extensions::GL::EXT::debug_label>())
CORRADE_SKIP("Required extension is not available");
{
/** @todo Is this even legal optimization? */
CORRADE_EXPECT_FAIL("The object must be used at least once before setting/querying label.");
CORRADE_VERIFY(false);
}
Buffer buffer{Buffer::Target::ElementArray};
Mesh mesh;
mesh.setIndexBuffer(buffer, 0, Mesh::IndexType::UnsignedShort);
CORRADE_COMPARE(mesh.label(), "");
MAGNUM_VERIFY_NO_ERROR();
mesh.setLabel("MyMesh");
CORRADE_COMPARE(mesh.label(), "MyMesh");
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(mesh.label(), "MyMesh");
}
namespace {
@ -912,8 +906,8 @@ void MeshGLTest::addVertexBufferIntWithShort() {
void MeshGLTest::addVertexBufferFloatWithHalfFloat() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::NV::half_float>())
CORRADE_SKIP(Extensions::GL::NV::half_float::string() + std::string(" is not supported."));
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::half_float_vertex>())
CORRADE_SKIP(Extensions::GL::ARB::half_float_vertex::string() + std::string(" is not supported."));
#elif defined(MAGNUM_TARGET_GLES2)
if(!Context::current()->isExtensionSupported<Extensions::GL::OES::vertex_half_float>())
CORRADE_SKIP(Extensions::GL::OES::vertex_half_float::string() + std::string(" is not supported."));
@ -1279,7 +1273,7 @@ void MeshGLTest::setIndexBuffer() {
vertices.setData(indexedVertexData, BufferUsage::StaticDraw);
constexpr UnsignedShort indexData[] = { 2, 1, 0 };
Buffer indices(Buffer::Target::ElementArray);
Buffer indices{Buffer::TargetHint::ElementArray};
indices.setData(indexData, BufferUsage::StaticDraw);
Mesh mesh;
@ -1306,7 +1300,7 @@ void MeshGLTest::setIndexBufferRange() {
vertices.setData(indexedVertexData, BufferUsage::StaticDraw);
constexpr UnsignedShort indexData[] = { 2, 1, 0 };
Buffer indices(Buffer::Target::ElementArray);
Buffer indices{Buffer::TargetHint::ElementArray};
indices.setData(indexData, BufferUsage::StaticDraw);
Mesh mesh;
@ -1338,7 +1332,7 @@ void MeshGLTest::setIndexBufferUnsignedInt() {
vertices.setData(indexedVertexData, BufferUsage::StaticDraw);
constexpr UnsignedInt indexData[] = { 2, 1, 0 };
Buffer indices(Buffer::Target::ElementArray);
Buffer indices{Buffer::TargetHint::ElementArray};
indices.setData(indexData, BufferUsage::StaticDraw);
Mesh mesh;
@ -1369,7 +1363,7 @@ void MeshGLTest::setBaseVertex() {
vertices.setData(indexedVertexDataBaseVertex, BufferUsage::StaticDraw);
constexpr UnsignedShort indexData[] = { 2, 1, 0 };
Buffer indices(Buffer::Target::ElementArray);
Buffer indices{Buffer::TargetHint::ElementArray};
indices.setData(indexData, BufferUsage::StaticDraw);
Mesh mesh;
@ -1445,7 +1439,7 @@ void MeshGLTest::setInstanceCountIndexed() {
vertices.setData(indexedVertexData, BufferUsage::StaticDraw);
constexpr UnsignedShort indexData[] = { 2, 1, 0 };
Buffer indices(Buffer::Target::ElementArray);
Buffer indices{Buffer::TargetHint::ElementArray};
indices.setData(indexData, BufferUsage::StaticDraw);
Mesh mesh;
@ -1517,7 +1511,7 @@ void MeshGLTest::setInstanceCountBaseInstanceIndexed() {
vertices.setData(indexedVertexData, BufferUsage::StaticDraw);
constexpr UnsignedShort indexData[] = { 2, 1, 0 };
Buffer indices(Buffer::Target::ElementArray);
Buffer indices{Buffer::TargetHint::ElementArray};
indices.setData(indexData, BufferUsage::StaticDraw);
Mesh mesh;
@ -1551,7 +1545,7 @@ void MeshGLTest::setInstanceCountBaseVertex() {
vertices.setData(indexedVertexDataBaseVertex, BufferUsage::StaticDraw);
constexpr UnsignedShort indexData[] = { 2, 1, 0 };
Buffer indices(Buffer::Target::ElementArray);
Buffer indices{Buffer::TargetHint::ElementArray};
indices.setData(indexData, BufferUsage::StaticDraw);
Mesh mesh;
@ -1587,7 +1581,7 @@ void MeshGLTest::setInstanceCountBaseVertexBaseInstance() {
vertices.setData(indexedVertexDataBaseVertex, BufferUsage::StaticDraw);
constexpr UnsignedShort indexData[] = { 2, 1, 0 };
Buffer indices(Buffer::Target::ElementArray);
Buffer indices{Buffer::TargetHint::ElementArray};
indices.setData(indexData, BufferUsage::StaticDraw);
Mesh mesh;
@ -1807,7 +1801,7 @@ void MeshGLTest::multiDrawIndexed() {
vertices.setData(indexedVertexData, BufferUsage::StaticDraw);
constexpr UnsignedShort indexData[] = { 2, 1, 0 };
Buffer indices(Buffer::Target::ElementArray);
Buffer indices{Buffer::TargetHint::ElementArray};
indices.setData(indexData, BufferUsage::StaticDraw);
Mesh mesh;
@ -1832,7 +1826,7 @@ void MeshGLTest::multiDrawBaseVertex() {
vertices.setData(indexedVertexDataBaseVertex, BufferUsage::StaticDraw);
constexpr UnsignedShort indexData[] = { 2, 1, 0 };
Buffer indices(Buffer::Target::ElementArray);
Buffer indices{Buffer::TargetHint::ElementArray};
indices.setData(indexData, BufferUsage::StaticDraw);
Mesh mesh;

24
src/Magnum/Test/MultisampleTextureGLTest.cpp

@ -135,15 +135,6 @@ void MultisampleTextureGLTest::bind2D() {
#endif
MultisampleTexture2D texture;
#ifndef MAGNUM_TARGET_GLES
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::multi_bind>()) {
CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it.");
texture.setStorage(4, TextureFormat::RGBA8, {16, 16});
CORRADE_VERIFY(false);
}
#endif
texture.bind(15);
MAGNUM_VERIFY_NO_ERROR();
@ -155,6 +146,10 @@ void MultisampleTextureGLTest::bind2D() {
AbstractTexture::bind(7, {&texture, nullptr, &texture});
MAGNUM_VERIFY_NO_ERROR();
AbstractTexture::unbind(7, 3);
MAGNUM_VERIFY_NO_ERROR();
}
#ifndef MAGNUM_TARGET_GLES
@ -163,13 +158,6 @@ void MultisampleTextureGLTest::bind2DArray() {
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
MultisampleTexture2DArray texture;
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::multi_bind>()) {
CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it.");
texture.setStorage(4, TextureFormat::RGBA8, {16, 16, 5});
CORRADE_VERIFY(false);
}
texture.bind(15);
MAGNUM_VERIFY_NO_ERROR();
@ -181,6 +169,10 @@ void MultisampleTextureGLTest::bind2DArray() {
AbstractTexture::bind(7, {&texture, nullptr, &texture});
MAGNUM_VERIFY_NO_ERROR();
AbstractTexture::unbind(7, 3);
MAGNUM_VERIFY_NO_ERROR();
}
#endif

6
src/Magnum/Test/PrimitiveQueryGLTest.cpp

@ -30,7 +30,7 @@
#include "Magnum/Buffer.h"
#include "Magnum/Framebuffer.h"
#include "Magnum/Mesh.h"
#include "Magnum/Query.h"
#include "Magnum/PrimitiveQuery.h"
#include "Magnum/Renderbuffer.h"
#include "Magnum/RenderbufferFormat.h"
#include "Magnum/Shader.h"
@ -94,8 +94,8 @@ void PrimitiveQueryGLTest::query() {
MAGNUM_VERIFY_NO_ERROR();
PrimitiveQuery q;
q.begin(PrimitiveQuery::Target::PrimitivesGenerated);
PrimitiveQuery q{PrimitiveQuery::Target::PrimitivesGenerated};
q.begin();
framebuffer.bind(FramebufferTarget::ReadDraw);
mesh.draw(shader);

13
src/Magnum/Test/RectangleTextureGLTest.cpp

@ -101,15 +101,6 @@ void RectangleTextureGLTest::bind() {
CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported."));
RectangleTexture texture;
#ifndef MAGNUM_TARGET_GLES
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::multi_bind>()) {
CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it.");
texture.setWrapping(Sampler::Wrapping::ClampToEdge);
CORRADE_VERIFY(false);
}
#endif
texture.bind(15);
MAGNUM_VERIFY_NO_ERROR();
@ -121,6 +112,10 @@ void RectangleTextureGLTest::bind() {
AbstractTexture::bind(7, {&texture, nullptr, &texture});
MAGNUM_VERIFY_NO_ERROR();
AbstractTexture::unbind(7, 3);
MAGNUM_VERIFY_NO_ERROR();
}
void RectangleTextureGLTest::sampling() {

20
src/Magnum/Test/RenderbufferGLTest.cpp

@ -118,29 +118,15 @@ void RenderbufferGLTest::label() {
CORRADE_SKIP(Extensions::GL::ARB::framebuffer_object::string() + std::string(" is not available."));
#endif
/* No-Op version is tested in AbstractObjectGLTest */
if(!Context::current()->isExtensionSupported<Extensions::GL::KHR::debug>() &&
!Context::current()->isExtensionSupported<Extensions::GL::EXT::debug_label>())
CORRADE_SKIP("Required extension is not available");
{
/** @todo Is this even legal optimization? */
CORRADE_EXPECT_FAIL("The object must be used at least once before setting/querying label.");
CORRADE_VERIFY(false);
}
Renderbuffer renderbuffer;
#ifndef MAGNUM_TARGET_GLES2
renderbuffer.setStorage(RenderbufferFormat::RGBA8, {128, 128});
#else
renderbuffer.setStorage(RenderbufferFormat::RGBA4, {128, 128});
#endif
CORRADE_COMPARE(renderbuffer.label(), "");
MAGNUM_VERIFY_NO_ERROR();
renderbuffer.setLabel("MyRenderbuffer");
CORRADE_COMPARE(renderbuffer.label(), "MyRenderbuffer");
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(renderbuffer.label(), "MyRenderbuffer");
}
void RenderbufferGLTest::setStorage() {

20
src/Magnum/Test/SampleQueryGLTest.cpp

@ -30,9 +30,9 @@
#include "Magnum/Buffer.h"
#include "Magnum/Framebuffer.h"
#include "Magnum/Mesh.h"
#include "Magnum/Query.h"
#include "Magnum/Renderbuffer.h"
#include "Magnum/RenderbufferFormat.h"
#include "Magnum/SampleQuery.h"
#include "Magnum/Shader.h"
#include "Magnum/Test/AbstractOpenGLTester.h"
@ -118,12 +118,12 @@ void SampleQueryGLTest::querySamplesPassed() {
MAGNUM_VERIFY_NO_ERROR();
SampleQuery q;
#ifndef MAGNUM_TARGET_GLES
q.begin(SampleQuery::Target::SamplesPassed);
SampleQuery q{SampleQuery::Target::SamplesPassed};
#else
q.begin(SampleQuery::Target::AnySamplesPassed);
SampleQuery q{SampleQuery::Target::AnySamplesPassed};
#endif
q.begin();
framebuffer.bind(FramebufferTarget::ReadDraw);
mesh.draw(shader);
@ -168,16 +168,18 @@ void SampleQueryGLTest::conditionalRender() {
MAGNUM_VERIFY_NO_ERROR();
SampleQuery qYes, qNo, q;
SampleQuery qYes{SampleQuery::Target::SamplesPassed},
qNo{SampleQuery::Target::SamplesPassed},
q{SampleQuery::Target::SamplesPassed};
/* This should generate some samples */
qYes.begin(SampleQuery::Target::SamplesPassed);
qYes.begin();
mesh.draw(shader);
qYes.end();
/* Thus this should be rendered */
qYes.beginConditionalRender(SampleQuery::ConditionalRenderMode::Wait);
q.begin(SampleQuery::Target::SamplesPassed);
q.begin();
mesh.draw(shader);
q.end();
qYes.endConditionalRender();
@ -187,12 +189,12 @@ void SampleQueryGLTest::conditionalRender() {
CORRADE_VERIFY(q.result<bool>());
/* This shouldn't generate any samples */
qNo.begin(SampleQuery::Target::SamplesPassed);
qNo.begin();
qNo.end();
/* Thus this should not be rendered */
qNo.beginConditionalRender(SampleQuery::ConditionalRenderMode::Wait);
q.begin(SampleQuery::Target::SamplesPassed);
q.begin();
mesh.draw(shader);
q.end();
qNo.endConditionalRender();

24
src/Magnum/Test/TextureArrayGLTest.cpp

@ -233,13 +233,6 @@ void TextureArrayGLTest::bind1D() {
CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported."));
Texture1DArray texture;
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::multi_bind>()) {
CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it.");
texture.setBaseLevel(0);
CORRADE_VERIFY(false);
}
texture.bind(15);
MAGNUM_VERIFY_NO_ERROR();
@ -251,6 +244,10 @@ void TextureArrayGLTest::bind1D() {
AbstractTexture::bind(7, {&texture, nullptr, &texture});
MAGNUM_VERIFY_NO_ERROR();
AbstractTexture::unbind(7, 3);
MAGNUM_VERIFY_NO_ERROR();
}
#endif
@ -261,15 +258,6 @@ void TextureArrayGLTest::bind2D() {
#endif
Texture2DArray texture;
#ifndef MAGNUM_TARGET_GLES
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::multi_bind>()) {
CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it.");
texture.setBaseLevel(0);
CORRADE_VERIFY(false);
}
#endif
texture.bind(15);
MAGNUM_VERIFY_NO_ERROR();
@ -281,6 +269,10 @@ void TextureArrayGLTest::bind2D() {
AbstractTexture::bind(7, {&texture, nullptr, &texture});
MAGNUM_VERIFY_NO_ERROR();
AbstractTexture::unbind(7, 3);
MAGNUM_VERIFY_NO_ERROR();
}
#ifndef MAGNUM_TARGET_GLES

37
src/Magnum/Test/TextureGLTest.cpp

@ -292,13 +292,6 @@ void TextureGLTest::construct3D() {
#ifndef MAGNUM_TARGET_GLES
void TextureGLTest::bind1D() {
Texture1D texture;
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::multi_bind>()) {
CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it.");
texture.setBaseLevel(0);
CORRADE_VERIFY(false);
}
texture.bind(15);
MAGNUM_VERIFY_NO_ERROR();
@ -310,20 +303,15 @@ void TextureGLTest::bind1D() {
AbstractTexture::bind(7, {&texture, nullptr, &texture});
MAGNUM_VERIFY_NO_ERROR();
AbstractTexture::unbind(7, 3);
MAGNUM_VERIFY_NO_ERROR();
}
#endif
void TextureGLTest::bind2D() {
Texture2D texture;
#ifndef MAGNUM_TARGET_GLES
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::multi_bind>()) {
CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it.");
texture.setBaseLevel(0);
CORRADE_VERIFY(false);
}
#endif
texture.bind(15);
MAGNUM_VERIFY_NO_ERROR();
@ -335,6 +323,10 @@ void TextureGLTest::bind2D() {
AbstractTexture::bind(7, {&texture, nullptr, &texture});
MAGNUM_VERIFY_NO_ERROR();
AbstractTexture::unbind(7, 3);
MAGNUM_VERIFY_NO_ERROR();
}
void TextureGLTest::bind3D() {
@ -344,15 +336,6 @@ void TextureGLTest::bind3D() {
#endif
Texture3D texture;
#ifndef MAGNUM_TARGET_GLES
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::multi_bind>()) {
CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it.");
texture.setBaseLevel(0);
CORRADE_VERIFY(false);
}
#endif
texture.bind(15);
MAGNUM_VERIFY_NO_ERROR();
@ -364,6 +347,10 @@ void TextureGLTest::bind3D() {
AbstractTexture::bind(7, {&texture, nullptr, &texture});
MAGNUM_VERIFY_NO_ERROR();
AbstractTexture::unbind(7, 3);
MAGNUM_VERIFY_NO_ERROR();
}
#ifndef MAGNUM_TARGET_GLES

24
src/Magnum/Test/TimeQueryGLTest.cpp

@ -23,7 +23,7 @@
DEALINGS IN THE SOFTWARE.
*/
#include "Magnum/Query.h"
#include "Magnum/TimeQuery.h"
#include "Magnum/Test/AbstractOpenGLTester.h"
namespace Magnum { namespace Test {
@ -50,23 +50,22 @@ void TimeQueryGLTest::queryTime() {
CORRADE_SKIP(Extensions::GL::EXT::disjoint_timer_query::string() + std::string(" is not available"));
#endif
TimeQuery q1;
q1.begin(TimeQuery::Target::TimeElapsed);
TimeQuery q1{TimeQuery::Target::TimeElapsed};
q1.begin();
q1.end();
const auto result1 = q1.result<UnsignedInt>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_VERIFY(result1 > 0);
TimeQuery q2;
q2.begin(TimeQuery::Target::TimeElapsed);
TimeQuery q2{TimeQuery::Target::TimeElapsed};
q2.begin();
Renderer::enable(Renderer::Feature::Blending);
Renderer::finish();
q2.end();
const auto result2 = q2.result<UnsignedInt>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_VERIFY(result2 > result1);
CORRADE_VERIFY(result2 >= result1);
}
void TimeQueryGLTest::queryTimestamp() {
@ -75,11 +74,13 @@ void TimeQueryGLTest::queryTimestamp() {
CORRADE_SKIP(Extensions::GL::EXT::disjoint_timer_query::string() + std::string(" is not available"));
#endif
TimeQuery q1, q2, q;
TimeQuery q1{TimeQuery::Target::Timestamp},
q2{TimeQuery::Target::Timestamp},
q{TimeQuery::Target::TimeElapsed};
q1.timestamp();
q.begin(TimeQuery::Target::TimeElapsed);
q.begin();
Renderer::enable(Renderer::Feature::Blending);
Renderer::finish();
q.end();
@ -91,9 +92,8 @@ void TimeQueryGLTest::queryTimestamp() {
const auto result2 = q2.result<UnsignedLong>();
MAGNUM_VERIFY_NO_ERROR();
CORRADE_VERIFY(result > 0);
CORRADE_VERIFY(result2 > result1);
CORRADE_VERIFY(result2-result1 > result);
CORRADE_VERIFY(result2 >= result1);
CORRADE_VERIFY(result2-result1 >= result);
}
}}

2
src/Magnum/Text/DistanceFieldGlyphCache.h

@ -49,7 +49,7 @@ Text::AbstractFont* font;
Text::GlyphCache* cache = new Text::DistanceFieldGlyphCache(Vector2i(2048), Vector2i(384));
font->createGlyphCache(cache, "abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789 ");
"0123456789?!:;,. ");
@endcode
@see @ref TextureTools::distanceField()

2
src/Magnum/Text/GlyphCache.h

@ -52,7 +52,7 @@ Text::AbstractFont* font;
Text::GlyphCache* cache = new GlyphCache(Vector2i(512));
font->createGlyphCache(cache, "abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789 ");
"0123456789?!:;,. ");
@endcode
See @ref Renderer for information about text rendering.

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save