Browse Source

Merge branch 'master' into compatibility

Conflicts:
	src/AbstractFramebuffer.h
	src/Context.cpp
	src/Context.h
	src/Framebuffer.h
	src/Math/Angle.h
	src/Math/Complex.h
	src/Math/Matrix3.h
	src/Math/Matrix4.h
	src/Math/Quaternion.h
	src/Math/RectangularMatrix.h
	src/Math/Unit.h
	src/Math/Vector.h
	src/Math/Vector2.h
	src/Math/Vector3.h
	src/Math/Vector4.h
	src/MeshTools/Clean.h
	src/Physics/AbstractShape.h
	src/Physics/Test/ShapeGroupTest.cpp
	src/Physics/Test/ShapeTestBase.h
	src/ResourceManager.h
	src/SceneGraph/DualComplexTransformation.h
	src/SceneGraph/DualQuaternionTransformation.h
	src/SceneGraph/FeatureGroup.h
	src/SceneGraph/MatrixTransformation2D.h
	src/SceneGraph/MatrixTransformation3D.h
	src/SceneGraph/Object.h
	src/SceneGraph/RigidMatrixTransformation2D.h
	src/SceneGraph/RigidMatrixTransformation3D.h
Vladimír Vondruš 13 years ago
parent
commit
a9eb5509ef
  1. 25
      CMakeLists.txt
  2. 255
      Doxyfile
  3. 4
      README.md
  4. 32
      doc/building.dox
  5. 6
      doc/cmake.dox
  6. 6
      doc/coding-style.dox
  7. 134
      doc/collision-detection.dox
  8. 2
      doc/compilation-speedup.dox
  9. 2
      doc/features.dox
  10. 4
      doc/mainpage.dox
  11. 17
      doc/method-chaining.dox
  12. 13
      doc/namespaces.dox
  13. 2
      doc/platform.dox
  14. 2
      doc/scenegraph.dox
  15. 120
      doc/shapes.dox
  16. 16
      external/OpenGL/GL/glcorearb.h
  17. 192
      external/OpenGL/GLES2/gl2ext.h
  18. 5
      modules/FindCorrade.cmake
  19. 24
      modules/FindMagnum.cmake
  20. 37
      modules/FindNodeJs.cmake
  21. 14
      modules/FindOpenGLES2.cmake
  22. 15
      modules/FindSDL2.cmake
  23. 108
      src/AbstractFramebuffer.cpp
  24. 249
      src/AbstractFramebuffer.h
  25. 189
      src/AbstractImage.cpp
  26. 470
      src/AbstractImage.h
  27. 46
      src/AbstractResourceLoader.h
  28. 105
      src/AbstractShaderProgram.cpp
  29. 636
      src/AbstractShaderProgram.h
  30. 165
      src/AbstractTexture.cpp
  31. 1104
      src/AbstractTexture.h
  32. 72
      src/Array.h
  33. 68
      src/Buffer.cpp
  34. 146
      src/Buffer.h
  35. 12
      src/BufferImage.cpp
  36. 8
      src/BufferImage.h
  37. 9
      src/BufferTexture.cpp
  38. 260
      src/BufferTexture.h
  39. 24
      src/CMakeLists.txt
  40. 82
      src/Color.h
  41. 67
      src/Context.cpp
  42. 102
      src/Context.h
  43. 97
      src/CubeMapTexture.h
  44. 88
      src/CubeMapTextureArray.h
  45. 2
      src/DebugMarker.h
  46. 4
      src/DebugTools/CMakeLists.txt
  47. 8
      src/DebugTools/ForceRenderer.cpp
  48. 12
      src/DebugTools/ForceRenderer.h
  49. 10
      src/DebugTools/Implementation/AbstractShapeRenderer.cpp
  50. 12
      src/DebugTools/Implementation/AbstractShapeRenderer.h
  51. 10
      src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp
  52. 6
      src/DebugTools/Implementation/AxisAlignedBoxRenderer.h
  53. 8
      src/DebugTools/Implementation/BoxRenderer.cpp
  54. 6
      src/DebugTools/Implementation/BoxRenderer.h
  55. 2
      src/DebugTools/Implementation/ForceRendererTransformation.h
  56. 8
      src/DebugTools/Implementation/LineSegmentRenderer.cpp
  57. 6
      src/DebugTools/Implementation/LineSegmentRenderer.h
  58. 8
      src/DebugTools/Implementation/PointRenderer.cpp
  59. 6
      src/DebugTools/Implementation/PointRenderer.h
  60. 10
      src/DebugTools/Implementation/SphereRenderer.cpp
  61. 6
      src/DebugTools/Implementation/SphereRenderer.h
  62. 26
      src/DebugTools/ObjectRenderer.cpp
  63. 8
      src/DebugTools/ObjectRenderer.h
  64. 4
      src/DebugTools/Profiler.h
  65. 2
      src/DebugTools/ResourceManager.h
  66. 75
      src/DebugTools/ShapeRenderer.cpp
  67. 38
      src/DebugTools/ShapeRenderer.h
  68. 2
      src/DebugTools/Test/ForceRendererTest.cpp
  69. 2
      src/DebugTools/Test/LineSegmentRendererTest.cpp
  70. 6
      src/DefaultFramebuffer.h
  71. 6
      src/Extensions.h
  72. 44
      src/Framebuffer.h
  73. 10
      src/Image.cpp
  74. 20
      src/Image.h
  75. 128
      src/ImageFormat.cpp
  76. 454
      src/ImageFormat.h
  77. 12
      src/ImageWrapper.h
  78. 2
      src/Implementation/BufferState.h
  79. 3
      src/Implementation/FramebufferState.h
  80. 2
      src/Implementation/MeshState.h
  81. 22
      src/Implementation/RendererState.h
  82. 4
      src/Implementation/ShaderProgramState.h
  83. 3
      src/Implementation/State.cpp
  84. 2
      src/Implementation/State.h
  85. 10
      src/Implementation/TextureState.cpp
  86. 5
      src/Implementation/TextureState.h
  87. 26
      src/Magnum.h
  88. 6
      src/Math/Algorithms/Svd.h
  89. 32
      src/Math/Angle.h
  90. 137
      src/Math/BoolVector.h
  91. 36
      src/Math/Complex.cpp
  92. 71
      src/Math/Complex.h
  93. 18
      src/Math/Constants.h
  94. 42
      src/Math/Dual.h
  95. 36
      src/Math/DualComplex.cpp
  96. 56
      src/Math/DualComplex.h
  97. 36
      src/Math/DualQuaternion.cpp
  98. 44
      src/Math/DualQuaternion.h
  99. 24
      src/Math/Functions.h
  100. 156
      src/Math/Geometry/Distance.h
  101. Some files were not shown because too many files have changed in this diff Show More

25
CMakeLists.txt

@ -35,16 +35,16 @@ cmake_dependent_option(TARGET_DESKTOP_GLES "Build for OpenGL ES on desktop" OFF
# Parts of the library
option(WITH_DEBUGTOOLS "Build DebugTools library" ON)
cmake_dependent_option(WITH_MESHTOOLS "Build MeshTools library" ON "NOT WITH_DEBUGTOOLS" ON)
cmake_dependent_option(WITH_PHYSICS "Build Physics library" ON "NOT WITH_DEBUGTOOLS" ON)
cmake_dependent_option(WITH_PRIMITIVES "Builf Primitives library" ON "NOT WITH_DEBUGTOOLS" ON)
cmake_dependent_option(WITH_SCENEGRAPH "Build SceneGraph library" ON "NOT WITH_DEBUGTOOLS;NOT WITH_PHYSICS" ON)
cmake_dependent_option(WITH_SCENEGRAPH "Build SceneGraph library" ON "NOT WITH_DEBUGTOOLS;NOT WITH_SHAPES" ON)
cmake_dependent_option(WITH_SHADERS "Build Shaders library" ON "NOT WITH_DEBUGTOOLS" ON)
cmake_dependent_option(WITH_SHAPES "Build Shapes library" ON "NOT WITH_DEBUGTOOLS" ON)
option(WITH_TEXT "Build Text library" ON)
cmake_dependent_option(WITH_TEXTURETOOLS "Build TextureTools library" ON "NOT WITH_TEXT" ON)
option(WITH_MAGNUMINFO "Build magnum-info utility" ON)
option(WITH_MAGNUMINFO "Build magnum-info utility" OFF)
# Application libraries
if(${CMAKE_SYSTEM_NAME} STREQUAL NaCl)
if(CORRADE_TARGET_NACL)
option(WITH_NACLAPPLICATION "Build NaClApplication library" OFF)
else()
option(WITH_GLXAPPLICATION "Build GlxApplication library" OFF)
@ -73,14 +73,19 @@ endif()
find_package(Corrade REQUIRED)
if(BUILD_STATIC)
set(MAGNUM_BUILD_STATIC 1)
endif()
# If targeting NaCl, set explicit OpenGL ES 2.0 support
if(CORRADE_TARGET_NACL)
# If targeting NaCl or Emscripten, set explicit OpenGL ES 2.0 support
if(CORRADE_TARGET_NACL OR CORRADE_TARGET_EMSCRIPTEN)
set(TARGET_GLES 1)
set(TARGET_GLES2 1)
# Newlib toolchain supports only static linking
if(CORRADE_TARGET_NACL_NEWLIB)
set(BUILD_STATIC OFF)
endif()
endif()
if(BUILD_STATIC)
set(MAGNUM_BUILD_STATIC 1)
endif()
# Check dependencies

255
Doxyfile

@ -1,8 +1,10 @@
# Doxyfile 1.8.1
# Doxyfile 1.8.4
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
#
# All text after a double hash (##) is considered a comment and is placed
# in front of the TAG it is preceding .
# All text after a hash (#) is considered a comment and will be ignored.
# The format is:
# TAG = value [value, ...]
@ -70,9 +72,9 @@ CREATE_SUBDIRS = NO
# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
# messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian,
# Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic,
# Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
OUTPUT_LANGUAGE = English
@ -126,7 +128,9 @@ FULL_PATH_NAMES = YES
# only done if one of the specified strings matches the left-hand part of
# the path. The tag can be used to show relative paths in the file list.
# If left blank the directory from which doxygen is run is used as the
# path to strip.
# path to strip. Note that you specify absolute paths here, but also
# relative paths, which will be relative from the directory where doxygen is
# started.
STRIP_FROM_PATH = ../
@ -254,14 +258,15 @@ OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
# Doxygen selects the parser to use depending on the extension of the files it
# parses. With this tag you can assign which parser to use for a given extension.
# Doxygen has a built-in mapping, but you can override or extend it using this
# tag. The format is ext=language, where ext is a file extension, and language
# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
# parses. With this tag you can assign which parser to use for a given
# extension. Doxygen has a built-in mapping, but you can override or extend it
# using this tag. The format is ext=language, where ext is a file extension,
# and language is one of the parsers supported by doxygen: IDL, Java,
# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C,
# C++. For instance to make doxygen treat .inc files as Fortran files (default
# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note
# that for custom extensions you also need to set FILE_PATTERNS otherwise the
# files are not read by doxygen.
EXTENSION_MAPPING =
@ -274,6 +279,13 @@ EXTENSION_MAPPING =
MARKDOWN_SUPPORT = YES
# When enabled doxygen tries to link words that correspond to documented
# classes, or namespaces to their corresponding documentation. Such a link can
# be prevented in individual cases by by putting a % sign in front of the word
# or globally by setting AUTOLINK_SUPPORT to NO.
AUTOLINK_SUPPORT = YES
# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
# to include (a tag file for) the STL sources as input, then you should
# set this tag to YES in order to let doxygen match functions declarations and
@ -294,10 +306,10 @@ CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO
# For Microsoft's IDL there are propget and propput attributes to indicate getter
# and setter methods for a property. Setting this option to YES (the default)
# will make doxygen replace the get and set methods by a property in the
# documentation. This will only work if the methods are indeed getting or
# For Microsoft's IDL there are propget and propput attributes to indicate
# getter and setter methods for a property. Setting this option to YES (the
# default) will make doxygen replace the get and set methods by a property in
# the documentation. This will only work if the methods are indeed getting or
# setting a simple type. If this is not the case, or you want to show the
# methods anyway, you should set this option to NO.
@ -326,13 +338,13 @@ SUBGROUPING = YES
INLINE_GROUPED_CLASSES = NO
# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
# unions with only public data fields will be shown inline in the documentation
# of the scope in which they are defined (i.e. file, namespace, or group
# documentation), provided this scope is documented. If set to NO (the default),
# structs, classes, and unions are shown on a separate page (for HTML and Man
# pages) or section (for LaTeX and RTF).
# unions with only public data fields or simple typedef fields will be shown
# inline in the documentation of the scope in which they are defined (i.e. file,
# namespace, or group documentation), provided this scope is documented. If set
# to NO (the default), structs, classes, and unions are shown on a separate
# page (for HTML and Man pages) or section (for LaTeX and RTF).
# `YES` causes unclosed <compound> element for TgaImporter class in tag file
## `YES` causes unclosed <compound> element for TgaImporter class in tag file
INLINE_SIMPLE_STRUCTS = NO
# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
@ -345,30 +357,14 @@ INLINE_SIMPLE_STRUCTS = NO
TYPEDEF_HIDES_STRUCT = NO
# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
# determine which symbols to keep in memory and which to flush to disk.
# When the cache is full, less often used symbols will be written to disk.
# For small to medium size projects (<1000 input files) the default value is
# probably good enough. For larger projects a too small cache size can cause
# doxygen to be busy swapping symbols to and from disk most of the time
# causing a significant performance penalty.
# If the system has enough physical memory increasing the cache will improve the
# performance by keeping more symbols in memory. Note that the value works on
# a logarithmic scale so increasing the size by one will roughly double the
# memory usage. The cache size is given by this formula:
# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
# corresponding to a cache size of 2^16 = 65536 symbols.
SYMBOL_CACHE_SIZE = 0
# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
# their name and scope. Since this can be an expensive process and often the
# same symbol appear multiple times in the code, doxygen keeps a cache of
# pre-resolved symbols. If the cache is too small doxygen will become slower.
# If the cache is too large, memory is wasted. The cache size is given by this
# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
# corresponding to a cache size of 2^16 = 65536 symbols.
# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
# cache is used to resolve symbols given their name and scope. Since this can
# be an expensive process and often the same symbol appear multiple times in
# the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too
# small doxygen will become slower. If the cache is too large, memory is wasted.
# The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid
# range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536
# symbols.
LOOKUP_CACHE_SIZE = 0
@ -379,7 +375,7 @@ LOOKUP_CACHE_SIZE = 0
# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
# documentation are documented, even if no documentation was available.
# Private class members and static file members will be hidden unless
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
# the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES
EXTRACT_ALL = NO
@ -388,7 +384,8 @@ EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal scope will be included in the documentation.
# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
# scope will be included in the documentation.
EXTRACT_PACKAGE = NO
@ -490,7 +487,7 @@ INLINE_INFO = YES
# alphabetically by member name. If set to NO the members will appear in
# declaration order.
SORT_MEMBER_DOCS = YES
SORT_MEMBER_DOCS = NO
# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
# brief documentation of file, namespace and class members alphabetically
@ -559,7 +556,8 @@ GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
# The ENABLED_SECTIONS tag can be used to enable conditional
# documentation sections, marked by \if sectionname ... \endif.
# documentation sections, marked by \if section-label ... \endif
# and \cond section-label ... \endcond blocks.
ENABLED_SECTIONS =
@ -604,7 +602,7 @@ FILE_VERSION_FILTER =
# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
# by doxygen. The layout file controls the global structure of the generated
# output files in an output format independent way. The create the layout file
# output files in an output format independent way. To create the layout file
# that represents doxygen's defaults, run doxygen with the -l option.
# You can optionally specify a file name after the option, if omitted
# DoxygenLayout.xml will be used as the name of the layout file.
@ -617,7 +615,8 @@ LAYOUT_FILE =
# requires the bibtex tool to be installed. See also
# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
# feature you need bibtex and perl available in the search path.
# feature you need bibtex and perl available in the search path. Do not use
# file names with spaces, bibtex cannot handle them.
CITE_BIB_FILES =
@ -734,9 +733,7 @@ EXCLUDE_SYMLINKS = NO
# against the file with absolute path, so to exclude all test directories
# for example use the pattern */test/*
EXCLUDE_PATTERNS = */Test/* \
*/Implementation/* \
*Visibility.h
EXCLUDE_PATTERNS =
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
@ -744,7 +741,8 @@ EXCLUDE_PATTERNS = */Test/* \
# wildcard * is used, a substring. Examples: ANamespace, AClass,
# AClass::ANamespace, ANamespace::*Test
EXCLUDE_SYMBOLS =
EXCLUDE_SYMBOLS = Magnum::*Implementation \
Magnum::*Test
# The EXAMPLE_PATH tag can be used to specify one or more files or
# directories that contain example code fragments that are included (see
@ -778,8 +776,10 @@ IMAGE_PATH = ../magnum-examples/src/
# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
# input file. Doxygen will then use the output that the filter program writes
# to standard output.
# If FILTER_PATTERNS is specified, this tag will be
# ignored.
# If FILTER_PATTERNS is specified, this tag will be ignored.
# Note that the filter must not add or remove lines; it is applied before the
# code is scanned, but not when the output code is generated. If lines are added
# or removed, the anchors will not be placed correctly.
INPUT_FILTER =
@ -808,6 +808,13 @@ FILTER_SOURCE_FILES = NO
FILTER_SOURCE_PATTERNS =
# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that
# is part of the input, its contents will be placed on the main page
# (index.html). This can be useful if you have a project on for instance GitHub
# and want reuse the introduction page also for the doxygen output.
USE_MDFILE_AS_MAINPAGE =
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
@ -826,7 +833,7 @@ INLINE_SOURCES = NO
# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
# doxygen to hide any special comment blocks from generated source code
# fragments. Normal C and C++ comments will always remain visible.
# fragments. Normal C, C++ and Fortran comments will always remain visible.
STRIP_CODE_COMMENTS = YES
@ -929,17 +936,27 @@ HTML_FOOTER =
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
# style sheet that is used by each HTML page. It can be used to
# fine-tune the look of the HTML output. If the tag is left blank doxygen
# will generate a default style sheet. Note that doxygen will try to copy
# the style sheet file to the HTML output directory, so don't put your own
# style sheet in the HTML output directory as well, or it will be erased!
# fine-tune the look of the HTML output. If left blank doxygen will
# generate a default style sheet. Note that it is recommended to use
# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this
# tag will in the future become obsolete.
HTML_STYLESHEET =
# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional
# user-defined cascading style sheet that is included after the standard
# style sheets created by doxygen. Using this option one can overrule
# certain style aspects. This is preferred over using HTML_STYLESHEET
# since it does not replace the standard style sheet and is therefor more
# robust against future updates. Doxygen will copy the style sheet file to
# the output directory.
HTML_EXTRA_STYLESHEET =
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the HTML output directory. Note
# that these files will be copied to the base HTML output directory. Use the
# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
# files. In the HTML_STYLESHEET file, use the file name only. Also note that
# the files will be copied as-is; there are no commands or markers available.
@ -978,9 +995,7 @@ HTML_TIMESTAMP = YES
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the
# page has loaded. For this to work a browser that supports
# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
# page has loaded.
HTML_DYNAMIC_SECTIONS = NO
@ -1022,9 +1037,9 @@ DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_BUNDLE_ID = org.doxygen.Project
# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
# the documentation publisher. This should be a reverse domain-name style
# string, e.g. com.mycompany.MyDocSet.documentation.
# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely
# identify the documentation publisher. This should be a reverse domain-name
# style string, e.g. com.mycompany.MyDocSet.documentation.
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
@ -1209,6 +1224,13 @@ FORMULA_TRANSPARENT = YES
USE_MATHJAX = NO
# When MathJax is enabled you can set the default output format to be used for
# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and
# SVG. The default value is HTML-CSS, which is slower, but has the best
# compatibility.
MATHJAX_FORMAT = HTML-CSS
# When MathJax is enabled you need to specify the location relative to the
# HTML output directory using the MATHJAX_RELPATH option. The destination
# directory should contain the MathJax.js script. For instance, if the mathjax
@ -1226,6 +1248,11 @@ MATHJAX_RELPATH = http://www.mathjax.org/mathjax
MATHJAX_EXTENSIONS =
# The MATHJAX_CODEFILE tag can be used to specify a file with javascript
# pieces of code that will be used on startup of the MathJax code.
MATHJAX_CODEFILE =
# When the SEARCHENGINE tag is enabled doxygen will generate a search box
# for the HTML output. The underlying search engine uses javascript
# and DHTML and should work on any modern browser. Note that when using
@ -1237,15 +1264,55 @@ MATHJAX_EXTENSIONS =
SEARCHENGINE = YES
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
# implemented using a PHP enabled web server instead of at the web client
# using Javascript. Doxygen will generate the search PHP script and index
# file to put on the web server. The advantage of the server
# based approach is that it scales better to large projects and allows
# full text search. The disadvantages are that it is more difficult to setup
# and does not have live searching capabilities.
# implemented using a web server instead of a web client using Javascript.
# There are two flavours of web server based search depending on the
# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
# searching and an index file used by the script. When EXTERNAL_SEARCH is
# enabled the indexing and searching needs to be provided by external tools.
# See the manual for details.
SERVER_BASED_SEARCH = NO
# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP
# script for searching. Instead the search results are written to an XML file
# which needs to be processed by an external indexer. Doxygen will invoke an
# external search engine pointed to by the SEARCHENGINE_URL option to obtain
# the search results. Doxygen ships with an example indexer (doxyindexer) and
# search engine (doxysearch.cgi) which are based on the open source search
# engine library Xapian. See the manual for configuration details.
EXTERNAL_SEARCH = NO
# The SEARCHENGINE_URL should point to a search engine hosted by a web server
# which will returned the search results when EXTERNAL_SEARCH is enabled.
# Doxygen ships with an example search engine (doxysearch) which is based on
# the open source search engine library Xapian. See the manual for configuration
# details.
SEARCHENGINE_URL =
# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
# search data is written to a file for indexing by an external tool. With the
# SEARCHDATA_FILE tag the name of this file can be specified.
SEARCHDATA_FILE = searchdata.xml
# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the
# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
# projects and redirect the results back to the right project.
EXTERNAL_SEARCH_ID =
# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
# projects other than the one defined by this configuration file, but that are
# all added to the same external search index. Each project needs to have a
# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id
# of to a relative location where the documentation can be found.
# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ...
EXTRA_SEARCH_MAPPINGS =
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
@ -1283,7 +1350,7 @@ COMPACT_LATEX = NO
# The PAPER_TYPE tag can be used to set the paper type that is used
# by the printer. Possible values are: a4, letter, legal and
# executive. If left blank a4wide will be used.
# executive. If left blank a4 will be used.
PAPER_TYPE = a4
@ -1306,6 +1373,13 @@ LATEX_HEADER =
LATEX_FOOTER =
# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images
# or other source files which should be copied to the LaTeX output directory.
# Note that the files will be copied as-is; there are no commands or markers
# available.
LATEX_EXTRA_FILES =
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
# is prepared for conversion to pdf (using ps2pdf). The pdf file will
# contain links (just like the HTML output) instead of page references
@ -1450,6 +1524,21 @@ XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options related to the DOCBOOK output
#---------------------------------------------------------------------------
# If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files
# that can be used to generate PDF.
GENERATE_DOCBOOK = NO
# The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
# front of it. If left blank docbook will be used as the default path.
DOCBOOK_OUTPUT = docbook
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
@ -1597,7 +1686,13 @@ ALLEXTERNALS = NO
# in the modules index. If set to NO, only the current project's groups will
# be listed.
EXTERNAL_GROUPS = YES
EXTERNAL_GROUPS = NO
# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed
# in the related pages index. If set to NO, only the current project's
# pages will be listed.
EXTERNAL_PAGES = NO
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of `which perl').
@ -1695,7 +1790,7 @@ UML_LOOK = NO
# the class node. If there are many fields or methods and many nodes the
# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
# threshold limits the number of items for each type to make the size more
# managable. Set this to 0 for no limit. Note that the threshold may be
# manageable. Set this to 0 for no limit. Note that the threshold may be
# exceeded by 50% before the limit is enforced.
UML_LIMIT_NUM_FIELDS = 10

4
README.md

@ -43,8 +43,8 @@ SUPPORTED PLATFORMS
* **Linux** and embedded Linux (natively using GLX/EGL and Xlib or through
GLUT or SDL2 toolkit)
* **Windows** (through GLUT or SDL2 toolkit)
* **Google Chrome Native Client** (natively using PPAPI, both `newlib`
and `glibc` toolchains are supported)
* **Google Chrome** (through [Native Client](https://developers.google.com/native-client/),
both `newlib` and `glibc` toolchains are supported)
FEATURES
========

32
doc/building.dox

@ -97,17 +97,17 @@ below). Using `WITH_*` CMake parameters you can specify which parts will be buil
and which not:
- `WITH_DEBUGTOOLS` - DebugTools library. Enables also building of MeshTools,
Physics, Primitives, SceneGraph and Shaders libraries.
Primitives, SceneGraph, Shaders and Shapes libraries.
- `WITH_MESHTOOLS` - MeshTools library. Enabled automatically if `WITH_DEBUGTOOLS`
is enabled.
- `WITH_PHYSICS` - Physics library. Enables also building of SceneGraph
library. Enabled automatically if `WITH_DEBUGTOOLS` is enabled.
- `WITH_PRIMITIVES` - Primitives library. Enabled automatically if `WITH_DEBUGTOOLS`
is enabled.
- `WITH_SCENEGRAPH` - SceneGraph library. Enabled automatically if `WITH_DEBUGTOOLS`
or `WITH_PHYSICS` is enabled.
or `WITH_SHAPES` is enabled.
- `WITH_SHADERS` - Shaders library. Enabled automatically if `WITH_DEBUGTOOLS`
is enabled.
- `WITH_SHAPES` - Shapes library. Enables also building of SceneGraph library.
Enabled automatically if `WITH_DEBUGTOOLS` is enabled.
- `WITH_TEXT` - Text library. Enables also building of TextureTools library.
- `WITH_TEXTURETOOLS` - TextureTools library. Enabled automatically if `WITH_TEXT`
is enabled.
@ -207,17 +207,21 @@ depending projects.
You will need [Native Client SDK](https://developers.google.com/native-client/beta/sdk/download).
Tested version is `pepper_22`.
Make sure you have `toolchains` Git submodule updated, as
@ref building-download "explained above". Don't forget to adapt `NACL_PREFIX`
variable in `generic/NaCl-glibc-x86-32.cmake` and `generic/NaCl-glibc-x86-64.cmake`
to path where your SDK is installed. Default is `/usr/nacl`. You may need to
adapt also `NACL_TOOLCHAIN_PATH` so CMake is able to find the compiler.
Make sure you have `toolchains` submodule updated, as
@ref building-download "explained above". You can choose from either `glibc` or
`newlib` toolchain. `Newlib` supports only static linking, thus `BUILD_STATIC`
is always enabled. Don't forget to adapt `NACL_PREFIX` variable in
`generic/NaCl-*-x86-32.cmake` and `generic/NaCl-*-x86-64.cmake` to path where
your SDK is installed. Default is `/usr/nacl`. You may need to adapt also
`NACL_TOOLCHAIN_PATH` so CMake is able to find the compiler. NaCl currently
supports only OpenGL ES 2, thus `TARGET_GLES` and `TARGET_GLES2` is always
enabled.
Then create build directories for x86-32 and x86-64 and run cmake and make in
them. The toolchains needs access to its platform file, so be sure to properly
them. The toolchains need access to its platform file, so be sure to properly
set **absolute** path to `modules/` directory containing `Platform/NaCl.cmake`.
Also adapt `CMAKE_INSTALL_PREFIX` to the same value you entered into toolchain
files above.
Also adapt `CMAKE_INSTALL_PREFIX` to the same value as in `NACL_PREFIX` in
toolchain file.
mkdir -p build-nacl-x86-32
cd build-nacl-x86-32
@ -243,8 +247,8 @@ files above.
Then you can install both versions using `make install` to make them available
for depending projects. The headers are shared by both versions.
For ArchLinux there is also prepared package file in root, named
`PKGBUILD-nacl`.
For ArchLinux there are also prepared package files in root, named
`PKGBUILD-nacl-glibc` and `PKGBUILD-nacl-newlib`.
*/
}

6
doc/cmake.dox

@ -51,13 +51,13 @@ components. The base library depends on %Corrade, OpenGL and GLEW libraries (or
OpenGL ES libraries). Additional dependencies are specified by the components.
The optional components are:
- `%DebugTools` -- DebugTools library (depends on `%MeshTools`, `%Physics`,
`%Primitives`, `%SceneGraph` and `%Shaders` components)
- `%DebugTools` -- DebugTools library (depends on `%MeshTools`,
`%Primitives`, `%SceneGraph`, `%Shaders` and `%Shapes` components)
- `%MeshTools` -- MeshTools library
- `%Physics` -- Physics library (depends on `%SceneGraph` component)
- `%Primitives` -- Primitives library
- `%SceneGraph` -- SceneGraph library
- `%Shaders` -- Shaders library
- `%Shapes` -- Shapes library (depends on `%SceneGraph` component)
- `%Text` -- Text library (depends on `%TextureTools` component)
- `%TextureTools` -- TextureTools library

6
doc/coding-style.dox

@ -100,9 +100,9 @@ void setPolygonMode(PolygonMode mode);
Additionally to @c \@todoc, @c \@debugoperator @c \@configurationvalue and
@c \@configurationvalueref (same as in Corrade), these are defined:
@subsubsection documentation-commands-collisionoperator Physics collision operators
@subsubsection documentation-commands-collisionoperator Shape collision operators
Out-of-class operators for collision in Physics namespace should be marked with
Out-of-class operators for collision in Shapes namespace should be marked with
@c \@collisionoperator, e.g.:
@code
// @collisionoperator{Point,Sphere}
@ -139,7 +139,7 @@ in @c \@see block with @c \@fn_gl command. If only specific definition is used
in the function, document it with @c \@def_gl command. Example usage:
@code
// @see @fn_gl{Enable}/@fn_gl{Disable} with @def_gl{TEXTURE_CUBE_MAP_SEAMLESS}
inline static void setSeamless(bool enabled) {
static void setSeamless(bool enabled) {
enabled ? glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS) : glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
}
@endcode

134
doc/collision-detection.dox

@ -1,134 +0,0 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 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.
*/
namespace Magnum { namespace Physics {
/** @page collision-detection Collision detection
@brief Collection of simple shapes for high performance collision detection.
The essential thing in collision detection is to define a complex object with
collection of simple shapes, for which it is easy to detect collisions. These
shapes can be either one-, two- or three-dimensional and they can be grouped
together using various operations.
@tableofcontents
@section collision-detection-shape-collection Available shapes
@subsection collision-detection-shapes1D One-dimensional shapes
- @ref Physics::Point "Physics::Point*D" - @copybrief Physics::Point
- @ref Physics::Line "Physics::Line*D" - @copybrief Physics::Line
- @ref Physics::LineSegment "Physics::LineSegment*D" - @copybrief Physics::LineSegment
Because of numerical instability it's not possible to detect collisions of
line and point. Collision of two lines can be detected only in 2D.
@subsection collision-detection-shapes2D Two-dimensional shapes
- Physics::Plane - @copybrief Physics::Plane
@subsection collision-detection-shapes3D Three-dimensional shapes
- @ref Physics::Sphere "Physics::Sphere*D" - @copybrief Physics::Sphere
- @ref Physics::Capsule "Physics::Capsule*D" - @copybrief Physics::Capsule
- @ref Physics::AxisAlignedBox "Physics::AxisAlignedBox*D" - @copybrief Physics::AxisAlignedBox
- @ref Physics::Box "Physics::Box*D" - @copybrief Physics::Box
The easiest (and most efficient) shape combination for detecting collisions
is point and sphere, followed by two spheres. Computing collision of two boxes
is least efficient.
@section collision-detection-shape-groups Creating hierarchic groups of shapes
Shapes can be grouped together using one of three available logical
operations: AND, OR and NOT. These operations are mapped to operator&&(),
operator||() and operator!(), so for example creating negation of logical OR
of line segment and point is simple as this:
@code
Physics::LineSegment3D segment;
Physics::Point3D point;
Physics::ShapeGroup3D group = !(segment || point);
@endcode
@note Logical operations are not the same as set operations -- intersection of
two spheres will not generate any collision if they are disjoint, but
logical AND will if the object collides with both of them.
The resulting object internally stores copies of both shapes, so the original
instances can be destroyed. For simple combinations appropriate resulting
shape is generated (e.g. logical OR of point and sphere can be only the sphere,
if the point lies inside) and stored inside ShapeGroup instead of two original
objects.
@subsection collision-detection-shape-reference Referencing the shapes for later changes
Sometimes you may want to modify the shape based on changes of the object
itself. In previous example all the shapes were copied into ShapeGroup, so it
was not possible to change their properties such as sphere radius without
recreating the group again. You can, however, explicitly pass a reference to
original object, so you can change it later:
@code
Physics::LineSegment3D segment;
Physics::Point3D point;
Physics::ShapeGroup3D group = !(segment || std::ref(point));
point.setPosition({1.0f, -6.0f, 0.5f});
@endcode
Note that passing a reference implies that you must not destroy the original
instance (in this case the point). Also because the referenced instance could
change, there are no shape optimizations done, unlike above.
@subsection collision-detection-shape-simplification Providing simplified version of shape for better performance
If there are many shapes grouped together, it might hurt performance of
collision detection, because it might be testing collision with more shapes
than necessary. It's then good to specify simplified version of such shape,
so the collision detection is done on the original if and only if collision
was detected with the simplified shape. It is in fact logical AND using
operator&&() - the collision is initially detected on first (simplified) shape
and then on the other:
@code
Physics::Sphere3D sphere;
Physics::Box3D box;
Physics::AxisAlignedBox3D simplified;
Physics::ShapeGroup3D object = simplified && (sphere || box);
@endcode
@section collision-detection-shape-collisions Detecting shape collisions
Shape pairs which have collision detection implemented can be tested for
collision using operator%(), for example:
@code
Physics::Point3D point;
Physics::Sphere3D sphere;
bool collide = point % sphere;
@endcode
*/
}}}

2
doc/compilation-speedup.dox

@ -46,9 +46,9 @@ available, each namespace has its own:
- Math/Math.h
- Magnum.h
- DebugTools/DebugTools.h
- Physics/Physics.h
- SceneGraph/SceneGraph.h
- Shaders/Shaders.h
- Shapes/Shapes.h
- Text/Text.h
- Trade/Trade.h

2
doc/features.dox

@ -31,7 +31,7 @@ namespace Magnum {
- @subpage matrix-vector -- @copybrief matrix-vector
- @subpage transformations -- @copybrief transformations
- @subpage scenegraph -- @copybrief scenegraph
- @subpage collision-detection -- @copybrief collision-detection
- @subpage shapes -- @copybrief shapes
- @subpage debug-tools -- @copybrief debug-tools
*/
}

4
doc/mainpage.dox

@ -68,8 +68,8 @@ namespace Magnum {
- **Linux** and embedded Linux (natively using GLX/EGL and Xlib or through
GLUT or SDL2 toolkit)
- **Windows** (through GLUT or SDL2 toolkit)
- **Google Chrome Native Client** (natively using PPAPI, both `newlib`
and `glibc` toolchains are supported)
- **Google Chrome** (through [Native Client](https://developers.google.com/native-client/),
both `newlib` and `glibc` toolchains are supported)
@section mainpage-features Features

17
doc/method-chaining.dox

@ -43,9 +43,9 @@ number of needed bindings. Consider the following example:
@code
Texture2D *carDiffuseTexture, *carSpecularTexture, *carBumpTexture;
carDiffuseTexture->setStorage(5, Texture2D::InternalFormat::SRGB8);
carSpecularTexture->setStorage(3, Texture2D::InternalFormat::R8);
carBumpTexture->setStorage(5, Texture2D::InternalFormat::RGB8);
carDiffuseTexture->setStorage(5, TextureFormat::SRGB8);
carSpecularTexture->setStorage(3, TextureFormat::R8);
carBumpTexture->setStorage(5, TextureFormat::RGB8);
carDiffuseTexture->setSubImage(0, {}, diffuse);
carSpecularTexture->setSubImage(0, {}, specular;
carBumpTexture->setSubImage(0, {}, bump);
@ -61,13 +61,13 @@ names and after each configuration step the texture must be rebound to another.
With method chaining used the code looks much lighter and each object is
configured in one run, reducing count of bind calls from 9 to 3.
@code
carDiffuseTexture->setStorage(5, Texture2D::InternalFormat::SRGB8)
carDiffuseTexture->setStorage(5, TextureFormat::SRGB8)
->setSubImage(0, {}, diffuse)
->generateMipmap();
carSpecularTexture->setStorage(3, Texture2D::InternalFormat::R8)
carSpecularTexture->setStorage(3, TextureFormat::R8)
->setSubImage(0, {}, diffuse)
->generateMipmap();
carBumpTexture->setStorage(5, Texture2D::InternalFormat::RGB8)
carBumpTexture->setStorage(5, TextureFormat::RGB8)
->setSubImage(0, {}, bump)
->generateMipmap();
@endcode
@ -86,5 +86,10 @@ Scene3D scene;
->rotateX(90.0_degf)
->translate({-1.5f, 0.5f, 7.0f});
@endcode
In most cases method chaining methods return pointer to the object, because
most of the objects are commonly created on the heap. The only exception are
Shader methods, which return reference, because the class is commonly created
as local variable in shader constructors.
*/
}

13
doc/namespaces.dox

@ -155,16 +155,15 @@ This library is built when `WITH_SHADERS` is enabled and found as `%Shaders`
component in CMake. See @ref building and @ref cmake for more information.
*/
/** @dir Physics
* @brief Namespace Magnum::Physics
/** @dir Shapes
* @brief Namespace Magnum::Shapes
*/
/** @namespace Magnum::Physics
@brief %Physics library
/** @namespace Magnum::Shapes
@brief %Shape library
Collision detection system and rigid body objects. See @ref collision-detection
for introduction.
Collision detection system. See @ref shapes for introduction.
This library is built when `WITH_PHYSICS` is enabled and found as `%Physics`
This library is built when `WITH_SHAPES` is enabled and found as `%Shapes`
component in CMake. See @ref building and @ref cmake for more information.
*/

2
doc/platform.dox

@ -76,7 +76,7 @@ void MyApplication::viewportEvent(const Vector2i& size) {
void MyApplication::drawEvent() {
// Clear the window
defaultFramebuffer.clear();
defaultFramebuffer.clear(DefaultFramebuffer::Clear::Color);
// The context is double-buffered, swap buffers
swapBuffers();

2
doc/scenegraph.dox

@ -151,7 +151,7 @@ Simplified example:
@code
class Bomb: public Object3D, SceneGraph::Drawable3D<>, SceneGraph:.Animable3D<> {
public:
inline Bomb(Object3D* parent): Object3D(parent), SceneGraph::Drawable3D<>(this), SceneGraph::Animable3D<>(this) {}
Bomb(Object3D* parent): Object3D(parent), SceneGraph::Drawable3D<>(this), SceneGraph::Animable3D<>(this) {}
protected:
// drawing implementation for Drawable feature

120
doc/shapes.dox

@ -0,0 +1,120 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 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.
*/
namespace Magnum { namespace Shapes {
/** @page shapes Collision detection
@brief Collection of simple shapes for high performance collision detection.
The essential thing in collision detection is to define a complex object with
collection of simple shapes, for which it is easy to detect collisions. These
shapes can be either one-, two- or three-dimensional and they can be grouped
together using various operations.
@tableofcontents
@section shapes-collection Available shapes
@subsection shapes-1D One-dimensional shapes
- @ref Shapes::Point "Shapes::Point*D" -- @copybrief Shapes::Point
- @ref Shapes::Line "Shapes::Line*D" -- @copybrief Shapes::Line
- @ref Shapes::LineSegment "Shapes::LineSegment*D" -- @copybrief Shapes::LineSegment
Because of numerical instability it's not possible to detect collisions of
line and point. Collision of two lines can be detected only in 2D.
@subsection shapes-2D Two-dimensional shapes
- Shapes::Plane -- @copybrief Shapes::Plane
@subsection shapes-3D Three-dimensional shapes
- @ref Shapes::Sphere "Shapes::Sphere*D" -- @copybrief Shapes::Sphere
- @ref Shapes::Capsule "Shapes::Capsule*D" -- @copybrief Shapes::Capsule
- @ref Shapes::AxisAlignedBox "Shapes::AxisAlignedBox*D" -- @copybrief Shapes::AxisAlignedBox
- @ref Shapes::Box "Shapes::Box*D" -- @copybrief Shapes::Box
The easiest (and most efficient) shape combination for detecting collisions
is point and sphere, followed by two spheres. Computing collision of two boxes
is least efficient.
@section shapes-composition Creating shape compositions
%Shapes can be composed together using one of three available logical
operations: AND, OR and NOT. These operations are mapped to operator&&(),
operator||() and operator!(), so for example creating negation of logical OR
of line segment and point is simple as this:
@code
Shapes::LineSegment3D segment;
Shapes::Point3D point;
Shapes::Composition3D composition = !(segment || point);
@endcode
@note Logical operations are not the same as set operations -- intersection of
two spheres will not generate any collision if they are disjoint, but
logical AND will if the object collides with both of them.
@subsection shapes-simplification Providing simplified version of shape for better performance
If there are many shapes composed together, it might hurt performance of
collision detection, because it might be testing collision with more shapes
than necessary. It's then good to specify simplified version of such shape,
so the collision detection is done on the complex one if and only if collision
was detected with the simplified shape. It is in fact logical AND using
operator&&() - the collision is initially detected on first (simplified) shape
and then on the other:
@code
Shapes::Sphere3D sphere;
Shapes::Box3D box;
Shapes::AxisAlignedBox3D simplified;
Shapes::Composition3D composition = simplified && (sphere || box);
@endcode
@section shapes-collisions Detecting shape collisions
%Shape pairs which have collision detection implemented can be tested for
collision using operator%(), for example:
@code
Shapes::Point3D point;
Shapes::Sphere3D sphere;
bool collide = point % sphere;
@endcode
@section shapes-scenegraph Integration with scene graph
%Shape can be attached to object in the scene using Shapes::Shape feature and
then used for collision detection. You can also use DebugTools::ShapeRenderer
to visualize the shape for debugging purposes.
@code
Object3D object;
auto shape = Shapes::Shape<Shapes::Sphere3D>(object, {{}, 23.0f});
@endcode
See also @ref scenegraph for introduction.
*/
}}}

16
external/OpenGL/GL/glcorearb.h vendored

@ -608,7 +608,7 @@ typedef void GLvoid;
#define GL_CONTEXT_FLAGS 0x821E
#define GL_COMPRESSED_RED 0x8225
#define GL_COMPRESSED_RG 0x8226
#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001
#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001
#define GL_RGBA32F 0x8814
#define GL_RGB32F 0x8815
#define GL_RGBA16F 0x881A
@ -1560,7 +1560,7 @@ typedef void GLvoid;
#define GL_TEXTURE_DEPTH_TYPE 0x8C16
#define GL_UNSIGNED_NORMALIZED 0x8C17
#define GL_FRAMEBUFFER_BINDING 0x8CA6
#define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING
#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6
#define GL_RENDERBUFFER_BINDING 0x8CA7
#define GL_READ_FRAMEBUFFER 0x8CA8
#define GL_DRAW_FRAMEBUFFER 0x8CA9
@ -1706,9 +1706,9 @@ typedef void GLvoid;
#ifndef GL_ARB_copy_buffer
#define GL_COPY_READ_BUFFER_BINDING 0x8F36
#define GL_COPY_READ_BUFFER GL_COPY_READ_BUFFER_BINDING
#define GL_COPY_READ_BUFFER 0x8F36
#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37
#define GL_COPY_WRITE_BUFFER GL_COPY_WRITE_BUFFER_BINDING
#define GL_COPY_WRITE_BUFFER 0x8F37
#endif
#ifndef GL_ARB_depth_clamp
@ -1955,9 +1955,9 @@ typedef void GLvoid;
#ifndef GL_ARB_transform_feedback2
#define GL_TRANSFORM_FEEDBACK 0x8E22
#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23
#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED GL_TRANSFORM_FEEDBACK_PAUSED
#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23
#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24
#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE GL_TRANSFORM_FEEDBACK_ACTIVE
#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24
#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25
#endif
@ -2579,8 +2579,8 @@ typedef void GLvoid;
#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD
#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE
#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF
#define GL_SHADER_STORAGE_BARRIER_BIT 0x2000
#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS
#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000
#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39
/* reuse GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS */
#endif

192
external/OpenGL/GLES2/gl2ext.h vendored

@ -1,7 +1,7 @@
#ifndef __gl2ext_h_
#define __gl2ext_h_
/* $Revision: 20800 $ on $Date:: 2013-03-07 03:33:09 -0800 #$ */
/* $Revision: 21470 $ on $Date:: 2013-05-08 17:33:40 -0700 #$ */
#ifdef __cplusplus
extern "C" {
@ -16,6 +16,20 @@ extern "C" {
# define GL_APIENTRYP GL_APIENTRY*
#endif
/* New types shared by several extensions */
#ifndef __gl3_h_
/* These are defineed with respect to <inttypes.h> in the
* Apple extension spec, but they are also used by non-APPLE
* extensions, and in the Khronos header we use the Khronos
* portable types in khrplatform.h, which must be defined.
*/
typedef khronos_int64_t GLint64;
typedef khronos_uint64_t GLuint64;
typedef struct __GLsync *GLsync;
#endif
/*------------------------------------------------------------------------*
* OES extension tokens
*------------------------------------------------------------------------*/
@ -183,47 +197,47 @@ typedef void* GLeglImageOES;
*------------------------------------------------------------------------*/
#ifndef GL_KHR_debug
typedef void (GL_APIENTRYP GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
#define GL_DEBUG_CALLBACK_FUNCTION 0x8244
#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245
#define GL_DEBUG_SOURCE_API 0x8246
#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247
#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248
#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249
#define GL_DEBUG_SOURCE_APPLICATION 0x824A
#define GL_DEBUG_SOURCE_OTHER 0x824B
#define GL_DEBUG_TYPE_ERROR 0x824C
#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D
#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E
#define GL_DEBUG_TYPE_PORTABILITY 0x824F
#define GL_DEBUG_TYPE_PERFORMANCE 0x8250
#define GL_DEBUG_TYPE_OTHER 0x8251
#define GL_DEBUG_TYPE_MARKER 0x8268
#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269
#define GL_DEBUG_TYPE_POP_GROUP 0x826A
#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C
#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D
#define GL_BUFFER 0x82E0
#define GL_SHADER 0x82E1
#define GL_PROGRAM 0x82E2
#define GL_QUERY 0x82E3
typedef void (GL_APIENTRYP GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
#define GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR 0x8242
#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR 0x8243
#define GL_DEBUG_CALLBACK_FUNCTION_KHR 0x8244
#define GL_DEBUG_CALLBACK_USER_PARAM_KHR 0x8245
#define GL_DEBUG_SOURCE_API_KHR 0x8246
#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR 0x8247
#define GL_DEBUG_SOURCE_SHADER_COMPILER_KHR 0x8248
#define GL_DEBUG_SOURCE_THIRD_PARTY_KHR 0x8249
#define GL_DEBUG_SOURCE_APPLICATION_KHR 0x824A
#define GL_DEBUG_SOURCE_OTHER_KHR 0x824B
#define GL_DEBUG_TYPE_ERROR_KHR 0x824C
#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR 0x824D
#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR 0x824E
#define GL_DEBUG_TYPE_PORTABILITY_KHR 0x824F
#define GL_DEBUG_TYPE_PERFORMANCE_KHR 0x8250
#define GL_DEBUG_TYPE_OTHER_KHR 0x8251
#define GL_DEBUG_TYPE_MARKER_KHR 0x8268
#define GL_DEBUG_TYPE_PUSH_GROUP_KHR 0x8269
#define GL_DEBUG_TYPE_POP_GROUP_KHR 0x826A
#define GL_DEBUG_SEVERITY_NOTIFICATION_KHR 0x826B
#define GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR 0x826C
#define GL_DEBUG_GROUP_STACK_DEPTH_KHR 0x826D
#define GL_BUFFER_KHR 0x82E0
#define GL_SHADER_KHR 0x82E1
#define GL_PROGRAM_KHR 0x82E2
#define GL_QUERY_KHR 0x82E3
/* PROGRAM_PIPELINE only in GL */
#define GL_SAMPLER 0x82E6
#define GL_SAMPLER_KHR 0x82E6
/* DISPLAY_LIST only in GL */
#define GL_MAX_LABEL_LENGTH 0x82E8
#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143
#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144
#define GL_DEBUG_LOGGED_MESSAGES 0x9145
#define GL_DEBUG_SEVERITY_HIGH 0x9146
#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
#define GL_DEBUG_SEVERITY_LOW 0x9148
#define GL_DEBUG_OUTPUT 0x92E0
#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
#define GL_STACK_OVERFLOW 0x0503
#define GL_STACK_UNDERFLOW 0x0504
#define GL_MAX_LABEL_LENGTH_KHR 0x82E8
#define GL_MAX_DEBUG_MESSAGE_LENGTH_KHR 0x9143
#define GL_MAX_DEBUG_LOGGED_MESSAGES_KHR 0x9144
#define GL_DEBUG_LOGGED_MESSAGES_KHR 0x9145
#define GL_DEBUG_SEVERITY_HIGH_KHR 0x9146
#define GL_DEBUG_SEVERITY_MEDIUM_KHR 0x9147
#define GL_DEBUG_SEVERITY_LOW_KHR 0x9148
#define GL_DEBUG_OUTPUT_KHR 0x92E0
#define GL_CONTEXT_FLAG_DEBUG_BIT_KHR 0x00000002
#define GL_STACK_OVERFLOW_KHR 0x0503
#define GL_STACK_UNDERFLOW_KHR 0x0504
#endif
#ifndef GL_KHR_texture_compression_astc_ldr
@ -385,19 +399,6 @@ typedef void (GL_APIENTRYP GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLen
/* GL_APPLE_sync */
#ifndef GL_APPLE_sync
#ifndef __gl3_h_
/* These types are defined with reference to <inttypes.h>
* in the Apple extension spec, but here we use the Khronos
* portable types in khrplatform.h, and assume those types
* are always defined.
* If any other extensions using these types are defined,
* the typedefs must move out of this block and be shared.
*/
typedef khronos_int64_t GLint64;
typedef khronos_uint64_t GLuint64;
typedef struct __GLsync *GLsync;
#endif
#define GL_SYNC_OBJECT_APPLE 0x8A53
#define GL_MAX_SERVER_WAIT_TIMEOUT_APPLE 0x9111
#define GL_OBJECT_TYPE_APPLE 0x9112
@ -483,6 +484,17 @@ typedef struct __GLsync *GLsync;
#define GL_STENCIL_EXT 0x1802
#endif
#ifndef GL_EXT_disjoint_timer_query
#define GL_EXT_disjoint_timer_query 1
#define GL_QUERY_COUNTER_BITS_EXT 0x8864
#define GL_CURRENT_QUERY_EXT 0x8865
#define GL_QUERY_RESULT_EXT 0x8866
#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867
#define GL_TIME_ELAPSED_EXT 0x88BF
#define GL_TIMESTAMP_EXT 0x8E28
#define GL_GPU_DISJOINT_EXT 0x8FBB
#endif
/* GL_EXT_map_buffer_range */
#ifndef GL_EXT_map_buffer_range
#define GL_MAP_READ_BIT_EXT 0x0001
@ -1145,29 +1157,29 @@ typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array);
#ifndef GL_KHR_debug
#define GL_KHR_debug 1
#ifdef GL_GLEXT_PROTOTYPES
GL_APICALL void GL_APIENTRY glDebugMessageControl (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
GL_APICALL void GL_APIENTRY glDebugMessageInsert (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
GL_APICALL void GL_APIENTRY glDebugMessageCallback (GLDEBUGPROC callback, const void *userParam);
GL_APICALL GLuint GL_APIENTRY glGetDebugMessageLog (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
GL_APICALL void GL_APIENTRY glPushDebugGroup (GLenum source, GLuint id, GLsizei length, const GLchar *message);
GL_APICALL void GL_APIENTRY glPopDebugGroup (void);
GL_APICALL void GL_APIENTRY glObjectLabel (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
GL_APICALL void GL_APIENTRY glGetObjectLabel (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);
GL_APICALL void GL_APIENTRY glObjectPtrLabel (const void *ptr, GLsizei length, const GLchar *label);
GL_APICALL void GL_APIENTRY glGetObjectPtrLabel (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);
GL_APICALL void GL_APIENTRY glGetPointerv (GLenum pname, void **params);
#endif
typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam);
typedef GLuint (GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
typedef void (GL_APIENTRYP PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message);
typedef void (GL_APIENTRYP PFNGLPOPDEBUGGROUPPROC) (void);
typedef void (GL_APIENTRYP PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);
typedef void (GL_APIENTRYP PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label);
typedef void (GL_APIENTRYP PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);
typedef void (GL_APIENTRYP PFNGLGETPOINTERVPROC) (GLenum pname, void **params);
GL_APICALL void GL_APIENTRY glDebugMessageControlKHR (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
GL_APICALL void GL_APIENTRY glDebugMessageInsertKHR (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
GL_APICALL void GL_APIENTRY glDebugMessageCallbackKHR (GLDEBUGPROCKHR callback, const void *userParam);
GL_APICALL GLuint GL_APIENTRY glGetDebugMessageLogKHR (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
GL_APICALL void GL_APIENTRY glPushDebugGroupKHR (GLenum source, GLuint id, GLsizei length, const GLchar *message);
GL_APICALL void GL_APIENTRY glPopDebugGroupKHR (void);
GL_APICALL void GL_APIENTRY glObjectLabelKHR (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
GL_APICALL void GL_APIENTRY glGetObjectLabelKHR (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);
GL_APICALL void GL_APIENTRY glObjectPtrLabelKHR (const void *ptr, GLsizei length, const GLchar *label);
GL_APICALL void GL_APIENTRY glGetObjectPtrLabelKHR (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);
GL_APICALL void GL_APIENTRY glGetPointervKHR (GLenum pname, void **params);
#endif
typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECONTROLKHRPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGEINSERTKHRPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECALLBACKKHRPROC) (GLDEBUGPROCKHR callback, const void *userParam);
typedef GLuint (GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC) (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
typedef void (GL_APIENTRYP PFNGLPUSHDEBUGGROUPKHRPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message);
typedef void (GL_APIENTRYP PFNGLPOPDEBUGGROUPKHRPROC) (void);
typedef void (GL_APIENTRYP PFNGLOBJECTLABELKHRPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELKHRPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);
typedef void (GL_APIENTRYP PFNGLOBJECTPTRLABELKHRPROC) (const void *ptr, GLsizei length, const GLchar *label);
typedef void (GL_APIENTRYP PFNGLGETOBJECTPTRLABELKHRPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);
typedef void (GL_APIENTRYP PFNGLGETPOINTERVKHRPROC) (GLenum pname, void **params);
#endif
#ifndef GL_KHR_texture_compression_astc_ldr
@ -1421,6 +1433,34 @@ GL_APICALL void GL_APIENTRY glDiscardFramebufferEXT (GLenum target, GLsizei numA
typedef void (GL_APIENTRYP PFNGLDISCARDFRAMEBUFFEREXTPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments);
#endif
#ifndef GL_EXT_disjoint_timer_query
#define GL_EXT_disjoint_timer_query 1
#ifdef GL_GLEXT_PROTOTYPES
GL_APICALL void GL_APIENTRY glGenQueriesEXT (GLsizei n, GLuint *ids);
GL_APICALL void GL_APIENTRY glDeleteQueriesEXT (GLsizei n, const GLuint *ids);
GL_APICALL GLboolean GL_APIENTRY glIsQueryEXT (GLuint id);
GL_APICALL void GL_APIENTRY glBeginQueryEXT (GLenum target, GLuint id);
GL_APICALL void GL_APIENTRY glEndQueryEXT (GLenum target);
GL_APICALL void GL_APIENTRY glQueryCounterEXT (GLuint id, GLenum target);
GL_APICALL void GL_APIENTRY glGetQueryivEXT (GLenum target, GLenum pname, GLint *params);
GL_APICALL void GL_APIENTRY glGetQueryObjectivEXT (GLuint id, GLenum pname, GLint *params);
GL_APICALL void GL_APIENTRY glGetQueryObjectuivEXT (GLuint id, GLenum pname, GLuint *params);
GL_APICALL void GL_APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64EXT *params);
GL_APICALL void GL_APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64EXT *params);
#endif
typedef void (GL_APIENTRYP PFNGLGENQUERIESEXTPROC) (GLsizei n, GLuint *ids);
typedef void (GL_APIENTRYP PFNGLDELETEQUERIESEXTPROC) (GLsizei n, const GLuint *ids);
typedef GLboolean (GL_APIENTRYP PFNGLISQUERYEXTPROC) (GLuint id);
typedef void (GL_APIENTRYP PFNGLBEGINQUERYEXTPROC) (GLenum target, GLuint id);
typedef void (GL_APIENTRYP PFNGLENDQUERYEXTPROC) (GLenum target);
typedef void (GL_APIENTRYP PFNGLQUERYCOUNTEREXTPROC) (GLuint id, GLenum target);
typedef void (GL_APIENTRYP PFNGLGETQUERYIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTIVEXTPROC) (GLuint id, GLenum pname, GLint *params);
typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVEXTPROC) (GLuint id, GLenum pname, GLuint *params);
typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params);
typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params);
#endif /* GL_EXT_disjoint_timer_query */
/* GL_EXT_map_buffer_range */
#ifndef GL_EXT_map_buffer_range
#define GL_EXT_map_buffer_range 1

5
modules/FindCorrade.cmake

@ -32,6 +32,7 @@
# Native Client with `newlib` toolchain
# CORRADE_TARGET_NACL_GLIBC - Defined if compiled for Google Chrome
# Native Client with `glibc` toolchain
# CORRADE_TARGET_EMSCRIPTEN - Defined if compiled for Emscripten
#
# Corrade provides these macros and functions:
#
@ -184,6 +185,10 @@ string(FIND "${_corradeConfigure}" "#define CORRADE_TARGET_NACL_GLIBC" _TARGET_N
if(NOT _TARGET_NACL_GLIBC EQUAL -1)
set(CORRADE_TARGET_NACL_GLIBC 1)
endif()
string(FIND "${_corradeConfigure}" "#define CORRADE_TARGET_EMSCRIPTEN" _TARGET_EMSCRIPTEN)
if(NOT _TARGET_EMSCRIPTEN EQUAL -1)
set(CORRADE_TARGET_EMSCRIPTEN 1)
endif()
set(CORRADE_UTILITY_LIBRARIES ${CORRADE_UTILITY_LIBRARY})
set(CORRADE_INTERCONNECT_LIBRARIES ${CORRADE_INTERCONNECT_LIBRARY} ${CORRADE_UTILITY_LIBRARIES})

24
modules/FindMagnum.cmake

@ -14,13 +14,13 @@
# components. The base library depends on Corrade, OpenGL and GLEW
# libraries. Additional dependencies are specified by the components. The
# optional components are:
# DebugTools - DebugTools library (depends on MeshTools, Physics,
# Primitives, SceneGraph and Shaders components)
# DebugTools - DebugTools library (depends on MeshTools, Primitives,
# SceneGraph, Shaders and Shapes components)
# MeshTools - MeshTools library
# Physics - Physics library (depends on SceneGraph component)
# Primitives - Primitives library
# SceneGraph - SceneGraph library
# Shaders - Shaders library
# Shapes - Shapes library (depends on SceneGraph component)
# Text - Text library (depends on TextureTools component)
# TextureTools - TextureTools library
# GlutApplication - GLUT application (depends on GLUT library)
@ -224,7 +224,7 @@ foreach(component ${Magnum_FIND_COMPONENTS})
# DebugTools library
if(${component} STREQUAL DebugTools)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Profiler.h)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES DebugTools.h)
endif()
# Mesh tools library
@ -232,11 +232,6 @@ foreach(component ${Magnum_FIND_COMPONENTS})
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES CompressIndices.h)
endif()
# Physics library
if(${component} STREQUAL Physics)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES AbstractShape.h)
endif()
# Primitives library
if(${component} STREQUAL Primitives)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Cube.h)
@ -244,17 +239,22 @@ foreach(component ${Magnum_FIND_COMPONENTS})
# Scene graph library
if(${component} STREQUAL SceneGraph)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Scene.h)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES SceneGraph.h)
endif()
# Shaders library
if(${component} STREQUAL Shaders)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES PhongShader.h)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Shaders.h)
endif()
# Shapes library
if(${component} STREQUAL Shapes)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Shapes.h)
endif()
# Text library
if(${component} STREQUAL Text)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES AbstractFont.h)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Text.h)
endif()
# TextureTools library

37
modules/FindNodeJs.cmake

@ -0,0 +1,37 @@
# - Find Node.js
#
# This module defines:
#
# NODEJS_FOUND - True if Node.js executable is found
# NODEJS_EXECUTABLE - Node.js executable
#
#
# This file is part of Corrade.
#
# Copyright © 2007, 2008, 2009, 2010, 2011, 2012, 2013
# 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.
#
find_program(NODEJS_EXECUTABLE node)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args("NodeJs" DEFAULT_MSG NODEJS_EXECUTABLE)

14
modules/FindOpenGLES2.cmake

@ -31,10 +31,14 @@
# DEALINGS IN THE SOFTWARE.
#
# Library
find_library(OPENGLES2_LIBRARY NAMES
GLESv2
ppapi_gles2) # NaCl
# In Emscripten OpenGL ES 2 is linked automatically, thus no need to find the
# library.
if(NOT CORRADE_TARGET_EMSCRIPTEN)
find_library(OPENGLES2_LIBRARY NAMES
GLESv2
ppapi_gles2) # NaCl
set(OPENGLES2_LIBRARY_NEEDED OPENGLES2_LIBRARY)
endif()
# Include dir
find_path(OPENGLES2_INCLUDE_DIR
@ -44,6 +48,6 @@ find_path(OPENGLES2_INCLUDE_DIR
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args("OpenGLES2" DEFAULT_MSG
OPENGLES2_LIBRARY
${OPENGLES2_LIBRARY_NEEDED}
OPENGLES2_INCLUDE_DIR
)

15
modules/FindSDL2.cmake

@ -31,17 +31,24 @@
# DEALINGS IN THE SOFTWARE.
#
# Library
find_library(SDL2_LIBRARY SDL2)
# In Emscripten SDL is linked automatically, thus no need to find the library.
# Also the includes are in SDL subdirectory, not SDL2.
if(CORRADE_TARGET_EMSCRIPTEN)
set(PATH_SUFFIXES SDL)
else()
find_library(SDL2_LIBRARY SDL2)
set(SDL2_LIBRARY_NEEDED SDL2_LIBRARY)
set(PATH_SUFFIXES SDL2)
endif()
# Include dir
find_path(SDL2_INCLUDE_DIR
NAMES SDL.h SDL_scancode.h
PATH_SUFFIXES SDL2
PATH_SUFFIXES ${PATH_SUFFIXES}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args("SDL2" DEFAULT_MSG
SDL2_LIBRARY
${SDL2_LIBRARY_NEEDED}
SDL2_INCLUDE_DIR
)

108
src/AbstractFramebuffer.cpp

@ -34,32 +34,33 @@
namespace Magnum {
#ifndef DOXYGEN_GENERATING_OUTPUT
AbstractFramebuffer::ReadImplementation AbstractFramebuffer::readImplementation = &AbstractFramebuffer::readImplementationDefault;
AbstractFramebuffer::DrawBuffersImplementation AbstractFramebuffer::drawBuffersImplementation = &AbstractFramebuffer::drawBuffersImplementationDefault;
AbstractFramebuffer::DrawBufferImplementation AbstractFramebuffer::drawBufferImplementation = &AbstractFramebuffer::drawBufferImplementationDefault;
AbstractFramebuffer::ReadBufferImplementation AbstractFramebuffer::readBufferImplementation = &AbstractFramebuffer::readBufferImplementationDefault;
AbstractFramebuffer::Target AbstractFramebuffer::readTarget = AbstractFramebuffer::Target::ReadDraw;
AbstractFramebuffer::Target AbstractFramebuffer::drawTarget = AbstractFramebuffer::Target::ReadDraw;
#endif
FramebufferTarget AbstractFramebuffer::readTarget = FramebufferTarget::ReadDraw;
FramebufferTarget AbstractFramebuffer::drawTarget = FramebufferTarget::ReadDraw;
AbstractFramebuffer::~AbstractFramebuffer() {}
void AbstractFramebuffer::bind(Target target) {
void AbstractFramebuffer::bind(FramebufferTarget target) {
bindInternal(target);
setViewportInternal();
}
#ifndef DOXYGEN_GENERATING_OUTPUT
void AbstractFramebuffer::bindInternal(Target target) {
void AbstractFramebuffer::bindInternal(FramebufferTarget target) {
Implementation::FramebufferState* state = Context::current()->state()->framebuffer;
/* If already bound, done, otherwise update tracked state */
if(target == Target::Read) {
if(target == FramebufferTarget::Read) {
if(state->readBinding == _id) return;
state->readBinding = _id;
} else if(target == Target::Draw) {
} else if(target == FramebufferTarget::Draw) {
if(state->drawBinding == _id) return;
state->drawBinding = _id;
} else if(target == Target::ReadDraw) {
} else if(target == FramebufferTarget::ReadDraw) {
if(state->readBinding == _id && state->drawBinding == _id) return;
state->readBinding = state->drawBinding = _id;
} else CORRADE_ASSERT_UNREACHABLE();
@ -67,29 +68,28 @@ void AbstractFramebuffer::bindInternal(Target target) {
glBindFramebuffer(static_cast<GLenum>(target), _id);
}
AbstractFramebuffer::Target AbstractFramebuffer::bindInternal() {
FramebufferTarget AbstractFramebuffer::bindInternal() {
Implementation::FramebufferState* state = Context::current()->state()->framebuffer;
/* Return target to which the framebuffer is already bound */
if(state->readBinding == _id && state->drawBinding == _id)
return Target::ReadDraw;
return FramebufferTarget::ReadDraw;
if(state->readBinding == _id)
return Target::Read;
return FramebufferTarget::Read;
if(state->drawBinding == _id)
return Target::Draw;
return FramebufferTarget::Draw;
/* Or bind it, if not already */
state->readBinding = _id;
if(readTarget == Target::ReadDraw) state->drawBinding = _id;
if(readTarget == FramebufferTarget::ReadDraw) state->drawBinding = _id;
glBindFramebuffer(GLenum(readTarget), _id);
return readTarget;
}
#endif
void AbstractFramebuffer::blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Rectanglei& sourceRectangle, const Rectanglei& destinationRectangle, AbstractFramebuffer::BlitMask mask, AbstractFramebuffer::BlitFilter filter) {
source.bindInternal(AbstractFramebuffer::Target::Read);
destination.bindInternal(AbstractFramebuffer::Target::Draw);
void AbstractFramebuffer::blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Rectanglei& sourceRectangle, const Rectanglei& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter) {
source.bindInternal(FramebufferTarget::Read);
destination.bindInternal(FramebufferTarget::Draw);
/** @todo Get some extension wrangler instead to avoid undeclared glBlitFramebuffer() on ES2 */
#ifndef MAGNUM_TARGET_GLES2
glBlitFramebuffer(sourceRectangle.left(), sourceRectangle.bottom(), sourceRectangle.right(), sourceRectangle.top(), destinationRectangle.left(), destinationRectangle.bottom(), destinationRectangle.right(), destinationRectangle.top(), static_cast<GLbitfield>(mask), static_cast<GLenum>(filter));
@ -111,7 +111,6 @@ AbstractFramebuffer* AbstractFramebuffer::setViewport(const Rectanglei& rectangl
return this;
}
#ifndef DOXYGEN_GENERATING_OUTPUT
void AbstractFramebuffer::setViewportInternal() {
Implementation::FramebufferState* state = Context::current()->state()->framebuffer;
@ -125,34 +124,34 @@ void AbstractFramebuffer::setViewportInternal() {
state->viewport = _viewport;
glViewport(_viewport.left(), _viewport.bottom(), _viewport.width(), _viewport.height());
}
#endif
void AbstractFramebuffer::clear(ClearMask mask) {
void AbstractFramebuffer::clear(FramebufferClearMask mask) {
bindInternal(drawTarget);
glClear(static_cast<GLbitfield>(mask));
}
void AbstractFramebuffer::read(const Vector2i& offset, const Vector2i& size, AbstractImage::Format format, AbstractImage::Type type, Image2D* image) {
void AbstractFramebuffer::read(const Vector2i& offset, const Vector2i& size, Image2D* image) {
bindInternal(readTarget);
char* data = new char[AbstractImage::pixelSize(format, type)*size.product()];
glReadPixels(offset.x(), offset.y(), size.x(), size.y(), static_cast<GLenum>(format), static_cast<GLenum>(type), data);
image->setData(size, format, type, data);
const std::size_t dataSize = image->pixelSize()*size.product();
char* const data = new char[dataSize];
readImplementation(offset, size, image->format(), image->type(), dataSize, data);
image->setData(size, image->format(), image->type(), data);
}
#ifndef MAGNUM_TARGET_GLES2
void AbstractFramebuffer::read(const Vector2i& offset, const Vector2i& size, AbstractImage::Format format, AbstractImage::Type type, BufferImage2D* image, Buffer::Usage usage) {
void AbstractFramebuffer::read(const Vector2i& offset, const Vector2i& size, BufferImage2D* image, Buffer::Usage usage) {
bindInternal(readTarget);
/* If the buffer doesn't have sufficient size, resize it */
/** @todo Explicitly reset also when buffer usage changes */
if(image->size() != size || image->format() != format || image->type() != type)
image->setData(size, format, type, nullptr, usage);
if(image->size() != size)
image->setData(size, image->format(), image->type(), nullptr, usage);
image->buffer()->bind(Buffer::Target::PixelPack);
glReadPixels(offset.x(), offset.y(), size.x(), size.y(), static_cast<GLenum>(format), static_cast<GLenum>(type), nullptr);
/** @todo De-duplicate buffer size computation */
readImplementation(offset, size, image->format(), image->type(), image->pixelSize()*size.product(), nullptr);
}
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
void AbstractFramebuffer::invalidateImplementation(GLsizei count, GLenum* attachments) {
/** @todo Re-enable when extension wrangler is available for ES2 */
#ifndef MAGNUM_TARGET_GLES2
@ -175,15 +174,14 @@ void AbstractFramebuffer::invalidateImplementation(GLsizei count, GLenum* attach
static_cast<void>(rectangle);
#endif
}
#endif
void AbstractFramebuffer::initializeContextBasedFunctionality(Context* context) {
#ifndef MAGNUM_TARGET_GLES
if(context->isExtensionSupported<Extensions::GL::EXT::framebuffer_blit>()) {
Debug() << "AbstractFramebuffer: using" << Extensions::GL::EXT::framebuffer_blit::string() << "features";
readTarget = Target::Read;
drawTarget = Target::Draw;
readTarget = FramebufferTarget::Read;
drawTarget = FramebufferTarget::Draw;
}
if(context->isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
@ -193,6 +191,26 @@ void AbstractFramebuffer::initializeContextBasedFunctionality(Context* context)
drawBufferImplementation = &AbstractFramebuffer::drawBufferImplementationDSA;
readBufferImplementation = &AbstractFramebuffer::readBufferImplementationDSA;
}
#endif
#ifndef MAGNUM_TARGET_GLES3
#ifndef MAGNUM_TARGET_GLES
if(context->isExtensionSupported<Extensions::GL::ARB::robustness>())
#else
if(context->isExtensionSupported<Extensions::GL::EXT::robustness>())
#endif
{
#ifndef MAGNUM_TARGET_GLES
Debug() << "AbstractFramebuffer: using" << Extensions::GL::ARB::robustness::string() << "features";
#else
//Debug() << "AbstractFramebuffer: using" << Extensions::GL::EXT::robustness::string() << "features";
#endif
/** @todo Enable when extension wrangler for ES is available */
#ifndef MAGNUM_TARGET_GLES
readImplementation = &AbstractFramebuffer::readImplementationRobustness;
#endif
}
#else
static_cast<void>(context);
#endif
@ -251,4 +269,26 @@ void AbstractFramebuffer::readBufferImplementationDSA(GLenum buffer) {
}
#endif
void AbstractFramebuffer::readImplementationDefault(const Vector2i& offset, const Vector2i& size, const ImageFormat format, const ImageType type, const std::size_t, GLvoid* const data) {
glReadPixels(offset.x(), offset.y(), size.x(), size.y(), static_cast<GLenum>(format), static_cast<GLenum>(type), data);
}
#ifndef MAGNUM_TARGET_GLES3
void AbstractFramebuffer::readImplementationRobustness(const Vector2i& offset, const Vector2i& size, const ImageFormat format, const ImageType type, const std::size_t dataSize, GLvoid* const data) {
/** @todo Enable when extension wrangler for ES is available */
#ifndef MAGNUM_TARGET_GLES
glReadnPixelsARB(offset.x(), offset.y(), size.x(), size.y(), static_cast<GLenum>(format), static_cast<GLenum>(type), dataSize, data);
#else
CORRADE_INTERNAL_ASSERT(false);
//glReadnPixelsEXT(offset.x(), offset.y(), size.x(), size.y(), static_cast<GLenum>(format), static_cast<GLenum>(type), data);
static_cast<void>(offset);
static_cast<void>(size);
static_cast<void>(format);
static_cast<void>(type);
static_cast<void>(dataSize);
static_cast<void>(data);
#endif
}
#endif
}

249
src/AbstractFramebuffer.h

@ -31,22 +31,111 @@
#include <Containers/EnumSet.h>
#include "Math/Geometry/Rectangle.h"
#include "AbstractImage.h"
#include "Buffer.h"
namespace Magnum {
/**
* @brief Mask for framebuffer clearing
*
* @see AbstractFramebuffer, FramebufferClearMask
*/
enum class FramebufferClear: GLbitfield {
Color = GL_COLOR_BUFFER_BIT, /**< Color */
Depth = GL_DEPTH_BUFFER_BIT, /**< Depth value */
Stencil = GL_STENCIL_BUFFER_BIT /**< Stencil value */
};
/**
* @brief Mask for clearing
*
* @see AbstractFramebuffer::clear()
*/
typedef Containers::EnumSet<FramebufferClear, GLbitfield,
GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT> FramebufferClearMask;
/**
* @brief Mask for framebuffer blitting
*
* @see AbstractFramebuffer, FramebufferBlitMask
* @requires_gl30 %Extension @extension{EXT,framebuffer_object}
* @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or
* @es_extension{NV,framebuffer_blit}
*/
enum class FramebufferBlit: GLbitfield {
ColorBuffer = GL_COLOR_BUFFER_BIT, /**< Color buffer */
DepthBuffer = GL_DEPTH_BUFFER_BIT, /**< Depth buffer */
StencilBuffer = GL_STENCIL_BUFFER_BIT /**< Stencil buffer */
};
/**
* @brief Mask for framebuffer blitting
*
* @see AbstractFramebuffer::blit()
* @requires_gl30 %Extension @extension{EXT,framebuffer_object}
* @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or
* @es_extension{NV,framebuffer_blit}
*/
typedef Containers::EnumSet<FramebufferBlit, GLbitfield,
GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT> FramebufferBlitMask;
/**
* @brief %Framebuffer blit filtering
*
* @see AbstractFramebuffer::blit()
*/
enum class FramebufferBlitFilter: GLenum {
Nearest = GL_NEAREST, /**< Nearest neighbor filtering */
Linear = GL_LINEAR /**< Linear interpolation filtering */
};
/**
* @brief Target for binding framebuffer
*
* @see DefaultFramebuffer::bind(), Framebuffer::bind()
* @requires_gl30 %Extension @extension{EXT,framebuffer_object}
*/
enum class FramebufferTarget: GLenum {
/**
* For reading only.
* @requires_gl30 %Extension @extension{EXT,framebuffer_blit}
* @requires_gles30 %Extension @es_extension{APPLE,framebuffer_multisample},
* @es_extension{ANGLE,framebuffer_blit} or @es_extension{NV,framebuffer_blit}
*/
#ifndef MAGNUM_TARGET_GLES2
Read = GL_READ_FRAMEBUFFER,
#else
Read = GL_READ_FRAMEBUFFER_APPLE,
#endif
/**
* For drawing only.
* @requires_gl30 %Extension @extension{EXT,framebuffer_blit}
* @requires_gles30 %Extension @es_extension{APPLE,framebuffer_multisample},
* @es_extension{ANGLE,framebuffer_blit} or @es_extension{NV,framebuffer_blit}
*/
#ifndef MAGNUM_TARGET_GLES2
Draw = GL_DRAW_FRAMEBUFFER,
#else
Draw = GL_DRAW_FRAMEBUFFER_APPLE,
#endif
ReadDraw = GL_FRAMEBUFFER /**< For both reading and drawing. */
};
/**
@brief Base for default and named framebuffers
See DefaultFramebuffer and Framebuffer for more information.
@section AbstractFramebuffer-performance-optimization Performance optimizations
@section AbstractFramebuffer-performance-optimization Performance optimizations and security
The engine tracks currently bound framebuffer and current viewport to avoid
unnecessary calls to @fn_gl{BindFramebuffer} and @fn_gl{Viewport} when
switching framebuffers.
If @extension{ARB,robustness} is available, read() operations are protected
from buffer overflow.
@todo @extension{ARB,viewport_array}
*/
class MAGNUM_EXPORT AbstractFramebuffer {
@ -58,94 +147,6 @@ class MAGNUM_EXPORT AbstractFramebuffer {
AbstractFramebuffer& operator=(AbstractFramebuffer&&) = delete;
public:
/**
* @brief Mask for clearing
*
* @see ClearMask
*/
enum class Clear: GLbitfield {
Color = GL_COLOR_BUFFER_BIT, /**< Color */
Depth = GL_DEPTH_BUFFER_BIT, /**< Depth value */
Stencil = GL_STENCIL_BUFFER_BIT /**< Stencil value */
};
/**
* @brief Mask for clearing
*
* @see clear()
*/
typedef Corrade::Containers::EnumSet<Clear, GLbitfield,
GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT> ClearMask;
/**
* @brief Mask for blitting
*
* @see BlitMask
* @requires_gl30 %Extension @extension{EXT,framebuffer_object}
* @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or
* @es_extension{NV,framebuffer_blit}
*/
enum class Blit: GLbitfield {
ColorBuffer = GL_COLOR_BUFFER_BIT, /**< Color buffer */
DepthBuffer = GL_DEPTH_BUFFER_BIT, /**< Depth buffer */
StencilBuffer = GL_STENCIL_BUFFER_BIT /**< Stencil buffer */
};
/**
* @brief Mask for blitting
*
* @see blit()
* @requires_gl30 %Extension @extension{EXT,framebuffer_object}
* @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or
* @es_extension{NV,framebuffer_blit}
*/
typedef Corrade::Containers::EnumSet<Blit, GLbitfield,
GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT> BlitMask;
/**
* @brief Blit filtering
*
* @see blit()
*/
enum class BlitFilter: GLenum {
Nearest = GL_NEAREST, /**< Nearest neighbor filtering */
Linear = GL_LINEAR /**< Linear interpolation filtering */
};
/**
* @brief Target for binding framebuffer
*
* @see DefaultFramebuffer::bind(), Framebuffer::bind()
* @requires_gl30 %Extension @extension{EXT,framebuffer_object}
*/
enum class Target: GLenum {
/**
* For reading only.
* @requires_gl30 %Extension @extension{EXT,framebuffer_blit}
* @requires_gles30 %Extension @es_extension{APPLE,framebuffer_multisample},
* @es_extension{ANGLE,framebuffer_blit} or @es_extension{NV,framebuffer_blit}
*/
#ifndef MAGNUM_TARGET_GLES2
Read = GL_READ_FRAMEBUFFER,
#else
Read = GL_READ_FRAMEBUFFER_APPLE,
#endif
/**
* For drawing only.
* @requires_gl30 %Extension @extension{EXT,framebuffer_blit}
* @requires_gles30 %Extension @es_extension{APPLE,framebuffer_multisample},
* @es_extension{ANGLE,framebuffer_blit} or @es_extension{NV,framebuffer_blit}
*/
#ifndef MAGNUM_TARGET_GLES2
Draw = GL_DRAW_FRAMEBUFFER,
#else
Draw = GL_DRAW_FRAMEBUFFER_APPLE,
#endif
ReadDraw = GL_FRAMEBUFFER /**< For both reading and drawing. */
};
/**
* @brief Copy block of pixels
* @param source Source framebuffer
@ -155,9 +156,9 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* @param mask Which buffers to perform blit operation on
* @param filter Interpolation filter
*
* Binds @p source framebuffer to @ref Target "Target::Read" and
* @p destination framebuffer to @ref Target "Target::Draw" and
* performs blitting operation. See DefaultFramebuffer::mapForRead(),
* Binds @p source framebuffer to @ref FramebufferTarget "FramebufferTarget::Read"
* and @p destination framebuffer to @ref FramebufferTarget "FramebufferTarget::Draw"
* and performs blitting operation. See DefaultFramebuffer::mapForRead(),
* Framebuffer::mapForRead(), DefaultFramebuffer::mapForDraw() and
* Framebuffer::mapForDraw() for specifying particular buffers for
* blitting operation.
@ -166,7 +167,7 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or
* @es_extension{NV,framebuffer_blit}
*/
static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Rectanglei& sourceRectangle, const Rectanglei& destinationRectangle, BlitMask mask, BlitFilter filter);
static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Rectanglei& sourceRectangle, const Rectanglei& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter);
/**
* @brief Copy block of pixels
@ -178,14 +179,15 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* Convenience alternative to above function when source rectangle is
* the same as destination rectangle. As the image is copied
* pixel-by-pixel, no interpolation is needed and thus
* @ref BlitFilter "BlitFilter::Nearest" filtering is used by default.
* @ref FramebufferBlitFilter "FramebufferBlitFilter::Nearest"
* filtering is used by default.
* @see @fn_gl{BlitFramebuffer}
* @requires_gl30 %Extension @extension{EXT,framebuffer_blit}
* @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} or
* @es_extension{NV,framebuffer_blit}
*/
inline static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Rectanglei& rectangle, BlitMask mask) {
blit(source, destination, rectangle, rectangle, mask, BlitFilter::Nearest);
static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Rectanglei& rectangle, FramebufferBlitMask mask) {
blit(source, destination, rectangle, rectangle, mask, FramebufferBlitFilter::Nearest);
}
explicit AbstractFramebuffer();
@ -200,10 +202,10 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* Framebuffer::mapForDraw(), @fn_gl{BindFramebuffer},
* @fn_gl{Viewport}
*/
void bind(Target target);
void bind(FramebufferTarget target);
/** @brief Viewport rectangle */
inline Rectanglei viewport() const { return _viewport; }
Rectanglei viewport() const { return _viewport; }
/**
* @brief Set viewport
@ -228,46 +230,50 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* Renderer::setClearStencil(), @fn_gl{BindFramebuffer},
* @fn_gl{Clear}
*/
void clear(ClearMask mask);
void clear(FramebufferClearMask mask);
/**
* @brief Read block of pixels from framebuffer to image
* @param offset Offset in the framebuffer
* @param size %Image size
* @param format Format of pixel data
* @param type Data type of pixel data
* @param image %Image where to put the data
*
* @see @fn_gl{BindFramebuffer}, @fn_gl{ReadPixels}
* @todo Read size, format & type from image?
* %Image parameters like format and type of pixel data are taken from
* given image.
*
* If @extension{ARB,robustness} is available, the operation is
* protected from buffer overflow.
* @see @fn_gl{BindFramebuffer}, @fn_gl{ReadPixels} or
* @fn_gl_extension{ReadnPixels,ARB,robustness}
*/
void read(const Vector2i& offset, const Vector2i& size, AbstractImage::Format format, AbstractImage::Type type, Image2D* image);
void read(const Vector2i& offset, const Vector2i& size, Image2D* image);
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Read block of pixels from framebuffer to buffer image
* @param offset Offset in the framebuffer
* @param size %Image size
* @param format Format of pixel data
* @param type Data type of pixel data
* @param image %Buffer image where to put the data
* @param usage %Buffer usage
*
* @see @fn_gl{BindFramebuffer}, @fn_gl{ReadPixels}
* See read(const Vector2i&, const Vector2i&, Image2D*) for more
* information.
* @requires_gles30 Pixel buffer objects are not available in OpenGL ES 2.0.
* @todo Read size, format & type from image?
*/
void read(const Vector2i& offset, const Vector2i& size, AbstractImage::Format format, AbstractImage::Type type, BufferImage2D* image, Buffer::Usage usage);
void read(const Vector2i& offset, const Vector2i& size, BufferImage2D* image, Buffer::Usage usage);
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifdef DOXYGEN_GENERATING_OUTPUT
private:
#else
protected:
void MAGNUM_LOCAL bindInternal(Target target);
Target MAGNUM_LOCAL bindInternal();
#endif
void MAGNUM_LOCAL bindInternal(FramebufferTarget target);
FramebufferTarget MAGNUM_LOCAL bindInternal();
void MAGNUM_LOCAL setViewportInternal();
static MAGNUM_LOCAL Target readTarget;
static MAGNUM_LOCAL Target drawTarget;
static MAGNUM_LOCAL FramebufferTarget readTarget;
static MAGNUM_LOCAL FramebufferTarget drawTarget;
typedef void(AbstractFramebuffer::*DrawBuffersImplementation)(GLsizei, const GLenum*);
static MAGNUM_LOCAL DrawBuffersImplementation drawBuffersImplementation;
@ -283,7 +289,6 @@ class MAGNUM_EXPORT AbstractFramebuffer {
GLuint _id;
Rectanglei _viewport;
#endif
private:
static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context);
@ -302,13 +307,19 @@ class MAGNUM_EXPORT AbstractFramebuffer {
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL readBufferImplementationDSA(GLenum buffer);
#endif
typedef void(*ReadImplementation)(const Vector2i&, const Vector2i&, ImageFormat, ImageType, std::size_t, GLvoid*);
static void MAGNUM_LOCAL readImplementationDefault(const Vector2i& offset, const Vector2i& size, ImageFormat format, ImageType type, std::size_t dataSize, GLvoid* data);
#ifndef MAGNUM_TARGET_GLES3
static void MAGNUM_LOCAL readImplementationRobustness(const Vector2i& offset, const Vector2i& size, ImageFormat format, ImageType type, std::size_t dataSize, GLvoid* data);
#endif
static ReadImplementation MAGNUM_LOCAL readImplementation;
};
inline AbstractFramebuffer::AbstractFramebuffer() = default;
inline AbstractFramebuffer::~AbstractFramebuffer() {}
CORRADE_ENUMSET_OPERATORS(AbstractFramebuffer::ClearMask)
CORRADE_ENUMSET_OPERATORS(AbstractFramebuffer::BlitMask)
CORRADE_ENUMSET_OPERATORS(FramebufferClearMask)
CORRADE_ENUMSET_OPERATORS(FramebufferBlitMask)
}

189
src/AbstractImage.cpp

@ -26,109 +26,113 @@
#include <Utility/Assert.h>
#include "ImageFormat.h"
namespace Magnum {
std::size_t AbstractImage::pixelSize(Format format, Type type) {
AbstractImage::~AbstractImage() {}
std::size_t AbstractImage::pixelSize(ImageFormat format, ImageType type) {
std::size_t size = 0;
switch(type) {
case Type::UnsignedByte:
case ImageType::UnsignedByte:
#ifndef MAGNUM_TARGET_GLES2
case Type::Byte:
case ImageType::Byte:
#endif
size = 1; break;
case Type::UnsignedShort:
case ImageType::UnsignedShort:
#ifndef MAGNUM_TARGET_GLES2
case Type::Short:
case ImageType::Short:
#endif
case Type::HalfFloat:
case ImageType::HalfFloat:
size = 2; break;
case Type::UnsignedInt:
case ImageType::UnsignedInt:
#ifndef MAGNUM_TARGET_GLES2
case Type::Int:
case ImageType::Int:
#endif
case Type::Float:
case ImageType::Float:
size = 4; break;
#ifndef MAGNUM_TARGET_GLES
case Type::UnsignedByte332:
case Type::UnsignedByte233Rev:
case ImageType::UnsignedByte332:
case ImageType::UnsignedByte233Rev:
return 1;
#endif
case Type::UnsignedShort565:
case ImageType::UnsignedShort565:
#ifndef MAGNUM_TARGET_GLES
case Type::UnsignedShort565Rev:
case ImageType::UnsignedShort565Rev:
#endif
case Type::UnsignedShort4444:
case ImageType::UnsignedShort4444:
#ifndef MAGNUM_TARGET_GLES3
case Type::UnsignedShort4444Rev:
case ImageType::UnsignedShort4444Rev:
#endif
case Type::UnsignedShort5551:
case ImageType::UnsignedShort5551:
#ifndef MAGNUM_TARGET_GLES3
case Type::UnsignedShort1555Rev:
case ImageType::UnsignedShort1555Rev:
#endif
return 2;
#ifndef MAGNUM_TARGET_GLES
case Type::UnsignedInt8888:
case Type::UnsignedInt8888Rev:
case Type::UnsignedInt1010102:
case ImageType::UnsignedInt8888:
case ImageType::UnsignedInt8888Rev:
case ImageType::UnsignedInt1010102:
#endif
case Type::UnsignedInt2101010Rev:
case ImageType::UnsignedInt2101010Rev:
#ifndef MAGNUM_TARGET_GLES2
case Type::UnsignedInt10F11F11FRev:
case Type::UnsignedInt5999Rev:
case ImageType::UnsignedInt10F11F11FRev:
case ImageType::UnsignedInt5999Rev:
#endif
case Type::UnsignedInt248:
case ImageType::UnsignedInt248:
return 4;
#ifndef MAGNUM_TARGET_GLES2
case Type::Float32UnsignedInt248Rev:
case ImageType::Float32UnsignedInt248Rev:
return 8;
#endif
}
switch(format) {
case Format::Red:
case ImageFormat::Red:
#ifndef MAGNUM_TARGET_GLES2
case Format::RedInteger:
case ImageFormat::RedInteger:
#endif
#ifndef MAGNUM_TARGET_GLES
case Format::Green:
case Format::Blue:
case Format::GreenInteger:
case Format::BlueInteger:
case ImageFormat::Green:
case ImageFormat::Blue:
case ImageFormat::GreenInteger:
case ImageFormat::BlueInteger:
#endif
return 1*size;
case Format::RG:
case ImageFormat::RG:
#ifndef MAGNUM_TARGET_GLES2
case Format::RGInteger:
case ImageFormat::RGInteger:
#endif
return 2*size;
case Format::RGB:
case ImageFormat::RGB:
#ifndef MAGNUM_TARGET_GLES2
case Format::RGBInteger:
case ImageFormat::RGBInteger:
#endif
#ifndef MAGNUM_TARGET_GLES
case Format::BGR:
case Format::BGRInteger:
case ImageFormat::BGR:
case ImageFormat::BGRInteger:
#endif
return 3*size;
case Format::RGBA:
case ImageFormat::RGBA:
#ifndef MAGNUM_TARGET_GLES2
case Format::RGBAInteger:
case ImageFormat::RGBAInteger:
#endif
#ifndef MAGNUM_TARGET_GLES3
case Format::BGRA:
case ImageFormat::BGRA:
#endif
#ifndef MAGNUM_TARGET_GLES
case Format::BGRAInteger:
case ImageFormat::BGRAInteger:
#endif
return 4*size;
/* Handled above */
case Format::DepthComponent:
case ImageFormat::DepthComponent:
#ifndef MAGNUM_TARGET_GLES3
case Format::StencilIndex:
case ImageFormat::StencilIndex:
#endif
case Format::DepthStencil:
case ImageFormat::DepthStencil:
CORRADE_ASSERT_UNREACHABLE();
}
@ -136,101 +140,4 @@ std::size_t AbstractImage::pixelSize(Format format, Type type) {
return 0;
}
#ifndef DOXYGEN_GENERATING_OUTPUT
Debug operator<<(Debug debug, AbstractImage::Format value) {
switch(value) {
#define _c(value) case AbstractImage::Format::value: return debug << "AbstractImage::Format::" #value;
_c(Red)
#ifndef MAGNUM_TARGET_GLES
_c(Green)
_c(Blue)
#endif
_c(RG)
_c(RGB)
_c(RGBA)
#ifndef MAGNUM_TARGET_GLES
_c(BGR)
#endif
#ifndef MAGNUM_TARGET_GLES3
_c(BGRA)
#endif
#ifndef MAGNUM_TARGET_GLES2
_c(RedInteger)
#ifndef MAGNUM_TARGET_GLES
_c(GreenInteger)
_c(BlueInteger)
#endif
_c(RGInteger)
_c(RGBInteger)
_c(RGBAInteger)
#ifndef MAGNUM_TARGET_GLES
_c(BGRInteger)
_c(BGRAInteger)
#endif
#endif
_c(DepthComponent)
#ifndef MAGNUM_TARGET_GLES3
_c(StencilIndex)
#endif
_c(DepthStencil)
#undef _c
}
return debug << "AbstractImage::Format::(invalid)";
}
Debug operator<<(Debug debug, AbstractImage::Type value) {
switch(value) {
#define _c(value) case AbstractImage::Type::value: return debug << "AbstractImage::Type::" #value;
_c(UnsignedByte)
#ifndef MAGNUM_TARGET_GLES2
_c(Byte)
#endif
_c(UnsignedShort)
#ifndef MAGNUM_TARGET_GLES2
_c(Short)
#endif
_c(UnsignedInt)
#ifndef MAGNUM_TARGET_GLES2
_c(Int)
#endif
_c(HalfFloat)
_c(Float)
#ifndef MAGNUM_TARGET_GLES
_c(UnsignedByte332)
_c(UnsignedByte233Rev)
#endif
_c(UnsignedShort565)
#ifndef MAGNUM_TARGET_GLES
_c(UnsignedShort565Rev)
#endif
_c(UnsignedShort4444)
#ifndef MAGNUM_TARGET_GLES3
_c(UnsignedShort4444Rev)
#endif
_c(UnsignedShort5551)
#ifndef MAGNUM_TARGET_GLES3
_c(UnsignedShort1555Rev)
#endif
#ifndef MAGNUM_TARGET_GLES
_c(UnsignedInt8888)
_c(UnsignedInt8888Rev)
_c(UnsignedInt1010102)
#endif
_c(UnsignedInt2101010Rev)
#ifndef MAGNUM_TARGET_GLES2
_c(UnsignedInt10F11F11FRev)
_c(UnsignedInt5999Rev)
#endif
_c(UnsignedInt248)
#ifndef MAGNUM_TARGET_GLES2
_c(Float32UnsignedInt248Rev)
#endif
#undef _c
}
return debug << "AbstractImage::Type::(invalid)";
}
#endif
}

470
src/AbstractImage.h

@ -31,7 +31,6 @@
#include <cstddef>
#include "Magnum.h"
#include "OpenGL.h"
#include "magnumVisibility.h"
namespace Magnum {
@ -53,480 +52,47 @@ class MAGNUM_EXPORT AbstractImage {
AbstractImage& operator=(AbstractImage&&) = delete;
public:
/**
* @{ @name Image formats
*
* Note that some formats can be used only for framebuffer reading
* (using Framebuffer::read()) and some only for texture data (using
* Texture::setImage() and others).
*/
/**
* @brief Format of pixel data
*
* @see pixelSize()
*/
enum class Format: GLenum {
/**
* Floating-point red channel.
* @requires_gles30 For texture data only, extension
* @es_extension{EXT,texture_rg}.
* @requires_es_extension For framebuffer reading, extension
* @es_extension{EXT,texture_rg}.
*/
#ifndef MAGNUM_TARGET_GLES2
Red = GL_RED,
#else
Red = GL_RED_EXT,
#endif
#ifndef MAGNUM_TARGET_GLES
/**
* Floating-point green channel.
* @requires_gl Only @ref Magnum::AbstractImage::Format "Format::Red"
* is available in OpenGL ES.
*/
Green = GL_GREEN,
/**
* Floating-point blue channel.
* @requires_gl Only @ref Magnum::AbstractImage::Format "Format::Red"
* is available in OpenGL ES.
*/
Blue = GL_BLUE,
/** @todo GL_ALPHA? */
#endif
/**
* Floating-point red and green channel.
* @requires_gl30 %Extension @extension{ARB,texture_rg} and
* @extension{EXT,texture_integer}
* @requires_gles30 For texture data only, extension
* @es_extension{EXT,texture_rg}.
* @requires_es_extension For framebuffer reading, extension
* @es_extension{EXT,texture_rg}.
*/
#ifndef MAGNUM_TARGET_GLES2
RG = GL_RG,
#else
RG = GL_RG_EXT,
#endif
/**
* Floating-point RGB.
* @requires_gl Can't be used for framebuffer reading in OpenGL ES.
*/
RGB = GL_RGB,
/** Floating-point RGBA. */
RGBA = GL_RGBA,
#ifndef MAGNUM_TARGET_GLES
/**
* Floating-point BGR.
* @requires_gl Only RGB component ordering is available in OpenGL
* ES.
*/
BGR = GL_BGR,
#endif
#ifndef MAGNUM_TARGET_GLES3
/**
* Floating-point BGRA.
* @requires_es_extension %Extension @es_extension{EXT,read_format_bgra}
* for framebuffer reading, extension @es_extension{APPLE,texture_format_BGRA8888}
* or @es_extension{EXT,texture_format_BGRA8888} for texture
* data.
*/
#ifndef MAGNUM_TARGET_GLES
BGRA = GL_BGRA,
#else
BGRA = GL_BGRA_EXT,
#endif
#endif
#ifndef MAGNUM_TARGET_GLES2
/**
* Integer red channel.
* @requires_gl30 %Extension @extension{EXT,texture_integer}
* @requires_gles30 Only floating-point image data are available
* in OpenGL ES 2.0.
*/
RedInteger = GL_RED_INTEGER,
#ifndef MAGNUM_TARGET_GLES
/**
* Integer green channel.
* @requires_gl30 %Extension @extension{EXT,texture_integer}
* @requires_gl Only @ref Magnum::AbstractImage::Format "Format::RedInteger"
* is available in OpenGL ES 3.0, only floating-point image
* data are available in OpenGL ES 2.0.
*/
GreenInteger = GL_GREEN_INTEGER,
/**
* Integer blue channel.
* @requires_gl30 %Extension @extension{EXT,texture_integer}
* @requires_gl Only @ref Magnum::AbstractImage::Format "Format::RedInteger"
* is available in OpenGL ES 3.0, only floating-point image
* data are available in OpenGL ES 2.0.
*/
BlueInteger = GL_BLUE_INTEGER,
#endif
/**
* Integer red and green channel.
* @requires_gl30 %Extension @extension{ARB,texture_rg} and
* @extension{EXT,texture_integer}
* @requires_gl Can't be used for framebuffer reading in OpenGL ES.
* @requires_gles30 For texture data only, only floating-point image
* data are available in OpenGL ES 2.0.
*/
RGInteger = GL_RG_INTEGER,
/**
* Integer RGB.
* @requires_gl30 %Extension @extension{EXT,texture_integer}
* @requires_gl Can't be used for framebuffer reading in OpenGL ES.
* @requires_gles30 For texture data only, only floating-point image
* data are available in OpenGL ES 2.0.
*/
RGBInteger = GL_RGB_INTEGER,
/**
* Integer RGBA.
* @requires_gl30 %Extension @extension{EXT,texture_integer}
* @requires_gles30 Only floating-point image data are available
* in OpenGL ES 2.0.
*/
RGBAInteger = GL_RGBA_INTEGER,
#ifndef MAGNUM_TARGET_GLES
/**
* Integer BGR.
* @requires_gl30 %Extension @extension{EXT,texture_integer}
* @requires_gl Only @ref Magnum::AbstractImage::Format "Format::RGBInteger"
* is available in OpenGL ES 3.0, only floating-point image
* data are available in OpenGL ES 2.0.
*/
BGRInteger = GL_BGR_INTEGER,
/**
* Integer BGRA.
* @requires_gl30 %Extension @extension{EXT,texture_integer}
* @requires_gl Only @ref Magnum::AbstractImage::Format "Format::RGBAInteger"
* is available in OpenGL ES 3.0, only floating-point image
* data are available in OpenGL ES 2.0.
*/
BGRAInteger = GL_BGRA_INTEGER,
#endif
#endif
/**
* Depth component.
* @requires_gles30 For texture data only, extension
* @es_extension{ANGLE,depth_texture}.
* @requires_es_extension For framebuffer reading only, extension
* @es_extension2{NV,read_depth,GL_NV_read_depth_stencil}.
*/
DepthComponent = GL_DEPTH_COMPONENT,
#ifndef MAGNUM_TARGET_GLES3
/**
* Stencil index. For framebuffer reading only.
* @requires_es_extension %Extension @es_extension2{NV,read_stencil,GL_NV_read_depth_stencil}
* @todo Where to get GL_STENCIL_INDEX in ES?
*/
#ifndef MAGNUM_TARGET_GLES
StencilIndex = GL_STENCIL_INDEX,
#else
StencilIndex = 0x1901,
#endif
#endif
/**
* Depth and stencil.
* @requires_gl30 %Extension @extension{EXT,packed_depth_stencil}
* @requires_gles30 For texture data only, extension
* @es_extension{OES,packed_depth_stencil}.
* @requires_es_extension For framebuffer reading only, extension
* @es_extension2{NV,read_depth_stencil,GL_NV_read_depth_stencil}.
*/
#ifndef MAGNUM_TARGET_GLES2
DepthStencil = GL_DEPTH_STENCIL
#else
DepthStencil = GL_DEPTH_STENCIL_OES
#endif
};
/**
* @brief Data type of pixel data
*
* @see pixelSize()
*/
enum class Type: GLenum {
/** Each component unsigned byte. */
UnsignedByte = GL_UNSIGNED_BYTE,
#ifndef MAGNUM_TARGET_GLES2
/**
* Each component signed byte.
* @requires_gl Can't be used for framebuffer reading in OpenGL ES.
* @requires_gles30 For texture data only, only
* @ref Magnum::AbstractImage::Type "Type::UnsignedByte" is
* available in OpenGL ES 2.0.
*/
Byte = GL_BYTE,
#endif
/**
* Each component unsigned short.
* @requires_gl Can't be used for framebuffer reading in OpenGL ES.
* @requires_gles30 For texture data only, extension
* @es_extension{OES,depth_texture} or @es_extension{ANGLE,depth_texture}.
*/
UnsignedShort = GL_UNSIGNED_SHORT,
#ifndef MAGNUM_TARGET_GLES2
/**
* Each component signed short.
* @requires_gl Can't be used for framebuffer reading in OpenGL ES.
* @requires_gles30 For texture data only, only
* @ref Magnum::AbstractImage::Type "Type::UnsignedShort" is
* available in OpenGL ES 2.0.
*/
Short = GL_SHORT,
#endif
/**
* Each component unsigned int.
* @requires_gles30 Can't be used for framebuffer reading in OpenGL
* ES 2.0.
* @requires_gles30 For texture data only, extension
* @es_extension{OES,depth_texture} or @es_extension{ANGLE,depth_texture}.
*/
UnsignedInt = GL_UNSIGNED_INT,
#ifndef MAGNUM_TARGET_GLES2
/**
* Each component signed int.
* @requires_gles30 Only @ref Magnum::AbstractImage::Type "Type::UnsignedInt"
* is available in OpenGL ES 2.0.
*/
Int = GL_INT,
#endif
/**
* Each component half float.
* @requires_gl30 %Extension @extension{NV,half_float} / @extension{ARB,half_float_pixel}
* @requires_gles30 For texture data only, extension
* @es_extension2{OES,texture_half_float,OES_texture_float}.
*/
#ifndef MAGNUM_TARGET_GLES2
HalfFloat = GL_HALF_FLOAT,
#else
HalfFloat = GL_HALF_FLOAT_OES,
#endif
/**
* Each component float.
* @requires_gles30 For texture data only, extension
* @es_extension{OES,texture_float}.
*/
Float = GL_FLOAT,
#ifndef MAGNUM_TARGET_GLES
/**
* RGB, unsigned byte, red and green component 3bit, blue
* component 2bit.
* @requires_gl Packed 12bit types are not available in OpenGL ES.
*/
UnsignedByte332 = GL_UNSIGNED_BYTE_3_3_2,
/**
* BGR, unsigned byte, red and green component 3bit, blue
* component 2bit.
* @requires_gl Packed 12bit types are not available in OpenGL ES.
*/
UnsignedByte233Rev = GL_UNSIGNED_BYTE_2_3_3_REV,
#endif
/**
* RGB, unsigned byte, red and blue component 5bit, green 6bit.
* @requires_gl Can't be used for framebuffer reading in OpenGL ES.
*/
UnsignedShort565 = GL_UNSIGNED_SHORT_5_6_5,
#ifndef MAGNUM_TARGET_GLES
/**
* BGR, unsigned short, red and blue 5bit, green 6bit.
* @requires_gl Only @ref Magnum::AbstractImage::Type "Type::RGB565"
* is available in OpenGL ES.
*/
UnsignedShort565Rev = GL_UNSIGNED_SHORT_5_6_5_REV,
#endif
/**
* RGBA, unsigned short, each component 4bit.
* @requires_gl Can't be used for framebuffer reading in OpenGL ES.
*/
UnsignedShort4444 = GL_UNSIGNED_SHORT_4_4_4_4,
#ifndef MAGNUM_TARGET_GLES3
/**
* ABGR, unsigned short, each component 4bit.
* @requires_es_extension For framebuffer reading only, extension
* @es_extension{EXT,read_format_bgra}.
*/
#ifndef MAGNUM_TARGET_GLES
UnsignedShort4444Rev = GL_UNSIGNED_SHORT_4_4_4_4_REV,
#else
UnsignedShort4444Rev = GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT,
#endif
#endif
/**
* RGBA, unsigned short, each RGB component 5bit, alpha component
* 1bit.
* @requires_gl Can't be used for framebuffer reading in OpenGL ES.
*/
UnsignedShort5551 = GL_UNSIGNED_SHORT_5_5_5_1,
#ifndef MAGNUM_TARGET_GLES3
/**
* ABGR, unsigned short, each RGB component 5bit, alpha component
* 1bit.
* @requires_es_extension For framebuffer reading only, extension
* @es_extension{EXT,read_format_bgra}.
*/
#ifndef MAGNUM_TARGET_GLES
UnsignedShort1555Rev = GL_UNSIGNED_SHORT_1_5_5_5_REV,
#else
UnsignedShort1555Rev = GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT,
#endif
#endif
#ifndef MAGNUM_TARGET_GLES
/**
* RGBA, unsigned int, each component 8bit.
* @requires_gl Use @ref Magnum::AbstractImage::Type "Type::UnsignedByte"
* in OpenGL ES instead.
*/
UnsignedInt8888 = GL_UNSIGNED_INT_8_8_8_8,
/**
* ABGR, unsigned int, each component 8bit.
* @requires_gl Only RGBA component ordering is available in
* OpenGL ES, see @ref Magnum::AbstractImage::Format "Format::UnsignedInt8888"
* for more information.
*/
UnsignedInt8888Rev = GL_UNSIGNED_INT_8_8_8_8_REV,
/**
* RGBA, unsigned int, each RGB component 10bit, alpha component
* 2bit.
* @requires_gl Only @ref Magnum::AbstractImage::Type "Type::UnsignedInt2101010Rev"
* is available in OpenGL ES.
*/
UnsignedInt1010102 = GL_UNSIGNED_INT_10_10_10_2,
#endif
/**
* ABGR, unsigned int, each RGB component 10bit, alpha component
* 2bit.
* @requires_gles30 Can't be used for framebuffer reading in OpenGL
* ES 2.0.
* @requires_gles30 For texture data only, extension
* @es_extension{EXT,texture_type_2_10_10_10_REV}.
*/
#ifndef MAGNUM_TARGET_GLES2
UnsignedInt2101010Rev = GL_UNSIGNED_INT_2_10_10_10_REV,
#else
UnsignedInt2101010Rev = GL_UNSIGNED_INT_2_10_10_10_REV_EXT,
#endif
#ifndef MAGNUM_TARGET_GLES2
/**
* BGR, unsigned int, red and green 11bit float, blue 10bit float.
* @requires_gl30 %Extension @extension{EXT,packed_float}
* @requires_gles30 Floating-point types are not available in
* OpenGL ES 2.0.
*/
UnsignedInt10F11F11FRev = GL_UNSIGNED_INT_10F_11F_11F_REV,
/**
* BGR, unsigned int, each component 9bit + 5bit exponent.
* @requires_gl30 %Extension @extension{EXT,texture_shared_exponent}
* @requires_gles30 Only 8bit and 16bit types are available in
* OpenGL ES 2.0.
*/
UnsignedInt5999Rev = GL_UNSIGNED_INT_5_9_9_9_REV,
#endif
/**
* Unsigned int, depth component 24bit, stencil index 8bit.
* @requires_gl30 %Extension @extension{EXT,packed_depth_stencil}
* @requires_gles30 For texture data only, extension
* @es_extension{OES,packed_depth_stencil}.
*/
#ifdef MAGNUM_TARGET_GLES2
UnsignedInt248 = GL_UNSIGNED_INT_24_8_OES
#else
UnsignedInt248 = GL_UNSIGNED_INT_24_8,
/**
* Float + unsigned int, depth component 32bit float, 24bit gap,
* stencil index 8bit.
* @requires_gl30 %Extension @extension{ARB,depth_buffer_float}
* @requires_gles30 For texture data only, only
* @ref Magnum::AbstractImage::Type "Type::UnsignedInt248" is
* available in OpenGL ES 2.0.
*/
Float32UnsignedInt248Rev = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
#endif
};
/*@}*/
/**
* @brief Pixel size (in bytes)
* @param format Format of the pixel
* @param type Data type of the pixel
*
* @see pixelSize() const
*/
static std::size_t pixelSize(Format format, Type type);
static std::size_t pixelSize(ImageFormat format, ImageType type);
/**
* @brief Constructor
* @param format Format of pixel data
* @param type Data type of pixel data
*/
inline explicit AbstractImage(Format format, Type type): _format(format), _type(type) {}
explicit AbstractImage(ImageFormat format, ImageType type): _format(format), _type(type) {}
/** @brief Destructor */
virtual ~AbstractImage() = 0;
/** @brief Format of pixel data */
inline Format format() const { return _format; }
ImageFormat format() const { return _format; }
/** @brief Data type of pixel data */
inline Type type() const { return _type; }
ImageType type() const { return _type; }
#ifndef DOXYGEN_GENERATING_OUTPUT
/**
* @brief Pixel size (in bytes)
*
* Convenience member alternative for pixelSize(Format, Type).
*/
std::size_t pixelSize() const { return pixelSize(_format, _type); }
#ifdef DOXYGEN_GENERATING_OUTPUT
private:
#else
protected:
Format _format;
Type _type;
#endif
ImageFormat _format;
ImageType _type;
};
inline AbstractImage::~AbstractImage() {}
/** @debugoperator{Magnum::AbstractImage} */
Debug MAGNUM_EXPORT operator<<(Debug debug, AbstractImage::Format value);
/** @debugoperator{Magnum::AbstractImage} */
Debug MAGNUM_EXPORT operator<<(Debug debug, AbstractImage::Type value);
}
#endif

46
src/AbstractResourceLoader.h

@ -98,18 +98,16 @@ template<class T> class AbstractResourceLoader {
friend class Implementation::ResourceManagerData<T>;
public:
inline explicit AbstractResourceLoader(): manager(nullptr), _requestedCount(0), _loadedCount(0), _notFoundCount(0) {}
explicit AbstractResourceLoader(): manager(nullptr), _requestedCount(0), _loadedCount(0), _notFoundCount(0) {}
inline virtual ~AbstractResourceLoader() {
if(manager) manager->_loader = nullptr;
}
virtual ~AbstractResourceLoader();
/**
* @brief Count of requested resources
*
* Count of resources requested by calling load().
*/
inline std::size_t requestedCount() const { return _requestedCount; }
std::size_t requestedCount() const { return _requestedCount; }
/**
* @brief Count of not found resources
@ -117,7 +115,7 @@ template<class T> class AbstractResourceLoader {
* Count of resources requested by calling load(), but not found by
* the loader.
*/
inline std::size_t notFoundCount() const { return _notFoundCount; }
std::size_t notFoundCount() const { return _notFoundCount; }
/**
* @brief Count of loaded resources
@ -125,7 +123,7 @@ template<class T> class AbstractResourceLoader {
* Count of resources requested by calling load(), but not found by
* the loader.
*/
inline std::size_t loadedCount() const { return _loadedCount; }
std::size_t loadedCount() const { return _loadedCount; }
/**
* @brief %Resource name corresponding to given key
@ -160,12 +158,7 @@ template<class T> class AbstractResourceLoader {
* ResourceManager::set() for more information.
* @see loadedCount()
*/
inline void set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy) {
CORRADE_ASSERT(state == ResourceDataState::Mutable || state == ResourceDataState::Final,
"AbstractResourceLoader::set(): state must be either Mutable or Final", );
++_loadedCount;
manager->set(key, data, state, policy);
}
void set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy);
/**
* @brief Mark resource as not found
@ -174,11 +167,7 @@ template<class T> class AbstractResourceLoader {
* ResourceManager::setNotFound() for more information.
* @see notFountCount()
*/
inline void setNotFound(ResourceKey key) {
++_notFoundCount;
/** @todo What policy for notfound resources? */
manager->set(key, nullptr, ResourceDataState::NotFound, ResourcePolicy::Resident);
}
void setNotFound(ResourceKey key);
private:
Implementation::ResourceManagerData<T>* manager;
@ -187,14 +176,31 @@ template<class T> class AbstractResourceLoader {
std::size_t _notFoundCount;
};
template<class T> inline std::string AbstractResourceLoader<T>::name(ResourceKey) const { return {}; }
template<class T> AbstractResourceLoader<T>::~AbstractResourceLoader() {
if(manager) manager->_loader = nullptr;
}
template<class T> std::string AbstractResourceLoader<T>::name(ResourceKey) const { return {}; }
template<class T> inline void AbstractResourceLoader<T>::load(ResourceKey key) {
template<class T> void AbstractResourceLoader<T>::load(ResourceKey key) {
++_requestedCount;
/** @todo What policy for loading resources? */
manager->set(key, nullptr, ResourceDataState::Loading, ResourcePolicy::Resident);
}
template<class T> void AbstractResourceLoader<T>::set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy) {
CORRADE_ASSERT(state == ResourceDataState::Mutable || state == ResourceDataState::Final,
"AbstractResourceLoader::set(): state must be either Mutable or Final", );
++_loadedCount;
manager->set(key, data, state, policy);
}
template<class T> inline void AbstractResourceLoader<T>::setNotFound(ResourceKey key) {
++_notFoundCount;
/** @todo What policy for notfound resources? */
manager->set(key, nullptr, ResourceDataState::NotFound, ResourcePolicy::Resident);
}
}
#endif

105
src/AbstractShaderProgram.cpp

@ -24,16 +24,11 @@
#include "AbstractShaderProgram.h"
#include <fstream>
#include <type_traits>
#include "Math/RectangularMatrix.h"
#include "Extensions.h"
#include "Shader.h"
#include "Implementation/State.h"
#include "Implementation/ShaderProgramState.h"
#include "Extensions.h"
#define LINKER_MESSAGE_MAX_LENGTH 1024
#include "Implementation/State.h"
namespace Magnum {
@ -91,83 +86,105 @@ Int AbstractShaderProgram::maxSupportedVertexAttributeCount() {
return value;
}
AbstractShaderProgram::AbstractShaderProgram(): _id(glCreateProgram()) {}
AbstractShaderProgram::AbstractShaderProgram(AbstractShaderProgram&& other) noexcept: _id(other._id) {
other._id = 0;
}
AbstractShaderProgram::~AbstractShaderProgram() {
/* Remove current usage from the state */
GLuint& current = Context::current()->state()->shaderProgram->current;
if(current == _id) current = 0;
glDeleteProgram(_id);
if(_id) glDeleteProgram(_id);
}
AbstractShaderProgram& AbstractShaderProgram::operator=(AbstractShaderProgram&& other) noexcept {
std::swap(_id, other._id);
return *this;
}
bool AbstractShaderProgram::use() {
if(state != Linked) return false;
std::pair<bool, std::string> AbstractShaderProgram::validate() {
glValidateProgram(_id);
/* Check validation status */
GLint success, logLength;
glGetProgramiv(_id, GL_VALIDATE_STATUS, &success);
glGetProgramiv(_id, GL_INFO_LOG_LENGTH, &logLength);
/* Error or warning message. The string is returned null-terminated, scrap
the \0 at the end afterwards */
std::string message(logLength, '\n');
if(!message.empty()) {
glGetProgramInfoLog(_id, message.size(), nullptr, &message[0]);
message.resize(logLength-1);
}
return {success, std::move(message)};
}
void AbstractShaderProgram::use() {
/* Use only if the program isn't already in use */
GLuint& current = Context::current()->state()->shaderProgram->current;
if(current != _id) glUseProgram(current = _id);
return true;
}
bool AbstractShaderProgram::attachShader(Shader& shader) {
GLuint _shader = shader.compile();
if(!_shader) return false;
glAttachShader(_id, _shader);
return true;
void AbstractShaderProgram::attachShader(Shader& shader) {
glAttachShader(_id, shader.id());
}
void AbstractShaderProgram::bindAttributeLocation(UnsignedInt location, const std::string& name) {
CORRADE_ASSERT(state == Initialized, "AbstractShaderProgram: attribute cannot be bound after linking.", );
glBindAttribLocation(_id, location, name.c_str());
}
#ifndef MAGNUM_TARGET_GLES
void AbstractShaderProgram::bindFragmentDataLocation(UnsignedInt location, const std::string& name) {
CORRADE_ASSERT(state == Initialized, "AbstractShaderProgram: fragment data location cannot be bound after linking.", );
glBindFragDataLocation(_id, location, name.c_str());
}
void AbstractShaderProgram::bindFragmentDataLocationIndexed(UnsignedInt location, UnsignedInt index, const std::string& name) {
CORRADE_ASSERT(state == Initialized, "AbstractShaderProgram: fragment data location cannot be bound after linking.", );
glBindFragDataLocationIndexed(_id, location, index, name.c_str());
}
#endif
void AbstractShaderProgram::link() {
/* Already compiled or failed, exit */
if(state != Initialized) return;
bool AbstractShaderProgram::link() {
/* Link shader program */
glLinkProgram(_id);
/* Check link status */
GLint status;
glGetProgramiv(_id, GL_LINK_STATUS, &status);
/* Display errors or warnings */
char message[LINKER_MESSAGE_MAX_LENGTH];
glGetProgramInfoLog(_id, LINKER_MESSAGE_MAX_LENGTH, nullptr, message);
GLint success, logLength;
glGetProgramiv(_id, GL_LINK_STATUS, &success);
glGetProgramiv(_id, GL_INFO_LOG_LENGTH, &logLength);
/* Error or warning message. The string is returned null-terminated, scrap
the \0 at the end afterwards */
std::string message(logLength, '\n');
if(!message.empty()) {
glGetProgramInfoLog(_id, message.size(), nullptr, &message[0]);
message.resize(logLength-1);
}
/* Show error log and delete shader */
if(status == GL_FALSE) {
Error() << "AbstractShaderProgram: linking failed with the following message:\n"
<< message;
if(!success) {
Error out;
out.setFlag(Debug::NewLineAtTheEnd, false);
out.setFlag(Debug::SpaceAfterEachValue, false);
out << "AbstractShaderProgram: linking failed with the following message:\n"
<< message;
/* Or just warnings, if there are any */
} else if(message[0] != 0) {
Debug() << "AbstractShaderProgram: linking succeeded with the following message:\n"
<< message;
} else if(!message.empty()) {
Debug out;
out.setFlag(Debug::NewLineAtTheEnd, false);
out.setFlag(Debug::SpaceAfterEachValue, false);
out << "AbstractShaderProgram: linking succeeded with the following message:\n"
<< message;
}
state = status == GL_FALSE ? Failed : Linked;
return success;
}
Int AbstractShaderProgram::uniformLocation(const std::string& name) {
/** @todo What if linking just failed (not programmer error?) */
CORRADE_ASSERT(state == Linked, "AbstractShaderProgram: uniform location cannot be retrieved before linking.", -1);
GLint location = glGetUniformLocation(_id, name.c_str());
if(location == -1)
Warning() << "AbstractShaderProgram: location of uniform \'" + name + "\' cannot be retrieved!";
@ -578,7 +595,6 @@ void AbstractShaderProgram::uniformImplementationDSA(const GLint location, const
}
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
std::size_t FloatAttribute::size(GLint components, DataType dataType) {
@ -837,6 +853,5 @@ Debug operator<<(Debug debug, Attribute<Math::Vector<4, Float>>::DataType value)
}
}
#endif
}

636
src/AbstractShaderProgram.h

@ -35,15 +35,11 @@
#include "OpenGL.h"
#include "magnumVisibility.h"
/** @todo early asserts (no bool returns?) */
namespace Magnum {
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
template<class> struct Attribute;
}
#endif
/**
@brief Base for shader program implementations
@ -86,12 +82,19 @@ Int TransformationUniform = 0,
gets uniform locations, for example:
@code
MyShader() {
// Load shaders from file and attach them to the program
attachShader(Shader::fromFile(Version::430, Shader::Type::Vertex, "PhongShader.vert"));
attachShader(Shader::fromFile(Version::430, Shader::Type::Fragment, "PhongShader.frag"));
// Link
link();
// Load shaders, compile them and attach them to the program
Shader vert(Version::GL430, Shader::Type::Vertex);
vert.attachFile("PhongShader.vert");
CORRADE_INTERNAL_ASSERT_OUTPUT(vert.compile());
attachShader(vert);
Shader frag(Version::GL430, Shader::Type::Fragment);
frag.attachFile("PhongShader.vert");
CORRADE_INTERNAL_ASSERT_OUTPUT(frag.compile());
attachShader(frag);
// Link the program together
CORRADE_INTERNAL_ASSERT_OUTPUT(link());
}
@endcode
- **Uniform setting functions**, which will provide public interface for
@ -283,230 +286,8 @@ comes in handy.
class MAGNUM_EXPORT AbstractShaderProgram {
friend class Context;
AbstractShaderProgram(const AbstractShaderProgram&) = delete;
AbstractShaderProgram(AbstractShaderProgram&&) = delete;
AbstractShaderProgram& operator=(const AbstractShaderProgram&) = delete;
AbstractShaderProgram& operator=(AbstractShaderProgram&&) = delete;
public:
/**
* @brief Base struct for attribute location and type
*
* Template parameter @p location is vertex attribute location, number
* between `0` and maxSupportedVertexAttributeCount(). To ensure
* compatibility, you should always have vertex attribute with
* location `0`.
*
* Template parameter @p T is the type which is used for shader
* attribute, e.g. @ref Vector4i for `ivec4`. DataType is type of
* passed data when adding vertex buffers to mesh. By default it is
* the same as type used in shader (e.g. @ref DataType "DataType::Int"
* for @ref Vector4i). It's also possible to pass integer data to
* floating-point shader inputs. In this case you may want to
* normalize the values (e.g. color components from 0-255 to
* 0.0f - 1.0f) -- see @ref DataOption "DataOption::Normalize".
*
* Only some types are allowed as attribute types, see
* @ref AbstractShaderProgram-types or TypeTraits::AttributeType for
* more information.
*
* See @ref AbstractShaderProgram-subclassing for example usage in
* shaders and @ref Mesh-configuration for example usage when adding
* vertex buffers to mesh.
*/
template<UnsignedInt location, class T> class Attribute {
public:
enum: UnsignedInt {
Location = location /**< Location to which the attribute is bound */
};
/**
* @brief Type
*
* Type used in shader code.
* @see DataType
*/
typedef typename Implementation::Attribute<T>::Type Type;
/**
* @brief Component count
*
* Count of components passed to the shader. If passing smaller
* count of components than corresponding type has, unspecified
* components are set to default values (second and third to `0`,
* fourth to `1`).
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
enum class Components: GLint {
/**
* Only first component is specified. Second, third and
* fourth component are set to `0`, `0`, `1`, respectively.
* Only for scalar and vector types, not matrices.
*/
One = 1,
/**
* First two components are specified. Third and fourth
* component are set to `0`, `1`, respectively. Only for
* two, three and four-component vector types and 2x2, 3x2
* and 4x2 matrix types.
*/
Two = 2,
/**
* First three components are specified. Fourth component is
* set to `1`. Only for three and four-component vector
* types, 2x3, 3x3 and 4x3 matrix types.
*/
Three = 3,
/**
* All four components are specified. Only for four-component
* vector types and 2x4, 3x4 and 4x4 matrix types.
*/
Four = 4
#ifndef MAGNUM_TARGET_GLES
,
/**
* Four components with BGRA ordering. Only for four-component
* float vector type.
* @requires_gl32 %Extension @extension{ARB,vertex_array_bgra}
* @requires_gl Only RGBA component ordering is supported
* in OpenGL ES.
*/
BGRA = 1 << 1
#endif
};
#else
typedef typename Implementation::Attribute<T>::Components Components;
#endif
/**
* @brief Data type
*
* Type of data passed to shader.
* @see Type, DataOptions, Attribute()
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
enum class DataType: GLenum {
UnsignedByte = GL_UNSIGNED_BYTE, /**< Unsigned byte */
Byte = GL_BYTE, /**< Byte */
UnsignedShort = GL_UNSIGNED_SHORT, /**< Unsigned short */
Short = GL_SHORT, /**< Short */
UnsignedInt = GL_UNSIGNED_INT, /**< Unsigned int */
Int = GL_INT, /**< Int */
/**
* Half float. Only for float attribute types.
* @requires_gl30 %Extension @extension{NV,half_float}
* @requires_gles30 %Extension @es_extension{OES,vertex_half_float}
*/
HalfFloat = GL_HALF_FLOAT,
/** Float. Only for float attribute types. */
Float = GL_FLOAT,
#ifndef MAGNUM_TARGET_GLES
/**
* Double. Only for float and double attribute types.
* @requires_gl Only floats are available in OpenGL ES.
*/
Double = GL_DOUBLE,
#endif
/* GL_FIXED not supported */
#ifndef MAGNUM_TARGET_GLES2
/**
* Unsigned 2.10.10.10 packed integer. Only for
* four-component float vector attribute type.
* @todo How about (incompatible) @es_extension{OES,vertex_type_10_10_10_2}?
* @requires_gl33 %Extension @extension{ARB,vertex_type_2_10_10_10_rev}
* @requires_gles30 (no extension providing this functionality)
*/
UnsignedInt2101010Rev = GL_UNSIGNED_INT_2_10_10_10_REV,
/**
* Signed 2.10.10.10 packed integer. Only for
* four-component float vector attribute type.
* @requires_gl33 %Extension @extension{ARB,vertex_type_2_10_10_10_rev}
* @requires_gles30 (no extension providing this functionality)
*/
Int2101010Rev = GL_INT_2_10_10_10_REV
#endif
};
#else
typedef typename Implementation::Attribute<T>::DataType DataType;
#endif
/**
* @brief Data option
* @see DataOptions, Attribute()
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
enum class DataOption: UnsignedByte {
/**
* Normalize integer components. Only for float attribute
* types. Default is to not normalize.
*/
Normalize = 1 << 0
};
#else
typedef typename Implementation::Attribute<T>::DataOption DataOption;
#endif
/**
* @brief Data options
* @see Attribute()
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
typedef typename Corrade::Containers::EnumSet<DataOption, UnsignedByte> DataOptions;
#else
typedef typename Implementation::Attribute<T>::DataOptions DataOptions;
#endif
/**
* @brief Constructor
* @param components Component count
* @param dataType Type of passed data. Default is the
* same as type used in shader (e.g. DataType::Integer
* for Vector4i).
* @param dataOptions Data options. Default is no options.
*/
inline constexpr Attribute(Components components, DataType dataType = Implementation::Attribute<T>::DefaultDataType, DataOptions dataOptions = DataOptions()): _components(components), _dataType(dataType), _dataOptions(dataOptions) {}
/**
* @brief Constructor
* @param dataType Type of passed data. Default is the
* same as type used in shader (e.g. DataType::Integer
* for Vector4i).
* @param dataOptions Data options. Default is no options.
*
* Component count is set to the same value as in type used in
* shader (e.g. @ref Components "Components::Three" for Vector3).
*/
inline constexpr Attribute(DataType dataType = Implementation::Attribute<T>::DefaultDataType, DataOptions dataOptions = DataOptions()): _components(Implementation::Attribute<T>::DefaultComponents), _dataType(dataType), _dataOptions(dataOptions) {}
/** @brief Component count of passed data */
inline constexpr Components components() const { return _components; }
/** @brief Type of passed data */
inline constexpr DataType dataType() const { return _dataType; }
/** @brief Size of passed data */
inline std::size_t dataSize() const {
return Implementation::Attribute<T>::size(GLint(_components)*Implementation::Attribute<T>::vectorCount(), _dataType);
}
/** @brief Data options */
inline constexpr DataOptions dataOptions() const { return _dataOptions; }
private:
const Components _components;
const DataType _dataType;
const DataOptions _dataOptions;
};
template<UnsignedInt, class> class Attribute;
/**
* @brief Max supported vertex attribute count
@ -523,9 +304,13 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* Creates one OpenGL shader program.
* @see @fn_gl{CreateProgram}
*/
inline explicit AbstractShaderProgram(): state(Initialized) {
_id = glCreateProgram();
}
explicit AbstractShaderProgram();
/** @brief Copying is not allowed */
AbstractShaderProgram(const AbstractShaderProgram&) = delete;
/** @brief Move constructor */
AbstractShaderProgram(AbstractShaderProgram&& other) noexcept;
/**
* @brief Destructor
@ -535,14 +320,31 @@ class MAGNUM_EXPORT AbstractShaderProgram {
*/
virtual ~AbstractShaderProgram() = 0;
/** @brief Copying is not allowed */
AbstractShaderProgram& operator=(const AbstractShaderProgram&) = delete;
/** @brief Move assignment */
AbstractShaderProgram& operator=(AbstractShaderProgram&& other) noexcept;
/** @brief OpenGL program ID */
GLuint id() const { return _id; }
/**
* @brief Validate program
*
* Returns validation status and optional validation message.
* @see @fn_gl{ValidateProgram}, @fn_gl{GetProgram} with
* @def_gl{VALIDATE_STATUS}, @def_gl{INFO_LOG_LENGTH},
* @fn_gl{GetProgramInfoLog}
*/
std::pair<bool, std::string> validate();
/**
* @brief Use shader for rendering
* @return False if the program wasn't successfully linked, true
* otherwise.
*
* @see @fn_gl{UseProgram}
*/
bool use();
void use();
protected:
#ifndef MAGNUM_TARGET_GLES2
@ -550,13 +352,11 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @brief Allow retrieving program binary
*
* Initially disabled.
* @note This function should be called after attachShader() calls and
* before link().
* @see @fn_gl{ProgramParameter} with @def_gl{PROGRAM_BINARY_RETRIEVABLE_HINT}
* @requires_gl41 %Extension @extension{ARB,get_program_binary}
* @requires_gles30 Always allowed in OpenGL ES 2.0.
*/
inline void setRetrievableBinary(bool enabled) {
void setRetrievableBinary(bool enabled) {
glProgramParameteri(_id, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, enabled ? GL_TRUE : GL_FALSE);
}
#endif
@ -565,13 +365,11 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @brief Allow the program to be bound to individual pipeline stages
*
* Initially disabled.
* @note This function should be called after attachShader() calls and
* before link().
* @see @fn_gl{ProgramParameter} with @def_gl{PROGRAM_SEPARABLE}
* @requires_gl41 %Extension @extension{ARB,separate_shader_objects}
* @requires_es_extension %Extension @es_extension{EXT,separate_shader_objects}
*/
inline void setSeparable(bool enabled) {
void setSeparable(bool enabled) {
/** @todo Remove when extension wrangler is available for ES */
#ifndef MAGNUM_TARGET_GLES
glProgramParameteri(_id, GL_PROGRAM_SEPARABLE, enabled ? GL_TRUE : GL_FALSE);
@ -581,20 +379,11 @@ class MAGNUM_EXPORT AbstractShaderProgram {
}
/**
* @brief Load shader
* @return False if the shader wasn't successfully compiled, true
* otherwise.
* @brief Attach shader
*
* Compiles the shader, if it is not already, and prepares it for
* linking.
* @see Shader::compile(), @fn_gl{AttachShader}
* @fn_gl{AttachShader}
*/
bool attachShader(Shader& shader);
/** @overload */
inline bool attachShader(Shader&& shader) {
return attachShader(shader);
}
void attachShader(Shader& shader);
/**
* @brief Bind attribute to given location
@ -603,8 +392,6 @@ class MAGNUM_EXPORT AbstractShaderProgram {
*
* Binds attribute to location which is used later for binding vertex
* buffers.
* @note This function should be called after attachShader() calls and
* before link().
* @deprecated Preferred usage is to specify attribute location
* explicitly in the shader instead of using this function. See
* @ref AbstractShaderProgram-attribute-location "class documentation"
@ -623,8 +410,6 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* Binds fragment data to location which is used later for framebuffer
* operations. See also Framebuffer::BlendFunction for more
* information about using color input index.
* @note This function should be called after attachShader() calls and
* before link().
* @deprecated Preferred usage is to specify attribute location
* explicitly in the shader instead of using this function. See
* @ref AbstractShaderProgram-attribute-location "class documentation"
@ -654,18 +439,19 @@ class MAGNUM_EXPORT AbstractShaderProgram {
/**
* @brief Link the shader
*
* Binds previously specified attributes to given indexes and links the
* shader program together.
* Returns `false` if linking failed, `true` otherwise. Compiler
* message (if any) is printed to error output. All attached shaders
* must be explicitly compiled with Shader::compile() before linking.
* @see @fn_gl{LinkProgram}, @fn_gl{GetProgram} with
* @def_gl{LINK_STATUS}, @fn_gl{GetProgramInfoLog}
* @def_gl{LINK_STATUS} and @def_gl{INFO_LOG_LENGTH},
* @fn_gl{GetProgramInfoLog}
*/
void link();
bool link();
/**
* @brief Get uniform location
* @param name Uniform name
*
* @note This function should be called after link().
* @deprecated Preferred usage is to specify uniform location
* explicitly in the shader instead of using this function. See
* @ref AbstractShaderProgram-uniform-location "class documentation"
@ -685,26 +471,26 @@ class MAGNUM_EXPORT AbstractShaderProgram {
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> inline void setUniform(Int location, const T& value);
#else
inline void setUniform(Int location, Float value) {
void setUniform(Int location, Float value) {
setUniform(location, 1, &value);
}
inline void setUniform(Int location, Int value) {
void setUniform(Int location, Int value) {
setUniform(location, 1, &value);
}
#ifndef MAGNUM_TARGET_GLES2
inline void setUniform(Int location, UnsignedInt value) {
void setUniform(Int location, UnsignedInt value) {
setUniform(location, 1, &value);
}
#endif
#ifndef MAGNUM_TARGET_GLES
inline void setUniform(Int location, Double value) {
void setUniform(Int location, Double value) {
setUniform(location, 1, &value);
}
#endif
template<std::size_t size, class T> inline void setUniform(Int location, const Math::Vector<size, T>& value) {
template<std::size_t size, class T> void setUniform(Int location, const Math::Vector<size, T>& value) {
setUniform(location, 1, &value);
}
template<std::size_t cols, std::size_t rows, class T> inline void setUniform(Int location, const Math::RectangularMatrix<cols, rows, T>& value) {
template<std::size_t cols, std::size_t rows, class T> void setUniform(Int location, const Math::RectangularMatrix<cols, rows, T>& value) {
setUniform(location, 1, &value);
}
#endif
@ -719,45 +505,44 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @extension{EXT,direct_state_access} is available, the shader is
* marked for use before the operation.
* @see setUniform(Int, const T&), @fn_gl{UseProgram}, @fn_gl{Uniform}
* or `glProgramUniform()` from
* @extension{ARB,separate_shader_objects}/@extension{EXT,direct_state_access}.
* or @fn_gl{ProgramUniform}/@fn_gl_extension{ProgramUniform,EXT,direct_state_access}.
*/
inline void setUniform(Int location, UnsignedInt count, const Float* values) {
void setUniform(Int location, UnsignedInt count, const Float* values) {
(this->*uniform1fvImplementation)(location, count, values);
}
/** @copydoc setUniform(Int, UnsignedInt, const Float*) */
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<2, Float>* values) {
void setUniform(Int location, UnsignedInt count, const Math::Vector<2, Float>* values) {
(this->*uniform2fvImplementation)(location, count, values);
}
/** @copydoc setUniform(Int, UnsignedInt, const Float*) */
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<3, Float>* values) {
void setUniform(Int location, UnsignedInt count, const Math::Vector<3, Float>* values) {
(this->*uniform3fvImplementation)(location, count, values);
}
/** @copydoc setUniform(Int, UnsignedInt, const Float*) */
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<4, Float>* values) {
void setUniform(Int location, UnsignedInt count, const Math::Vector<4, Float>* values) {
(this->*uniform4fvImplementation)(location, count, values);
}
/** @copydoc setUniform(Int, UnsignedInt, const Float*) */
inline void setUniform(Int location, UnsignedInt count, const Int* values) {
void setUniform(Int location, UnsignedInt count, const Int* values) {
(this->*uniform1ivImplementation)(location, count, values);
}
/** @copydoc setUniform(Int, UnsignedInt, const Float*) */
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<2, Int>* values) {
void setUniform(Int location, UnsignedInt count, const Math::Vector<2, Int>* values) {
(this->*uniform2ivImplementation)(location, count, values);
}
/** @copydoc setUniform(Int, UnsignedInt, const Float*) */
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<3, Int>* values) {
void setUniform(Int location, UnsignedInt count, const Math::Vector<3, Int>* values) {
(this->*uniform3ivImplementation)(location, count, values);
}
/** @copydoc setUniform(Int, UnsignedInt, const Float*) */
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<4, Int>* values) {
void setUniform(Int location, UnsignedInt count, const Math::Vector<4, Int>* values) {
(this->*uniform4ivImplementation)(location, count, values);
}
@ -767,7 +552,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl30 %Extension @extension{EXT,gpu_shader4}
* @requires_gles30 Only signed integers are available in OpenGL ES 2.0.
*/
inline void setUniform(Int location, UnsignedInt count, const UnsignedInt* values) {
void setUniform(Int location, UnsignedInt count, const UnsignedInt* values) {
(this->*uniform1uivImplementation)(location, count, values);
}
@ -776,7 +561,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl30 %Extension @extension{EXT,gpu_shader4}
* @requires_gles30 Only signed integers are available in OpenGL ES 2.0.
*/
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<2, UnsignedInt>* values) {
void setUniform(Int location, UnsignedInt count, const Math::Vector<2, UnsignedInt>* values) {
(this->*uniform2uivImplementation)(location, count, values);
}
@ -785,7 +570,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl30 %Extension @extension{EXT,gpu_shader4}
* @requires_gles30 Only signed integers are available in OpenGL ES 2.0.
*/
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<3, UnsignedInt>* values) {
void setUniform(Int location, UnsignedInt count, const Math::Vector<3, UnsignedInt>* values) {
(this->*uniform3uivImplementation)(location, count, values);
}
@ -794,7 +579,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl30 %Extension @extension{EXT,gpu_shader4}
* @requires_gles30 Only signed integers are available in OpenGL ES 2.0.
*/
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<4, UnsignedInt>* values) {
void setUniform(Int location, UnsignedInt count, const Math::Vector<4, UnsignedInt>* values) {
(this->*uniform4uivImplementation)(location, count, values);
}
#endif
@ -805,7 +590,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(Int location, UnsignedInt count, const Double* values) {
void setUniform(Int location, UnsignedInt count, const Double* values) {
(this->*uniform1dvImplementation)(location, count, values);
}
@ -814,7 +599,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<2, Double>* values) {
void setUniform(Int location, UnsignedInt count, const Math::Vector<2, Double>* values) {
(this->*uniform2dvImplementation)(location, count, values);
}
@ -823,7 +608,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<3, Double>* values) {
void setUniform(Int location, UnsignedInt count, const Math::Vector<3, Double>* values) {
(this->*uniform3dvImplementation)(location, count, values);
}
@ -832,23 +617,23 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(Int location, UnsignedInt count, const Math::Vector<4, Double>* values) {
void setUniform(Int location, UnsignedInt count, const Math::Vector<4, Double>* values) {
(this->*uniform4dvImplementation)(location, count, values);
}
#endif
/** @copydoc setUniform(Int, UnsignedInt, const Float*) */
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 2, Float>* values) {
void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 2, Float>* values) {
(this->*uniformMatrix2fvImplementation)(location, count, values);
}
/** @copydoc setUniform(Int, UnsignedInt, const Float*) */
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 3, Float>* values) {
void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 3, Float>* values) {
(this->*uniformMatrix3fvImplementation)(location, count, values);
}
/** @copydoc setUniform(Int, UnsignedInt, const Float*) */
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 4, Float>* values) {
void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 4, Float>* values) {
(this->*uniformMatrix4fvImplementation)(location, count, values);
}
@ -857,7 +642,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @copydoc setUniform(Int, UnsignedInt, const Float*)
* @requires_gles30 Only square matrices are available in OpenGL ES 2.0.
*/
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 3, Float>* values) {
void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 3, Float>* values) {
(this->*uniformMatrix2x3fvImplementation)(location, count, values);
}
@ -865,7 +650,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @copydoc setUniform(Int, UnsignedInt, const Float*)
* @requires_gles30 Only square matrices are available in OpenGL ES 2.0.
*/
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 2, Float>* values) {
void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 2, Float>* values) {
(this->*uniformMatrix3x2fvImplementation)(location, count, values);
}
@ -873,7 +658,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @copydoc setUniform(Int, UnsignedInt, const Float*)
* @requires_gles30 Only square matrices are available in OpenGL ES 2.0.
*/
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 4, Float>* values) {
void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 4, Float>* values) {
(this->*uniformMatrix2x4fvImplementation)(location, count, values);
}
@ -881,7 +666,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @copydoc setUniform(Int, UnsignedInt, const Float*)
* @requires_gles30 Only square matrices are available in OpenGL ES 2.0.
*/
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 2, Float>* values) {
void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 2, Float>* values) {
(this->*uniformMatrix4x2fvImplementation)(location, count, values);
}
@ -889,7 +674,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @copydoc setUniform(Int, UnsignedInt, const Float*)
* @requires_gles30 Only square matrices are available in OpenGL ES 2.0.
*/
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 4, Float>* values) {
void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 4, Float>* values) {
(this->*uniformMatrix3x4fvImplementation)(location, count, values);
}
@ -897,7 +682,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @copydoc setUniform(Int, UnsignedInt, const Float*)
* @requires_gles30 Only square matrices are available in OpenGL ES 2.0.
*/
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 3, Float>* values) {
void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 3, Float>* values) {
(this->*uniformMatrix4x3fvImplementation)(location, count, values);
}
#endif
@ -908,7 +693,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 2, Double>* values) {
void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 2, Double>* values) {
(this->*uniformMatrix2dvImplementation)(location, count, values);
}
@ -917,7 +702,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 3, Double>* values) {
void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 3, Double>* values) {
(this->*uniformMatrix3dvImplementation)(location, count, values);
}
@ -926,7 +711,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 4, Double>* values) {
void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 4, Double>* values) {
(this->*uniformMatrix4dvImplementation)(location, count, values);
}
@ -935,7 +720,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 3, Double>* values) {
void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 3, Double>* values) {
(this->*uniformMatrix2x3dvImplementation)(location, count, values);
}
@ -944,7 +729,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 2, Double>* values) {
void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 2, Double>* values) {
(this->*uniformMatrix3x2dvImplementation)(location, count, values);
}
@ -953,7 +738,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 4, Double>* values) {
void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<2, 4, Double>* values) {
(this->*uniformMatrix2x4dvImplementation)(location, count, values);
}
@ -962,7 +747,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 2, Double>* values) {
void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 2, Double>* values) {
(this->*uniformMatrix4x2dvImplementation)(location, count, values);
}
@ -971,7 +756,7 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 4, Double>* values) {
void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<3, 4, Double>* values) {
(this->*uniformMatrix3x4dvImplementation)(location, count, values);
}
@ -980,18 +765,12 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @requires_gl40 %Extension @extension{ARB,gpu_shader_fp64}
* @requires_gl Only floats are available in OpenGL ES.
*/
inline void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 3, Double>* values) {
void setUniform(Int location, UnsignedInt count, const Math::RectangularMatrix<4, 3, Double>* values) {
(this->*uniformMatrix4x3dvImplementation)(location, count, values);
}
#endif
private:
enum State {
Initialized,
Linked,
Failed
};
static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context);
typedef void(AbstractShaderProgram::*Uniform1fvImplementation)(GLint, GLsizei, const GLfloat*);
@ -1157,7 +936,216 @@ class MAGNUM_EXPORT AbstractShaderProgram {
#endif
GLuint _id;
State state;
};
/**
@brief Base struct for attribute location and type
Template parameter @p location is vertex attribute location, number between `0`
and maxSupportedVertexAttributeCount(). To ensure compatibility, you should
always have vertex attribute with location `0`.
Template parameter @p T is the type which is used for shader attribute, e.g.
@ref Vector4i for `ivec4`. DataType is type of passed data when adding vertex
buffers to mesh. By default it is the same as type used in shader (e.g.
@ref DataType "DataType::Int" for @ref Vector4i). It's also possible to pass
integer data to floating-point shader inputs. In this case you may want to
normalize the values (e.g. color components from 0-255 to 0.0f - 1.0f) -- see
@ref DataOption "DataOption::Normalize".
Only some types are allowed as attribute types, see @ref AbstractShaderProgram-types
or TypeTraits::AttributeType for more information.
See @ref AbstractShaderProgram-subclassing for example usage in shaders and
@ref Mesh-configuration for example usage when adding vertex buffers to mesh.
*/
template<UnsignedInt location, class T> class AbstractShaderProgram::Attribute {
public:
enum: UnsignedInt {
Location = location /**< Location to which the attribute is bound */
};
/**
* @brief Type
*
* Type used in shader code.
* @see DataType
*/
typedef typename Implementation::Attribute<T>::Type Type;
/**
* @brief Component count
*
* Count of components passed to the shader. If passing smaller count
* of components than corresponding type has, unspecified components
* are set to default values (second and third to `0`, fourth to `1`).
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
enum class Components: GLint {
/**
* Only first component is specified. Second, third and fourth
* component are set to `0`, `0`, `1`, respectively. Only for
* scalar and vector types, not matrices.
*/
One = 1,
/**
* First two components are specified. Third and fourth component
* are set to `0`, `1`, respectively. Only for two, three and
* four-component vector types and 2x2, 3x2 and 4x2 matrix types.
*/
Two = 2,
/**
* First three components are specified. Fourth component is set to
* `1`. Only for three and four-component vector types, 2x3, 3x3
* and 4x3 matrix types.
*/
Three = 3,
/**
* All four components are specified. Only for four-component
* vector types and 2x4, 3x4 and 4x4 matrix types.
*/
Four = 4,
#ifndef MAGNUM_TARGET_GLES
/**
* Four components with BGRA ordering. Only for four-component
* float vector type.
* @requires_gl32 %Extension @extension{ARB,vertex_array_bgra}
* @requires_gl Only RGBA component ordering is supported in OpenGL
* ES.
*/
BGRA = 1 << 1
#endif
};
#else
typedef typename Implementation::Attribute<T>::Components Components;
#endif
/**
* @brief Data type
*
* Type of data passed to shader.
* @see Type, DataOptions, Attribute()
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
enum class DataType: GLenum {
UnsignedByte = GL_UNSIGNED_BYTE, /**< Unsigned byte */
Byte = GL_BYTE, /**< Byte */
UnsignedShort = GL_UNSIGNED_SHORT, /**< Unsigned short */
Short = GL_SHORT, /**< Short */
UnsignedInt = GL_UNSIGNED_INT, /**< Unsigned int */
Int = GL_INT, /**< Int */
/**
* Half float. Only for float attribute types.
* @requires_gl30 %Extension @extension{NV,half_float}
* @requires_gles30 %Extension @es_extension{OES,vertex_half_float}
*/
HalfFloat = GL_HALF_FLOAT,
/** Float. Only for float attribute types. */
Float = GL_FLOAT,
#ifndef MAGNUM_TARGET_GLES
/**
* Double. Only for float and double attribute types.
* @requires_gl Only floats are available in OpenGL ES.
*/
Double = GL_DOUBLE,
#endif
/* GL_FIXED not supported */
#ifndef MAGNUM_TARGET_GLES2
/**
* Unsigned 2.10.10.10 packed integer. Only for four-component
* float vector attribute type.
* @todo How about (incompatible) @es_extension{OES,vertex_type_10_10_10_2}?
* @requires_gl33 %Extension @extension{ARB,vertex_type_2_10_10_10_rev}
* @requires_gles30 (no extension providing this functionality)
*/
UnsignedInt2101010Rev = GL_UNSIGNED_INT_2_10_10_10_REV,
/**
* Signed 2.10.10.10 packed integer. Only for four-component float
* vector attribute type.
* @requires_gl33 %Extension @extension{ARB,vertex_type_2_10_10_10_rev}
* @requires_gles30 (no extension providing this functionality)
*/
Int2101010Rev = GL_INT_2_10_10_10_REV
#endif
};
#else
typedef typename Implementation::Attribute<T>::DataType DataType;
#endif
/**
* @brief Data option
* @see DataOptions, Attribute()
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
enum class DataOption: UnsignedByte {
/**
* Normalize integer components. Only for float attribute types.
* Default is to not normalize.
*/
Normalize = 1 << 0
};
#else
typedef typename Implementation::Attribute<T>::DataOption DataOption;
#endif
/**
* @brief Data options
* @see Attribute()
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
typedef typename Containers::EnumSet<DataOption, UnsignedByte> DataOptions;
#else
typedef typename Implementation::Attribute<T>::DataOptions DataOptions;
#endif
/**
* @brief Constructor
* @param components Component count
* @param dataType Type of passed data. Default is the same as
* type used in shader (e.g. DataType::Integer for Vector4i).
* @param dataOptions Data options. Default is no options.
*/
constexpr Attribute(Components components, DataType dataType = Implementation::Attribute<T>::DefaultDataType, DataOptions dataOptions = DataOptions()): _components(components), _dataType(dataType), _dataOptions(dataOptions) {}
/**
* @brief Constructor
* @param dataType Type of passed data. Default is the same as
* type used in shader (e.g. DataType::Integer for Vector4i).
* @param dataOptions Data options. Default is no options.
*
* Component count is set to the same value as in type used in shader
* (e.g. @ref Components "Components::Three" for Vector3).
*/
constexpr Attribute(DataType dataType = Implementation::Attribute<T>::DefaultDataType, DataOptions dataOptions = DataOptions()): _components(Implementation::Attribute<T>::DefaultComponents), _dataType(dataType), _dataOptions(dataOptions) {}
/** @brief Component count of passed data */
constexpr Components components() const { return _components; }
/** @brief Type of passed data */
constexpr DataType dataType() const { return _dataType; }
/** @brief Size of passed data */
std::size_t dataSize() const {
return Implementation::Attribute<T>::size(GLint(_components)*Implementation::Attribute<T>::vectorCount(), _dataType);
}
/** @brief Data options */
constexpr DataOptions dataOptions() const { return _dataOptions; }
private:
const Components _components;
const DataType _dataType;
const DataOptions _dataOptions;
};
#ifdef DOXYGEN_GENERATING_OUTPUT
@ -1168,7 +1156,6 @@ template<class T> Debug operator<<(Debug debug, AbstractShaderProgram::Attribute
template<class T> Debug operator<<(Debug debug, AbstractShaderProgram::Attribute<T>::DataType);
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
/* Base for sized attributes */
@ -1176,7 +1163,7 @@ template<std::size_t cols, std::size_t rows> struct SizedAttribute;
/* Vector attribute sizes */
template<std::size_t cols> struct SizedVectorAttribute {
inline constexpr static std::size_t vectorCount() { return cols; }
constexpr static std::size_t vectorCount() { return cols; }
};
template<> struct SizedAttribute<1, 1>: SizedVectorAttribute<1> {
enum class Components: GLint { One = 1 };
@ -1299,7 +1286,7 @@ struct FloatAttribute {
enum class DataOption: UnsignedByte {
Normalized = 1 << 0
};
typedef Corrade::Containers::EnumSet<DataOption, UnsignedByte> DataOptions;
typedef Containers::EnumSet<DataOption, UnsignedByte> DataOptions;
static std::size_t MAGNUM_EXPORT size(GLint components, DataType dataType);
};
@ -1329,7 +1316,7 @@ struct IntAttribute {
DataType DefaultDataType = DataType::Int;
enum class DataOption: UnsignedByte {};
typedef Corrade::Containers::EnumSet<DataOption, UnsignedByte> DataOptions;
typedef Containers::EnumSet<DataOption, UnsignedByte> DataOptions;
static std::size_t MAGNUM_EXPORT size(GLint components, DataType dataType);
};
@ -1349,9 +1336,9 @@ struct UnsignedIntAttribute {
DataType DefaultDataType = DataType::UnsignedInt;
typedef IntAttribute::DataOption DataOption;
typedef Corrade::Containers::EnumSet<DataOption, UnsignedByte> DataOptions;
typedef Containers::EnumSet<DataOption, UnsignedByte> DataOptions;
inline static std::size_t size(GLint components, DataType dataType) {
static std::size_t size(GLint components, DataType dataType) {
return IntAttribute::size(components, dataType);
}
};
@ -1373,7 +1360,7 @@ struct DoubleAttribute {
DataType DefaultDataType = DataType::Double;
enum class DataOption: UnsignedByte {};
typedef Corrade::Containers::EnumSet<DataOption, UnsignedByte> DataOptions;
typedef Containers::EnumSet<DataOption, UnsignedByte> DataOptions;
static std::size_t MAGNUM_EXPORT size(GLint components, DataType dataType);
};
@ -1435,9 +1422,9 @@ template<> struct Attribute<Math::Vector<4, Float>> {
enum class DataOption: UnsignedByte {
Normalized = 1 << 0
};
typedef Corrade::Containers::EnumSet<DataOption, UnsignedByte> DataOptions;
typedef Containers::EnumSet<DataOption, UnsignedByte> DataOptions;
inline constexpr static std::size_t vectorCount() { return 1; }
constexpr static std::size_t vectorCount() { return 1; }
static std::size_t MAGNUM_EXPORT size(GLint components, DataType dataType);
};
@ -1488,7 +1475,6 @@ template<class T> struct Attribute<Math::Matrix3<T>>: Attribute<Math::Matrix<3,
template<class T> struct Attribute<Math::Matrix4<T>>: Attribute<Math::Matrix<4, T>> {};
}
#endif
}

165
src/AbstractTexture.cpp

@ -28,6 +28,7 @@
#include "BufferImage.h"
#include "Context.h"
#include "Extensions.h"
#include "Image.h"
#include "Implementation/State.h"
#include "Implementation/TextureState.h"
@ -56,6 +57,8 @@ AbstractTexture::Storage2DImplementation AbstractTexture::storage2DImplementatio
AbstractTexture::Storage3DImplementation AbstractTexture::storage3DImplementation =
&AbstractTexture::storageImplementationDefault;
#ifndef MAGNUM_TARGET_GLES
AbstractTexture::GetImageImplementation AbstractTexture::getImageImplementation =
&AbstractTexture::getImageImplementationDefault;
AbstractTexture::Image1DImplementation AbstractTexture::image1DImplementation =
&AbstractTexture::imageImplementationDefault;
#endif
@ -72,45 +75,13 @@ AbstractTexture::SubImage2DImplementation AbstractTexture::subImage2DImplementat
AbstractTexture::SubImage3DImplementation AbstractTexture::subImage3DImplementation =
&AbstractTexture::subImageImplementationDefault;
AbstractTexture::InvalidateImplementation AbstractTexture::invalidateImplementation = &AbstractTexture::invalidateImplementationNoOp;
AbstractTexture::InvalidateSubImplementation AbstractTexture::invalidateSubImplementation = &AbstractTexture::invalidateSubImplementationNoOp;
#ifndef DOXYGEN_GENERATING_OUTPUT
/* Check correctness of binary OR in setMinificationFilter(). If nobody fucks
anything up, this assert should produce the same results on all dimensions,
thus testing only on AbstractTexture. */
#define filter_or(filter, mipmap) \
(static_cast<GLint>(AbstractTexture::Filter::filter)|static_cast<GLint>(AbstractTexture::Mipmap::mipmap))
static_assert((filter_or(Nearest, Base) == GL_NEAREST) &&
(filter_or(Nearest, Nearest) == GL_NEAREST_MIPMAP_NEAREST) &&
(filter_or(Nearest, Linear) == GL_NEAREST_MIPMAP_LINEAR) &&
(filter_or(Linear, Base) == GL_LINEAR) &&
(filter_or(Linear, Nearest) == GL_LINEAR_MIPMAP_NEAREST) &&
(filter_or(Linear, Linear) == GL_LINEAR_MIPMAP_LINEAR),
"Unsupported constants for GL texture filtering");
#undef filter_or
#endif
AbstractTexture::InvalidateImageImplementation AbstractTexture::invalidateImageImplementation = &AbstractTexture::invalidateImageImplementationNoOp;
AbstractTexture::InvalidateSubImageImplementation AbstractTexture::invalidateSubImageImplementation = &AbstractTexture::invalidateSubImageImplementationNoOp;
Int AbstractTexture::maxSupportedLayerCount() {
return Context::current()->state()->texture->maxSupportedLayerCount;
}
#ifndef MAGNUM_TARGET_GLES3
Float AbstractTexture::maxSupportedAnisotropy() {
GLfloat& value = Context::current()->state()->texture->maxSupportedAnisotropy;
/** @todo Re-enable when extension header is available */
#ifndef MAGNUM_TARGET_GLES
/* Get the value, if not already cached */
if(value == 0.0f)
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &value);
#endif
return value;
}
#endif
void AbstractTexture::destroy() {
/* Moved out */
if(!_id) return;
@ -169,9 +140,9 @@ void AbstractTexture::bindImplementationDSA(GLint layer) {
}
#endif
AbstractTexture* AbstractTexture::setMinificationFilter(Filter filter, Mipmap mipmap) {
AbstractTexture* AbstractTexture::setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap) {
#ifndef MAGNUM_TARGET_GLES
CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE || mipmap == Mipmap::Base, "AbstractTexture: rectangle textures cannot have mipmaps", this);
CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE || mipmap == Sampler::Mipmap::Base, "AbstractTexture: rectangle textures cannot have mipmaps", this);
#endif
(this->*parameteriImplementation)(GL_TEXTURE_MIN_FILTER,
@ -199,7 +170,6 @@ void AbstractTexture::mipmapImplementationDSA() {
}
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
void AbstractTexture::bindInternal() {
Implementation::TextureState* const textureState = Context::current()->state()->texture;
@ -216,7 +186,6 @@ void AbstractTexture::bindInternal() {
if(textureState->bindings[internalLayer] != _id)
glBindTexture(_target, (textureState->bindings[internalLayer] = _id));
}
#endif
void AbstractTexture::initializeContextBasedFunctionality(Context* context) {
Implementation::TextureState* const textureState = context->state()->texture;
@ -239,6 +208,7 @@ void AbstractTexture::initializeContextBasedFunctionality(Context* context) {
storage1DImplementation = &AbstractTexture::storageImplementationDSA;
storage2DImplementation = &AbstractTexture::storageImplementationDSA;
storage3DImplementation = &AbstractTexture::storageImplementationDSA;
getImageImplementation = &AbstractTexture::getImageImplementationDSA;
image1DImplementation = &AbstractTexture::imageImplementationDSA;
image2DImplementation = &AbstractTexture::imageImplementationDSA;
image3DImplementation = &AbstractTexture::imageImplementationDSA;
@ -250,8 +220,15 @@ void AbstractTexture::initializeContextBasedFunctionality(Context* context) {
if(context->isExtensionSupported<Extensions::GL::ARB::invalidate_subdata>()) {
Debug() << "AbstractTexture: using" << Extensions::GL::ARB::invalidate_subdata::string() << "features";
invalidateImplementation = &AbstractTexture::invalidateImplementationARB;
invalidateSubImplementation = &AbstractTexture::invalidateSubImplementationARB;
invalidateImageImplementation = &AbstractTexture::invalidateImageImplementationARB;
invalidateSubImageImplementation = &AbstractTexture::invalidateSubImageImplementationARB;
}
if(context->isExtensionSupported<Extensions::GL::ARB::robustness>() &&
!context->isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
Debug() << "AbstractTexture: using" << Extensions::GL::ARB::robustness::string() << "features";
getImageImplementation = &AbstractTexture::getImageImplementationRobustness;
}
#endif
}
@ -301,7 +278,7 @@ void AbstractTexture::getLevelParameterImplementationDSA(GLenum target, GLint le
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels, AbstractTexture::InternalFormat internalFormat, const Math::Vector< 1, GLsizei >& size) {
void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector< 1, GLsizei >& size) {
bindInternal();
/** @todo Re-enable when extension wrangler is available for ES2 */
#ifndef MAGNUM_TARGET_GLES2
@ -315,12 +292,12 @@ void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels
#endif
}
void AbstractTexture::storageImplementationDSA(GLenum target, GLsizei levels, AbstractTexture::InternalFormat internalFormat, const Math::Vector< 1, GLsizei >& size) {
void AbstractTexture::storageImplementationDSA(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector< 1, GLsizei >& size) {
glTextureStorage1DEXT(_id, target, levels, GLenum(internalFormat), size[0]);
}
#endif
void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels, AbstractTexture::InternalFormat internalFormat, const Vector2i& size) {
void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size) {
bindInternal();
/** @todo Re-enable when extension wrangler is available for ES2 */
#ifndef MAGNUM_TARGET_GLES2
@ -335,12 +312,12 @@ void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::storageImplementationDSA(GLenum target, GLsizei levels, AbstractTexture::InternalFormat internalFormat, const Vector2i& size) {
void AbstractTexture::storageImplementationDSA(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size) {
glTextureStorage2DEXT(_id, target, levels, GLenum(internalFormat), size.x(), size.y());
}
#endif
void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels, AbstractTexture::InternalFormat internalFormat, const Vector3i& size) {
void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size) {
bindInternal();
/** @todo Re-enable when extension wrangler is available for ES2 */
#ifndef MAGNUM_TARGET_GLES2
@ -355,32 +332,60 @@ void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::storageImplementationDSA(GLenum target, GLsizei levels, AbstractTexture::InternalFormat internalFormat, const Vector3i& size) {
void AbstractTexture::storageImplementationDSA(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size) {
glTextureStorage3DEXT(_id, target, levels, GLenum(internalFormat), size.x(), size.y(), size.z());
}
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::getImageImplementationDefault(const GLenum target, const GLint level, const ImageFormat format, const ImageType type, const std::size_t, GLvoid* const data) {
bindInternal();
glGetTexImage(target, level, GLenum(format), GLenum(type), data);
}
void AbstractTexture::getImageImplementationDSA(const GLenum target, const GLint level, const ImageFormat format, const ImageType type, const std::size_t, GLvoid* const data) {
glGetTextureImageEXT(_id, target, level, GLenum(format), GLenum(type), data);
}
void AbstractTexture::imageImplementationDefault(GLenum target, GLint level, InternalFormat internalFormat, const Math::Vector<1, GLsizei>& size, AbstractImage::Format format, AbstractImage::Type type, const GLvoid* data) {
void AbstractTexture::getImageImplementationRobustness(const GLenum target, const GLint level, const ImageFormat format, const ImageType type, const std::size_t dataSize, GLvoid* const data) {
#ifndef MAGNUM_TARGET_GLES
bindInternal();
glGetnTexImageARB(target, level, GLenum(format), GLenum(type), dataSize, data);
#else
CORRADE_INTERNAL_ASSERT(false);
static_cast<void>(target);
static_cast<void>(level);
static_cast<void>(format);
static_cast<void>(type);
static_cast<void>(dataSize);
static_cast<void>(data);
#endif
}
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::imageImplementationDefault(GLenum target, GLint level, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size, ImageFormat format, ImageType type, const GLvoid* data) {
bindInternal();
glTexImage1D(target, level, static_cast<GLint>(internalFormat), size[0], 0, static_cast<GLenum>(format), static_cast<GLenum>(type), data);
}
void AbstractTexture::imageImplementationDSA(GLenum target, GLint level, InternalFormat internalFormat, const Math::Vector<1, GLsizei>& size, AbstractImage::Format format, AbstractImage::Type type, const GLvoid* data) {
void AbstractTexture::imageImplementationDSA(GLenum target, GLint level, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size, ImageFormat format, ImageType type, const GLvoid* data) {
glTextureImage1DEXT(_id, target, level, GLint(internalFormat), size[0], 0, static_cast<GLenum>(format), static_cast<GLenum>(type), data);
}
#endif
void AbstractTexture::imageImplementationDefault(GLenum target, GLint level, InternalFormat internalFormat, const Vector2i& size, AbstractImage::Format format, AbstractImage::Type type, const GLvoid* data) {
void AbstractTexture::imageImplementationDefault(GLenum target, GLint level, TextureFormat internalFormat, const Vector2i& size, ImageFormat format, ImageType type, const GLvoid* data) {
bindInternal();
glTexImage2D(target, level, GLint(internalFormat), size.x(), size.y(), 0, static_cast<GLenum>(format), static_cast<GLenum>(type), data);
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::imageImplementationDSA(GLenum target, GLint level, InternalFormat internalFormat, const Vector2i& size, AbstractImage::Format format, AbstractImage::Type type, const GLvoid* data) {
void AbstractTexture::imageImplementationDSA(GLenum target, GLint level, TextureFormat internalFormat, const Vector2i& size, ImageFormat format, ImageType type, const GLvoid* data) {
glTextureImage2DEXT(_id, target, level, GLint(internalFormat), size.x(), size.y(), 0, static_cast<GLenum>(format), static_cast<GLenum>(type), data);
}
#endif
void AbstractTexture::imageImplementationDefault(GLenum target, GLint level, InternalFormat internalFormat, const Vector3i& size, AbstractImage::Format format, AbstractImage::Type type, const GLvoid* data) {
void AbstractTexture::imageImplementationDefault(GLenum target, GLint level, TextureFormat internalFormat, const Vector3i& size, ImageFormat format, ImageType type, const GLvoid* data) {
bindInternal();
/** @todo Get some extension wrangler instead to avoid linker errors to glTexImage3D() on ES2 */
#ifndef MAGNUM_TARGET_GLES2
@ -397,34 +402,34 @@ void AbstractTexture::imageImplementationDefault(GLenum target, GLint level, Int
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::imageImplementationDSA(GLenum target, GLint level, InternalFormat internalFormat, const Vector3i& size, AbstractImage::Format format, AbstractImage::Type type, const GLvoid* data) {
void AbstractTexture::imageImplementationDSA(GLenum target, GLint level, TextureFormat internalFormat, const Vector3i& size, ImageFormat format, ImageType type, const GLvoid* data) {
glTextureImage3DEXT(_id, target, level, GLint(internalFormat), size.x(), size.y(), size.z(), 0, static_cast<GLenum>(format), static_cast<GLenum>(type), data);
}
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, AbstractImage::Format format, AbstractImage::Type type, const GLvoid* data) {
void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ImageFormat format, ImageType type, const GLvoid* data) {
bindInternal();
glTexSubImage1D(target, level, offset[0], size[0], static_cast<GLenum>(format), static_cast<GLenum>(type), data);
}
void AbstractTexture::subImageImplementationDSA(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, AbstractImage::Format format, AbstractImage::Type type, const GLvoid* data) {
void AbstractTexture::subImageImplementationDSA(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ImageFormat format, ImageType type, const GLvoid* data) {
glTextureSubImage1DEXT(_id, target, level, offset[0], size[0], static_cast<GLenum>(format), static_cast<GLenum>(type), data);
}
#endif
void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, AbstractImage::Format format, AbstractImage::Type type, const GLvoid* data) {
void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, ImageFormat format, ImageType type, const GLvoid* data) {
bindInternal();
glTexSubImage2D(target, level, offset.x(), offset.y(), size.x(), size.y(), static_cast<GLenum>(format), static_cast<GLenum>(type), data);
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::subImageImplementationDSA(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, AbstractImage::Format format, AbstractImage::Type type, const GLvoid* data) {
void AbstractTexture::subImageImplementationDSA(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, ImageFormat format, ImageType type, const GLvoid* data) {
glTextureSubImage2DEXT(_id, target, level, offset.x(), offset.y(), size.x(), size.y(), static_cast<GLenum>(format), static_cast<GLenum>(type), data);
}
#endif
void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, AbstractImage::Format format, AbstractImage::Type type, const GLvoid* data) {
void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, ImageFormat format, ImageType type, const GLvoid* data) {
bindInternal();
/** @todo Get some extension wrangler instead to avoid linker errors to glTexSubImage3D() on ES2 */
#ifndef MAGNUM_TARGET_GLES2
@ -441,27 +446,57 @@ void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level,
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::subImageImplementationDSA(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, AbstractImage::Format format, AbstractImage::Type type, const GLvoid* data) {
void AbstractTexture::subImageImplementationDSA(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, ImageFormat format, ImageType type, const GLvoid* data) {
glTextureSubImage3DEXT(_id, target, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), static_cast<GLenum>(format), static_cast<GLenum>(type), data);
}
#endif
void AbstractTexture::invalidateImplementationNoOp(GLint) {}
void AbstractTexture::invalidateImageImplementationNoOp(GLint) {}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::invalidateImplementationARB(GLint level) {
void AbstractTexture::invalidateImageImplementationARB(GLint level) {
glInvalidateTexImage(_id, level);
}
#endif
void AbstractTexture::invalidateSubImplementationNoOp(GLint, const Vector3i&, const Vector3i&) {}
void AbstractTexture::invalidateSubImageImplementationNoOp(GLint, const Vector3i&, const Vector3i&) {}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::invalidateSubImplementationARB(GLint level, const Vector3i& offset, const Vector3i& size) {
void AbstractTexture::invalidateSubImageImplementationARB(GLint level, const Vector3i& offset, const Vector3i& size) {
glInvalidateTexSubImage(_id, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z());
}
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_TARGET_GLES
template<UnsignedInt dimensions> void AbstractTexture::image(GLenum target, GLint level, Image<dimensions>* image) {
const Math::Vector<dimensions, Int> size = DataHelper<dimensions>::imageSize(this, target, level);
const std::size_t dataSize = size.product()*image->pixelSize();
char* data = new char[dataSize];
(this->*getImageImplementation)(target, level, image->format(), image->type(), dataSize, data);
image->setData(size, image->format(), image->type(), data);
}
template void AbstractTexture::image<1>(GLenum, GLint, Image<1>*);
template void AbstractTexture::image<2>(GLenum, GLint, Image<2>*);
template void AbstractTexture::image<3>(GLenum, GLint, Image<3>*);
template<UnsignedInt dimensions> void AbstractTexture::image(GLenum target, GLint level, BufferImage<dimensions>* image, Buffer::Usage usage) {
const Math::Vector<dimensions, Int> size = DataHelper<dimensions>::imageSize(this, target, level);
const std::size_t dataSize = size.product()*image->pixelSize();
if(image->size() != size)
image->setData(size, image->format(), image->type(), nullptr, usage);
image->buffer()->bind(Buffer::Target::PixelPack);
(this->*getImageImplementation)(target, level, image->format(), image->type(), dataSize, nullptr);
}
template void AbstractTexture::image<1>(GLenum, GLint, BufferImage<1>*, Buffer::Usage);
template void AbstractTexture::image<2>(GLenum, GLint, BufferImage<2>*, Buffer::Usage);
template void AbstractTexture::image<3>(GLenum, GLint, BufferImage<3>*, Buffer::Usage);
#endif
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef MAGNUM_TARGET_GLES2
namespace Implementation {
@ -499,16 +534,16 @@ Vector3i AbstractTexture::DataHelper<3>::imageSize(AbstractTexture* texture, GLe
}
#endif
void AbstractTexture::DataHelper<2>::setWrapping(AbstractTexture* texture, const Array2D<Wrapping>& wrapping) {
void AbstractTexture::DataHelper<2>::setWrapping(AbstractTexture* texture, const Array2D<Sampler::Wrapping>& wrapping) {
#ifndef MAGNUM_TARGET_GLES
CORRADE_ASSERT(texture->_target != GL_TEXTURE_RECTANGLE || ((wrapping.x() == Wrapping::ClampToEdge || wrapping.x() == Wrapping::ClampToBorder) && (wrapping.y() == Wrapping::ClampToEdge || wrapping.y() == Wrapping::ClampToEdge)), "AbstractTexture: rectangle texture wrapping must either clamp to border or to edge", );
CORRADE_ASSERT(texture->_target != GL_TEXTURE_RECTANGLE || ((wrapping.x() == Sampler::Wrapping::ClampToEdge || wrapping.x() == Sampler::Wrapping::ClampToBorder) && (wrapping.y() == Sampler::Wrapping::ClampToEdge || wrapping.y() == Sampler::Wrapping::ClampToEdge)), "AbstractTexture: rectangle texture wrapping must either clamp to border or to edge", );
#endif
(texture->*parameteriImplementation)(GL_TEXTURE_WRAP_S, static_cast<GLint>(wrapping.x()));
(texture->*parameteriImplementation)(GL_TEXTURE_WRAP_T, static_cast<GLint>(wrapping.y()));
}
void AbstractTexture::DataHelper<3>::setWrapping(AbstractTexture* texture, const Array3D<Wrapping>& wrapping) {
void AbstractTexture::DataHelper<3>::setWrapping(AbstractTexture* texture, const Array3D<Sampler::Wrapping>& wrapping) {
(texture->*parameteriImplementation)(GL_TEXTURE_WRAP_S, static_cast<GLint>(wrapping.x()));
(texture->*parameteriImplementation)(GL_TEXTURE_WRAP_T, static_cast<GLint>(wrapping.y()));
#ifndef MAGNUM_TARGET_GLES

1104
src/AbstractTexture.h

File diff suppressed because it is too large Load Diff

72
src/Array.h

@ -24,7 +24,7 @@
DEALINGS IN THE SOFTWARE.
*/
/** @file
/** @file /Array.h
* @brief Class Magnum::Array, Magnum::Array1D, Magnum::Array2D, Magnum::Array3D
*/
@ -55,7 +55,7 @@ template<UnsignedInt dimensions, class T> class Array {
*
* Sets all components to their default-constructed values
*/
inline constexpr /*implicit*/ Array(): _data() {}
constexpr /*implicit*/ Array(): _data() {}
/**
* @brief Initializer-list constructor
@ -63,45 +63,45 @@ template<UnsignedInt dimensions, class T> class Array {
* @param next Next values
*/
#ifndef DOXYGEN_GENERATING_OUTPUT
template<class ...U> inline constexpr /*implicit*/ Array(T first, T second, U... next): _data{first, second, next...} {
template<class ...U> constexpr /*implicit*/ Array(T first, T second, U... next): _data{first, second, next...} {
static_assert(sizeof...(next)+2 == dimensions, "Improper number of arguments passed to Array constructor");
}
template<class U = T> inline constexpr /*implicit*/ Array(typename std::enable_if<std::is_same<T, U>::value && dimensions == 1, U>::type first): _data{first} {}
template<class U = T> constexpr /*implicit*/ Array(typename std::enable_if<std::is_same<T, U>::value && dimensions == 1, U>::type first): _data{first} {}
#else
template<class ...U> inline constexpr /*implicit*/ Array(T first, U... next);
template<class ...U> constexpr /*implicit*/ Array(T first, U... next);
#endif
/**
* @brief Constructor
* @param value Value for all fields
*/
template<class U, class = typename std::enable_if<std::is_same<T, U>::value && dimensions != 1, U>::type> inline /*implicit*/ Array(U value) {
template<class U, class = typename std::enable_if<std::is_same<T, U>::value && dimensions != 1, U>::type> /*implicit*/ Array(U value) {
for(UnsignedInt i = 0; i != dimensions; ++i)
_data[i] = value;
}
/** @brief Equality */
inline bool operator==(const Array<dimensions, T>& other) const {
bool operator==(const Array<dimensions, T>& other) const {
for(UnsignedInt i = 0; i != dimensions; ++i)
if(_data[i] != other._data[i]) return false;
return true;
}
/** @brief Non-equality */
inline bool operator!=(const Array<dimensions, T>& other) const {
bool operator!=(const Array<dimensions, T>& other) const {
return !operator==(other);
}
/** @brief Value at given position */
inline T& operator[](UnsignedInt pos) { return _data[pos]; }
inline constexpr T operator[](UnsignedInt pos) const { return _data[pos]; } /**< @overload */
T& operator[](UnsignedInt pos) { return _data[pos]; }
constexpr T operator[](UnsignedInt pos) const { return _data[pos]; } /**< @overload */
/**
* @brief Raw data
* @return One-dimensional array of `dimensions` length
*/
inline T* data() { return _data; }
inline constexpr const T* data() const { return _data; } /**< @overload */
T* data() { return _data; }
constexpr const T* data() const { return _data; } /**< @overload */
private:
T _data[dimensions];
@ -114,19 +114,19 @@ template<UnsignedInt dimensions, class T> class Array {
template<class T> class Array1D: public Array<1, T> {
public:
/** @copydoc Array::Array() */
inline constexpr /*implicit*/ Array1D() = default;
constexpr /*implicit*/ Array1D() = default;
/**
* @brief Constructor
* @param x X component
*/
inline constexpr /*implicit*/ Array1D(T x): Array<1, T>(x) {}
constexpr /*implicit*/ Array1D(T x): Array<1, T>(x) {}
/** @brief Copy constructor */
inline constexpr Array1D(const Array<1, T>& other): Array<1, T>(other) {}
constexpr Array1D(const Array<1, T>& other): Array<1, T>(other) {}
inline T& x() { return (*this)[0]; } /**< @brief X component */
inline constexpr T x() const { return (*this)[0]; } /**< @overload */
T& x() { return (*this)[0]; } /**< @brief X component */
constexpr T x() const { return (*this)[0]; } /**< @overload */
};
/**
@ -136,25 +136,25 @@ template<class T> class Array1D: public Array<1, T> {
template<class T> class Array2D: public Array<2, T> {
public:
/** @copydoc Array::Array() */
inline constexpr /*implicit*/ Array2D() = default;
constexpr /*implicit*/ Array2D() = default;
/**
* @brief Constructor
* @param x X component
* @param y Y component
*/
inline constexpr /*implicit*/ Array2D(T x, T y): Array<2, T>(x, y) {}
constexpr /*implicit*/ Array2D(T x, T y): Array<2, T>(x, y) {}
/** @copydoc Array::Array(U) */
inline constexpr /*implicit*/ Array2D(T value): Array<2, T>(value, value) {}
constexpr /*implicit*/ Array2D(T value): Array<2, T>(value, value) {}
/** @brief Copy constructor */
inline constexpr Array2D(const Array<2, T>& other): Array<2, T>(other) {}
constexpr Array2D(const Array<2, T>& other): Array<2, T>(other) {}
inline T& x() { return (*this)[0]; } /**< @brief X component */
inline constexpr T x() const { return (*this)[0]; } /**< @overload */
inline T& y() { return (*this)[1]; } /**< @brief Y component */
inline constexpr T y() const { return (*this)[1]; } /**< @overload */
T& x() { return (*this)[0]; } /**< @brief X component */
constexpr T x() const { return (*this)[0]; } /**< @overload */
T& y() { return (*this)[1]; } /**< @brief Y component */
constexpr T y() const { return (*this)[1]; } /**< @overload */
};
/**
@ -164,7 +164,7 @@ template<class T> class Array2D: public Array<2, T> {
template<class T> class Array3D: public Array<3, T> {
public:
/** @copydoc Array::Array() */
inline constexpr /*implicit*/ Array3D() {}
constexpr /*implicit*/ Array3D() {}
/**
* @brief Constructor
@ -172,20 +172,20 @@ template<class T> class Array3D: public Array<3, T> {
* @param y Y component
* @param z Z component
*/
inline constexpr /*implicit*/ Array3D(T x, T y, T z): Array<3, T>(x, y, z) {}
constexpr /*implicit*/ Array3D(T x, T y, T z): Array<3, T>(x, y, z) {}
/** @copydoc Array::Array(U) */
inline constexpr /*implicit*/ Array3D(T value): Array<3, T>(value, value, value) {}
constexpr /*implicit*/ Array3D(T value): Array<3, T>(value, value, value) {}
/** @brief Copy constructor */
inline constexpr Array3D(const Array<3, T>& other): Array<3, T>(other) {}
inline T& x() { return (*this)[0]; } /**< @brief X component */
inline constexpr T x() const { return (*this)[0]; } /**< @overload */
inline T& y() { return (*this)[1]; } /**< @brief Y component */
inline constexpr T y() const { return (*this)[1]; } /**< @overload */
inline T& z() { return (*this)[2]; } /**< @brief Z component */
inline constexpr T z() const { return (*this)[2]; } /**< @overload */
constexpr Array3D(const Array<3, T>& other): Array<3, T>(other) {}
T& x() { return (*this)[0]; } /**< @brief X component */
constexpr T x() const { return (*this)[0]; } /**< @overload */
T& y() { return (*this)[1]; } /**< @brief Y component */
constexpr T y() const { return (*this)[1]; } /**< @overload */
T& z() { return (*this)[2]; } /**< @brief Z component */
constexpr T z() const { return (*this)[2]; } /**< @overload */
};
/** @debugoperator{Magnum::Array} */

68
src/Buffer.cpp

@ -24,6 +24,7 @@
#include "Buffer.h"
#include <Containers/Array.h>
#include <Utility/Debug.h>
#include "Context.h"
@ -36,8 +37,12 @@ namespace Magnum {
#ifndef MAGNUM_TARGET_GLES2
Buffer::CopyImplementation Buffer::copyImplementation = &Buffer::copyImplementationDefault;
#endif
Buffer::SetDataImplementation Buffer::setDataImplementation = &Buffer::setDataImplementationDefault;
Buffer::SetSubDataImplementation Buffer::setSubDataImplementation = &Buffer::setSubDataImplementationDefault;
Buffer::GetParameterImplementation Buffer::getParameterImplementation = &Buffer::getParameterImplementationDefault;
#ifndef MAGNUM_TARGET_GLES
Buffer::GetSubDataImplementation Buffer::getSubDataImplementation = &Buffer::getSubDataImplementationDefault;
#endif
Buffer::DataImplementation Buffer::dataImplementation = &Buffer::dataImplementationDefault;
Buffer::SubDataImplementation Buffer::subDataImplementation = &Buffer::subDataImplementationDefault;
Buffer::InvalidateImplementation Buffer::invalidateImplementation = &Buffer::invalidateImplementationNoOp;
Buffer::InvalidateSubImplementation Buffer::invalidateSubImplementation = &Buffer::invalidateSubImplementationNoOp;
#ifndef MAGNUM_TARGET_GLES3
@ -53,8 +58,10 @@ void Buffer::initializeContextBasedFunctionality(Context* context) {
Debug() << "Buffer: using" << Extensions::GL::EXT::direct_state_access::string() << "features";
copyImplementation = &Buffer::copyImplementationDSA;
setDataImplementation = &Buffer::setDataImplementationDSA;
setSubDataImplementation = &Buffer::setSubDataImplementationDSA;
getParameterImplementation = &Buffer::getParameterImplementationDSA;
getSubDataImplementation = &Buffer::getSubDataImplementationDSA;
dataImplementation = &Buffer::dataImplementationDSA;
subDataImplementation = &Buffer::subDataImplementationDSA;
mapImplementation = &Buffer::mapImplementationDSA;
mapRangeImplementation = &Buffer::mapRangeImplementationDSA;
flushMappedRangeImplementation = &Buffer::flushMappedRangeImplementationDSA;
@ -101,8 +108,9 @@ Buffer::Target Buffer::bindInternal(Target hint) {
if(hintBinding == _id) return hint;
/* Return first target in which the buffer is bound */
/** @todo wtf there is one more? */
for(std::size_t i = 1; i != Implementation::BufferState::TargetCount; ++i)
if(bindings[i] == _id) return Implementation::BufferState::targetForIndex[i];
if(bindings[i] == _id) return Implementation::BufferState::targetForIndex[i-1];
/* Bind the buffer to hint target otherwise */
hintBinding = _id;
@ -110,6 +118,28 @@ Buffer::Target Buffer::bindInternal(Target hint) {
return hint;
}
Int Buffer::size() {
/**
* @todo there is something like glGetBufferParameteri64v in 3.2 (I
* couldn't find any matching extension, though)
*/
GLint size;
(this->*getParameterImplementation)(GL_BUFFER_SIZE, &size);
return size;
}
#ifndef MAGNUM_TARGET_GLES
Containers::Array<char> Buffer::data() {
return subData(0, size());
}
Containers::Array<char> Buffer::subData(const GLintptr offset, const GLsizeiptr size) {
Containers::Array<char> data(size);
if(size) (this->*getSubDataImplementation)(offset, size, data);
return std::move(data);
}
#endif
#ifndef MAGNUM_TARGET_GLES2
void Buffer::copyImplementationDefault(Buffer* read, Buffer* write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) {
glCopyBufferSubData(static_cast<GLenum>(read->bindInternal(Target::CopyRead)), static_cast<GLenum>(write->bindInternal(Target::CopyWrite)), readOffset, writeOffset, size);
@ -122,22 +152,42 @@ void Buffer::copyImplementationDSA(Buffer* read, Buffer* write, GLintptr readOff
#endif
#endif
void Buffer::setDataImplementationDefault(GLsizeiptr size, const GLvoid* data, Buffer::Usage usage) {
void Buffer::getParameterImplementationDefault(const GLenum value, GLint* const data) {
glGetBufferParameteriv(GLenum(bindInternal(_targetHint)), value, data);
}
#ifndef MAGNUM_TARGET_GLES
void Buffer::getParameterImplementationDSA(const GLenum value, GLint* const data) {
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);
}
void Buffer::getSubDataImplementationDSA(const GLintptr offset, const GLsizeiptr size, GLvoid* const data) {
glGetNamedBufferSubDataEXT(_id, offset, size, data);
}
#endif
void Buffer::dataImplementationDefault(GLsizeiptr size, const GLvoid* data, Buffer::Usage usage) {
glBufferData(static_cast<GLenum>(bindInternal(_targetHint)), size, data, static_cast<GLenum>(usage));
}
#ifndef MAGNUM_TARGET_GLES
void Buffer::setDataImplementationDSA(GLsizeiptr size, const GLvoid* data, Buffer::Usage usage) {
void Buffer::dataImplementationDSA(GLsizeiptr size, const GLvoid* data, Buffer::Usage usage) {
glNamedBufferDataEXT(_id, size, data, static_cast<GLenum>(usage));
}
#endif
void Buffer::setSubDataImplementationDefault(GLintptr offset, GLsizeiptr size, const GLvoid* data) {
void Buffer::subDataImplementationDefault(GLintptr offset, GLsizeiptr size, const GLvoid* data) {
glBufferSubData(static_cast<GLenum>(bindInternal(_targetHint)), offset, size, data);
}
#ifndef MAGNUM_TARGET_GLES
void Buffer::setSubDataImplementationDSA(GLintptr offset, GLsizeiptr size, const GLvoid* data) {
void Buffer::subDataImplementationDSA(GLintptr offset, GLsizeiptr size, const GLvoid* data) {
glNamedBufferSubDataEXT(_id, offset, size, data);
}
#endif

146
src/Buffer.h

@ -31,6 +31,7 @@
#include <cstddef>
#include <array>
#include <vector>
#include <Containers/Containers.h>
#include <Containers/EnumSet.h>
#include "Magnum.h"
@ -428,7 +429,7 @@ class MAGNUM_EXPORT Buffer {
* @requires_gl30 %Extension @extension{ARB,map_buffer_range}
* @requires_gles30 %Extension @es_extension{EXT,map_buffer_range}
*/
typedef Corrade::Containers::EnumSet<MapFlag, GLbitfield> MapFlags;
typedef Containers::EnumSet<MapFlag, GLbitfield> MapFlags;
/**
* @brief Unbind any buffer from given target
@ -436,7 +437,7 @@ class MAGNUM_EXPORT Buffer {
*
* @see @fn_gl{BindBuffer}
*/
inline static void unbind(Target target) { bind(target, 0); }
static void unbind(Target target) { bind(target, 0); }
#ifndef MAGNUM_TARGET_GLES2
/**
@ -456,7 +457,7 @@ class MAGNUM_EXPORT Buffer {
* @requires_gl31 %Extension @extension{ARB,copy_buffer}
* @requires_gles30 %Buffer copying is not available in OpenGL ES 2.0.
*/
inline static void copy(Buffer* read, Buffer* write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) {
static void copy(Buffer* read, Buffer* write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) {
copyImplementation(read, write, readOffset, writeOffset, size);
}
#endif
@ -469,7 +470,7 @@ class MAGNUM_EXPORT Buffer {
* Generates new OpenGL buffer.
* @see @fn_gl{GenBuffers}
*/
inline explicit Buffer(Target targetHint = Target::Array): _targetHint(targetHint) {
explicit Buffer(Target targetHint = Target::Array): _targetHint(targetHint) {
glGenBuffers(1, &_id);
}
@ -482,13 +483,14 @@ class MAGNUM_EXPORT Buffer {
virtual ~Buffer();
/** @brief OpenGL buffer ID */
inline GLuint id() const { return _id; }
GLuint id() const { return _id; }
/** @brief Target hint */
inline Target targetHint() const { return _targetHint; }
Target targetHint() const { return _targetHint; }
/**
* @brief Set target hint
* @return Pointer to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available, the buffer
* must be internally bound to some target before any operation. You
@ -501,7 +503,10 @@ class MAGNUM_EXPORT Buffer {
* http://www.opengl.org/wiki/Vertex_Specification#Index_buffers
* ... damned GL state
*/
inline void setTargetHint(Target hint) { _targetHint = hint; }
Buffer* setTargetHint(Target hint) {
_targetHint = hint;
return this;
}
/**
* @brief Bind buffer
@ -513,13 +518,58 @@ class MAGNUM_EXPORT Buffer {
* @todo Don't allow user to bind buffers?
* @see @fn_gl{BindBuffer}
*/
inline void bind(Target target) { bind(target, _id); }
void bind(Target target) { bind(target, _id); }
/**
* @brief %Buffer size
*
* If @extension{EXT,direct_state_access} is not available and the
* buffer is not already bound somewhere, it is bound to hinted target
* before the operation.
* @see @fn_gl{BindBuffer} and @fn_gl{GetBufferParameter} or
* @fn_gl_extension{GetNamedBufferParameter,EXT,direct_state_access}
* with @def_gl{BUFFER_SIZE}
*/
Int size();
#ifndef MAGNUM_TARGET_GLES
/**
* @brief %Buffer data
*
* Returns data of whole buffer. If @extension{EXT,direct_state_access}
* is not available and the buffer is not already bound somewhere, it
* is bound to hinted target before the operation.
* @see size(), subData(), setData(), @fn_gl{BindBuffer} and @fn_gl{GetBufferParameter} or
* @fn_gl_extension{GetNamedBufferParameter,EXT,direct_state_access}
* with @def_gl{BUFFER_SIZE}, @fn_gl{GetBufferSubData} or
* @fn_gl_extension{GetNamedBufferSubData,EXT,direct_state_access}
* @requires_gl %Buffer data queries are not available in OpenGL ES.
* Use @ref Magnum::Buffer::map() "map()" instead.
*/
Containers::Array<char> data();
/**
* @brief %Buffer subdata
* @param offset Offset in the buffer
* @param size Data size
*
* Returns data of given buffer portion. If @extension{EXT,direct_state_access}
* is not available and the buffer is not already bound somewhere, it
* is bound to hinted target before the operation.
* @see size(), data(), setSubData(), @fn_gl{BindBuffer} and @fn_gl{GetBufferSubData}
* or @fn_gl_extension{GetNamedBufferSubData,EXT,direct_state_access}
* @requires_gl %Buffer data queries are not available in OpenGL ES.
* Use @ref Magnum::Buffer::map() "map()" instead.
*/
Containers::Array<char> subData(GLintptr offset, GLsizeiptr size);
#endif
/**
* @brief Set buffer data
* @param size Data size
* @param data Pointer to data
* @param usage %Buffer usage
* @return Pointer to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available and the
* buffer is not already bound somewhere, it is bound to hinted target
@ -527,34 +577,39 @@ class MAGNUM_EXPORT Buffer {
* @see setTargetHint(), @fn_gl{BindBuffer} and @fn_gl{BufferData} or
* @fn_gl_extension{NamedBufferData,EXT,direct_state_access}
*/
inline void setData(GLsizeiptr size, const GLvoid* data, Usage usage) {
(this->*setDataImplementation)(size, data, usage);
Buffer* setData(GLsizeiptr size, const GLvoid* data, Usage usage) {
(this->*dataImplementation)(size, data, usage);
return this;
}
/**
* @brief Set buffer data
* @param data Fixed-size array with data
* @param usage %Buffer usage
* @return Pointer to self (for method chaining)
*
* @see setData(GLsizeiptr, const GLvoid*, Usage).
*/
template<std::size_t size, class T> inline void setData(const T(&data)[size], Usage usage) {
template<std::size_t size, class T> Buffer* setData(const T(&data)[size], Usage usage) {
setData(size*sizeof(T), data, usage);
return this;
}
/**
* @brief Set buffer data
* @param data Vector with data
* @param usage %Buffer usage
* @return Pointer to self (for method chaining)
*
* @see setData(GLsizeiptr, const GLvoid*, Usage)
*/
template<class T> inline void setData(const std::vector<T>& data, Usage usage) {
template<class T> Buffer* setData(const std::vector<T>& data, Usage usage) {
setData(data.size()*sizeof(T), data.data(), usage);
return this;
}
/** @overload */
template<std::size_t size, class T> inline void setData(const std::array<T, size>& data, Usage usage) {
template<std::size_t size, class T> void setData(const std::array<T, size>& data, Usage usage) {
setData(data.size()*sizeof(T), data.data(), usage);
}
@ -563,6 +618,7 @@ class MAGNUM_EXPORT Buffer {
* @param offset Offset in the buffer
* @param size Data size
* @param data Pointer to data
* @return Pointer to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available and the
* buffer is not already bound somewhere, it is bound to hinted target
@ -570,60 +626,70 @@ class MAGNUM_EXPORT Buffer {
* @see setTargetHint(), @fn_gl{BindBuffer} and @fn_gl{BufferSubData}
* or @fn_gl_extension{NamedBufferSubData,EXT,direct_state_access}
*/
inline void setSubData(GLintptr offset, GLsizeiptr size, const GLvoid* data) {
(this->*setSubDataImplementation)(offset, size, data);
Buffer* setSubData(GLintptr offset, GLsizeiptr size, const GLvoid* data) {
(this->*subDataImplementation)(offset, size, data);
return this;
}
/**
* @brief Set buffer subdata
* @param offset Offset in the buffer
* @param data Fixed-size array with data
* @return Pointer to self (for method chaining)
*
* @see setSubData(GLintptr, GLsizeiptr, const GLvoid*)
*/
template<std::size_t size, class T> inline void setSubData(GLintptr offset, const T(&data)[size]) {
template<std::size_t size, class T> Buffer* setSubData(GLintptr offset, const T(&data)[size]) {
setSubData(offset, size*sizeof(T), data);
return this;
}
/**
* @brief Set buffer subdata
* @param offset Offset in the buffer
* @param data Vector with data
* @return Pointer to self (for method chaining)
*
* @see setSubData(GLintptr, GLsizeiptr, const GLvoid*)
*/
template<class T> inline void setSubData(GLintptr offset, const std::vector<T>& data) {
template<class T> Buffer* setSubData(GLintptr offset, const std::vector<T>& data) {
setSubData(offset, data.size()*sizeof(T), data.data());
return this;
}
/** @overload */
template<std::size_t size, class T> inline void setSubData(GLintptr offset, const std::array<T, size>& data) {
template<std::size_t size, class T> Buffer* setSubData(GLintptr offset, const std::array<T, size>& data) {
setSubData(offset, data.size()*sizeof(T), data.data());
return this;
}
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Invalidate buffer data
* @return Pointer to self (for method chaining)
*
* If running on OpenGL ES or extension @extension{ARB,invalidate_subdata}
* is not available, this function does nothing.
* @see @ref MapFlag "MapFlag::InvalidateBuffer", @fn_gl{InvalidateBufferData}
*/
inline void invalidateData() {
Buffer* invalidateData() {
(this->*invalidateImplementation)();
return this;
}
/**
* @brief Invalidate buffer subdata
* @param offset Offset into the buffer
* @param length Length of the invalidated range
* @return Pointer to self (for method chaining)
*
* If running on OpenGL ES or extension @extension{ARB,invalidate_subdata}
* is not available, this function does nothing.
* @see @ref MapFlag "MapFlag::InvalidateRange", @fn_gl{InvalidateBufferData}
*/
inline void invalidateSubData(GLintptr offset, GLsizeiptr length) {
Buffer* invalidateSubData(GLintptr offset, GLsizeiptr length) {
(this->*invalidateSubImplementation)(offset, length);
return this;
}
#endif
@ -644,7 +710,7 @@ class MAGNUM_EXPORT Buffer {
* OpenGL ES 2.0, use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)"
* in OpenGL ES 3.0 instead.
*/
inline void* map(MapAccess access) {
void* map(MapAccess access) {
return (this->*mapImplementation)(access);
}
#endif
@ -665,7 +731,7 @@ class MAGNUM_EXPORT Buffer {
* @requires_gl30 %Extension @extension{ARB,map_buffer_range}
* @requires_gles30 %Extension @es_extension{EXT,map_buffer_range}
*/
inline void* map(GLintptr offset, GLsizeiptr length, MapFlags flags) {
void* map(GLintptr offset, GLsizeiptr length, MapFlags flags) {
return (this->*mapRangeImplementation)(offset, length, flags);
}
@ -673,6 +739,7 @@ class MAGNUM_EXPORT Buffer {
* @brief Flush mapped range
* @param offset Offset relative to start of mapped range
* @param length Length of the flushed memory
* @return Pointer to self (for method chaining)
*
* Flushes specified subsection of mapped range. Use only if you called
* map() with @ref MapFlag "MapFlag::FlushExplicit" flag. See
@ -686,8 +753,9 @@ class MAGNUM_EXPORT Buffer {
* @requires_gl30 %Extension @extension{ARB,map_buffer_range}
* @requires_gles30 %Extension @es_extension{EXT,map_buffer_range}
*/
inline void flushMappedRange(GLintptr offset, GLsizeiptr length) {
Buffer* flushMappedRange(GLintptr offset, GLsizeiptr length) {
(this->*flushMappedRangeImplementation)(offset, length);
return this;
}
/**
@ -704,7 +772,7 @@ class MAGNUM_EXPORT Buffer {
* @fn_gl_extension{UnmapNamedBuffer,EXT,direct_state_access}
* @requires_gles30 %Extension @es_extension{OES,mapbuffer}
*/
inline bool unmap() {
bool unmap() {
return (this->*unmapImplementation)();
}
@ -723,19 +791,33 @@ class MAGNUM_EXPORT Buffer {
static CopyImplementation copyImplementation;
#endif
typedef void(Buffer::*SetDataImplementation)(GLsizeiptr, const GLvoid*, Usage);
void MAGNUM_LOCAL setDataImplementationDefault(GLsizeiptr size, const GLvoid* data, Usage usage);
typedef void(Buffer::*GetParameterImplementation)(GLenum, GLint*);
void MAGNUM_LOCAL getParameterImplementationDefault(GLenum value, GLint* data);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL getParameterImplementationDSA(GLenum value, GLint* data);
#endif
static MAGNUM_LOCAL GetParameterImplementation getParameterImplementation;
#ifndef MAGNUM_TARGET_GLES
typedef void(Buffer::*GetSubDataImplementation)(GLintptr, GLsizeiptr, GLvoid*);
void MAGNUM_LOCAL getSubDataImplementationDefault(GLintptr offset, GLsizeiptr size, GLvoid* data);
void MAGNUM_LOCAL getSubDataImplementationDSA(GLintptr offset, GLsizeiptr size, GLvoid* data);
static MAGNUM_LOCAL GetSubDataImplementation getSubDataImplementation;
#endif
typedef void(Buffer::*DataImplementation)(GLsizeiptr, const GLvoid*, Usage);
void MAGNUM_LOCAL dataImplementationDefault(GLsizeiptr size, const GLvoid* data, Usage usage);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL setDataImplementationDSA(GLsizeiptr size, const GLvoid* data, Usage usage);
void MAGNUM_LOCAL dataImplementationDSA(GLsizeiptr size, const GLvoid* data, Usage usage);
#endif
static SetDataImplementation setDataImplementation;
static DataImplementation dataImplementation;
typedef void(Buffer::*SetSubDataImplementation)(GLintptr, GLsizeiptr, const GLvoid*);
void MAGNUM_LOCAL setSubDataImplementationDefault(GLintptr offset, GLsizeiptr size, const GLvoid* data);
typedef void(Buffer::*SubDataImplementation)(GLintptr, GLsizeiptr, const GLvoid*);
void MAGNUM_LOCAL subDataImplementationDefault(GLintptr offset, GLsizeiptr size, const GLvoid* data);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL setSubDataImplementationDSA(GLintptr offset, GLsizeiptr size, const GLvoid* data);
void MAGNUM_LOCAL subDataImplementationDSA(GLintptr offset, GLsizeiptr size, const GLvoid* data);
#endif
static SetSubDataImplementation setSubDataImplementation;
static SubDataImplementation subDataImplementation;
typedef void(Buffer::*InvalidateImplementation)();
void MAGNUM_LOCAL invalidateImplementationNoOp();

12
src/BufferImage.cpp

@ -27,16 +27,18 @@
namespace Magnum {
#ifndef MAGNUM_TARGET_GLES2
template<UnsignedInt dimensions> void BufferImage<dimensions>::setData(const typename DimensionTraits<Dimensions, GLsizei>::VectorType& size, Format format, Type type, const GLvoid* data, Buffer::Usage usage) {
template<UnsignedInt dimensions> void BufferImage<dimensions>::setData(const typename DimensionTraits<Dimensions, Int>::VectorType& size, ImageFormat format, ImageType type, const void* data, Buffer::Usage usage) {
_format = format;
_type = type;
_size = size;
_buffer.setData(pixelSize(format, type)*size.product(), data, usage);
_buffer.setData(pixelSize()*size.product(), data, usage);
}
template class BufferImage<1>;
template class BufferImage<2>;
template class BufferImage<3>;
#ifndef DOXYGEN_GENERATING_OUTPUT
template class MAGNUM_EXPORT BufferImage<1>;
template class MAGNUM_EXPORT BufferImage<2>;
template class MAGNUM_EXPORT BufferImage<3>;
#endif
#endif
}

8
src/BufferImage.h

@ -58,15 +58,15 @@ template<UnsignedInt dimensions> class MAGNUM_EXPORT BufferImage: public Abstrac
* Dimensions and buffer are empty, call setData() to fill the image
* with data.
*/
inline explicit BufferImage(Format format, Type type): AbstractImage(format, type) {
explicit BufferImage(ImageFormat format, ImageType type): AbstractImage(format, type) {
_buffer.setTargetHint(Buffer::Target::PixelPack);
}
/** @brief %Image size */
inline typename DimensionTraits<Dimensions, Int>::VectorType size() const { return _size; }
typename DimensionTraits<Dimensions, Int>::VectorType size() const { return _size; }
/** @brief %Image buffer */
inline Buffer* buffer() { return &_buffer; }
Buffer* buffer() { return &_buffer; }
/**
* @brief Set image data
@ -81,7 +81,7 @@ template<UnsignedInt dimensions> class MAGNUM_EXPORT BufferImage: public Abstrac
*
* @see Buffer::setData()
*/
void setData(const typename DimensionTraits<Dimensions, Int>::VectorType& size, Format format, Type type, const GLvoid* data, Buffer::Usage usage);
void setData(const typename DimensionTraits<Dimensions, Int>::VectorType& size, ImageFormat format, ImageType type, const void* data, Buffer::Usage usage);
private:
Math::Vector<Dimensions, Int> _size;

9
src/BufferTexture.cpp

@ -43,24 +43,23 @@ void BufferTexture::initializeContextBasedFunctionality(Context* context) {
}
}
void BufferTexture::setBufferImplementationDefault(InternalFormat internalFormat, Buffer* buffer) {
void BufferTexture::setBufferImplementationDefault(BufferTextureFormat internalFormat, Buffer* buffer) {
bindInternal();
glTexBuffer(GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer->id());
}
void BufferTexture::setBufferImplementationDSA(InternalFormat internalFormat, Buffer* buffer) {
void BufferTexture::setBufferImplementationDSA(BufferTextureFormat internalFormat, Buffer* buffer) {
glTextureBufferEXT(id(), GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer->id());
}
void BufferTexture::setBufferRangeImplementationDefault(InternalFormat internalFormat, Buffer* buffer, GLintptr offset, GLsizeiptr size) {
void BufferTexture::setBufferRangeImplementationDefault(BufferTextureFormat internalFormat, Buffer* buffer, GLintptr offset, GLsizeiptr size) {
bindInternal();
glTexBufferRange(GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer->id(), offset, size);
}
void BufferTexture::setBufferRangeImplementationDSA(InternalFormat internalFormat, Buffer* buffer, GLintptr offset, GLsizeiptr size) {
void BufferTexture::setBufferRangeImplementationDSA(BufferTextureFormat internalFormat, Buffer* buffer, GLintptr offset, GLsizeiptr size) {
glTextureBufferRangeEXT(id(), GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer->id(), offset, size);
}
}
#endif

260
src/BufferTexture.h

@ -26,7 +26,7 @@
#ifndef MAGNUM_TARGET_GLES
/** @file
* @brief Class Magnum::BufferTexture
* @brief Class Magnum::BufferTexture, enum Magnum::BufferTextureFormat
*/
#endif
@ -56,7 +56,7 @@ Example usage:
@code
Buffer* buffer;
BufferTexture texture;
texture.setBuffer(buffer);
texture.setBuffer(BufferTextureFormat::RGB32F, buffer);
constexpr static Vector3 data[] = {
// ...
@ -65,9 +65,10 @@ buffer.setData(data, Buffer::Usage::StaticDraw);
@endcode
The texture is bound to layer specified by shader via bind(). In shader, the
texture is used via `samplerBuffer`. Unlike in classic textures, coordinates
for buffer textures are integer coordinates passed to `texelFetch()`. See also
AbstractShaderProgram documentation for more information.
texture is used via `samplerBuffer`, `isamplerBuffer` or `usamplerBuffer`.
Unlike in classic textures, coordinates for buffer textures are integer
coordinates passed to `texelFetch()`. See also AbstractShaderProgram
documentation for more information.
@section BufferTexture-performance-optimization Performance optimizations
If extension @extension{EXT,direct_state_access} is available, setBuffer()
@ -76,6 +77,7 @@ functions use DSA to avoid unnecessary calls to @fn_gl{ActiveTexture} and
"relevant section in AbstractTexture documentation" and respective function
documentation for more information.
@see Texture, CubeMapTexture, CubeMapTextureArray
@requires_gl31 %Extension @extension{ARB,texture_buffer_object}
@requires_gl Texture buffers are not available in OpenGL ES.
*/
@ -88,171 +90,171 @@ class MAGNUM_EXPORT BufferTexture: private AbstractTexture {
BufferTexture& operator=(BufferTexture&&) = delete;
public:
explicit BufferTexture(): AbstractTexture(GL_TEXTURE_BUFFER) {}
/** @copydoc AbstractTexture::bind() */
void bind(Int layer) { AbstractTexture::bind(layer); }
/**
* @brief Internal format
* @brief Set texture buffer
* @param internalFormat Internal format
* @param buffer %Buffer with data
*
* @see setBuffer()
* Binds given buffer to this texture. The buffer itself can be then
* filled with data of proper format at any time using Buffer own data
* setting functions.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexBuffer}
* or @fn_gl_extension{TextureBuffer,EXT,direct_state_access}
*/
enum class InternalFormat: GLenum {
/** Red component, normalized unsigned byte. */
R8 = GL_R8,
/** Red and green component, each normalized unsigned byte. */
RG8 = GL_RG8,
void setBuffer(BufferTextureFormat internalFormat, Buffer* buffer) {
(this->*setBufferImplementation)(internalFormat, buffer);
}
/** RGBA, each component normalized unsigned byte. */
RGBA8 = GL_RGBA8,
/**
* @brief Set texture buffer
* @param internalFormat Internal format
* @param buffer %Buffer
* @param offset Offset
* @param size Data size
*
* Binds range of given buffer to this texture. The buffer itself can
* be then filled with data of proper format at any time using Buffer
* own data setting functions.
* @requires_gl43 %Extension @extension{ARB,texture_buffer_range}
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexBufferRange}
* or @fn_gl_extension{TextureBufferRange,EXT,direct_state_access}
*/
void setBuffer(BufferTextureFormat internalFormat, Buffer* buffer, GLintptr offset, GLsizeiptr size) {
(this->*setBufferRangeImplementation)(internalFormat, buffer, offset, size);
}
/** Red component, normalized unsigned short. */
R16 = GL_R16,
private:
static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context);
/** Red and green component, each normalized unsigned short. */
RG16 = GL_RG16,
typedef void(BufferTexture::*SetBufferImplementation)(BufferTextureFormat, Buffer*);
void MAGNUM_LOCAL setBufferImplementationDefault(BufferTextureFormat internalFormat, Buffer* buffer);
void MAGNUM_LOCAL setBufferImplementationDSA(BufferTextureFormat internalFormat, Buffer* buffer);
static SetBufferImplementation setBufferImplementation;
/** RGBA, each component normalized unsigned short. */
RGBA16 = GL_RGBA16,
typedef void(BufferTexture::*SetBufferRangeImplementation)(BufferTextureFormat, Buffer*, GLintptr, GLsizeiptr);
void MAGNUM_LOCAL setBufferRangeImplementationDefault(BufferTextureFormat internalFormat, Buffer* buffer, GLintptr offset, GLsizeiptr size);
void MAGNUM_LOCAL setBufferRangeImplementationDSA(BufferTextureFormat internalFormat, Buffer* buffer, GLintptr offset, GLsizeiptr size);
static SetBufferRangeImplementation setBufferRangeImplementation;
};
/** Red component, non-normalized unsigned byte. */
R8UI = GL_R8UI,
/**
@brief Internal buffer texture format
/** Red and green component, each non-normalized unsigned byte. */
RG8UI = GL_RG8UI,
@see BufferTexture
*/
enum class BufferTextureFormat: GLenum {
/** Red component, normalized unsigned byte. */
R8 = GL_R8,
/** RGBA, each component non-normalized unsigned byte. */
RGBA8UI = GL_RGBA8UI,
/** Red and green component, each normalized unsigned byte. */
RG8 = GL_RG8,
/** Red component, non-normalized signed byte. */
R8I = GL_R8I,
/** RGBA, each component normalized unsigned byte. */
RGBA8 = GL_RGBA8,
/** Red and green component, each non-normalized signed byte. */
RG8I = GL_RG8I,
/** Red component, normalized unsigned short. */
R16 = GL_R16,
/** RGBA, each component non-normalized signed byte. */
RGBA8I = GL_RGBA8I,
/** Red and green component, each normalized unsigned short. */
RG16 = GL_RG16,
/** Red component, non-normalized unsigned short. */
R16UI = GL_R16UI,
/** RGBA, each component normalized unsigned short. */
RGBA16 = GL_RGBA16,
/** Red and green component, each non-normalized unsigned short. */
RG16UI = GL_RG16UI,
/** Red component, non-normalized unsigned byte. */
R8UI = GL_R8UI,
/** RGBA, each component non-normalized unsigned short. */
RGBA16UI = GL_RGBA16UI,
/** Red and green component, each non-normalized unsigned byte. */
RG8UI = GL_RG8UI,
/** Red component, non-normalized signed short. */
R16I = GL_R16I,
/** RGBA, each component non-normalized unsigned byte. */
RGBA8UI = GL_RGBA8UI,
/** Red and green component, each non-normalized signed short. */
RG16I = GL_RG16I,
/** Red component, non-normalized signed byte. */
R8I = GL_R8I,
/** RGBA, each component non-normalized signed short. */
RGBA16I = GL_RGBA16I,
/** Red and green component, each non-normalized signed byte. */
RG8I = GL_RG8I,
/** Red component, non-normalized unsigned int. */
R32UI = GL_R32UI,
/** RGBA, each component non-normalized signed byte. */
RGBA8I = GL_RGBA8I,
/** Red and green component, each non-normalized unsigned int. */
RG32UI = GL_RG32UI,
/** Red component, non-normalized unsigned short. */
R16UI = GL_R16UI,
/**
* RGB, each component non-normalized unsigned int.
* @requires_gl40 %Extension @extension{ARB,texture_buffer_object_rgb32}
*/
RGB32UI = GL_RGB32UI,
/** Red and green component, each non-normalized unsigned short. */
RG16UI = GL_RG16UI,
/** RGBA, each component non-normalized unsigned int. */
RGBA32UI = GL_RGBA32UI,
/** RGBA, each component non-normalized unsigned short. */
RGBA16UI = GL_RGBA16UI,
/** Red component, non-normalized signed int. */
R32I = GL_R32I,
/** Red component, non-normalized signed short. */
R16I = GL_R16I,
/** Red and green component, each non-normalized signed int. */
RG32I = GL_RG32I,
/** Red and green component, each non-normalized signed short. */
RG16I = GL_RG16I,
/**
* RGB, each component non-normalized signed int.
* @requires_gl40 %Extension @extension{ARB,texture_buffer_object_rgb32}
*/
RGB32I = GL_RGB32I,
/** RGBA, each component non-normalized signed short. */
RGBA16I = GL_RGBA16I,
/** RGBA, each component non-normalized signed int. */
RGBA32I = GL_RGBA32I,
/** Red component, non-normalized unsigned int. */
R32UI = GL_R32UI,
/** Red component, half float. */
R16F = GL_R16F,
/** Red and green component, each non-normalized unsigned int. */
RG32UI = GL_RG32UI,
/** Red and green component, each half float. */
RG16F = GL_RG16F,
/**
* RGB, each component non-normalized unsigned int.
* @requires_gl40 %Extension @extension{ARB,texture_buffer_object_rgb32}
*/
RGB32UI = GL_RGB32UI,
/** RGBA, each component half float. */
RGBA16F = GL_RGBA16F,
/** RGBA, each component non-normalized unsigned int. */
RGBA32UI = GL_RGBA32UI,
/** Red component, float. */
R32F = GL_R32F,
/** Red component, non-normalized signed int. */
R32I = GL_R32I,
/** Red and green component, each float. */
RG32F = GL_RG32F,
/** Red and green component, each non-normalized signed int. */
RG32I = GL_RG32I,
/**
* RGB, each component float.
* @requires_gl40 %Extension @extension{ARB,texture_buffer_object_rgb32}
*/
RGB32F = GL_RGB32F,
/**
* RGB, each component non-normalized signed int.
* @requires_gl40 %Extension @extension{ARB,texture_buffer_object_rgb32}
*/
RGB32I = GL_RGB32I,
/** RGBA, each component float. */
RGBA32F = GL_RGBA32F
};
/** RGBA, each component non-normalized signed int. */
RGBA32I = GL_RGBA32I,
inline explicit BufferTexture(): AbstractTexture(GL_TEXTURE_BUFFER) {}
/** Red component, half float. */
R16F = GL_R16F,
/** @copydoc AbstractTexture::bind() */
inline void bind(Int layer) { AbstractTexture::bind(layer); }
/** Red and green component, each half float. */
RG16F = GL_RG16F,
/**
* @brief Set texture buffer
* @param internalFormat Internal format
* @param buffer %Buffer with data
*
* Binds given buffer to this texture. The buffer itself can be then
* filled with data of proper format at any time using Buffer own data
* setting functions.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexBuffer}
* or @fn_gl_extension{TextureBuffer,EXT,direct_state_access}
*/
inline void setBuffer(InternalFormat internalFormat, Buffer* buffer) {
(this->*setBufferImplementation)(internalFormat, buffer);
}
/** RGBA, each component half float. */
RGBA16F = GL_RGBA16F,
/**
* @brief Set texture buffer
* @param internalFormat Internal format
* @param buffer %Buffer
* @param offset Offset
* @param size Data size
*
* Binds range of given buffer to this texture. The buffer itself can
* be then filled with data of proper format at any time using Buffer
* own data setting functions.
* @requires_gl43 %Extension @extension{ARB,texture_buffer_range}
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexBuffer}
* or @fn_gl_extension{TextureBufferRange,EXT,direct_state_access}
*/
inline void setBuffer(InternalFormat internalFormat, Buffer* buffer, GLintptr offset, GLsizeiptr size) {
(this->*setBufferRangeImplementation)(internalFormat, buffer, offset, size);
}
/** Red component, float. */
R32F = GL_R32F,
private:
static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context);
/** Red and green component, each float. */
RG32F = GL_RG32F,
typedef void(BufferTexture::*SetBufferImplementation)(InternalFormat, Buffer*);
void MAGNUM_LOCAL setBufferImplementationDefault(InternalFormat internalFormat, Buffer* buffer);
void MAGNUM_LOCAL setBufferImplementationDSA(InternalFormat internalFormat, Buffer* buffer);
static SetBufferImplementation setBufferImplementation;
/**
* RGB, each component float.
* @requires_gl40 %Extension @extension{ARB,texture_buffer_object_rgb32}
*/
RGB32F = GL_RGB32F,
typedef void(BufferTexture::*SetBufferRangeImplementation)(InternalFormat, Buffer*, GLintptr, GLsizeiptr);
void MAGNUM_LOCAL setBufferRangeImplementationDefault(InternalFormat internalFormat, Buffer* buffer, GLintptr offset, GLsizeiptr size);
void MAGNUM_LOCAL setBufferRangeImplementationDSA(InternalFormat internalFormat, Buffer* buffer, GLintptr offset, GLsizeiptr size);
static SetBufferRangeImplementation setBufferRangeImplementation;
/** RGBA, each component float. */
RGBA32F = GL_RGBA32F
};
}

24
src/CMakeLists.txt

@ -56,16 +56,20 @@ set(Magnum_SRCS
DefaultFramebuffer.cpp
Framebuffer.cpp
Image.cpp
ImageFormat.cpp
Mesh.cpp
OpenGL.cpp
Query.cpp
Renderbuffer.cpp
Renderer.cpp
Resource.cpp
Sampler.cpp
Shader.cpp
Timeline.cpp
Implementation/BufferState.cpp
Implementation/State.cpp
Implementation/TextureState.cpp
Trade/AbstractImageConverter.cpp
Trade/AbstractImporter.cpp
@ -108,18 +112,22 @@ set(Magnum_HEADERS
Extensions.h
Framebuffer.h
Image.h
ImageFormat.h
ImageWrapper.h
Magnum.h
Mesh.h
OpenGL.h
Query.h
Renderbuffer.h
RenderbufferFormat.h
Renderer.h
Resource.h
ResourceManager.h
Sampler.h
Shader.h
Swizzle.h
Texture.h
TextureFormat.h
Timeline.h
Types.h
@ -140,14 +148,8 @@ endif()
# Files shared between main library and math unit test library
set(MagnumMath_SRCS
Math/Angle.cpp
Math/Complex.cpp
Math/DualComplex.cpp
Math/DualQuaternion.cpp
Math/Functions.cpp
Math/Quaternion.cpp
Math/RectangularMatrix.cpp
Math/Vector.cpp)
Math/instantiation.cpp)
# Set shared library flags for the objects, as they will be part of shared lib
# TODO: fix when CMake sets target_EXPORTS for OBJECT targets as well
@ -194,10 +196,6 @@ if(WITH_MESHTOOLS)
add_subdirectory(MeshTools)
endif()
if(WITH_PHYSICS)
add_subdirectory(Physics)
endif()
if(WITH_PRIMITIVES)
add_subdirectory(Primitives)
endif()
@ -210,6 +208,10 @@ if(WITH_SHADERS)
add_subdirectory(Shaders)
endif()
if(WITH_SHAPES)
add_subdirectory(Shapes)
endif()
if(WITH_TEXT)
add_subdirectory(Text)
endif()

82
src/Color.h

@ -36,11 +36,10 @@
namespace Magnum {
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
/* Convert color from HSV */
template<class T> inline typename std::enable_if<std::is_floating_point<T>::value, Color3<T>>::type fromHSV(typename Color3<T>::HSV hsv) {
template<class T> typename std::enable_if<std::is_floating_point<T>::value, Color3<T>>::type fromHSV(typename Color3<T>::HSV hsv) {
Math::Deg<T> hue;
T saturation, value;
std::tie(hue, saturation, value) = hsv;
@ -133,7 +132,6 @@ template<class T> inline constexpr typename std::enable_if<std::is_integral<T>::
}
}
#endif
/**
@brief Three-component (RGB) color
@ -174,11 +172,11 @@ class Color3: public Math::Vector3<T> {
*
* Hue can overflow the range @f$ [0.0, 360.0] @f$.
*/
inline constexpr static Color3<T> fromHSV(HSV hsv) {
constexpr static Color3<T> fromHSV(HSV hsv) {
return Implementation::fromHSV<T>(hsv);
}
/** @overload */
inline constexpr static Color3<T> fromHSV(Math::Deg<FloatingPointType> hue, FloatingPointType saturation, FloatingPointType value) {
constexpr static Color3<T> fromHSV(Math::Deg<FloatingPointType> hue, FloatingPointType saturation, FloatingPointType value) {
return fromHSV(std::make_tuple(hue, saturation, value));
}
@ -187,13 +185,13 @@ class Color3: public Math::Vector3<T> {
*
* All components are set to zero.
*/
inline constexpr /*implicit*/ Color3() {}
constexpr /*implicit*/ Color3() {}
/**
* @brief Gray constructor
* @param rgb RGB value
*/
inline constexpr explicit Color3(T rgb): Math::Vector3<T>(rgb) {}
constexpr explicit Color3(T rgb): Math::Vector3<T>(rgb) {}
/**
* @brief Constructor
@ -201,20 +199,20 @@ class Color3: public Math::Vector3<T> {
* @param g G value
* @param b B value
*/
inline constexpr /*implicit*/ Color3(T r, T g, T b): Math::Vector3<T>(r, g, b) {}
constexpr /*implicit*/ Color3(T r, T g, T b): Math::Vector3<T>(r, g, b) {}
/** @copydoc Math::Vector::Vector(const Vector<size, U>&) */
template<class U> inline constexpr explicit Color3(const Math::Vector<3, U>& other): Math::Vector3<T>(other) {}
template<class U> constexpr explicit Color3(const Math::Vector<3, U>& other): Math::Vector3<T>(other) {}
/** @brief Copy constructor */
inline constexpr Color3(const Math::Vector<3, T>& other): Math::Vector3<T>(other) {}
constexpr Color3(const Math::Vector<3, T>& other): Math::Vector3<T>(other) {}
inline T& r() { return Math::Vector3<T>::x(); } /**< @brief R component */
inline constexpr T r() const { return Math::Vector3<T>::x(); } /**< @overload */
inline T& g() { return Math::Vector3<T>::y(); } /**< @brief G component */
inline constexpr T g() const { return Math::Vector3<T>::y(); } /**< @overload */
inline T& b() { return Math::Vector3<T>::z(); } /**< @brief B component */
inline constexpr T b() const { return Math::Vector3<T>::z(); } /**< @overload */
T& r() { return Math::Vector3<T>::x(); } /**< @brief R component */
constexpr T r() const { return Math::Vector3<T>::x(); } /**< @overload */
T& g() { return Math::Vector3<T>::y(); } /**< @brief G component */
constexpr T g() const { return Math::Vector3<T>::y(); } /**< @overload */
T& b() { return Math::Vector3<T>::z(); } /**< @brief B component */
constexpr T b() const { return Math::Vector3<T>::z(); } /**< @overload */
/**
* @brief Convert to HSV
@ -227,7 +225,7 @@ class Color3: public Math::Vector3<T> {
*
* @see hue(), saturation(), value(), fromHSV()
*/
inline constexpr HSV toHSV() const {
constexpr HSV toHSV() const {
return Implementation::toHSV<T>(*this);
}
@ -237,7 +235,7 @@ class Color3: public Math::Vector3<T> {
*
* @see saturation(), value(), toHSV(), fromHSV()
*/
inline constexpr Math::Deg<FloatingPointType> hue() const {
constexpr Math::Deg<FloatingPointType> hue() const {
return Math::Deg<FloatingPointType>(Implementation::hue<T>(*this));
}
@ -247,7 +245,7 @@ class Color3: public Math::Vector3<T> {
*
* @see hue(), value(), toHSV(), fromHSV()
*/
inline constexpr FloatingPointType saturation() const {
constexpr FloatingPointType saturation() const {
return Implementation::saturation<T>(*this);
}
@ -257,7 +255,7 @@ class Color3: public Math::Vector3<T> {
*
* @see hue(), saturation(), toHSV(), fromHSV()
*/
inline constexpr FloatingPointType value() const {
constexpr FloatingPointType value() const {
return Implementation::value<T>(*this);
}
@ -291,11 +289,11 @@ class Color4: public Math::Vector4<T> {
* @param a Alpha value, defaults to 1.0 for floating-point types
* and maximum positive value for integral types.
*/
inline constexpr static Color4<T> fromHSV(HSV hsv, T a = Implementation::defaultAlpha<T>()) {
constexpr static Color4<T> fromHSV(HSV hsv, T a = Implementation::defaultAlpha<T>()) {
return Color4<T>(Implementation::fromHSV<T>(hsv), a);
}
/** @overload */
inline constexpr static Color4<T> fromHSV(Math::Deg<FloatingPointType> hue, FloatingPointType saturation, FloatingPointType value, T alpha) {
constexpr static Color4<T> fromHSV(Math::Deg<FloatingPointType> hue, FloatingPointType saturation, FloatingPointType value, T alpha) {
return fromHSV(std::make_tuple(hue, saturation, value), alpha);
}
@ -305,14 +303,14 @@ class Color4: public Math::Vector4<T> {
* RGB components are set to zero, A component is set to 1.0 for
* floating-point types and maximum positive value for integral types.
*/
inline constexpr /*implicit*/ Color4(): Math::Vector4<T>(T(0), T(0), T(0), Implementation::defaultAlpha<T>()) {}
constexpr /*implicit*/ Color4(): Math::Vector4<T>(T(0), T(0), T(0), Implementation::defaultAlpha<T>()) {}
/**
* @copydoc Color3::Color3(T)
* @param alpha Alpha value, defaults to 1.0 for floating-point types
* and maximum positive value for integral types.
*/
inline constexpr explicit Color4(T rgb, T alpha = Implementation::defaultAlpha<T>()): Math::Vector4<T>(rgb, rgb, rgb, alpha) {}
constexpr explicit Color4(T rgb, T alpha = Implementation::defaultAlpha<T>()): Math::Vector4<T>(rgb, rgb, rgb, alpha) {}
/**
* @brief Constructor
@ -322,7 +320,7 @@ class Color4: public Math::Vector4<T> {
* @param a A value, defaults to 1.0 for floating-point types and
* maximum positive value for integral types.
*/
inline constexpr /*implicit*/ Color4(T r, T g, T b, T a = Implementation::defaultAlpha<T>()): Math::Vector4<T>(r, g, b, a) {}
constexpr /*implicit*/ Color4(T r, T g, T b, T a = Implementation::defaultAlpha<T>()): Math::Vector4<T>(r, g, b, a) {}
/**
* @brief Constructor
@ -331,22 +329,22 @@ class Color4: public Math::Vector4<T> {
*/
/* Not marked as explicit, because conversion from Color3 to Color4
is fairly common, nearly always with A set to 1 */
inline constexpr /*implicit*/ Color4(const Math::Vector3<T>& rgb, T a = Implementation::defaultAlpha<T>()): Math::Vector4<T>(rgb[0], rgb[1], rgb[2], a) {}
constexpr /*implicit*/ Color4(const Math::Vector3<T>& rgb, T a = Implementation::defaultAlpha<T>()): Math::Vector4<T>(rgb[0], rgb[1], rgb[2], a) {}
/** @copydoc Math::Vector::Vector(const Vector<size, U>&) */
template<class U> inline constexpr explicit Color4(const Math::Vector<4, U>& other): Math::Vector4<T>(other) {}
template<class U> constexpr explicit Color4(const Math::Vector<4, U>& other): Math::Vector4<T>(other) {}
/** @brief Copy constructor */
inline constexpr Color4(const Math::Vector<4, T>& other): Math::Vector4<T>(other) {}
constexpr Color4(const Math::Vector<4, T>& other): Math::Vector4<T>(other) {}
inline T& r() { return Math::Vector4<T>::x(); } /**< @brief R component */
inline constexpr T r() const { return Math::Vector4<T>::x(); } /**< @overload */
inline T& g() { return Math::Vector4<T>::y(); } /**< @brief G component */
inline constexpr T g() const { return Math::Vector4<T>::y(); } /**< @overload */
inline T& b() { return Math::Vector4<T>::z(); } /**< @brief B component */
inline constexpr T b() const { return Math::Vector4<T>::z(); } /**< @overload */
inline T& a() { return Math::Vector4<T>::w(); } /**< @brief A component */
inline constexpr T a() const { return Math::Vector4<T>::w(); } /**< @overload */
T& r() { return Math::Vector4<T>::x(); } /**< @brief R component */
constexpr T r() const { return Math::Vector4<T>::x(); } /**< @overload */
T& g() { return Math::Vector4<T>::y(); } /**< @brief G component */
constexpr T g() const { return Math::Vector4<T>::y(); } /**< @overload */
T& b() { return Math::Vector4<T>::z(); } /**< @brief B component */
constexpr T b() const { return Math::Vector4<T>::z(); } /**< @overload */
T& a() { return Math::Vector4<T>::w(); } /**< @brief A component */
constexpr T a() const { return Math::Vector4<T>::w(); } /**< @overload */
/**
* @brief RGB part of the vector
@ -354,26 +352,26 @@ class Color4: public Math::Vector4<T> {
*
* @see swizzle()
*/
inline Color3<T>& rgb() { return Color3<T>::from(Math::Vector4<T>::data()); }
inline constexpr Color3<T> rgb() const { return Color3<T>::from(Math::Vector4<T>::data()); } /**< @overload */
Color3<T>& rgb() { return Color3<T>::from(Math::Vector4<T>::data()); }
constexpr Color3<T> rgb() const { return Color3<T>::from(Math::Vector4<T>::data()); } /**< @overload */
/** @copydoc Color3::toHSV() */
inline constexpr HSV toHSV() const {
constexpr HSV toHSV() const {
return Implementation::toHSV<T>(rgb());
}
/** @copydoc Color3::hue() */
inline constexpr Math::Deg<FloatingPointType> hue() const {
constexpr Math::Deg<FloatingPointType> hue() const {
return Implementation::hue<T>(rgb());
}
/** @copydoc Color3::saturation() */
inline constexpr FloatingPointType saturation() const {
constexpr FloatingPointType saturation() const {
return Implementation::saturation<T>(rgb());
}
/** @copydoc Color3::value() */
inline constexpr FloatingPointType value() const {
constexpr FloatingPointType value() const {
return Implementation::value<T>(rgb());
}

67
src/Context.cpp

@ -40,6 +40,7 @@
#include "Framebuffer.h"
#include "Mesh.h"
#include "Renderbuffer.h"
#include "Renderer.h"
#include "Implementation/State.h"
@ -79,6 +80,7 @@ const std::vector<Extension>& Extension::extensions(Version version) {
static const std::vector<Extension> extensions{
_extension(GL,AMD,vertex_shader_layer), // done
_extension(GL,AMD,shader_trinary_minmax), // done
_extension(GL,ARB,robustness), // done
_extension(GL,EXT,texture_filter_anisotropic), // done
_extension(GL,EXT,direct_state_access),
_extension(GL,GREMEDY,string_marker)}; // done
@ -208,8 +210,10 @@ const std::vector<Extension>& Extension::extensions(Version version) {
_extension(GL,EXT,texture_format_BGRA8888),
_extension(GL,EXT,read_format_bgra),
_extension(GL,EXT,debug_marker),
_extension(GL,EXT,disjoint_timer_query),
_extension(GL,EXT,separate_shader_objects),
_extension(GL,EXT,sRGB),
_extension(GL,EXT,robustness),
_extension(GL,NV,read_buffer_front),
_extension(GL,NV,read_stencil),
_extension(GL,NV,texture_border_clamp), // done
@ -220,6 +224,7 @@ const std::vector<Extension>& Extension::extensions(Version version) {
_extension(GL,OES,texture_3D)};
static const std::vector<Extension> extensionsES300{
_extension(GL,ANGLE,framebuffer_blit),
_extension(GL,ANGLE,framebuffer_multisample),
_extension(GL,ANGLE,depth_texture), // done
_extension(GL,APPLE,framebuffer_multisample),
_extension(GL,ARM,rgba8),
@ -235,6 +240,7 @@ const std::vector<Extension>& Extension::extensions(Version version) {
_extension(GL,NV,read_depth),
_extension(GL,NV,read_depth_stencil),
_extension(GL,NV,framebuffer_blit), // done
_extension(GL,NV,framebuffer_multisample),
_extension(GL,OES,depth24),
_extension(GL,OES,element_index_uint),
_extension(GL,OES,rgb8_rgba8),
@ -245,6 +251,7 @@ const std::vector<Extension>& Extension::extensions(Version version) {
_extension(GL,OES,vertex_half_float),
_extension(GL,OES,packed_depth_stencil),
_extension(GL,OES,depth_texture),
_extension(GL,OES,standard_derivatives), // done
_extension(GL,OES,vertex_array_object),
_extension(GL,OES,required_internalformat)};
#endif
@ -285,6 +292,16 @@ Context::Context() {
#endif
_version = static_cast<Version>(_majorVersion*100+_minorVersion*10);
/* Context flags are supported since GL 3.0 */
#ifndef MAGNUM_TARGET_GLES
/**
* @todo According to KHR_debug specs this should be also present in ES2
* if KHR_debug is available, but in headers it is nowhere to be found
*/
if(isVersionSupported(Version::GL300))
glGetIntegerv(GL_CONTEXT_FLAGS, reinterpret_cast<GLint*>(&_flags));
#endif
/* Get first future (not supported) version */
std::vector<Version> versions{
#ifndef MAGNUM_TARGET_GLES
@ -317,29 +334,35 @@ Context::Context() {
}
/* Check for presence of extensions in future versions */
#ifndef MAGNUM_TARGET_GLES
if(isVersionSupported(Version::GL300)) {
#else
if(isVersionSupported(Version::GLES300)) {
#ifndef MAGNUM_TARGET_GLES2
GLint extensionCount = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &extensionCount);
#ifndef MAGNUM_TARGET_GLES3
if(extensionCount || isVersionSupported(Version::GL300))
#endif
#ifndef MAGNUM_TARGET_GLES2
GLuint index = 0;
const char* extension;
while((extension = reinterpret_cast<const char*>(glGetStringi(GL_EXTENSIONS, index++)))) {
{
_supportedExtensions.reserve(extensionCount);
for(GLint i = 0; i != extensionCount; ++i) {
const std::string extension(reinterpret_cast<const char*>(glGetStringi(GL_EXTENSIONS, i)));
auto found = futureExtensions.find(extension);
if(found != futureExtensions.end()) {
_supportedExtensions.push_back(found->second);
extensionStatus.set(found->second._index);
}
}
#endif
}
#ifndef MAGNUM_TARGET_GLES3
else
#endif
#endif
#ifndef MAGNUM_TARGET_GLES3
/* OpenGL 2.1 / OpenGL ES 2.0 doesn't have glGetStringi() */
} else {
{
/* Don't crash when glGetString() returns nullptr */
const char* e = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
if(e) {
std::vector<std::string> extensions = Corrade::Utility::String::split(e, ' ');
std::vector<std::string> extensions = Utility::String::split(e, ' ');
for(auto it = extensions.begin(); it != extensions.end(); ++it) {
auto found = futureExtensions.find(*it);
if(found != futureExtensions.end()) {
@ -349,6 +372,7 @@ Context::Context() {
}
}
}
#endif
/* Set this context as current */
CORRADE_ASSERT(!_current, "Context: Another context currently active", );
@ -370,6 +394,7 @@ Context::Context() {
Framebuffer::initializeContextBasedFunctionality(this);
Mesh::initializeContextBasedFunctionality(this);
Renderbuffer::initializeContextBasedFunctionality(this);
Renderer::initializeContextBasedFunctionality(this);
}
Context::~Context() {
@ -378,6 +403,26 @@ Context::~Context() {
_current = nullptr;
}
std::vector<std::string> Context::shadingLanguageVersionStrings() const {
#ifndef MAGNUM_TARGET_GLES
GLint versionCount = 0;
glGetIntegerv(GL_NUM_SHADING_LANGUAGE_VERSIONS, &versionCount);
/* The implementation doesn't yet support this query (< OpenGL 4.3) */
if(!versionCount)
return {shadingLanguageVersionString()};
/* Get all of them */
std::vector<std::string> versions;
versions.reserve(versionCount);
for(GLint i = 0; i != versionCount; ++i)
versions.push_back(reinterpret_cast<const char*>(glGetStringi(GL_SHADING_LANGUAGE_VERSION, i)));
return std::move(versions);
#else
return {shadingLanguageVersionString()};
#endif
}
Version Context::supportedVersion(std::initializer_list<Version> versions) const {
for(auto it = versions.begin(); it != versions.end(); ++it)
if(isVersionSupported(*it)) return *it;

102
src/Context.h

@ -30,6 +30,7 @@
#include <bitset>
#include <vector>
#include <Containers/EnumSet.h>
#include "Magnum.h"
#include "OpenGL.h"
@ -37,11 +38,9 @@
namespace Magnum {
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
struct State;
}
#endif
/**
@brief OpenGL version
@ -110,13 +109,13 @@ class MAGNUM_EXPORT Extension {
static const std::vector<Extension>& extensions(Version version);
/** @brief Minimal version required by this extension */
inline constexpr Version requiredVersion() const { return _requiredVersion; }
constexpr Version requiredVersion() const { return _requiredVersion; }
/** @brief Version in which this extension was adopted to core */
inline constexpr Version coreVersion() const { return _coreVersion; }
constexpr Version coreVersion() const { return _coreVersion; }
/** @brief %Extension string */
inline constexpr const char* string() const { return _string; }
constexpr const char* string() const { return _string; }
private:
/* GCC 4.6 doesn't like const members, as std::vector doesn't have
@ -126,7 +125,7 @@ class MAGNUM_EXPORT Extension {
Version _coreVersion;
const char* _string;
inline constexpr Extension(std::size_t index, Version requiredVersion, Version coreVersion, const char* string): _index(index), _requiredVersion(requiredVersion), _coreVersion(coreVersion), _string(string) {}
constexpr Extension(std::size_t index, Version requiredVersion, Version coreVersion, const char* string): _index(index), _requiredVersion(requiredVersion), _coreVersion(coreVersion), _string(string) {}
};
/**
@ -146,12 +145,51 @@ class MAGNUM_EXPORT Context {
Context& operator=(Context&&) = delete;
public:
/**
* @brief Context flag
*
* @see Flags, flags()
*/
enum class Flag: GLint {
#ifndef MAGNUM_TARGET_GLES3
/**
* Debug context
* @requires_gl43 %Extension @es_extension{KHR,debug}
* @requires_es_extension %Extension @es_extension{KHR,debug}
*/
#ifndef MAGNUM_TARGET_GLES
Debug = GL_CONTEXT_FLAG_DEBUG_BIT,
#else
Debug = GL_CONTEXT_FLAG_DEBUG_BIT_KHR,
#endif
#endif
#ifndef MAGNUM_TARGET_GLES
/**
* Context with robust buffer access
* @requires_extension %Extension @extension{EXT,robustness}
* @requires_es_extension %Extension @es_extension{EXT,robustness}
* @todo In ES available under glGetIntegerv(CONTEXT_ROBUST_ACCESS_EXT),
* how to make it compatible?
*/
Robustness = GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB
#endif
};
/**
* @brief Context flags
*
* @see flags()
*/
typedef Containers::EnumSet<Flag, GLint> Flags;
/**
* @brief Constructor
*
* Constructed automatically, see class documentation for more
* information.
* @see @fn_gl{Get} with @def_gl{MAJOR_VERSION}, @def_gl{MINOR_VERSION},
* @def_gl{CONTEXT_FLAGS}, @def_gl{NUM_EXTENSIONS},
* @fn_gl{GetString} with @def_gl{EXTENSIONS}
*/
explicit Context();
@ -159,7 +197,7 @@ class MAGNUM_EXPORT Context {
~Context();
/** @brief Current context */
inline static Context* current() { return _current; }
static Context* current() { return _current; }
/**
* @brief OpenGL version
@ -167,7 +205,7 @@ class MAGNUM_EXPORT Context {
* @see majorVersion(), minorVersion(), versionString(),
* shadingLanguageVersionString()
*/
inline Version version() const { return _version; }
Version version() const { return _version; }
/**
* @brief Major OpenGL version (e.g. `4`)
@ -175,7 +213,7 @@ class MAGNUM_EXPORT Context {
* @see minorVersion(), version(), versionString(),
* shadingLanguageVersionString()
*/
inline Int majorVersion() const { return _majorVersion; }
Int majorVersion() const { return _majorVersion; }
/**
* @brief Minor OpenGL version (e.g. `3`)
@ -183,46 +221,67 @@ class MAGNUM_EXPORT Context {
* @see majorVersion(), version(), versionString(),
* shadingLanguageVersionString()
*/
inline Int minorVersion() const { return _minorVersion; }
Int minorVersion() const { return _minorVersion; }
/**
* @brief Vendor string
*
* The result is *not* cached, repeated queries will result in repeated
* OpenGL calls.
* @see rendererString(), @fn_gl{GetString} with @def_gl{VENDOR}
*/
inline std::string vendorString() const {
std::string vendorString() const {
return reinterpret_cast<const char*>(glGetString(GL_VENDOR));
}
/**
* @brief %Renderer string
*
* The result is *not* cached, repeated queries will result in repeated
* OpenGL calls.
* @see vendorString(), @fn_gl{GetString} with @def_gl{RENDERER}
*/
inline std::string rendererString() const {
std::string rendererString() const {
return reinterpret_cast<const char*>(glGetString(GL_RENDERER));
}
/**
* @brief Version string
*
* The result is *not* cached, repeated queries will result in repeated
* OpenGL calls.
* @see shadingLanguageVersionString(), version(), @fn_gl{GetString}
* with @def_gl{VERSION}
*/
inline std::string versionString() const {
std::string versionString() const {
return reinterpret_cast<const char*>(glGetString(GL_VERSION));
}
/**
* @brief Shading language version string
*
* The result is *not* cached, repeated queries will result in repeated
* OpenGL calls.
* @see versionString(), version(), @fn_gl{GetString} with
* @def_gl{SHADING_LANGUAGE_VERSION}
*/
inline std::string shadingLanguageVersionString() const {
std::string shadingLanguageVersionString() const {
return reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION));
}
/**
* @brief Shading language version strings
*
* The result is *not* cached, repeated queries will result in repeated
* OpenGL calls.
* @see versionString(), version(), @fn_gl{Get} with @def_gl{NUM_SHADING_LANGUAGE_VERSIONS},
* @fn_gl{GetString} with @def_gl{SHADING_LANGUAGE_VERSION}
*/
std::vector<std::string> shadingLanguageVersionStrings() const;
/** @brief Context flags */
Flags flags() const { return _flags; }
/**
* @brief Supported extensions
*
@ -231,7 +290,7 @@ class MAGNUM_EXPORT Context {
*
* @see isExtensionSupported(), Extension::extensions()
*/
inline const std::vector<Extension>& supportedExtensions() const {
const std::vector<Extension>& supportedExtensions() const {
return _supportedExtensions;
}
@ -240,7 +299,7 @@ class MAGNUM_EXPORT Context {
*
* @see supportedVersion(), MAGNUM_ASSERT_VERSION_SUPPORTED()
*/
inline bool isVersionSupported(Version version) const {
bool isVersionSupported(Version version) const {
#ifndef CORRADE_GCC44_COMPATIBILITY
return _version >= version;
#else
@ -280,7 +339,7 @@ class MAGNUM_EXPORT Context {
* @see isExtensionSupported(const Extension&) const,
* MAGNUM_ASSERT_EXTENSION_SUPPORTED()
*/
template<class T> inline bool isExtensionSupported() const {
template<class T> bool isExtensionSupported() const {
return isVersionSupported(T::coreVersion()) || (isVersionSupported(T::requiredVersion()) && extensionStatus[T::Index]);
}
@ -294,12 +353,12 @@ class MAGNUM_EXPORT Context {
* @see supportedExtensions(), Extension::extensions(),
* MAGNUM_ASSERT_EXTENSION_SUPPORTED()
*/
inline bool isExtensionSupported(const Extension& extension) const {
bool isExtensionSupported(const Extension& extension) const {
return isVersionSupported(extension._coreVersion) || (isVersionSupported(extension._requiredVersion) && extensionStatus[extension._index]);
}
#ifndef DOXYGEN_GENERATING_OUTPUT
inline Implementation::State* state() { return _state; }
Implementation::State* state() { return _state; }
#endif
private:
@ -308,6 +367,7 @@ class MAGNUM_EXPORT Context {
Version _version;
Int _majorVersion;
Int _minorVersion;
Flags _flags;
std::bitset<128> extensionStatus;
std::vector<Extension> _supportedExtensions;
@ -337,7 +397,7 @@ MAGNUM_ASSERT_VERSION_SUPPORTED(Version::GL330);
#else
#define MAGNUM_ASSERT_VERSION_SUPPORTED(version) \
do { \
if(!Context::current()->isVersionSupported(version)) { \
if(!Magnum::Context::current()->isVersionSupported(version)) { \
Corrade::Utility::Error() << "Magnum: required version" << version << "is not supported"; \
std::exit(-3); \
} \
@ -367,7 +427,7 @@ MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::geometry_shader4);
#else
#define MAGNUM_ASSERT_EXTENSION_SUPPORTED(extension) \
do { \
if(!Context::current()->isExtensionSupported<extension>()) { \
if(!Magnum::Context::current()->isExtensionSupported<extension>()) { \
Corrade::Utility::Error() << "Magnum: required extension" << extension::string() << "is not supported"; \
std::exit(-3); \
} \

97
src/CubeMapTexture.h

@ -54,30 +54,32 @@ See Texture documentation for introduction.
Common usage is to fully configure all texture parameters and then set the
data from e.g. set of Image objects:
@code
Image2D positiveX({256, 256}, Image2D::Components::RGBA, Image2D::ComponentType::UnsignedByte, dataPositiveX);
Image2D positiveX({256, 256}, ImageFormat::RGBA, ImageType::UnsignedByte, dataPositiveX);
// ...
CubeMapTexture texture;
texture.setMagnificationFilter(Texture2D::Filter::Linear)
texture.setMagnificationFilter(Sampler::Filter::Linear)
// ...
->setStorage(Math::log2(256)+1, Texture2D::Format::RGBA8, {256, 256})
->setStorage(Math::log2(256)+1, TextureFormat::RGBA8, {256, 256})
->setSubImage(CubeMapTexture::Coordinate::PositiveX, 0, {}, &positiveX)
->setSubImage(CubeMapTexture::Coordinate::NegativeX, 0, {}, &negativeX)
// ...
@endcode
The texture is bound to layer specified by shader via bind(). In shader, the
texture is used via `samplerCube`. Unlike in classic textures, coordinates for
cube map textures is signed three-part vector from the center of the cube,
which intersects one of the six sides of the cube map. See also
AbstractShaderProgram for more information.
@see CubeMapTextureArray
texture is used via `samplerCube`, `samplerCubeShadow`, `isamplerCube` or
`usamplerCube`. Unlike in classic textures, coordinates for cube map textures
is signed three-part vector from the center of the cube, which intersects one
of the six sides of the cube map. See also AbstractShaderProgram for more
information about usage in shaders.
@see @ref Renderer::Feature "Renderer::Feature::SeamlessCubeMapTexture",
CubeMapTextureArray, Texture, BufferTexture
*/
class CubeMapTexture: public AbstractTexture {
public:
/** @brief Cube map coordinate */
enum Coordinate: GLenum {
enum class Coordinate: GLenum {
PositiveX = GL_TEXTURE_CUBE_MAP_POSITIVE_X, /**< +X cube side */
NegativeX = GL_TEXTURE_CUBE_MAP_NEGATIVE_X, /**< -X cube side */
PositiveY = GL_TEXTURE_CUBE_MAP_POSITIVE_Y, /**< +Y cube side */
@ -86,35 +88,20 @@ class CubeMapTexture: public AbstractTexture {
NegativeZ = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z /**< -Z cube side */
};
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Enable/disable seamless cube map textures
*
* Initially disabled on desktop OpenGL.
* @see @fn_gl{Enable}/@fn_gl{Disable} with @def_gl{TEXTURE_CUBE_MAP_SEAMLESS}
* @requires_gl32 %Extension @extension{ARB,seamless_cube_map}
* @requires_gl Not available in OpenGL ES 2.0, always enabled in
* OpenGL ES 3.0.
*/
inline static void setSeamless(bool enabled) {
enabled ? glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS) : glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
}
#endif
/**
* @brief Constructor
*
* Creates one cube map OpenGL texture.
* @see @fn_gl{GenTextures} with @def_gl{TEXTURE_CUBE_MAP}
*/
inline explicit CubeMapTexture(): AbstractTexture(GL_TEXTURE_CUBE_MAP) {}
explicit CubeMapTexture(): AbstractTexture(GL_TEXTURE_CUBE_MAP) {}
/**
* @brief Set wrapping
*
* See Texture::setWrapping() for more information.
*/
inline CubeMapTexture* setWrapping(const Array3D<Wrapping>& wrapping) {
CubeMapTexture* setWrapping(const Array3D<Sampler::Wrapping>& wrapping) {
DataHelper<3>::setWrapping(this, wrapping);
return this;
}
@ -128,7 +115,7 @@ class CubeMapTexture: public AbstractTexture {
* See Texture::imageSize() for more information.
* @requires_gl %Texture image queries are not available in OpenGL ES.
*/
inline Vector2i imageSize(Coordinate coordinate, Int level) {
Vector2i imageSize(Coordinate coordinate, Int level) {
return DataHelper<2>::imageSize(this, static_cast<GLenum>(coordinate), level);
}
#endif
@ -138,11 +125,41 @@ class CubeMapTexture: public AbstractTexture {
*
* See Texture::setStorage() for more information.
*/
inline CubeMapTexture* setStorage(Int levels, InternalFormat internalFormat, const Vector2i& size) {
CubeMapTexture* setStorage(Int levels, TextureFormat internalFormat, const Vector2i& size) {
DataHelper<2>::setStorage(this, _target, levels, internalFormat, size);
return this;
}
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Read given mip level of texture to image
* @param coordinate Coordinate
* @param level Mip level
* @param image %Image where to put the data
*
* See Texture::image(Int, Image*) for more information.
* @requires_gl %Texture image queries are not available in OpenGL ES.
*/
void image(Coordinate coordinate, Int level, Image2D* image) {
AbstractTexture::image<2>(GLenum(coordinate), level, image);
}
/**
* @brief Read given mip level of texture to buffer image
* @param coordinate Coordinate
* @param level Mip level
* @param image %Buffer image where to put the data
* @param usage %Buffer usage
*
* See Texture::image(Int, BufferImage*, Buffer::Usage) for more
* information.
* @requires_gl %Texture image queries are not available in OpenGL ES.
*/
void image(Coordinate coordinate, Int level, BufferImage2D* image, Buffer::Usage usage) {
AbstractTexture::image<2>(GLenum(coordinate), level, image, usage);
}
#endif
/**
* @brief Set image data
* @param coordinate Coordinate
@ -154,8 +171,8 @@ class CubeMapTexture: public AbstractTexture {
*
* See Texture::setImage() for more information.
*/
template<class Image> inline CubeMapTexture* setImage(Coordinate coordinate, Int level, InternalFormat internalFormat, Image* image) {
DataHelper<2>::set(this, static_cast<GLenum>(coordinate), level, internalFormat, image);
template<class Image> CubeMapTexture* setImage(Coordinate coordinate, Int level, TextureFormat internalFormat, Image* image) {
DataHelper<2>::setImage(this, static_cast<GLenum>(coordinate), level, internalFormat, image);
return this;
}
@ -170,8 +187,8 @@ class CubeMapTexture: public AbstractTexture {
*
* See Texture::setSubImage() for more information.
*/
template<class Image> inline CubeMapTexture* setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, const Image* image) {
DataHelper<2>::setSub(this, static_cast<GLenum>(coordinate), level, offset, image);
template<class Image> CubeMapTexture* setSubImage(Coordinate coordinate, Int level, const Vector2i& offset, const Image* image) {
DataHelper<2>::setSubImage(this, static_cast<GLenum>(coordinate), level, offset, image);
return this;
}
@ -187,31 +204,31 @@ class CubeMapTexture: public AbstractTexture {
*
* See Texture::invalidateSubImage() for more information.
*/
inline void invalidateSubImage(Int level, const Vector3i& offset, const Vector3i& size) {
DataHelper<3>::invalidateSub(this, level, offset, size);
void invalidateSubImage(Int level, const Vector3i& offset, const Vector3i& size) {
DataHelper<3>::invalidateSubImage(this, level, offset, size);
}
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
inline CubeMapTexture* setMinificationFilter(Filter filter, Mipmap mipmap = Mipmap::Base) {
CubeMapTexture* setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap);
return this;
}
inline CubeMapTexture* setMagnificationFilter(Filter filter) {
CubeMapTexture* setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter);
return this;
}
#ifndef MAGNUM_TARGET_GLES3
inline CubeMapTexture* setBorderColor(const Color4<>& color) {
CubeMapTexture* setBorderColor(const Color4<>& color) {
AbstractTexture::setBorderColor(color);
return this;
}
inline CubeMapTexture* setMaxAnisotropy(Float anisotropy) {
CubeMapTexture* setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy);
return this;
}
#endif
inline CubeMapTexture* generateMipmap() {
CubeMapTexture* generateMipmap() {
AbstractTexture::generateMipmap();
return this;
}

88
src/CubeMapTextureArray.h

@ -48,16 +48,16 @@ calling setStorage() or by passing properly sized empty Image to setImage().
Example: array with 16 layers of cube map faces, each face consisting of six
64x64 images:
@code
Image3D dummy({64, 64, 16*6}, Image3D::Components::RGBA, Image3D::ComponentType::UnsignedByte, nullptr);
Image3D dummy({64, 64, 16*6}, ImageFormat::RGBA, ImageType::UnsignedByte, nullptr);
CubeMapTextureArray texture;
texture.setMagnificationFilter(CubeMapTextureArray::Filter::Linear)
texture.setMagnificationFilter(Sampler::Filter::Linear)
// ...
->setStorage(Math::log2(64)+1, CubeMapTextureArray::Format::RGBA8, {64, 64, 16});
->setStorage(Math::log2(64)+1, TextureFormat::RGBA8, {64, 64, 16});
for(std::size_t i = 0; i != 16; ++i) {
void* dataPositiveX = ...;
Image2D imagePositiveX({64, 64}, Image3D::Components::RGBA, Image3D::ComponentType::UnsignedByte, imagePositiveX);
Image2D imagePositiveX({64, 64}, ImageFormat::RGBA, ImageType::UnsignedByte, imagePositiveX);
// ...
texture->setSubImage(i, CubeMapTextureArray::Coordinate::PositiveX, 0, {}, imagePositiveX);
texture->setSubImage(i, CubeMapTextureArray::Coordinate::NegativeX, 0, {}, imageNegativeX);
@ -68,20 +68,22 @@ for(std::size_t i = 0; i != 16; ++i) {
@endcode
The texture is bound to layer specified by shader via bind(). In shader, the
texture is used via `samplerCubeArray`. Unlike in classic textures,
coordinates for cube map texture arrays is signed four-part vector. First
three parts define vector from the center of the cube which intersects with
one of the six sides of the cube map, fourth part is layer in the array. See
also AbstractShaderProgram for more information.
texture is used via `samplerCubeArray`, `samplerCubeArrayShadow`,
`isamplerCubeArray` or `usamplerCubeArray`. Unlike in classic textures,
coordinates for cube map texture arrays is signed four-part vector. First three
parts define vector from the center of the cube which intersects with one of
the six sides of the cube map, fourth part is layer in the array. See also
AbstractShaderProgram for more information about usage in shaders.
@see CubeMapTexture::setSeamless()
@see @ref Renderer::Feature "Renderer::Feature::SeamlessCubeMapTexture",
CubeMapTexture, Texture, BufferTexture
@requires_gl40 %Extension @extension{ARB,texture_cube_map_array}
@requires_gl Cube map texture arrays are not available in OpenGL ES.
*/
class CubeMapTextureArray: public AbstractTexture {
public:
/** @brief Cube map coordinate */
enum Coordinate: GLsizei {
enum class Coordinate: GLsizei {
PositiveX = 0, /**< +X cube side */
NegativeX = 1, /**< -X cube side */
PositiveY = 2, /**< +Y cube side */
@ -96,14 +98,14 @@ class CubeMapTextureArray: public AbstractTexture {
* Creates one cube map OpenGL texture.
* @see @fn_gl{GenTextures} with @def_gl{TEXTURE_CUBE_MAP}
*/
inline explicit CubeMapTextureArray(): AbstractTexture(GL_TEXTURE_CUBE_MAP_ARRAY) {}
explicit CubeMapTextureArray(): AbstractTexture(GL_TEXTURE_CUBE_MAP_ARRAY) {}
/**
* @brief Set wrapping
*
* See Texture::setWrapping() for more information.
*/
inline CubeMapTextureArray* setWrapping(const Array3D<Wrapping>& wrapping) {
CubeMapTextureArray* setWrapping(const Array3D<Sampler::Wrapping>& wrapping) {
DataHelper<3>::setWrapping(this, wrapping);
return this;
}
@ -115,7 +117,7 @@ class CubeMapTextureArray: public AbstractTexture {
*
* See Texture::imageSize() for more information.
*/
inline Vector3i imageSize(Coordinate coordinate, Int level) {
Vector3i imageSize(Coordinate coordinate, Int level) {
return DataHelper<3>::imageSize(this, GL_TEXTURE_CUBE_MAP_POSITIVE_X + static_cast<GLenum>(coordinate), level);
}
@ -124,11 +126,41 @@ class CubeMapTextureArray: public AbstractTexture {
*
* See Texture::setStorage() for more information.
*/
inline CubeMapTextureArray* setStorage(Int levels, InternalFormat internalFormat, const Vector3i& size) {
CubeMapTextureArray* setStorage(Int levels, TextureFormat internalFormat, const Vector3i& size) {
DataHelper<3>::setStorage(this, _target, levels, internalFormat, size);
return this;
}
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Read given mip level of texture to image
* @param coordinate Coordinate
* @param level Mip level
* @param image %Image where to put the data
*
* See Texture::image(Int, Image*) for more information.
* @requires_gl %Texture image queries are not available in OpenGL ES.
*/
void image(Coordinate coordinate, Int level, Image3D* image) {
AbstractTexture::image<3>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + GLenum(coordinate), level, image);
}
/**
* @brief Read given mip level of texture to buffer image
* @param coordinate Coordinate
* @param level Mip level
* @param image %Buffer image where to put the data
* @param usage %Buffer usage
*
* See Texture::image(Int, BufferImage*, Buffer::Usage) for more
* information.
* @requires_gl %Texture image queries are not available in OpenGL ES.
*/
void image(Coordinate coordinate, Int level, BufferImage3D* image, Buffer::Usage usage) {
AbstractTexture::image<3>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + GLenum(coordinate), level, image, usage);
}
#endif
/**
* @brief Set image data
* @param level Mip level
@ -143,8 +175,8 @@ class CubeMapTextureArray: public AbstractTexture {
*
* See Texture::setImage() for more information.
*/
template<class T> inline CubeMapTextureArray* setImage(Int level, InternalFormat internalFormat, T* image) {
DataHelper<3>::set(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, internalFormat, image);
template<class T> CubeMapTextureArray* setImage(Int level, TextureFormat internalFormat, T* image) {
DataHelper<3>::setImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, internalFormat, image);
return this;
}
@ -167,8 +199,8 @@ class CubeMapTextureArray: public AbstractTexture {
*
* @see setSubImage(Int, Coordinate, Int, const Math::Vector<2, Int>&, const Image*)
*/
template<class Image> inline CubeMapTextureArray* setSubImage(Int level, const Vector3i& offset, const Image* image) {
DataHelper<3>::setSub(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, offset, image, Vector3i(Math::Vector<Image::Dimensions, GLsizei>()));
template<class Image> CubeMapTextureArray* setSubImage(Int level, const Vector3i& offset, const Image* image) {
DataHelper<3>::setSubImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, offset, image, Vector3i(Math::Vector<Image::Dimensions, GLsizei>()));
return this;
}
@ -186,8 +218,8 @@ class CubeMapTextureArray: public AbstractTexture {
*
* @see setSubImage(Int, const Math::Vector<3, Int>&, const Image*)
*/
template<class Image> inline CubeMapTextureArray* setSubImage(Int layer, Coordinate coordinate, Int level, const Vector2i& offset, const Image* image) {
DataHelper<3>::setSub(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, Vector3i(offset, layer*6+static_cast<GLsizei>(coordinate)), image, Vector2i(Math::Vector<Image::Dimensions, GLsizei>()));
template<class Image> CubeMapTextureArray* setSubImage(Int layer, Coordinate coordinate, Int level, const Vector2i& offset, const Image* image) {
DataHelper<3>::setSubImage(this, GL_TEXTURE_CUBE_MAP_ARRAY, level, Vector3i(offset, layer*6+static_cast<GLsizei>(coordinate)), image, Vector2i(Math::Vector<Image::Dimensions, GLsizei>()));
return this;
}
@ -203,31 +235,31 @@ class CubeMapTextureArray: public AbstractTexture {
*
* See Texture::invalidateSubImage() for more information.
*/
inline void invalidateSubImage(Int level, const Vector3i& offset, const Vector3i& size) {
DataHelper<3>::invalidateSub(this, level, offset, size);
void invalidateSubImage(Int level, const Vector3i& offset, const Vector3i& size) {
DataHelper<3>::invalidateSubImage(this, level, offset, size);
}
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
inline CubeMapTextureArray* setMinificationFilter(Filter filter, Mipmap mipmap = Mipmap::Base) {
CubeMapTextureArray* setMinificationFilter(Sampler::Filter filter, Sampler::Mipmap mipmap = Sampler::Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap);
return this;
}
inline CubeMapTextureArray* setMagnificationFilter(Filter filter) {
CubeMapTextureArray* setMagnificationFilter(Sampler::Filter filter) {
AbstractTexture::setMagnificationFilter(filter);
return this;
}
#ifndef MAGNUM_TARGET_GLES3
inline CubeMapTextureArray* setBorderColor(const Color4<>& color) {
CubeMapTextureArray* setBorderColor(const Color4<>& color) {
AbstractTexture::setBorderColor(color);
return this;
}
inline CubeMapTextureArray* setMaxAnisotropy(Float anisotropy) {
CubeMapTextureArray* setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy);
return this;
}
#endif
inline CubeMapTextureArray* generateMipmap() {
CubeMapTextureArray* generateMipmap() {
AbstractTexture::generateMipmap();
return this;
}

2
src/DebugMarker.h

@ -53,7 +53,7 @@ class MAGNUM_EXPORT DebugMarker {
DebugMarker() = delete;
/** @brief Put string mark into OpenGL command stream */
inline static void mark(const std::string& string) {
static void mark(const std::string& string) {
markImplementation(string);
}

4
src/DebugTools/CMakeLists.txt

@ -55,10 +55,10 @@ endif()
target_link_libraries(MagnumDebugTools
Magnum
MagnumMeshTools
MagnumPhysics
MagnumPrimitives
MagnumSceneGraph
MagnumShaders)
MagnumShaders
MagnumShapes)
install(TARGETS MagnumDebugTools DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR})
install(FILES ${MagnumDebugTools_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/DebugTools)

8
src/DebugTools/ForceRenderer.cpp

@ -28,7 +28,7 @@
#include "Mesh.h"
#include "DebugTools/ResourceManager.h"
#include "SceneGraph/AbstractCamera.h"
#include "Shaders/FlatShader.h"
#include "Shaders/Flat.h"
#include "DebugTools/Implementation/ForceRendererTransformation.h"
@ -66,8 +66,8 @@ const std::array<UnsignedByte, 6> indices{{
template<UnsignedInt dimensions> ForceRenderer<dimensions>::ForceRenderer(SceneGraph::AbstractObject<dimensions>* object, const typename DimensionTraits<dimensions, Float>::VectorType& forcePosition, const typename DimensionTraits<dimensions, Float>::VectorType* force, ResourceKey options, SceneGraph::DrawableGroup<dimensions>* drawables): SceneGraph::Drawable<dimensions>(object, drawables), forcePosition(forcePosition), force(force), options(ResourceManager::instance()->get<ForceRendererOptions>(options)) {
/* Shader */
shader = ResourceManager::instance()->get<AbstractShaderProgram, Shaders::FlatShader<dimensions>>(shaderKey<dimensions>());
if(!shader) ResourceManager::instance()->set<AbstractShaderProgram>(shader.key(), new Shaders::FlatShader<dimensions>);
shader = ResourceManager::instance()->get<AbstractShaderProgram, Shaders::Flat<dimensions>>(shaderKey<dimensions>());
if(!shader) ResourceManager::instance()->set<AbstractShaderProgram>(shader.key(), new Shaders::Flat<dimensions>);
/* Mesh and vertex buffer */
mesh = ResourceManager::instance()->get<Mesh>("force");
@ -89,7 +89,7 @@ template<UnsignedInt dimensions> ForceRenderer<dimensions>::ForceRenderer(SceneG
mesh->setPrimitive(Mesh::Primitive::Lines)
->setIndexCount(indices.size())
->addVertexBuffer(vertexBuffer, 0,
typename Shaders::FlatShader<dimensions>::Position(Shaders::FlatShader<dimensions>::Position::Components::Two))
typename Shaders::Flat<dimensions>::Position(Shaders::Flat<dimensions>::Position::Components::Two))
->setIndexBuffer(indexBuffer, 0, Mesh::IndexType::UnsignedByte, 0, positions.size());
ResourceManager::instance()->set<Mesh>(this->mesh.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual);
}

12
src/DebugTools/ForceRenderer.h

@ -44,10 +44,10 @@ See ForceRenderer documentation for more information.
*/
class ForceRendererOptions {
public:
inline constexpr ForceRendererOptions(): _color(1.0f), _size(1.0f) {}
constexpr ForceRendererOptions(): _color(1.0f), _size(1.0f) {}
/** @brief Color of rendered arrow */
inline constexpr Color4<> color() const { return _color; }
constexpr Color4<> color() const { return _color; }
/**
* @brief Set color of rendered arrow
@ -55,13 +55,13 @@ class ForceRendererOptions {
*
* Default is 100% opaque white.
*/
inline ForceRendererOptions* setColor(const Color4<>& color) {
ForceRendererOptions* setColor(const Color4<>& color) {
_color = color;
return this;
}
/** @brief Scale of rendered arrow */
inline constexpr Float scale() const { return _size; }
constexpr Float scale() const { return _size; }
/**
* @brief Set scale of rendered arrow
@ -69,7 +69,7 @@ class ForceRendererOptions {
*
* Default is `1.0f`.
*/
inline ForceRendererOptions* setSize(Float size) {
ForceRendererOptions* setSize(Float size) {
_size = size;
return this;
}
@ -128,7 +128,7 @@ template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ForceRenderer: p
const typename DimensionTraits<dimensions, Float>::VectorType* const force;
Resource<ForceRendererOptions> options;
Resource<AbstractShaderProgram, Shaders::FlatShader<dimensions>> shader;
Resource<AbstractShaderProgram, Shaders::Flat<dimensions>> shader;
Resource<Mesh> mesh;
Resource<Buffer> vertexBuffer, indexBuffer;
};

10
src/DebugTools/Implementation/AbstractShapeRenderer.cpp

@ -29,7 +29,7 @@
#include "Mesh.h"
#include "DebugTools/ResourceManager.h"
#include "MeshTools/CompressIndices.h"
#include "Shaders/FlatShader.h"
#include "Shaders/Flat.h"
#include "Trade/MeshData2D.h"
#include "Trade/MeshData3D.h"
@ -53,7 +53,7 @@ template<> void create<2>(Trade::MeshData2D& data, Resource<Mesh>& meshResource,
Mesh* mesh = new Mesh;
mesh->setPrimitive(data.primitive())
->setVertexCount(data.positions(0)->size())
->addVertexBuffer(buffer, 0, Shaders::FlatShader2D::Position());
->addVertexBuffer(buffer, 0, Shaders::Flat2D::Position());
ResourceManager::instance()->set(meshResource.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual);
/* Index buffer, if needed, if not, resource key doesn't have to be set */
@ -75,7 +75,7 @@ template<> void create<3>(Trade::MeshData3D& data, Resource<Mesh>& meshResource,
Mesh* mesh = new Mesh;
mesh->setPrimitive(data.primitive())
->setVertexCount(data.positions(0)->size())
->addVertexBuffer(vertexBuffer, 0, Shaders::FlatShader3D::Position());
->addVertexBuffer(vertexBuffer, 0, Shaders::Flat3D::Position());
ResourceManager::instance()->set(meshResource.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual);
/* Index buffer, if needed, if not, resource key doesn't have to be set */
@ -90,13 +90,13 @@ template<> void create<3>(Trade::MeshData3D& data, Resource<Mesh>& meshResource,
}
template<UnsignedInt dimensions> AbstractShapeRenderer<dimensions>::AbstractShapeRenderer(ResourceKey meshKey, ResourceKey vertexBufferKey, ResourceKey indexBufferKey) {
wireframeShader = ResourceManager::instance()->get<AbstractShaderProgram, Shaders::FlatShader<dimensions>>(shaderKey<dimensions>());
wireframeShader = ResourceManager::instance()->get<AbstractShaderProgram, Shaders::Flat<dimensions>>(shaderKey<dimensions>());
wireframeMesh = ResourceManager::instance()->get<Mesh>(meshKey);
vertexBuffer = ResourceManager::instance()->get<Buffer>(vertexBufferKey);
indexBuffer = ResourceManager::instance()->get<Buffer>(indexBufferKey);
if(!wireframeShader) ResourceManager::instance()->set<AbstractShaderProgram>(shaderKey<dimensions>(),
new Shaders::FlatShader<dimensions>, ResourceDataState::Final, ResourcePolicy::Resident);
new Shaders::Flat<dimensions>, ResourceDataState::Final, ResourcePolicy::Resident);
}
template<UnsignedInt dimensions> AbstractShapeRenderer<dimensions>::~AbstractShapeRenderer() {}

12
src/DebugTools/Implementation/AbstractShapeRenderer.h

@ -31,9 +31,15 @@
#include "Shaders/Shaders.h"
#include "Trade/Trade.h"
namespace Magnum { namespace DebugTools { namespace Implementation {
namespace Magnum {
template<UnsignedInt dimensions> struct MeshData;
namespace Shapes { namespace Implementation {
template<UnsignedInt> struct AbstractShape;
}}
namespace DebugTools { namespace Implementation {
template<UnsignedInt> struct MeshData;
template<> struct MeshData<2> { typedef Trade::MeshData2D Type; };
template<> struct MeshData<3> { typedef Trade::MeshData3D Type; };
@ -49,7 +55,7 @@ template<UnsignedInt dimensions> class AbstractShapeRenderer {
/* Call only if the mesh resource isn't already present */
void createResources(typename MeshData<dimensions>::Type data);
Resource<AbstractShaderProgram, Shaders::FlatShader<dimensions>> wireframeShader;
Resource<AbstractShaderProgram, Shaders::Flat<dimensions>> wireframeShader;
Resource<Mesh> wireframeMesh;
private:

10
src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp

@ -26,17 +26,17 @@
#include "Mesh.h"
#include "DebugTools/ShapeRenderer.h"
#include "Physics/AxisAlignedBox.h"
#include "Shaders/FlatShader.h"
#include "Shapes/AxisAlignedBox.h"
#include "Shaders/Flat.h"
namespace Magnum { namespace DebugTools { namespace Implementation {
template<UnsignedInt dimensions> AxisAlignedBoxRenderer<dimensions>::AxisAlignedBoxRenderer(Physics::AxisAlignedBox<dimensions>& axisAlignedBox): axisAlignedBox(axisAlignedBox) {}
template<UnsignedInt dimensions> AxisAlignedBoxRenderer<dimensions>::AxisAlignedBoxRenderer(const Shapes::Implementation::AbstractShape<dimensions>* axisAlignedBox): axisAlignedBox(static_cast<const Shapes::Implementation::Shape<Shapes::AxisAlignedBox<dimensions>>*>(axisAlignedBox)->shape) {}
template<UnsignedInt dimensions> void AxisAlignedBoxRenderer<dimensions>::draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions>::MatrixType& projectionMatrix) {
this->wireframeShader->setTransformationProjectionMatrix(projectionMatrix*
DimensionTraits<dimensions>::MatrixType::translation((axisAlignedBox.transformedMin()+axisAlignedBox.transformedMax())/2)*
DimensionTraits<dimensions>::MatrixType::scaling(axisAlignedBox.transformedMax()-axisAlignedBox.transformedMin()))
DimensionTraits<dimensions>::MatrixType::translation((axisAlignedBox.min()+axisAlignedBox.max())/2)*
DimensionTraits<dimensions>::MatrixType::scaling(axisAlignedBox.max()-axisAlignedBox.min()))
->setColor(options->color())
->use();
this->wireframeMesh->draw();

6
src/DebugTools/Implementation/AxisAlignedBoxRenderer.h

@ -26,7 +26,7 @@
#include "AbstractBoxRenderer.h"
#include "Physics/Physics.h"
#include "Shapes/Shapes.h"
#include "corradeCompatibility.h"
@ -34,12 +34,12 @@ namespace Magnum { namespace DebugTools { namespace Implementation {
template<UnsignedInt dimensions> class AxisAlignedBoxRenderer: public AbstractBoxRenderer<dimensions> {
public:
AxisAlignedBoxRenderer(Physics::AxisAlignedBox<dimensions>& axisAlignedBox);
AxisAlignedBoxRenderer(const Shapes::Implementation::AbstractShape<dimensions>* axisAlignedBox);
void draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions>::MatrixType& projectionMatrix) override;
private:
Physics::AxisAlignedBox<dimensions>& axisAlignedBox;
const Shapes::AxisAlignedBox<dimensions>& axisAlignedBox;
};
}}}

8
src/DebugTools/Implementation/BoxRenderer.cpp

@ -26,15 +26,15 @@
#include "Mesh.h"
#include "DebugTools/ShapeRenderer.h"
#include "Physics/Box.h"
#include "Shaders/FlatShader.h"
#include "Shapes/Box.h"
#include "Shaders/Flat.h"
namespace Magnum { namespace DebugTools { namespace Implementation {
template<UnsignedInt dimensions> BoxRenderer<dimensions>::BoxRenderer(Physics::Box<dimensions>& box): box(box) {}
template<UnsignedInt dimensions> BoxRenderer<dimensions>::BoxRenderer(const Shapes::Implementation::AbstractShape<dimensions>* box): box(static_cast<const Shapes::Implementation::Shape<Shapes::Box<dimensions>>*>(box)->shape) {}
template<UnsignedInt dimensions> void BoxRenderer<dimensions>::draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions>::MatrixType& projectionMatrix) {
this->wireframeShader->setTransformationProjectionMatrix(projectionMatrix*box.transformedTransformation())
this->wireframeShader->setTransformationProjectionMatrix(projectionMatrix*box.transformation())
->setColor(options->color())
->use();
this->wireframeMesh->draw();

6
src/DebugTools/Implementation/BoxRenderer.h

@ -26,7 +26,7 @@
#include "AbstractBoxRenderer.h"
#include "Physics/Physics.h"
#include "Shapes/Shapes.h"
#include "corradeCompatibility.h"
@ -34,12 +34,12 @@ namespace Magnum { namespace DebugTools { namespace Implementation {
template<UnsignedInt dimensions> class BoxRenderer: public AbstractBoxRenderer<dimensions> {
public:
BoxRenderer(Physics::Box<dimensions>& box);
BoxRenderer(const Shapes::Implementation::AbstractShape<dimensions>* box);
void draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions>::MatrixType& projectionMatrix) override;
private:
Physics::Box<dimensions>& box;
const Shapes::Box<dimensions>& box;
};
}}}

2
src/DebugTools/Implementation/ForceRendererTransformation.h

@ -37,7 +37,7 @@ template<> inline Matrix3 forceRendererTransformation<2>(const Vector2& forcePos
return Matrix3::from({force, Vector2(-force.y(), force.x())}, forcePosition);
}
template<> inline Matrix4 forceRendererTransformation<3>(const Vector3& forcePosition, const Vector3& force) {
template<> Matrix4 forceRendererTransformation<3>(const Vector3& forcePosition, const Vector3& force) {
const Matrix4 translation = Matrix4::translation(forcePosition);
const Float forceLength = force.length();

8
src/DebugTools/Implementation/LineSegmentRenderer.cpp

@ -26,9 +26,9 @@
#include "Mesh.h"
#include "DebugTools/ShapeRenderer.h"
#include "Physics/Line.h"
#include "Shapes/LineSegment.h"
#include "Primitives/Line.h"
#include "Shaders/FlatShader.h"
#include "Shaders/Flat.h"
#include "Trade/MeshData2D.h"
#include "Trade/MeshData3D.h"
@ -50,13 +50,13 @@ namespace {
template<> inline Trade::MeshData3D meshData<3>() { return Primitives::Line3D::wireframe(); }
}
template<UnsignedInt dimensions> LineSegmentRenderer<dimensions>::LineSegmentRenderer(Physics::Line<dimensions>& line): AbstractShapeRenderer<dimensions>(meshKey<dimensions>(), vertexBufferKey<dimensions>(), {}), line(line) {
template<UnsignedInt dimensions> LineSegmentRenderer<dimensions>::LineSegmentRenderer(const Shapes::Implementation::AbstractShape<dimensions>* line): AbstractShapeRenderer<dimensions>(meshKey<dimensions>(), vertexBufferKey<dimensions>(), {}), line(static_cast<const Shapes::Implementation::Shape<Shapes::LineSegment<dimensions>>*>(line)->shape) {
if(!this->wireframeMesh) this->createResources(meshData<dimensions>());
}
template<UnsignedInt dimensions> void LineSegmentRenderer<dimensions>::draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions>::MatrixType& projectionMatrix) {
this->wireframeShader->setTransformationProjectionMatrix(projectionMatrix*
Implementation::lineSegmentRendererTransformation<dimensions>(line.transformedA(), line.transformedB()))
Implementation::lineSegmentRendererTransformation<dimensions>(line.a(), line.b()))
->setColor(options->color())
->use();
this->wireframeMesh->draw();

6
src/DebugTools/Implementation/LineSegmentRenderer.h

@ -26,7 +26,7 @@
#include "AbstractShapeRenderer.h"
#include "Physics/Physics.h"
#include "Shapes/Shapes.h"
#include "corradeCompatibility.h"
@ -34,12 +34,12 @@ namespace Magnum { namespace DebugTools { namespace Implementation {
template<UnsignedInt dimensions> class LineSegmentRenderer: public AbstractShapeRenderer<dimensions> {
public:
LineSegmentRenderer(Physics::Line<dimensions>& line);
LineSegmentRenderer(const Shapes::Implementation::AbstractShape<dimensions>* line);
void draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions>::MatrixType& projectionMatrix) override;
private:
Physics::Line<dimensions>& line;
const Shapes::LineSegment<dimensions>& line;
};
}}}

8
src/DebugTools/Implementation/PointRenderer.cpp

@ -26,9 +26,9 @@
#include "Mesh.h"
#include "DebugTools/ShapeRenderer.h"
#include "Physics/Point.h"
#include "Shapes/Point.h"
#include "Primitives/Crosshair.h"
#include "Shaders/FlatShader.h"
#include "Shaders/Flat.h"
#include "Trade/MeshData2D.h"
#include "Trade/MeshData3D.h"
@ -48,14 +48,14 @@ namespace {
template<> inline Trade::MeshData3D meshData<3>() { return Primitives::Crosshair3D::wireframe(); }
}
template<UnsignedInt dimensions> PointRenderer<dimensions>::PointRenderer(Physics::Point<dimensions>& point): AbstractShapeRenderer<dimensions>(meshKey<dimensions>(), vertexBufferKey<dimensions>(), {}), point(point) {
template<UnsignedInt dimensions> PointRenderer<dimensions>::PointRenderer(const Shapes::Implementation::AbstractShape<dimensions>* point): AbstractShapeRenderer<dimensions>(meshKey<dimensions>(), vertexBufferKey<dimensions>(), {}), point(static_cast<const Shapes::Implementation::Shape<Shapes::Point<dimensions>>*>(point)->shape) {
if(!this->wireframeMesh) this->createResources(meshData<dimensions>());
}
template<UnsignedInt dimensions> void PointRenderer<dimensions>::draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions>::MatrixType& projectionMatrix) {
/* Half scale, because the point is 2x2(x2) */
this->wireframeShader->setTransformationProjectionMatrix(projectionMatrix*
DimensionTraits<dimensions>::MatrixType::translation(point.transformedPosition())*
DimensionTraits<dimensions>::MatrixType::translation(point.position())*
DimensionTraits<dimensions>::MatrixType::scaling(typename DimensionTraits<dimensions>::VectorType(options->pointSize()/2)))
->setColor(options->color())
->use();

6
src/DebugTools/Implementation/PointRenderer.h

@ -26,7 +26,7 @@
#include "AbstractShapeRenderer.h"
#include "Physics/Physics.h"
#include "Shapes/Shapes.h"
#include "corradeCompatibility.h"
@ -34,12 +34,12 @@ namespace Magnum { namespace DebugTools { namespace Implementation {
template<UnsignedInt dimensions> class PointRenderer: public AbstractShapeRenderer<dimensions> {
public:
PointRenderer(Physics::Point<dimensions>& point);
PointRenderer(const Shapes::Implementation::AbstractShape<dimensions>* point);
void draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions>::MatrixType& projectionMatrix) override;
private:
Physics::Point<dimensions>& point;
const Shapes::Point<dimensions>& point;
};
}}}

10
src/DebugTools/Implementation/SphereRenderer.cpp

@ -26,9 +26,9 @@
#include "Mesh.h"
#include "DebugTools/ShapeRenderer.h"
#include "Physics/Sphere.h"
#include "Shapes/Sphere.h"
#include "Primitives/Circle.h"
#include "Shaders/FlatShader.h"
#include "Shaders/Flat.h"
#include "Trade/MeshData2D.h"
namespace Magnum { namespace DebugTools { namespace Implementation {
@ -37,12 +37,12 @@ AbstractSphereRenderer<2>::AbstractSphereRenderer(): AbstractShapeRenderer<2>("s
if(!wireframeMesh) createResources(Primitives::Circle::wireframe(40));
}
template<UnsignedInt dimensions> SphereRenderer<dimensions>::SphereRenderer(Physics::Sphere<dimensions>& sphere): sphere(sphere) {}
template<UnsignedInt dimensions> SphereRenderer<dimensions>::SphereRenderer(const Shapes::Implementation::AbstractShape<dimensions>* sphere): sphere(static_cast<const Shapes::Implementation::Shape<Shapes::Sphere<dimensions>>*>(sphere)->shape) {}
template<UnsignedInt dimensions> void SphereRenderer<dimensions>::draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions>::MatrixType& projectionMatrix) {
this->wireframeShader->setTransformationProjectionMatrix(projectionMatrix*
DimensionTraits<dimensions>::MatrixType::translation(sphere.transformedPosition())*
DimensionTraits<dimensions>::MatrixType::scaling(typename DimensionTraits<dimensions>::VectorType(sphere.transformedRadius())))
DimensionTraits<dimensions>::MatrixType::translation(sphere.position())*
DimensionTraits<dimensions>::MatrixType::scaling(typename DimensionTraits<dimensions>::VectorType(sphere.radius())))
->setColor(options->color())
->use();
this->wireframeMesh->draw();

6
src/DebugTools/Implementation/SphereRenderer.h

@ -26,7 +26,7 @@
#include "AbstractShapeRenderer.h"
#include "Physics/Physics.h"
#include "Shapes/Shapes.h"
#include "corradeCompatibility.h"
@ -41,12 +41,12 @@ template<> class AbstractSphereRenderer<2>: public AbstractShapeRenderer<2> {
template<UnsignedInt dimensions> class SphereRenderer: public AbstractSphereRenderer<dimensions> {
public:
SphereRenderer(Physics::Sphere<dimensions>& sphere);
SphereRenderer(const Shapes::Implementation::AbstractShape<dimensions>* sphere);
void draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions>::MatrixType& projectionMatrix) override;
private:
Physics::Sphere<dimensions>& sphere;
const Shapes::Sphere<dimensions>& sphere;
};
}}}

26
src/DebugTools/ObjectRenderer.cpp

@ -28,7 +28,7 @@
#include "DebugTools/ResourceManager.h"
#include "MeshTools/Interleave.h"
#include "SceneGraph/AbstractCamera.h"
#include "Shaders/VertexColorShader.h"
#include "Shaders/VertexColor.h"
namespace Magnum { namespace DebugTools {
@ -37,10 +37,10 @@ namespace {
template<UnsignedInt> struct Renderer;
template<> struct Renderer<2> {
inline static ResourceKey shader() { return {"VertexColorShader2D"}; }
inline static ResourceKey vertexBuffer() { return {"object2d-vertices"}; }
inline static ResourceKey indexBuffer() { return {"object2d-indices"}; }
inline static ResourceKey mesh() { return {"object2d"}; }
static ResourceKey shader() { return {"VertexColorShader2D"}; }
static ResourceKey vertexBuffer() { return {"object2d-vertices"}; }
static ResourceKey indexBuffer() { return {"object2d-indices"}; }
static ResourceKey mesh() { return {"object2d"}; }
static const std::array<Vector2, 8> positions;
static const std::array<Color3<>, 8> colors;
@ -82,10 +82,10 @@ const std::array<UnsignedByte, 12> Renderer<2>::indices{{
}};
template<> struct Renderer<3> {
inline static ResourceKey shader() { return {"VertexColorShader3D"}; }
inline static ResourceKey vertexBuffer() { return {"object3d-vertices"}; }
inline static ResourceKey indexBuffer() { return {"object3d-indices"}; }
inline static ResourceKey mesh() { return {"object3d"}; }
static ResourceKey shader() { return {"VertexColorShader3D"}; }
static ResourceKey vertexBuffer() { return {"object3d-vertices"}; }
static ResourceKey indexBuffer() { return {"object3d-indices"}; }
static ResourceKey mesh() { return {"object3d"}; }
static const std::array<Vector3, 12> positions;
static const std::array<Color3<>, 12> colors;
@ -144,8 +144,8 @@ const std::array<UnsignedByte, 18> Renderer<3>::indices{{
template<UnsignedInt dimensions> ObjectRenderer<dimensions>::ObjectRenderer(SceneGraph::AbstractObject<dimensions>* object, ResourceKey options, SceneGraph::DrawableGroup<dimensions>* drawables): SceneGraph::Drawable<dimensions>(object, drawables), options(ResourceManager::instance()->get<ObjectRendererOptions>(options)) {
/* Shader */
shader = ResourceManager::instance()->get<AbstractShaderProgram, Shaders::VertexColorShader<dimensions>>(Renderer<dimensions>::shader());
if(!shader) ResourceManager::instance()->set<AbstractShaderProgram>(shader.key(), new Shaders::VertexColorShader<dimensions>);
shader = ResourceManager::instance()->get<AbstractShaderProgram, Shaders::VertexColor<dimensions>>(Renderer<dimensions>::shader());
if(!shader) ResourceManager::instance()->set<AbstractShaderProgram>(shader.key(), new Shaders::VertexColor<dimensions>);
/* Mesh and vertex buffer */
mesh = ResourceManager::instance()->get<Mesh>(Renderer<dimensions>::mesh());
@ -167,8 +167,8 @@ template<UnsignedInt dimensions> ObjectRenderer<dimensions>::ObjectRenderer(Scen
mesh->setPrimitive(Mesh::Primitive::Lines)
->setIndexCount(Renderer<dimensions>::indices.size())
->addInterleavedVertexBuffer(vertexBuffer, 0,
typename Shaders::VertexColorShader<dimensions>::Position(),
typename Shaders::VertexColorShader<dimensions>::Color())
typename Shaders::VertexColor<dimensions>::Position(),
typename Shaders::VertexColor<dimensions>::Color())
->setIndexBuffer(indexBuffer, 0, Mesh::IndexType::UnsignedByte, 0, Renderer<dimensions>::positions.size());
ResourceManager::instance()->set<Mesh>(this->mesh.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual);
}

8
src/DebugTools/ObjectRenderer.h

@ -43,10 +43,10 @@ See ObjectRenderer documentation for more information.
*/
class ObjectRendererOptions {
public:
inline constexpr ObjectRendererOptions(): _size(1.0f) {}
constexpr ObjectRendererOptions(): _size(1.0f) {}
/** @brief Size of the rendered axes */
inline constexpr Float size() const { return _size; }
constexpr Float size() const { return _size; }
/**
* @brief Set size of the rendered axes
@ -54,7 +54,7 @@ class ObjectRendererOptions {
*
* Default is `1.0f`.
*/
inline ObjectRendererOptions* setSize(Float size) {
ObjectRendererOptions* setSize(Float size) {
_size = size;
return this;
}
@ -104,7 +104,7 @@ template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ObjectRenderer:
private:
Resource<ObjectRendererOptions> options;
Resource<AbstractShaderProgram, Shaders::VertexColorShader<dimensions>> shader;
Resource<AbstractShaderProgram, Shaders::VertexColor<dimensions>> shader;
Resource<Mesh> mesh;
Resource<Buffer> vertexBuffer, indexBuffer;
};

4
src/DebugTools/Profiler.h

@ -115,9 +115,7 @@ class MAGNUM_DEBUGTOOLS_EXPORT Profiler {
*/
static const Section otherSection = 0;
#ifndef DOXYGEN_GENERATING_OUTPUT
explicit Profiler(): enabled(false), measureDuration(60), currentFrame(0), frameCount(0), sections{"Other"}, currentSection(otherSection) {}
#endif
/**
* @brief Set measure duration
@ -174,7 +172,7 @@ class MAGNUM_DEBUGTOOLS_EXPORT Profiler {
* Same as calling `start(Profiler::otherSection)`.
* @note Does nothing if profiling is disabled.
*/
inline void start() { start(otherSection); }
void start() { start(otherSection); }
/**
* @brief Stop profiling

2
src/DebugTools/ResourceManager.h

@ -36,7 +36,7 @@
#include "../ResourceManager.h"
#include "SceneGraph/SceneGraph.h"
#include "Physics/Physics.h"
#include "Shapes/Shapes.h"
#include "DebugTools.h"
#include "magnumDebugToolsVisibility.h"

75
src/DebugTools/ShapeRenderer.cpp

@ -25,14 +25,8 @@
#include "ShapeRenderer.h"
#include "ResourceManager.h"
#include "Physics/AbstractShape.h"
#include "Physics/AxisAlignedBox.h"
#include "Physics/Box.h"
#include "Physics/ObjectShape.h"
#include "Physics/LineSegment.h"
#include "Physics/Point.h"
#include "Physics/ShapeGroup.h"
#include "Physics/Sphere.h"
#include "Shapes/Composition.h"
#include "Shapes/Shape.h"
#include "SceneGraph/AbstractCamera.h"
#include "Implementation/AxisAlignedBoxRenderer.h"
@ -43,54 +37,55 @@
namespace Magnum { namespace DebugTools {
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
template<> void createDebugMesh(ShapeRenderer<2>* renderer, Physics::AbstractShape<2>* shape) {
template<> void createDebugMesh(ShapeRenderer<2>* renderer, const Shapes::Implementation::AbstractShape<2>* shape) {
switch(shape->type()) {
case Physics::AbstractShape2D::Type::AxisAlignedBox:
renderer->renderers.push_back(new Implementation::AxisAlignedBoxRenderer<2>(*static_cast<Physics::AxisAlignedBox2D*>(shape)));
case Shapes::AbstractShape2D::Type::AxisAlignedBox:
renderer->renderers.push_back(new Implementation::AxisAlignedBoxRenderer<2>(shape));
break;
case Physics::AbstractShape2D::Type::Box:
renderer->renderers.push_back(new Implementation::BoxRenderer<2>(*static_cast<Physics::Box2D*>(shape)));
case Shapes::AbstractShape2D::Type::Box:
renderer->renderers.push_back(new Implementation::BoxRenderer<2>(shape));
break;
case Physics::AbstractShape2D::Type::LineSegment:
renderer->renderers.push_back(new Implementation::LineSegmentRenderer<2>(*static_cast<Physics::LineSegment2D*>(shape)));
case Shapes::AbstractShape2D::Type::LineSegment:
renderer->renderers.push_back(new Implementation::LineSegmentRenderer<2>(shape));
break;
case Physics::AbstractShape2D::Type::Point:
renderer->renderers.push_back(new Implementation::PointRenderer<2>(*static_cast<Physics::Point2D*>(shape)));
case Shapes::AbstractShape2D::Type::Point:
renderer->renderers.push_back(new Implementation::PointRenderer<2>(shape));
break;
case Physics::AbstractShape2D::Type::ShapeGroup: {
Physics::ShapeGroup2D* group = static_cast<Physics::ShapeGroup2D*>(shape);
if(group->first()) createDebugMesh(renderer, group->first());
if(group->second()) createDebugMesh(renderer, group->second());
case Shapes::AbstractShape2D::Type::Composition: {
const Shapes::Composition2D& composition =
static_cast<const Shapes::Implementation::Shape<Shapes::Composition2D>*>(shape)->shape;
for(std::size_t i = 0; i != composition.size(); ++i)
createDebugMesh(renderer, Shapes::Implementation::getAbstractShape(composition, i));
} break;
case Physics::AbstractShape2D::Type::Sphere:
renderer->renderers.push_back(new Implementation::SphereRenderer<2>(*static_cast<Physics::Sphere2D*>(shape)));
case Shapes::AbstractShape2D::Type::Sphere:
renderer->renderers.push_back(new Implementation::SphereRenderer<2>(shape));
break;
default:
Warning() << "DebugTools::ShapeRenderer2D::createShapeRenderer(): type" << shape->type() << "not implemented";
}
}
template<> void createDebugMesh(ShapeRenderer<3>* renderer, Physics::AbstractShape<3>* shape) {
template<> void createDebugMesh(ShapeRenderer<3>* renderer, const Shapes::Implementation::AbstractShape<3>* shape) {
switch(shape->type()) {
case Physics::AbstractShape3D::Type::AxisAlignedBox:
renderer->renderers.push_back(new Implementation::AxisAlignedBoxRenderer<3>(*static_cast<Physics::AxisAlignedBox3D*>(shape)));
case Shapes::AbstractShape3D::Type::AxisAlignedBox:
renderer->renderers.push_back(new Implementation::AxisAlignedBoxRenderer<3>(shape));
break;
case Physics::AbstractShape3D::Type::Box:
renderer->renderers.push_back(new Implementation::BoxRenderer<3>(*static_cast<Physics::Box3D*>(shape)));
case Shapes::AbstractShape3D::Type::Box:
renderer->renderers.push_back(new Implementation::BoxRenderer<3>(shape));
break;
case Physics::AbstractShape3D::Type::LineSegment:
renderer->renderers.push_back(new Implementation::LineSegmentRenderer<3>(*static_cast<Physics::LineSegment3D*>(shape)));
case Shapes::AbstractShape3D::Type::LineSegment:
renderer->renderers.push_back(new Implementation::LineSegmentRenderer<3>(shape));
break;
case Physics::AbstractShape3D::Type::Point:
renderer->renderers.push_back(new Implementation::PointRenderer<3>(*static_cast<Physics::Point3D*>(shape)));
case Shapes::AbstractShape3D::Type::Point:
renderer->renderers.push_back(new Implementation::PointRenderer<3>(shape));
break;
case Physics::AbstractShape3D::Type::ShapeGroup: {
Physics::ShapeGroup3D* group = static_cast<Physics::ShapeGroup3D*>(shape);
if(group->first()) createDebugMesh(renderer, group->first());
if(group->second()) createDebugMesh(renderer, group->second());
case Shapes::AbstractShape3D::Type::Composition: {
const Shapes::Composition3D& composition =
static_cast<const Shapes::Implementation::Shape<Shapes::Composition3D>*>(shape)->shape;
for(std::size_t i = 0; i != composition.size(); ++i)
createDebugMesh(renderer, Shapes::Implementation::getAbstractShape(composition, i));
} break;
default:
Warning() << "DebugTools::ShapeRenderer3D::createShapeRenderer(): type" << shape->type() << "not implemented";
@ -98,11 +93,9 @@ template<> void createDebugMesh(ShapeRenderer<3>* renderer, Physics::AbstractSha
}
}
#endif
template<UnsignedInt dimensions> ShapeRenderer<dimensions>::ShapeRenderer(Physics::ObjectShape<dimensions>* shape, ResourceKey options, SceneGraph::DrawableGroup<dimensions>* drawables): SceneGraph::Drawable<dimensions>(shape->object(), drawables), options(ResourceManager::instance()->get<ShapeRendererOptions>(options)) {
CORRADE_ASSERT(shape->shape() != nullptr, "DebugTools::ShapeRenderer: cannot create renderer for empty shape", );
Implementation::createDebugMesh(this, shape->shape());
template<UnsignedInt dimensions> ShapeRenderer<dimensions>::ShapeRenderer(Shapes::AbstractShape<dimensions>* shape, ResourceKey options, SceneGraph::DrawableGroup<dimensions>* drawables): SceneGraph::Drawable<dimensions>(shape->object(), drawables), options(ResourceManager::instance()->get<ShapeRendererOptions>(options)) {
Implementation::createDebugMesh(this, Shapes::Implementation::getAbstractShape(shape));
}
template<UnsignedInt dimensions> ShapeRenderer<dimensions>::~ShapeRenderer() {

38
src/DebugTools/ShapeRenderer.h

@ -31,7 +31,8 @@
#include "Color.h"
#include "Resource.h"
#include "SceneGraph/Drawable.h"
#include "Physics/Physics.h"
#include "Shapes/Shapes.h"
#include "Shapes/shapeImplementation.h"
#include "magnumDebugToolsVisibility.h"
@ -42,13 +43,11 @@ namespace Magnum { namespace DebugTools {
template<UnsignedInt> class ShapeRenderer;
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
template<UnsignedInt> class AbstractShapeRenderer;
template<UnsignedInt dimensions> void createDebugMesh(ShapeRenderer<dimensions>* renderer, Physics::AbstractShape<dimensions>* shape);
template<UnsignedInt dimensions> void createDebugMesh(ShapeRenderer<dimensions>* renderer, const Shapes::Implementation::AbstractShape<dimensions>* shape);
}
#endif
/**
@brief Shape renderer options
@ -67,10 +66,10 @@ class ShapeRendererOptions {
Solid
};
inline constexpr ShapeRendererOptions(): _color(1.0f), _pointSize(0.25f), _renderMode(RenderMode::Wireframe) {}
constexpr ShapeRendererOptions(): _color(1.0f), _pointSize(0.25f), _renderMode(RenderMode::Wireframe) {}
/** @brief Shape rendering mode */
inline constexpr RenderMode renderMode() const { return _renderMode; }
constexpr RenderMode renderMode() const { return _renderMode; }
/**
* @brief Set shape rendering mode
@ -78,13 +77,13 @@ class ShapeRendererOptions {
*
* Default is @ref RenderMode "RenderMode::Wireframe".
*/
inline ShapeRendererOptions* setRenderMode(RenderMode mode) {
ShapeRendererOptions* setRenderMode(RenderMode mode) {
_renderMode = mode;
return this;
}
/** @brief Color of rendered shape */
inline constexpr Color4<> color() const { return _color; }
constexpr Color4<> color() const { return _color; }
/**
* @brief Set color of rendered shape
@ -92,22 +91,22 @@ class ShapeRendererOptions {
*
* Default is 100% opaque white.
*/
inline ShapeRendererOptions* setColor(const Color4<>& color) {
ShapeRendererOptions* setColor(const Color4<>& color) {
_color = color;
return this;
}
/** @brief Point size */
inline constexpr Float pointSize() const { return _pointSize; }
constexpr Float pointSize() const { return _pointSize; }
/**
* @brief Set point size
* @return Pointer to self (for method chaining)
*
* Size of rendered crosshairs, representing Physics::Point shapes.
* Size of rendered crosshairs, representing Shapes::Point shapes.
* Default is `0.25f`.
*/
inline ShapeRendererOptions* setPointSize(Float size) {
ShapeRendererOptions* setPointSize(Float size) {
_pointSize = size;
return this;
}
@ -133,32 +132,29 @@ DebugTools::ResourceManager::instance()->set("red", (new DebugTools::ShapeRender
->setColor({1.0f, 0.0f, 0.0f}));
// Create debug renderer for given shape, use "red" options for it
Physics::ObjectShape2D* shape;
Shapes::AbstractShape2D* shape;
new DebugTools::ShapeRenderer2D(shape, "red", debugDrawables);
@endcode
@see ShapeRenderer2D, ShapeRenderer3D
*/
template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ShapeRenderer: public SceneGraph::Drawable<dimensions> {
#ifndef DOXYGEN_GENERATING_OUTPUT
friend void Implementation::createDebugMesh<>(ShapeRenderer<dimensions>*, Physics::AbstractShape<dimensions>*);
#endif
friend void Implementation::createDebugMesh<>(ShapeRenderer<dimensions>*, const Shapes::Implementation::AbstractShape<dimensions>*);
public:
/**
* @brief Constructor
* @param shape Object for which to create debug renderer
* @param shape Shape for which to create debug renderer
* @param options Options resource key. See
* @ref ShapeRenderer-usage "class documentation" for more
* information.
* @param drawables Drawable group
*
* The renderer is automatically added to shape's object features,
* @p shape must be available for the whole lifetime of the renderer.
*
* @attention Passed object must have assigned shape.
* @p shape must be available for the whole lifetime of the renderer
* and if it is group, it must not change its internal structure.
*/
explicit ShapeRenderer(Physics::ObjectShape<dimensions>* shape, ResourceKey options = ResourceKey(), SceneGraph::DrawableGroup<dimensions>* drawables = nullptr);
explicit ShapeRenderer(Shapes::AbstractShape<dimensions>* shape, ResourceKey options = ResourceKey(), SceneGraph::DrawableGroup<dimensions>* drawables = nullptr);
~ShapeRenderer();

2
src/DebugTools/Test/ForceRendererTest.cpp

@ -28,7 +28,7 @@
namespace Magnum { namespace DebugTools { namespace Implementation { namespace Test {
class ForceRendererTest: public Corrade::TestSuite::Tester {
class ForceRendererTest: public TestSuite::Tester {
public:
explicit ForceRendererTest();

2
src/DebugTools/Test/LineSegmentRendererTest.cpp

@ -31,7 +31,7 @@
namespace Magnum { namespace DebugTools { namespace Test {
class LineSegmentRendererTest: public Corrade::TestSuite::Tester {
class LineSegmentRendererTest: public TestSuite::Tester {
public:
explicit LineSegmentRendererTest();

6
src/DefaultFramebuffer.h

@ -311,7 +311,7 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* @requires_gles30 Draw attachments for default framebuffer are
* available only in OpenGL ES 3.0.
*/
inline DefaultFramebuffer* mapForDraw(DrawAttachment attachment) {
DefaultFramebuffer* mapForDraw(DrawAttachment attachment) {
(this->*drawBufferImplementation)(static_cast<GLenum>(attachment));
return this;
}
@ -329,7 +329,7 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access}
* @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer}
*/
inline DefaultFramebuffer* mapForRead(ReadAttachment attachment) {
DefaultFramebuffer* mapForRead(ReadAttachment attachment) {
(this->*readBufferImplementation)(static_cast<GLenum>(attachment));
return this;
}
@ -367,7 +367,7 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
inline DefaultFramebuffer* setViewport(const Rectanglei& rectangle) {
DefaultFramebuffer* setViewport(const Rectanglei& rectangle) {
AbstractFramebuffer::setViewport(rectangle);
return this;
}

6
src/Extensions.h

@ -120,6 +120,7 @@ namespace GL {
_extension(GL,ARB,shader_precision, GL400, GL410) // #98
_extension(GL,ARB,vertex_attrib_64bit, GL300, GL410) // #99
_extension(GL,ARB,viewport_array, GL210, GL410) // #100
_extension(GL,ARB,robustness, GL210, None) // #105
_extension(GL,ARB,base_instance, GL210, GL420) // #107
_extension(GL,ARB,shading_language_420pack, GL300, GL420) // #108
_extension(GL,ARB,transform_feedback_instanced, GL210, GL420) // #109
@ -186,6 +187,7 @@ namespace GL {
#line 1
namespace ANGLE {
_extension(GL,ANGLE,framebuffer_blit, GLES200, GLES300) // #83
_extension(GL,ANGLE,framebuffer_multisample, GLES200, GLES300) // #84
_extension(GL,ANGLE,depth_texture, GLES200, GLES300) // #138
} namespace APPLE {
_extension(GL,APPLE,framebuffer_multisample, GLES200, GLES300) // #78
@ -204,8 +206,10 @@ namespace GL {
_extension(GL,EXT,separate_shader_objects, GLES200, None) // #101
_extension(GL,EXT,texture_rg, GLES200, GLES300) // #103
_extension(GL,EXT,sRGB, GLES200, None) // #105
_extension(GL,EXT,robustness, GLES200, None) // #105
_extension(GL,EXT,texture_storage, GLES200, GLES300) // #108
_extension(GL,EXT,map_buffer_range, GLES200, GLES300) // #121
_extension(GL,EXT,disjoint_timer_query, GLES200, None) // #150
} namespace NV {
_extension(GL,NV,draw_buffers, GLES200, GLES300) // #91
_extension(GL,NV,read_buffer, GLES200, GLES300) // #93
@ -214,6 +218,7 @@ namespace GL {
_extension(GL,NV,read_stencil, GLES200, None) // #94
_extension(GL,NV,read_depth_stencil, GLES200, GLES300) // #94
_extension(GL,NV,framebuffer_blit, GLES200, GLES300) // #142
_extension(GL,NV,framebuffer_multisample, GLES200, GLES300) // #143
_extension(GL,NV,texture_border_clamp, GLES200, None) // #149
} namespace OES {
_extension(GL,OES,depth24, GLES200, GLES300) // #24
@ -231,6 +236,7 @@ namespace GL {
_extension(GL,OES,vertex_half_float, GLES200, GLES300) // #38
_extension(GL,OES,packed_depth_stencil, GLES200, GLES300) // #43
_extension(GL,OES,depth_texture, GLES200, GLES300) // #44
_extension(GL,OES,standard_derivatives, GLES200, GLES300) // #45
_extension(GL,OES,vertex_array_object, GLES200, GLES300) // #71
_extension(GL,OES,required_internalformat, GLES200, GLES300) // #?
}

44
src/Framebuffer.h

@ -114,13 +114,13 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @brief Constructor
* @param id Color attachment id
*/
inline constexpr explicit ColorAttachment(UnsignedInt id): attachment(GL_COLOR_ATTACHMENT0 + id) {}
constexpr explicit ColorAttachment(UnsignedInt id): attachment(GL_COLOR_ATTACHMENT0 + id) {}
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef CORRADE_GCC44_COMPATIBILITY
inline constexpr explicit operator GLenum() const { return attachment; }
constexpr explicit operator GLenum() const { return attachment; }
#else
inline constexpr operator GLenum() const { return attachment; }
constexpr operator GLenum() const { return attachment; }
#endif
#endif
@ -139,18 +139,18 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
static const DrawAttachment None;
/** @brief Color attachment */
inline constexpr /*implicit*/ DrawAttachment(Framebuffer::ColorAttachment attachment): attachment(GLenum(attachment)) {}
constexpr /*implicit*/ DrawAttachment(Framebuffer::ColorAttachment attachment): attachment(GLenum(attachment)) {}
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef CORRADE_GCC44_COMPATIBILITY
inline constexpr explicit operator GLenum() const { return attachment; }
constexpr explicit operator GLenum() const { return attachment; }
#else
inline constexpr operator GLenum() const { return attachment; }
constexpr operator GLenum() const { return attachment; }
#endif
#endif
private:
inline constexpr explicit DrawAttachment(GLenum attachment): attachment(attachment) {}
constexpr explicit DrawAttachment(GLenum attachment): attachment(attachment) {}
GLenum attachment;
};
@ -180,18 +180,18 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
#endif
/** @brief Color buffer */
inline constexpr /*implicit*/ BufferAttachment(Framebuffer::ColorAttachment attachment): attachment(GLenum(attachment)) {}
constexpr /*implicit*/ BufferAttachment(Framebuffer::ColorAttachment attachment): attachment(GLenum(attachment)) {}
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef CORRADE_GCC44_COMPATIBILITY
inline constexpr explicit operator GLenum() const { return attachment; }
constexpr explicit operator GLenum() const { return attachment; }
#else
inline constexpr operator GLenum() const { return attachment; }
constexpr operator GLenum() const { return attachment; }
#endif
#endif
private:
inline constexpr explicit BufferAttachment(GLenum attachment): attachment(attachment) {}
constexpr explicit BufferAttachment(GLenum attachment): attachment(attachment) {}
GLenum attachment;
};
@ -212,18 +212,18 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
static const InvalidationAttachment Stencil;
/** @brief Invalidate color buffer */
inline constexpr /*implicit*/ InvalidationAttachment(Framebuffer::ColorAttachment attachment): attachment(GLenum(attachment)) {}
constexpr /*implicit*/ InvalidationAttachment(Framebuffer::ColorAttachment attachment): attachment(GLenum(attachment)) {}
#ifndef DOXYGEN_GENERATING_OUTPUT
#ifndef CORRADE_GCC44_COMPATIBILITY
inline constexpr explicit operator GLenum() const { return attachment; }
constexpr explicit operator GLenum() const { return attachment; }
#else
inline constexpr operator GLenum() const { return attachment; }
constexpr operator GLenum() const { return attachment; }
#endif
#endif
private:
inline constexpr explicit InvalidationAttachment(GLenum attachment): attachment(attachment) {}
constexpr explicit InvalidationAttachment(GLenum attachment): attachment(attachment) {}
GLenum attachment;
};
@ -282,7 +282,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @fn_gl{DrawBuffers} in OpenGL ES 3.0
* @requires_gles30 %Extension @es_extension2{NV,draw_buffers,GL_NV_draw_buffers}
*/
inline Framebuffer* mapForDraw(DrawAttachment attachment) {
Framebuffer* mapForDraw(DrawAttachment attachment) {
(this->*drawBufferImplementation)(GLenum(attachment));
return this;
}
@ -330,7 +330,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access}
* @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer}
*/
inline Framebuffer* mapForRead(ColorAttachment attachment) {
Framebuffer* mapForRead(ColorAttachment attachment) {
(this->*readBufferImplementation)(GLenum(attachment));
return this;
}
@ -347,7 +347,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @see @fn_gl{BindFramebuffer}, @fn_gl{FramebufferRenderbuffer} or
* @fn_gl_extension{NamedFramebufferRenderbuffer,EXT,direct_state_access}
*/
inline Framebuffer* attachRenderbuffer(BufferAttachment attachment, Renderbuffer* renderbuffer) {
Framebuffer* attachRenderbuffer(BufferAttachment attachment, Renderbuffer* renderbuffer) {
(this->*renderbufferImplementation)(attachment, renderbuffer);
return this;
}
@ -367,7 +367,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @fn_gl_extension{NamedFramebufferTexture1D,EXT,direct_state_access}
* @requires_gl Only 2D and 3D textures are available in OpenGL ES.
*/
inline Framebuffer* attachTexture1D(BufferAttachment attachment, Texture1D* texture, Int level) {
Framebuffer* attachTexture1D(BufferAttachment attachment, Texture1D* texture, Int level) {
(this->*texture1DImplementation)(attachment, texture, level);
return this;
}
@ -402,7 +402,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @see attachTexture2D(), @fn_gl{BindFramebuffer}, @fn_gl{FramebufferTexture}
* or @fn_gl_extension{NamedFramebufferTexture2D,EXT,direct_state_access}
*/
inline Framebuffer* attachCubeMapTexture(BufferAttachment attachment, CubeMapTexture* texture, CubeMapTexture::Coordinate coordinate, Int level) {
Framebuffer* attachCubeMapTexture(BufferAttachment attachment, CubeMapTexture* texture, CubeMapTexture::Coordinate coordinate, Int level) {
(this->*texture2DImplementation)(attachment, GLenum(coordinate), texture->id(), level);
return this;
}
@ -422,7 +422,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
* @fn_gl_extension{NamedFramebufferTexture3D,EXT,direct_state_access}
* @requires_es_extension %Extension @es_extension{OES,texture_3D}
*/
inline Framebuffer* attachTexture3D(BufferAttachment attachment, Texture3D* texture, Int level, Int layer) {
Framebuffer* attachTexture3D(BufferAttachment attachment, Texture3D* texture, Int level, Int layer) {
/** @todo Check for texture target compatibility */
(this->*texture3DImplementation)(attachment, texture, level, layer);
return this;
@ -430,7 +430,7 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer {
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
inline Framebuffer* setViewport(const Rectanglei& rectangle) {
Framebuffer* setViewport(const Rectanglei& rectangle) {
AbstractFramebuffer::setViewport(rectangle);
return this;
}

10
src/Image.cpp

@ -26,7 +26,7 @@
namespace Magnum {
template<UnsignedInt dimensions> void Image<dimensions>::setData(const typename DimensionTraits<Dimensions, GLsizei>::VectorType& size, Format format, Type type, GLvoid* data) {
template<UnsignedInt dimensions> void Image<dimensions>::setData(const typename DimensionTraits<Dimensions, Int>::VectorType& size, ImageFormat format, ImageType type, void* data) {
delete[] _data;
_format = format;
_type = type;
@ -34,8 +34,10 @@ template<UnsignedInt dimensions> void Image<dimensions>::setData(const typename
_data = reinterpret_cast<unsigned char*>(data);
}
template class Image<1>;
template class Image<2>;
template class Image<3>;
#ifndef DOXYGEN_GENERATING_OUTPUT
template class MAGNUM_EXPORT Image<1>;
template class MAGNUM_EXPORT Image<2>;
template class MAGNUM_EXPORT Image<3>;
#endif
}

20
src/Image.h

@ -55,7 +55,7 @@ template<UnsignedInt dimensions> class Image: public AbstractImage {
* Note that the image data are not copied on construction, but they
* are deleted on class destruction.
*/
inline explicit Image(const typename DimensionTraits<Dimensions, Int>::VectorType& size, Format format, Type type, GLvoid* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast<unsigned char*>(data)) {}
explicit Image(const typename DimensionTraits<Dimensions, Int>::VectorType& size, ImageFormat format, ImageType type, void* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast<unsigned char*>(data)) {}
/**
* @brief Constructor
@ -65,17 +65,17 @@ template<UnsignedInt dimensions> class Image: public AbstractImage {
* Dimensions and data pointer are set to zero, call setData() to fill
* the image with data.
*/
inline explicit Image(Format format, Type type): AbstractImage(format, type), _data(nullptr) {}
explicit Image(ImageFormat format, ImageType type): AbstractImage(format, type), _data(nullptr) {}
/** @brief Destructor */
inline ~Image() { delete[] _data; }
~Image() { delete[] _data; }
/** @brief %Image size */
inline typename DimensionTraits<Dimensions, Int>::VectorType size() const { return _size; }
typename DimensionTraits<Dimensions, Int>::VectorType size() const { return _size; }
/** @brief Pointer to raw data */
inline unsigned char* data() { return _data; }
inline const unsigned char* data() const { return _data; } /**< @overload */
unsigned char* data() { return _data; }
const unsigned char* data() const { return _data; } /**< @overload */
/**
* @brief Set image data
@ -87,19 +87,13 @@ template<UnsignedInt dimensions> class Image: public AbstractImage {
* Deletes previous data and replaces them with new. Note that the
* data are not copied, but they are deleted on destruction.
*/
void setData(const typename DimensionTraits<Dimensions, Int>::VectorType& size, Format format, Type type, GLvoid* data);
void setData(const typename DimensionTraits<Dimensions, Int>::VectorType& size, ImageFormat format, ImageType type, void* data);
private:
Math::Vector<Dimensions, Int> _size;
unsigned char* _data;
};
#ifndef DOXYGEN_GENERATING_OUTPUT
extern template class MAGNUM_EXPORT Image<1>;
extern template class MAGNUM_EXPORT Image<2>;
extern template class MAGNUM_EXPORT Image<3>;
#endif
/** @brief One-dimensional image */
typedef Image<1> Image1D;

128
src/ImageFormat.cpp

@ -0,0 +1,128 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 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 "ImageFormat.h"
#include <Utility/Debug.h>
namespace Magnum {
#ifndef DOXYGEN_GENERATING_OUTPUT
Debug operator<<(Debug debug, ImageFormat value) {
switch(value) {
#define _c(value) case ImageFormat::value: return debug << "ImageFormat::" #value;
_c(Red)
#ifndef MAGNUM_TARGET_GLES
_c(Green)
_c(Blue)
#endif
_c(RG)
_c(RGB)
_c(RGBA)
#ifndef MAGNUM_TARGET_GLES
_c(BGR)
#endif
#ifndef MAGNUM_TARGET_GLES3
_c(BGRA)
#endif
#ifndef MAGNUM_TARGET_GLES2
_c(RedInteger)
#ifndef MAGNUM_TARGET_GLES
_c(GreenInteger)
_c(BlueInteger)
#endif
_c(RGInteger)
_c(RGBInteger)
_c(RGBAInteger)
#ifndef MAGNUM_TARGET_GLES
_c(BGRInteger)
_c(BGRAInteger)
#endif
#endif
_c(DepthComponent)
#ifndef MAGNUM_TARGET_GLES3
_c(StencilIndex)
#endif
_c(DepthStencil)
#undef _c
}
return debug << "ImageFormat::(invalid)";
}
Debug operator<<(Debug debug, ImageType value) {
switch(value) {
#define _c(value) case ImageType::value: return debug << "ImageType::" #value;
_c(UnsignedByte)
#ifndef MAGNUM_TARGET_GLES2
_c(Byte)
#endif
_c(UnsignedShort)
#ifndef MAGNUM_TARGET_GLES2
_c(Short)
#endif
_c(UnsignedInt)
#ifndef MAGNUM_TARGET_GLES2
_c(Int)
#endif
_c(HalfFloat)
_c(Float)
#ifndef MAGNUM_TARGET_GLES
_c(UnsignedByte332)
_c(UnsignedByte233Rev)
#endif
_c(UnsignedShort565)
#ifndef MAGNUM_TARGET_GLES
_c(UnsignedShort565Rev)
#endif
_c(UnsignedShort4444)
#ifndef MAGNUM_TARGET_GLES3
_c(UnsignedShort4444Rev)
#endif
_c(UnsignedShort5551)
#ifndef MAGNUM_TARGET_GLES3
_c(UnsignedShort1555Rev)
#endif
#ifndef MAGNUM_TARGET_GLES
_c(UnsignedInt8888)
_c(UnsignedInt8888Rev)
_c(UnsignedInt1010102)
#endif
_c(UnsignedInt2101010Rev)
#ifndef MAGNUM_TARGET_GLES2
_c(UnsignedInt10F11F11FRev)
_c(UnsignedInt5999Rev)
#endif
_c(UnsignedInt248)
#ifndef MAGNUM_TARGET_GLES2
_c(Float32UnsignedInt248Rev)
#endif
#undef _c
}
return debug << "ImageType::(invalid)";
}
#endif
}

454
src/ImageFormat.h

@ -0,0 +1,454 @@
#ifndef Magnum_ImageFormat_h
#define Magnum_ImageFormat_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 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 Enum Magnum::ImageFormat, Magnum::ImageType
*/
#include "Magnum.h"
#include "OpenGL.h"
#include "magnumVisibility.h"
namespace Magnum {
/**
@brief Format of image data
Note that some formats can be used only for framebuffer reading (using
AbstractFramebuffer::read()) and some only for texture data (using Texture::setImage()
and others).
@see Image, ImageWrapper, BufferImage, Trade::ImageData
*/
enum class ImageFormat: GLenum {
/**
* Floating-point red channel.
* @requires_gles30 For texture data only, extension @es_extension{EXT,texture_rg}.
* @requires_es_extension For framebuffer reading, extension @es_extension{EXT,texture_rg}.
*/
#ifndef MAGNUM_TARGET_GLES2
Red = GL_RED,
#else
Red = GL_RED_EXT,
#endif
#ifndef MAGNUM_TARGET_GLES
/**
* Floating-point green channel.
* @requires_gl Only @ref Magnum::ImageFormat "ImageFormat::Red" is
* available in OpenGL ES.
*/
Green = GL_GREEN,
/**
* Floating-point blue channel.
* @requires_gl Only @ref Magnum::ImageFormat "ImageFormat::Red" is
* available in OpenGL ES.
*/
Blue = GL_BLUE,
/** @todo GL_ALPHA? */
#endif
/**
* Floating-point red and green channel.
* @requires_gl30 %Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer}
* @requires_gles30 For texture data only, extension @es_extension{EXT,texture_rg}.
* @requires_es_extension For framebuffer reading, extension @es_extension{EXT,texture_rg}.
*/
#ifndef MAGNUM_TARGET_GLES2
RG = GL_RG,
#else
RG = GL_RG_EXT,
#endif
/**
* Floating-point RGB.
* @requires_gl Can't be used for framebuffer reading in OpenGL ES.
*/
RGB = GL_RGB,
/** Floating-point RGBA. */
RGBA = GL_RGBA,
#ifndef MAGNUM_TARGET_GLES
/**
* Floating-point BGR.
* @requires_gl Only RGB component ordering is available in OpenGL ES.
*/
BGR = GL_BGR,
#endif
#ifndef MAGNUM_TARGET_GLES3
/**
* Floating-point BGRA.
* @requires_es_extension %Extension @es_extension{EXT,read_format_bgra}
* for framebuffer reading, extension @es_extension{APPLE,texture_format_BGRA8888}
* or @es_extension{EXT,texture_format_BGRA8888} for texture data.
*/
#ifndef MAGNUM_TARGET_GLES
BGRA = GL_BGRA,
#else
BGRA = GL_BGRA_EXT,
#endif
#endif
#ifndef MAGNUM_TARGET_GLES2
/**
* Integer red channel.
* @requires_gl30 %Extension @extension{EXT,texture_integer}
* @requires_gles30 Only floating-point image data are available in OpenGL
* ES 2.0.
*/
RedInteger = GL_RED_INTEGER,
#ifndef MAGNUM_TARGET_GLES
/**
* Integer green channel.
* @requires_gl30 %Extension @extension{EXT,texture_integer}
* @requires_gl Only @ref Magnum::ImageFormat "ImageFormat::RedInteger"
* is available in OpenGL ES 3.0, only floating-point image data are
* available in OpenGL ES 2.0.
*/
GreenInteger = GL_GREEN_INTEGER,
/**
* Integer blue channel.
* @requires_gl30 %Extension @extension{EXT,texture_integer}
* @requires_gl Only @ref Magnum::ImageFormat "ImageFormat::RedInteger" is
* available in OpenGL ES 3.0, only floating-point image data are
* available in OpenGL ES 2.0.
*/
BlueInteger = GL_BLUE_INTEGER,
#endif
/**
* Integer red and green channel.
* @requires_gl30 %Extension @extension{ARB,texture_rg} and @extension{EXT,texture_integer}
* @requires_gl Can't be used for framebuffer reading in OpenGL ES.
* @requires_gles30 For texture data only, only floating-point image data
* are available in OpenGL ES 2.0.
*/
RGInteger = GL_RG_INTEGER,
/**
* Integer RGB.
* @requires_gl30 %Extension @extension{EXT,texture_integer}
* @requires_gl Can't be used for framebuffer reading in OpenGL ES.
* @requires_gles30 For texture data only, only floating-point image data
* are available in OpenGL ES 2.0.
*/
RGBInteger = GL_RGB_INTEGER,
/**
* Integer RGBA.
* @requires_gl30 %Extension @extension{EXT,texture_integer}
* @requires_gles30 Only floating-point image data are available in OpenGL
* ES 2.0.
*/
RGBAInteger = GL_RGBA_INTEGER,
#ifndef MAGNUM_TARGET_GLES
/**
* Integer BGR.
* @requires_gl30 %Extension @extension{EXT,texture_integer}
* @requires_gl Only @ref Magnum::ImageFormat "ImageFormat::RGBInteger" is
* available in OpenGL ES 3.0, only floating-point image data are
* available in OpenGL ES 2.0.
*/
BGRInteger = GL_BGR_INTEGER,
/**
* Integer BGRA.
* @requires_gl30 %Extension @extension{EXT,texture_integer}
* @requires_gl Only @ref Magnum::ImageFormat "ImageFormat::RGBAInteger" is
* available in OpenGL ES 3.0, only floating-point image data are
* available in OpenGL ES 2.0.
*/
BGRAInteger = GL_BGRA_INTEGER,
#endif
#endif
/**
* Depth component.
* @requires_gles30 For texture data only, extension @es_extension{ANGLE,depth_texture}.
* @requires_es_extension For framebuffer reading only, extension
* @es_extension2{NV,read_depth,GL_NV_read_depth_stencil}.
*/
DepthComponent = GL_DEPTH_COMPONENT,
#ifndef MAGNUM_TARGET_GLES3
/**
* Stencil index. For framebuffer reading only.
* @requires_es_extension %Extension @es_extension2{NV,read_stencil,GL_NV_read_depth_stencil}
* @todo Where to get GL_STENCIL_INDEX in ES?
*/
#ifndef MAGNUM_TARGET_GLES
StencilIndex = GL_STENCIL_INDEX,
#else
StencilIndex = 0x1901,
#endif
#endif
/**
* Depth and stencil.
* @requires_gl30 %Extension @extension{EXT,packed_depth_stencil}
* @requires_gles30 For texture data only, extension @es_extension{OES,packed_depth_stencil}.
* @requires_es_extension For framebuffer reading only, extension
* @es_extension2{NV,read_depth_stencil,GL_NV_read_depth_stencil}.
*/
#ifndef MAGNUM_TARGET_GLES2
DepthStencil = GL_DEPTH_STENCIL
#else
DepthStencil = GL_DEPTH_STENCIL_OES
#endif
};
/**
@brief Type of image data
Note that some formats can be used only for framebuffer reading (using
AbstractFramebuffer::read()) and some only for texture data (using Texture::setImage()
and others).
@see Image, ImageWrapper, BufferImage, Trade::ImageData
*/
enum class ImageType: GLenum {
/** Each component unsigned byte. */
UnsignedByte = GL_UNSIGNED_BYTE,
#ifndef MAGNUM_TARGET_GLES2
/**
* Each component signed byte.
* @requires_gl Can't be used for framebuffer reading in OpenGL ES.
* @requires_gles30 For texture data only, only @ref Magnum::ImageType "ImageType::UnsignedByte"
* is available in OpenGL ES 2.0.
*/
Byte = GL_BYTE,
#endif
/**
* Each component unsigned short.
* @requires_gl Can't be used for framebuffer reading in OpenGL ES.
* @requires_gles30 For texture data only, extension @es_extension{OES,depth_texture}
* or @es_extension{ANGLE,depth_texture}.
*/
UnsignedShort = GL_UNSIGNED_SHORT,
#ifndef MAGNUM_TARGET_GLES2
/**
* Each component signed short.
* @requires_gl Can't be used for framebuffer reading in OpenGL ES.
* @requires_gles30 For texture data only, only @ref Magnum::ImageType "ImageType::UnsignedShort"
* is available in OpenGL ES 2.0.
*/
Short = GL_SHORT,
#endif
/**
* Each component unsigned int.
* @requires_gles30 Can't be used for framebuffer reading in OpenGL ES 2.0.
* @requires_gles30 For texture data only, extension @es_extension{OES,depth_texture}
* or @es_extension{ANGLE,depth_texture}.
*/
UnsignedInt = GL_UNSIGNED_INT,
#ifndef MAGNUM_TARGET_GLES2
/**
* Each component signed int.
* @requires_gles30 Only @ref Magnum::ImageType "ImageType::UnsignedInt"
* is available in OpenGL ES 2.0.
*/
Int = GL_INT,
#endif
/**
* Each component half float.
* @requires_gl30 %Extension @extension{NV,half_float} / @extension{ARB,half_float_pixel}
* @requires_gles30 For texture data only, extension
* @es_extension2{OES,texture_half_float,OES_texture_float}.
*/
#ifndef MAGNUM_TARGET_GLES2
HalfFloat = GL_HALF_FLOAT,
#else
HalfFloat = GL_HALF_FLOAT_OES,
#endif
/**
* Each component float.
* @requires_gles30 For texture data only, extension @es_extension{OES,texture_float}.
*/
Float = GL_FLOAT,
#ifndef MAGNUM_TARGET_GLES
/**
* RGB, unsigned byte, red and green component 3bit, blue component 2bit.
* @requires_gl Packed 12bit types are not available in OpenGL ES.
*/
UnsignedByte332 = GL_UNSIGNED_BYTE_3_3_2,
/**
* BGR, unsigned byte, red and green component 3bit, blue component 2bit.
* @requires_gl Packed 12bit types are not available in OpenGL ES.
*/
UnsignedByte233Rev = GL_UNSIGNED_BYTE_2_3_3_REV,
#endif
/**
* RGB, unsigned byte, red and blue component 5bit, green 6bit.
* @requires_gl Can't be used for framebuffer reading in OpenGL ES.
*/
UnsignedShort565 = GL_UNSIGNED_SHORT_5_6_5,
#ifndef MAGNUM_TARGET_GLES
/**
* BGR, unsigned short, red and blue 5bit, green 6bit.
* @requires_gl Only @ref Magnum::ImageType "ImageType::RGB565" is
* available in OpenGL ES.
*/
UnsignedShort565Rev = GL_UNSIGNED_SHORT_5_6_5_REV,
#endif
/**
* RGBA, unsigned short, each component 4bit.
* @requires_gl Can't be used for framebuffer reading in OpenGL ES.
*/
UnsignedShort4444 = GL_UNSIGNED_SHORT_4_4_4_4,
#ifndef MAGNUM_TARGET_GLES3
/**
* ABGR, unsigned short, each component 4bit.
* @requires_es_extension For framebuffer reading only, extension
* @es_extension{EXT,read_format_bgra}.
*/
#ifndef MAGNUM_TARGET_GLES
UnsignedShort4444Rev = GL_UNSIGNED_SHORT_4_4_4_4_REV,
#else
UnsignedShort4444Rev = GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT,
#endif
#endif
/**
* RGBA, unsigned short, each RGB component 5bit, alpha component 1bit.
* @requires_gl Can't be used for framebuffer reading in OpenGL ES.
*/
UnsignedShort5551 = GL_UNSIGNED_SHORT_5_5_5_1,
#ifndef MAGNUM_TARGET_GLES3
/**
* ABGR, unsigned short, each RGB component 5bit, alpha component 1bit.
* @requires_es_extension For framebuffer reading only, extension
* @es_extension{EXT,read_format_bgra}.
*/
#ifndef MAGNUM_TARGET_GLES
UnsignedShort1555Rev = GL_UNSIGNED_SHORT_1_5_5_5_REV,
#else
UnsignedShort1555Rev = GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT,
#endif
#endif
#ifndef MAGNUM_TARGET_GLES
/**
* RGBA, unsigned int, each component 8bit.
* @requires_gl Use @ref Magnum::ImageType "ImageType::UnsignedByte" in
* OpenGL ES instead.
*/
UnsignedInt8888 = GL_UNSIGNED_INT_8_8_8_8,
/**
* ABGR, unsigned int, each component 8bit.
* @requires_gl Only RGBA component ordering is available in OpenGL ES, see
* @ref Magnum::ImageType "ImageType::UnsignedInt8888" for more
* information.
*/
UnsignedInt8888Rev = GL_UNSIGNED_INT_8_8_8_8_REV,
/**
* RGBA, unsigned int, each RGB component 10bit, alpha component 2bit.
* @requires_gl Only @ref Magnum::ImageType "ImageType::UnsignedInt2101010Rev"
* is available in OpenGL ES.
*/
UnsignedInt1010102 = GL_UNSIGNED_INT_10_10_10_2,
#endif
/**
* ABGR, unsigned int, each RGB component 10bit, alpha component 2bit.
* @requires_gles30 Can't be used for framebuffer reading in OpenGL ES 2.0.
* @requires_gles30 For texture data only, extension
* @es_extension{EXT,texture_type_2_10_10_10_REV}.
*/
#ifndef MAGNUM_TARGET_GLES2
UnsignedInt2101010Rev = GL_UNSIGNED_INT_2_10_10_10_REV,
#else
UnsignedInt2101010Rev = GL_UNSIGNED_INT_2_10_10_10_REV_EXT,
#endif
#ifndef MAGNUM_TARGET_GLES2
/**
* BGR, unsigned int, red and green 11bit float, blue 10bit float.
* @requires_gl30 %Extension @extension{EXT,packed_float}
* @requires_gles30 Floating-point types are not available in OpenGL ES
* 2.0.
*/
UnsignedInt10F11F11FRev = GL_UNSIGNED_INT_10F_11F_11F_REV,
/**
* BGR, unsigned int, each component 9bit + 5bit exponent.
* @requires_gl30 %Extension @extension{EXT,texture_shared_exponent}
* @requires_gles30 Only 8bit and 16bit types are available in OpenGL ES
* 2.0.
*/
UnsignedInt5999Rev = GL_UNSIGNED_INT_5_9_9_9_REV,
#endif
/**
* Unsigned int, depth component 24bit, stencil index 8bit.
* @requires_gl30 %Extension @extension{EXT,packed_depth_stencil}
* @requires_gles30 For texture data only, extension @es_extension{OES,packed_depth_stencil}.
*/
#ifdef MAGNUM_TARGET_GLES2
UnsignedInt248 = GL_UNSIGNED_INT_24_8_OES
#else
UnsignedInt248 = GL_UNSIGNED_INT_24_8,
/**
* Float + unsigned int, depth component 32bit float, 24bit gap, stencil
* index 8bit.
* @requires_gl30 %Extension @extension{ARB,depth_buffer_float}
* @requires_gles30 For texture data only, only @ref Magnum::ImageType "ImageType::UnsignedInt248"
* is available in OpenGL ES 2.0.
*/
Float32UnsignedInt248Rev = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
#endif
};
/** @debugoperator{ImageFormat} */
Debug MAGNUM_EXPORT operator<<(Debug debug, ImageFormat value);
/** @debugoperator{ImageFormat} */
Debug MAGNUM_EXPORT operator<<(Debug debug, ImageType value);
}
#endif

12
src/ImageWrapper.h

@ -62,7 +62,7 @@ template<UnsignedInt dimensions> class ImageWrapper: public AbstractImage {
* Note that the image data are not copied on construction, but they
* are deleted on class destruction.
*/
inline explicit ImageWrapper(const typename DimensionTraits<Dimensions, Int>::VectorType& size, Format format, Type type, GLvoid* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast<unsigned char*>(data)) {}
explicit ImageWrapper(const typename DimensionTraits<Dimensions, Int>::VectorType& size, ImageFormat format, ImageType type, void* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast<unsigned char*>(data)) {}
/**
* @brief Constructor
@ -73,14 +73,14 @@ template<UnsignedInt dimensions> class ImageWrapper: public AbstractImage {
* Data pointer is set to zero, call setData() to fill the image with
* data.
*/
inline explicit ImageWrapper(const typename DimensionTraits<Dimensions, Int>::VectorType& size, Format format, Type type): AbstractImage(format, type), _size(size), _data(nullptr) {}
explicit ImageWrapper(const typename DimensionTraits<Dimensions, Int>::VectorType& size, ImageFormat format, ImageType type): AbstractImage(format, type), _size(size), _data(nullptr) {}
/** @brief %Image size */
inline typename DimensionTraits<Dimensions, Int>::VectorType size() const { return _size; }
typename DimensionTraits<Dimensions, Int>::VectorType size() const { return _size; }
/** @brief Pointer to raw data */
inline unsigned char* data() { return _data; }
inline const unsigned char* data() const { return _data; } /**< @overload */
unsigned char* data() { return _data; }
const unsigned char* data() const { return _data; } /**< @overload */
/**
* @brief Set image data
@ -90,7 +90,7 @@ template<UnsignedInt dimensions> class ImageWrapper: public AbstractImage {
* passed in constructor. The data are not copied nor deleted on
* destruction.
*/
inline void setData(GLvoid* data) {
void setData(void* data) {
_data = reinterpret_cast<unsigned char*>(data);
}

2
src/Implementation/BufferState.h

@ -43,7 +43,7 @@ struct BufferState {
static std::size_t indexForTarget(Buffer::Target target);
static const Buffer::Target targetForIndex[TargetCount-1];
inline constexpr BufferState(): bindings() {}
constexpr BufferState(): bindings() {}
/* Currently bound buffer for all targets */
GLuint bindings[TargetCount];

3
src/Implementation/FramebufferState.h

@ -26,11 +26,12 @@
#include "Math/Geometry/Rectangle.h"
#include "Magnum.h"
#include "OpenGL.h"
namespace Magnum { namespace Implementation {
struct FramebufferState {
inline constexpr FramebufferState(): readBinding(0), drawBinding(0), renderbufferBinding(0) {}
constexpr FramebufferState(): readBinding(0), drawBinding(0), renderbufferBinding(0) {}
GLuint readBinding, drawBinding, renderbufferBinding;
Rectanglei viewport;

2
src/Implementation/MeshState.h

@ -29,7 +29,7 @@
namespace Magnum { namespace Implementation {
struct MeshState {
inline constexpr MeshState(): currentVAO(0) {}
constexpr MeshState(): currentVAO(0) {}
GLuint currentVAO;
};

22
src/SceneGraph/DualComplexTransformation.cpp → src/Implementation/RendererState.h

@ -1,3 +1,5 @@
#ifndef Magnum_Implementation_RendererState_h
#define Magnum_Implementation_RendererState_h
/*
This file is part of Magnum.
@ -22,14 +24,22 @@
DEALINGS IN THE SOFTWARE.
*/
#include "DualComplexTransformation.h"
#include "Renderer.h"
#include "Object.hpp"
namespace Magnum { namespace Implementation {
namespace Magnum { namespace SceneGraph {
struct RendererState {
constexpr RendererState()
#ifndef MAGNUM_TARGET_GLES3
: resetNotificationStrategy()
#endif
{}
#ifndef DOXYGEN_GENERATING_OUTPUT
template class MAGNUM_SCENEGRAPH_EXPORT Object<DualComplexTransformation<>>;
#endif
#ifndef MAGNUM_TARGET_GLES3
Renderer::ResetNotificationStrategy resetNotificationStrategy;
#endif
};
}}
#endif

4
src/Implementation/ShaderProgramState.h

@ -24,12 +24,12 @@
DEALINGS IN THE SOFTWARE.
*/
#include "Magnum.h"
#include "OpenGL.h"
namespace Magnum { namespace Implementation {
struct ShaderProgramState {
inline constexpr ShaderProgramState(): current(0), maxSupportedVertexAttributeCount(0) {}
constexpr ShaderProgramState(): current(0), maxSupportedVertexAttributeCount(0) {}
/* Currently used program */
GLuint current;

3
src/Implementation/State.cpp

@ -27,6 +27,7 @@
#include "BufferState.h"
#include "FramebufferState.h"
#include "MeshState.h"
#include "RendererState.h"
#include "ShaderProgramState.h"
#include "TextureState.h"
@ -36,12 +37,14 @@ State::State():
buffer(new BufferState),
framebuffer(new FramebufferState),
mesh(new MeshState),
renderer(new RendererState),
shaderProgram(new ShaderProgramState),
texture(new TextureState) {}
State::~State() {
delete texture;
delete shaderProgram;
delete renderer;
delete mesh;
delete framebuffer;
delete buffer;

2
src/Implementation/State.h

@ -29,6 +29,7 @@ namespace Magnum { namespace Implementation {
struct BufferState;
struct FramebufferState;
struct MeshState;
struct RendererState;
struct ShaderProgramState;
struct TextureState;
@ -39,6 +40,7 @@ struct State {
BufferState* const buffer;
FramebufferState* const framebuffer;
MeshState* const mesh;
RendererState* const renderer;
ShaderProgramState* const shaderProgram;
TextureState* const texture;
};

10
src/SceneGraph/MatrixTransformation2D.cpp → src/Implementation/TextureState.cpp

@ -22,14 +22,12 @@
DEALINGS IN THE SOFTWARE.
*/
#include "MatrixTransformation2D.h"
#include "TextureState.h"
#include "Object.hpp"
namespace Magnum { namespace Implementation {
namespace Magnum { namespace SceneGraph {
TextureState::TextureState(): maxSupportedLayerCount(0), maxSupportedAnisotropy(0.0f), currentLayer(0) {}
#ifndef DOXYGEN_GENERATING_OUTPUT
template class MAGNUM_SCENEGRAPH_EXPORT Object<MatrixTransformation2D<>>;
#endif
TextureState::~TextureState() = default;
}}

5
src/Implementation/TextureState.h

@ -26,12 +26,13 @@
#include <vector>
#include "Magnum.h"
#include "OpenGL.h"
namespace Magnum { namespace Implementation {
struct TextureState {
inline TextureState(): maxSupportedLayerCount(0), maxSupportedAnisotropy(0.0f), currentLayer(0) {}
explicit TextureState();
~TextureState();
GLint maxSupportedLayerCount;
GLfloat maxSupportedAnisotropy;

26
src/Magnum.h

@ -34,6 +34,10 @@
#include "Types.h"
#include "magnumConfigure.h"
#ifndef DOXYGEN_GENERATING_OUTPUT
typedef unsigned int GLenum; /* Needed for *Format and *Type enums */
#endif
namespace Corrade {
namespace Utility {
class Debug;
@ -59,6 +63,9 @@ namespace Math {
#endif
}
/* Bring whole Corrade namespace */
using namespace Corrade;
/* Bring debugging facility from Corrade::Utility namespace */
using Corrade::Utility::Debug;
using Corrade::Utility::Warning;
@ -325,7 +332,11 @@ using Math::operator "" _radf;
/** @todoc Remove `ifndef` when Doxygen is sane again */
#ifndef DOXYGEN_GENERATING_OUTPUT
/* Forward declarations for all types in root namespace */
/* FramebufferClear[Mask], FramebufferBlit[Mask], FramebufferBlitFilter,
FramebufferTarget enums used only directly with framebuffer instance */
class AbstractFramebuffer;
class AbstractImage;
class AbstractShaderProgram;
class AbstractTexture;
@ -346,6 +357,7 @@ typedef BufferImage<3> BufferImage3D;
#ifndef MAGNUM_TARGET_GLES
class BufferTexture;
enum class BufferTextureFormat: GLenum;
#endif
template<class T = Float> class Color3;
@ -373,14 +385,23 @@ typedef Image<1> Image1D;
typedef Image<2> Image2D;
typedef Image<3> Image3D;
enum class ImageFormat: GLenum;
enum class ImageType: GLenum;
template<UnsignedInt> class ImageWrapper;
typedef ImageWrapper<1> ImageWrapper1D;
typedef ImageWrapper<2> ImageWrapper2D;
typedef ImageWrapper<3> ImageWrapper3D;
class Mesh;
class Query;
/* AbstractQuery is not used directly */
class PrimitiveQuery;
class SampleQuery;
class TimeQuery;
class Renderbuffer;
enum class RenderbufferFormat: GLenum;
#ifndef CORRADE_GCC45_COMPATIBILITY
enum class ResourceState: UnsignedByte;
@ -391,6 +412,7 @@ template<class T, class U = T> class Resource;
class ResourceKey;
template<class...> class ResourceManager;
class Sampler;
class Shader;
template<UnsignedInt> class Texture;
@ -400,6 +422,8 @@ typedef Texture<1> Texture1D;
typedef Texture<2> Texture2D;
typedef Texture<3> Texture3D;
enum class TextureFormat: GLenum;
class Timeline;
#endif

6
src/Math/Algorithms/Svd.h

@ -35,7 +35,6 @@
namespace Magnum { namespace Math { namespace Algorithms {
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
template<class T> T pythagoras(T a, T b) {
@ -50,13 +49,12 @@ template<class T> T pythagoras(T a, T b) {
}
template<class T> constexpr T smallestDelta();
template<> inline constexpr Float smallestDelta<Float>() { return 1.0e-32; }
template<> constexpr Float smallestDelta<Float>() { return 1.0e-32; }
#ifndef MAGNUM_TARGET_GLES
template<> inline constexpr Double smallestDelta<Double>() { return 1.0e-64; }
template<> constexpr Double smallestDelta<Double>() { return 1.0e-64; }
#endif
}
#endif
/**
@brief Singular Value Decomposition

32
src/Math/Angle.h

@ -124,16 +124,16 @@ std::sin(Float(Rad<Float>(angleInDegrees)); // required explicit conversion hint
template<class T> class Deg: public Unit<Deg, T> {
public:
/** @brief Default constructor */
inline constexpr /*implicit*/ Deg() {}
constexpr /*implicit*/ Deg() {}
/** @brief Explicit constructor from unitless type */
inline constexpr explicit Deg(T value): Unit<Math::Deg, T>(value) {}
constexpr explicit Deg(T value): Unit<Math::Deg, T>(value) {}
/** @brief Copy constructor */
inline constexpr /*implicit*/ Deg(Unit<Math::Deg, T> value): Unit<Math::Deg, T>(value) {}
constexpr /*implicit*/ Deg(Unit<Math::Deg, T> value): Unit<Math::Deg, T>(value) {}
/** @brief Construct from another underlying type */
template<class U> inline constexpr explicit Deg(Unit<Math::Deg, U> value): Unit<Math::Deg, T>(value) {}
template<class U> constexpr explicit Deg(Unit<Math::Deg, U> value): Unit<Math::Deg, T>(value) {}
/**
* @brief Construct degrees from radians
@ -143,7 +143,7 @@ template<class T> class Deg: public Unit<Deg, T> {
* deg = 180 \frac {rad} \pi
* @f]
*/
inline constexpr /*implicit*/ Deg(Unit<Rad, T> value);
constexpr /*implicit*/ Deg(Unit<Rad, T> value);
};
#ifndef CORRADE_GCC46_COMPATIBILITY
@ -160,7 +160,7 @@ Double cosine = Math::cos(1.047_rad); // cosine = 0.5
@note Not available on GCC < 4.7. Use Deg::Deg(T) instead.
@requires_gl Only single-precision types are available in OpenGL ES.
*/
inline constexpr Deg<Double> operator "" _deg(long double value) { return Deg<Double>(value); }
constexpr Deg<Double> operator "" _deg(long double value) { return Deg<Double>(value); }
#endif
/** @relates Deg
@ -175,7 +175,7 @@ Float tangent = Math::tan(1.047_radf); // tangent = 1.732f
@note Not available on GCC < 4.7. Use Deg::Deg(T) instead.
@requires_gl Only single-precision types are available in OpenGL ES.
*/
inline constexpr Deg<Float> operator "" _degf(long double value) { return Deg<Float>(value); }
constexpr Deg<Float> operator "" _degf(long double value) { return Deg<Float>(value); }
#endif
/**
@ -187,16 +187,16 @@ See Deg for more information.
template<class T> class Rad: public Unit<Rad, T> {
public:
/** @brief Default constructor */
inline constexpr /*implicit*/ Rad() {}
constexpr /*implicit*/ Rad() {}
/** @brief Construct from unitless type */
inline constexpr explicit Rad(T value): Unit<Math::Rad, T>(value) {}
constexpr explicit Rad(T value): Unit<Math::Rad, T>(value) {}
/** @brief Copy constructor */
inline constexpr /*implicit*/ Rad(Unit<Math::Rad, T> value): Unit<Math::Rad, T>(value) {}
constexpr /*implicit*/ Rad(Unit<Math::Rad, T> value): Unit<Math::Rad, T>(value) {}
/** @brief Construct from another underlying type */
template<class U> inline constexpr explicit Rad(Unit<Math::Rad, U> value): Unit<Math::Rad, T>(value) {}
template<class U> constexpr explicit Rad(Unit<Math::Rad, U> value): Unit<Math::Rad, T>(value) {}
/**
* @brief Construct radians from degrees
@ -206,7 +206,7 @@ template<class T> class Rad: public Unit<Rad, T> {
* rad = deg \frac \pi 180
* @f]
*/
inline constexpr /*implicit*/ Rad(Unit<Deg, T> value);
constexpr /*implicit*/ Rad(Unit<Deg, T> value);
};
#ifndef CORRADE_GCC46_COMPATIBILITY
@ -218,7 +218,7 @@ See operator""_rad() for more information.
@see Magnum::operator""_rad(), operator""_radf(), operator""_deg()
@note Not available on GCC < 4.7. Use Rad::Rad(T) instead.
*/
inline constexpr Rad<Double> operator "" _rad(long double value) { return Rad<Double>(value); }
constexpr Rad<Double> operator "" _rad(long double value) { return Rad<Double>(value); }
#endif
/** @relates Rad
@ -228,11 +228,11 @@ See operator""_degf() for more information.
@see Magnum::operator""_radf(), operator""_rad(), operator""_degf()
@note Not available on GCC < 4.7. Use Rad::Rad(T) instead.
*/
inline constexpr Rad<Float> operator "" _radf(long double value) { return Rad<Float>(value); }
constexpr Rad<Float> operator "" _radf(long double value) { return Rad<Float>(value); }
#endif
template<class T> inline constexpr Deg<T>::Deg(Unit<Rad, T> value): Unit<Math::Deg, T>(T(180)*value.toUnderlyingType()/Math::Constants<T>::pi()) {}
template<class T> inline constexpr Rad<T>::Rad(Unit<Deg, T> value): Unit<Math::Rad, T>(value.toUnderlyingType()*Math::Constants<T>::pi()/T(180)) {}
template<class T> constexpr Deg<T>::Deg(Unit<Rad, T> value): Unit<Math::Deg, T>(T(180)*value.toUnderlyingType()/Math::Constants<T>::pi()) {}
template<class T> constexpr Rad<T>::Rad(Unit<Deg, T> value): Unit<Math::Rad, T>(value.toUnderlyingType()*Math::Constants<T>::pi()/T(180)) {}
/** @debugoperator{Magnum::Math::Rad} */
template<class T> Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Unit<Rad, T>& value) {

137
src/Math/BoolVector.h

@ -35,10 +35,11 @@
namespace Magnum { namespace Math {
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
/** @todo C++14: use std::make_index_sequence and std::integer_sequence */
template<std::size_t ...> struct Sequence {};
#ifndef DOXYGEN_GENERATING_OUTPUT
/* E.g. GenerateSequence<3>::Type is Sequence<0, 1, 2> */
template<std::size_t N, std::size_t ...sequence> struct GenerateSequence:
GenerateSequence<N-1, N-1, sequence...> {};
@ -46,10 +47,10 @@ namespace Implementation {
template<std::size_t ...sequence> struct GenerateSequence<0, sequence...> {
typedef Sequence<sequence...> Type;
};
#endif
template<class T> inline constexpr T repeat(T value, std::size_t) { return value; }
template<class T> constexpr T repeat(T value, std::size_t) { return value; }
}
#endif
/**
@brief %Vector storing boolean values
@ -68,7 +69,7 @@ template<std::size_t size> class BoolVector {
static const std::size_t DataSize = (size-1)/8+1; /**< @brief %Vector storage size */
/** @brief Construct zero-filled boolean vector */
inline constexpr BoolVector(): _data() {}
constexpr BoolVector(): _data() {}
/**
* @brief Construct boolean vector from segment values
@ -76,9 +77,9 @@ template<std::size_t size> class BoolVector {
* @param next Values for next Bbit segments
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class ...T> inline constexpr /*implicit*/ BoolVector(UnsignedByte first, T... next);
template<class ...T> constexpr /*implicit*/ BoolVector(UnsignedByte first, T... next);
#else
template<class ...T, class U = typename std::enable_if<sizeof...(T)+1 == DataSize, bool>::type> inline constexpr /*implicit*/ BoolVector(UnsignedByte first, T... next): _data{first, UnsignedByte(next)...} {}
template<class ...T, class U = typename std::enable_if<sizeof...(T)+1 == DataSize, bool>::type> constexpr /*implicit*/ BoolVector(UnsignedByte first, T... next): _data{first, UnsignedByte(next)...} {}
#endif
/** @brief Construct boolean vector with one value for all fields */
@ -86,19 +87,19 @@ template<std::size_t size> class BoolVector {
inline explicit BoolVector(T value);
#else
#ifndef CORRADE_GCC46_COMPATIBILITY
template<class T, class U = typename std::enable_if<std::is_same<bool, T>::value && size != 1, bool>::type> inline constexpr explicit BoolVector(T value): BoolVector(typename Implementation::GenerateSequence<DataSize>::Type(), value ? FullSegmentMask : 0) {}
template<class T, class U = typename std::enable_if<std::is_same<bool, T>::value && size != 1, bool>::type> constexpr explicit BoolVector(T value): BoolVector(typename Implementation::GenerateSequence<DataSize>::Type(), value ? FullSegmentMask : 0) {}
#else
template<class T, class U = typename std::enable_if<std::is_same<bool, T>::value && size != 1, bool>::type> inline explicit BoolVector(T value) {
template<class T, class U = typename std::enable_if<std::is_same<bool, T>::value && size != 1, bool>::type> explicit BoolVector(T value) {
*this = BoolVector(typename Implementation::GenerateSequence<DataSize>::Type(), value ? FullSegmentMask : 0);
}
#endif
#endif
/** @brief Copy constructor */
inline constexpr BoolVector(const BoolVector<size>&) = default;
constexpr BoolVector(const BoolVector<size>&) = default;
/** @brief Copy assignment */
inline BoolVector<size>& operator=(const BoolVector<size>&) = default;
BoolVector<size>& operator=(const BoolVector<size>&) = default;
/**
* @brief Raw data
@ -106,84 +107,46 @@ template<std::size_t size> class BoolVector {
*
* @see operator[](), set()
*/
inline UnsignedByte* data() { return _data; }
inline constexpr const UnsignedByte* data() const { return _data; } /**< @overload */
UnsignedByte* data() { return _data; }
constexpr const UnsignedByte* data() const { return _data; } /**< @overload */
/** @brief Bit at given position */
inline constexpr bool operator[](std::size_t i) const {
constexpr bool operator[](std::size_t i) const {
return (_data[i/8] >> i%8) & 0x01;
}
/** @brief Set bit at given position */
inline BoolVector<size>& set(std::size_t i, bool value) {
BoolVector<size>& set(std::size_t i, bool value) {
_data[i/8] |= ((value & 0x01) << i%8);
return *this;
}
/** @brief Equality comparison */
inline bool operator==(const BoolVector<size>& other) const {
for(std::size_t i = 0; i != size/8; ++i)
if(_data[i] != other._data[i]) return false;
/* Check last segment */
if(size%8 && (_data[DataSize-1] & LastSegmentMask) != (other._data[DataSize-1] & LastSegmentMask))
return false;
return true;
}
bool operator==(const BoolVector<size>& other) const;
/** @brief Non-equality comparison */
inline bool operator!=(const BoolVector<size>& other) const {
bool operator!=(const BoolVector<size>& other) const {
return !operator==(other);
}
/** @brief Whether all bits are set */
bool all() const {
/* Check all full segments */
for(std::size_t i = 0; i != size/8; ++i)
if(_data[i] != FullSegmentMask) return false;
/* Check last segment */
if(size%8 && (_data[DataSize-1] & LastSegmentMask) != LastSegmentMask)
return false;
return true;
}
bool all() const;
/** @brief Whether no bits are set */
bool none() const {
/* Check all full segments */
for(std::size_t i = 0; i != size/8; ++i)
if(_data[i]) return false;
/* Check last segment */
if(size%8 && (_data[DataSize-1] & LastSegmentMask))
return false;
return true;
}
bool none() const;
/** @brief Whether any bit is set */
inline bool any() const {
return !none();
}
bool any() const { return !none(); }
/** @brief Bitwise inversion */
inline BoolVector<size> operator~() const {
BoolVector<size> out;
for(std::size_t i = 0; i != DataSize; ++i)
out._data[i] = ~_data[i];
return out;
}
BoolVector<size> operator~() const;
/**
* @brief Bitwise AND and assign
*
* The computation is done in-place.
*/
inline BoolVector<size>& operator&=(const BoolVector<size>& other) {
BoolVector<size>& operator&=(const BoolVector<size>& other) {
for(std::size_t i = 0; i != DataSize; ++i)
_data[i] &= other._data[i];
@ -195,7 +158,7 @@ template<std::size_t size> class BoolVector {
*
* @see operator&=()
*/
inline BoolVector<size> operator&(const BoolVector<size>& other) const {
BoolVector<size> operator&(const BoolVector<size>& other) const {
return BoolVector<size>(*this) &= other;
}
@ -204,7 +167,7 @@ template<std::size_t size> class BoolVector {
*
* The computation is done in-place.
*/
inline BoolVector<size>& operator|=(const BoolVector<size>& other) {
BoolVector<size>& operator|=(const BoolVector<size>& other) {
for(std::size_t i = 0; i != DataSize; ++i)
_data[i] |= other._data[i];
@ -216,7 +179,7 @@ template<std::size_t size> class BoolVector {
*
* @see operator|=()
*/
inline BoolVector<size> operator|(const BoolVector<size>& other) const {
BoolVector<size> operator|(const BoolVector<size>& other) const {
return BoolVector<size>(*this) |= other;
}
@ -225,7 +188,7 @@ template<std::size_t size> class BoolVector {
*
* The computation is done in-place.
*/
inline BoolVector<size>& operator^=(const BoolVector<size>& other) {
BoolVector<size>& operator^=(const BoolVector<size>& other) {
for(std::size_t i = 0; i != DataSize; ++i)
_data[i] ^= other._data[i];
@ -237,7 +200,7 @@ template<std::size_t size> class BoolVector {
*
* @see operator^=()
*/
inline BoolVector<size> operator^(const BoolVector<size>& other) const {
BoolVector<size> operator^(const BoolVector<size>& other) const {
return BoolVector<size>(*this) ^= other;
}
@ -248,7 +211,7 @@ template<std::size_t size> class BoolVector {
};
/* Implementation for Vector<size, T>::Vector(U) */
template<std::size_t ...sequence> inline constexpr explicit BoolVector(Implementation::Sequence<sequence...>, UnsignedByte value): _data{Implementation::repeat(value, sequence)...} {}
template<std::size_t ...sequence> constexpr explicit BoolVector(Implementation::Sequence<sequence...>, UnsignedByte value): _data{Implementation::repeat(value, sequence)...} {}
UnsignedByte _data[(size-1)/8+1];
};
@ -266,6 +229,50 @@ template<std::size_t size> Corrade::Utility::Debug operator<<(Corrade::Utility::
return debug;
}
template<std::size_t size> inline bool BoolVector<size>::operator==(const BoolVector< size >& other) const {
for(std::size_t i = 0; i != size/8; ++i)
if(_data[i] != other._data[i]) return false;
/* Check last segment */
if(size%8 && (_data[DataSize-1] & LastSegmentMask) != (other._data[DataSize-1] & LastSegmentMask))
return false;
return true;
}
template<std::size_t size> inline bool BoolVector<size>::all() const {
/* Check all full segments */
for(std::size_t i = 0; i != size/8; ++i)
if(_data[i] != FullSegmentMask) return false;
/* Check last segment */
if(size%8 && (_data[DataSize-1] & LastSegmentMask) != LastSegmentMask)
return false;
return true;
}
template<std::size_t size> inline bool BoolVector<size>::none() const {
/* Check all full segments */
for(std::size_t i = 0; i != size/8; ++i)
if(_data[i]) return false;
/* Check last segment */
if(size%8 && (_data[DataSize-1] & LastSegmentMask))
return false;
return true;
}
template<std::size_t size> inline BoolVector<size> BoolVector<size>::operator~() const {
BoolVector<size> out;
for(std::size_t i = 0; i != DataSize; ++i)
out._data[i] = ~_data[i];
return out;
}
}}
#endif

36
src/Math/Complex.cpp

@ -1,36 +0,0 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 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 "Complex.h"
namespace Magnum { namespace Math {
#ifndef DOXYGEN_GENERATING_OUTPUT
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Complex<Float>&);
#ifndef MAGNUM_TARGET_GLES
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const Complex<Double>&);
#endif
#endif
}}

71
src/Math/Complex.h

@ -37,14 +37,13 @@
namespace Magnum { namespace Math {
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
/* No assertions fired, for internal use */
template<class T> inline static Complex<T> complexFromMatrix(const Matrix<2, T>& matrix) {
/* No assertions fired, for internal use. Not private member because used
from outside the class. */
template<class T> constexpr static Complex<T> complexFromMatrix(const Matrix<2, T>& matrix) {
return {matrix[0][0], matrix[0][1]};
}
}
#endif
/**
@brief %Complex number
@ -65,7 +64,7 @@ template<class T> class Complex {
* @f]
* @see dot() const
*/
inline static T dot(const Complex<T>& a, const Complex<T>& b) {
static T dot(const Complex<T>& a, const Complex<T>& b) {
return a._real*b._real + a._imaginary*b._imaginary;
}
@ -77,7 +76,7 @@ template<class T> class Complex {
* @f]
* @see isNormalized(), Quaternion::angle(), Vector::angle()
*/
inline static Rad<T> angle(const Complex<T>& normalizedA, const Complex<T>& normalizedB) {
static Rad<T> angle(const Complex<T>& normalizedA, const Complex<T>& normalizedB) {
CORRADE_ASSERT(normalizedA.isNormalized() && normalizedB.isNormalized(),
"Math::Complex::angle(): complex numbers must be normalized", Rad<T>(std::numeric_limits<T>::quiet_NaN()));
return Rad<T>(std::acos(normalizedA._real*normalizedB._real + normalizedA._imaginary*normalizedB._imaginary));
@ -92,7 +91,7 @@ template<class T> class Complex {
* @f]
* @see angle(), Matrix3::rotation(), Quaternion::rotation()
*/
inline static Complex<T> rotation(Rad<T> angle) {
static Complex<T> rotation(Rad<T> angle) {
return {std::cos(angle.toUnderlyingType()), std::sin(angle.toUnderlyingType())};
}
@ -102,7 +101,7 @@ template<class T> class Complex {
* Expects that the matrix is orthogonal (i.e. pure rotation).
* @see toMatrix(), DualComplex::fromMatrix(), Matrix::isOrthogonal()
*/
inline static Complex<T> fromMatrix(const Matrix<2, T>& matrix) {
static Complex<T> fromMatrix(const Matrix<2, T>& matrix) {
CORRADE_ASSERT(matrix.isOrthogonal(),
"Math::Complex::fromMatrix(): the matrix is not orthogonal", {});
return Implementation::complexFromMatrix(matrix);
@ -115,7 +114,7 @@ template<class T> class Complex {
* c = 1 + i0
* @f]
*/
inline constexpr /*implicit*/ Complex(): _real(T(1)), _imaginary(T(0)) {}
constexpr /*implicit*/ Complex(): _real(T(1)), _imaginary(T(0)) {}
/**
* @brief Construct complex number from real and imaginary part
@ -124,7 +123,7 @@ template<class T> class Complex {
* c = a + ib
* @f]
*/
inline constexpr /*implicit*/ Complex(T real, T imaginary): _real(real), _imaginary(imaginary) {}
constexpr /*implicit*/ Complex(T real, T imaginary): _real(real), _imaginary(imaginary) {}
/**
* @brief Construct complex number from vector
@ -134,16 +133,16 @@ template<class T> class Complex {
* @f]
* @see operator Vector2(), transformVector()
*/
inline constexpr explicit Complex(const Vector2<T>& vector): _real(vector.x()), _imaginary(vector.y()) {}
constexpr explicit Complex(const Vector2<T>& vector): _real(vector.x()), _imaginary(vector.y()) {}
/** @brief Equality comparison */
inline bool operator==(const Complex<T>& other) const {
bool operator==(const Complex<T>& other) const {
return TypeTraits<T>::equals(_real, other._real) &&
TypeTraits<T>::equals(_imaginary, other._imaginary);
}
/** @brief Non-equality comparison */
inline bool operator!=(const Complex<T>& other) const {
bool operator!=(const Complex<T>& other) const {
return !operator==(other);
}
@ -155,15 +154,15 @@ template<class T> class Complex {
* @f]
* @see dot(), normalized()
*/
inline bool isNormalized() const {
bool isNormalized() const {
return Implementation::isNormalizedSquared(dot());
}
/** @brief Real part */
inline constexpr T real() const { return _real; }
constexpr T real() const { return _real; }
/** @brief Imaginary part */
inline constexpr T imaginary() const { return _imaginary; }
constexpr T imaginary() const { return _imaginary; }
/**
* @brief Convert complex number to vector
@ -173,9 +172,9 @@ template<class T> class Complex {
* @f]
*/
#ifndef CORRADE_GCC44_COMPATIBILITY
inline constexpr explicit operator Vector2<T>() const {
constexpr explicit operator Vector2<T>() const {
#else
inline constexpr operator Vector2<T>() const {
constexpr operator Vector2<T>() const {
#endif
return {_real, _imaginary};
}
@ -188,7 +187,7 @@ template<class T> class Complex {
* @f]
* @see rotation()
*/
inline Rad<T> angle() const {
Rad<T> angle() const {
return Rad<T>(std::atan2(_imaginary, _real));
}
@ -216,7 +215,7 @@ template<class T> class Complex {
* c_0 + c_1 = (a_0 + a_1) + i(b_0 + b_1)
* @f]
*/
inline Complex<T>& operator+=(const Complex<T>& other) {
Complex<T>& operator+=(const Complex<T>& other) {
_real += other._real;
_imaginary += other._imaginary;
return *this;
@ -227,7 +226,7 @@ template<class T> class Complex {
*
* @see operator+=()
*/
inline Complex<T> operator+(const Complex<T>& other) const {
Complex<T> operator+(const Complex<T>& other) const {
return Complex<T>(*this) += other;
}
@ -238,7 +237,7 @@ template<class T> class Complex {
* -c = -a -ib
* @f]
*/
inline Complex<T> operator-() const {
Complex<T> operator-() const {
return {-_real, -_imaginary};
}
@ -249,7 +248,7 @@ template<class T> class Complex {
* c_0 - c_1 = (a_0 - a_1) + i(b_0 - b_1)
* @f]
*/
inline Complex<T>& operator-=(const Complex<T>& other) {
Complex<T>& operator-=(const Complex<T>& other) {
_real -= other._real;
_imaginary -= other._imaginary;
return *this;
@ -260,7 +259,7 @@ template<class T> class Complex {
*
* @see operator-=()
*/
inline Complex<T> operator-(const Complex<T>& other) const {
Complex<T> operator-(const Complex<T>& other) const {
return Complex<T>(*this) -= other;
}
@ -271,7 +270,7 @@ template<class T> class Complex {
* c \cdot t = ta + itb
* @f]
*/
inline Complex<T>& operator*=(T scalar) {
Complex<T>& operator*=(T scalar) {
_real *= scalar;
_imaginary *= scalar;
return *this;
@ -282,7 +281,7 @@ template<class T> class Complex {
*
* @see operator*=(T)
*/
inline Complex<T> operator*(T scalar) const {
Complex<T> operator*(T scalar) const {
return Complex<T>(*this) *= scalar;
}
@ -293,7 +292,7 @@ template<class T> class Complex {
* \frac c t = \frac a t + i \frac b t
* @f]
*/
inline Complex<T>& operator/=(T scalar) {
Complex<T>& operator/=(T scalar) {
_real /= scalar;
_imaginary /= scalar;
return *this;
@ -304,7 +303,7 @@ template<class T> class Complex {
*
* @see operator/=(T)
*/
inline Complex<T> operator/(T scalar) const {
Complex<T> operator/(T scalar) const {
return Complex<T>(*this) /= scalar;
}
@ -315,7 +314,7 @@ template<class T> class Complex {
* c_0 c_1 = (a_0 + ib_0)(a_1 + ib_1) = (a_0 a_1 - b_0 b_1) + i(a_1 b_0 + a_0 b_1)
* @f]
*/
inline Complex<T> operator*(const Complex<T>& other) const {
Complex<T> operator*(const Complex<T>& other) const {
return {_real*other._real - _imaginary*other._imaginary,
_imaginary*other._real + _real*other._imaginary};
}
@ -329,7 +328,7 @@ template<class T> class Complex {
* @f]
* @see dot(const Complex&, const Complex&), isNormalized()
*/
inline T dot() const {
T dot() const {
return dot(*this, *this);
}
@ -342,7 +341,7 @@ template<class T> class Complex {
* @f]
* @see isNormalized()
*/
inline T length() const {
T length() const {
/** @todo Remove when NaCl's newlib has this fixed */
#ifndef CORRADE_TARGET_NACL_NEWLIB
return std::hypot(_real, _imaginary);
@ -356,7 +355,7 @@ template<class T> class Complex {
*
* @see isNormalized()
*/
inline Complex<T> normalized() const {
Complex<T> normalized() const {
return (*this)/length();
}
@ -367,7 +366,7 @@ template<class T> class Complex {
* c^* = a - ib
* @f]
*/
inline Complex<T> conjugated() const {
Complex<T> conjugated() const {
return {_real, -_imaginary};
}
@ -379,7 +378,7 @@ template<class T> class Complex {
* c^{-1} = \frac{c^*}{|c|^2} = \frac{c^*}{c \cdot c}
* @f]
*/
inline Complex<T> inverted() const {
Complex<T> inverted() const {
return conjugated()/dot();
}
@ -392,7 +391,7 @@ template<class T> class Complex {
* @f]
* @see isNormalized(), inverted()
*/
inline Complex<T> invertedNormalized() const {
Complex<T> invertedNormalized() const {
CORRADE_ASSERT(isNormalized(),
"Math::Complex::invertedNormalized(): complex number must be normalized",
Complex<T>(std::numeric_limits<T>::quiet_NaN(), {}));
@ -407,7 +406,7 @@ template<class T> class Complex {
* @f]
* @see Complex(const Vector2&), operator Vector2(), Matrix3::transformVector()
*/
inline Vector2<T> transformVector(const Vector2<T>& vector) const {
Vector2<T> transformVector(const Vector2<T>& vector) const {
return Vector2<T>((*this)*Complex<T>(vector));
}

18
src/Math/Constants.h

@ -47,10 +47,10 @@ template<class T> struct Constants {
*
* @see Deg, Rad
*/
static inline constexpr T pi();
static constexpr T pi();
static inline constexpr T sqrt2(); /**< @brief Square root of 2 */
static inline constexpr T sqrt3(); /**< @brief Square root of 3 */
static constexpr T sqrt2(); /**< @brief Square root of 2 */
static constexpr T sqrt3(); /**< @brief Square root of 3 */
#endif
};
@ -59,17 +59,17 @@ template<class T> struct Constants {
template<> struct Constants<Double> {
Constants() = delete;
static inline constexpr Double pi() { return 3.141592653589793; }
static inline constexpr Double sqrt2() { return 1.414213562373095; }
static inline constexpr Double sqrt3() { return 1.732050807568877; }
static constexpr Double pi() { return 3.141592653589793; }
static constexpr Double sqrt2() { return 1.414213562373095; }
static constexpr Double sqrt3() { return 1.732050807568877; }
};
#endif
template<> struct Constants<Float> {
Constants() = delete;
static inline constexpr Float pi() { return 3.141592654f; }
static inline constexpr Float sqrt2() { return 1.414213562f; }
static inline constexpr Float sqrt3() { return 1.732050808f; }
static constexpr Float pi() { return 3.141592654f; }
static constexpr Float sqrt2() { return 1.414213562f; }
static constexpr Float sqrt3() { return 1.732050808f; }
};
#endif

42
src/Math/Dual.h

@ -50,7 +50,7 @@ template<class T> class Dual {
*
* Both parts are default-constructed.
*/
inline constexpr /*implicit*/ Dual(): _real(), _dual() {}
constexpr /*implicit*/ Dual(): _real(), _dual() {}
/**
* @brief Construct dual number from real and dual part
@ -59,24 +59,24 @@ template<class T> class Dual {
* \hat a = a_0 + \epsilon a_\epsilon
* @f]
*/
inline constexpr /*implicit*/ Dual(const T& real, const T& dual = T()): _real(real), _dual(dual) {}
constexpr /*implicit*/ Dual(const T& real, const T& dual = T()): _real(real), _dual(dual) {}
/** @brief Equality comparison */
inline bool operator==(const Dual<T>& other) const {
bool operator==(const Dual<T>& other) const {
return TypeTraits<T>::equals(_real, other._real) &&
TypeTraits<T>::equals(_dual, other._dual);
}
/** @brief Non-equality comparison */
inline bool operator!=(const Dual<T>& other) const {
bool operator!=(const Dual<T>& other) const {
return !operator==(other);
}
/** @brief Real part */
inline constexpr T real() const { return _real; }
constexpr T real() const { return _real; }
/** @brief %Dual part */
inline constexpr T dual() const { return _dual; }
constexpr T dual() const { return _dual; }
/**
* @brief Add and assign dual number
@ -85,7 +85,7 @@ template<class T> class Dual {
* \hat a + \hat b = a_0 + b_0 + \epsilon (a_\epsilon + b_\epsilon)
* @f]
*/
inline Dual<T>& operator+=(const Dual<T>& other) {
Dual<T>& operator+=(const Dual<T>& other) {
_real += other._real;
_dual += other._dual;
return *this;
@ -96,7 +96,7 @@ template<class T> class Dual {
*
* @see operator+=()
*/
inline Dual<T> operator+(const Dual<T>& other) const {
Dual<T> operator+(const Dual<T>& other) const {
return Dual<T>(*this)+=other;
}
@ -107,7 +107,7 @@ template<class T> class Dual {
* -\hat a = -a_0 - \epsilon a_\epsilon
* @f]
*/
inline Dual<T> operator-() const {
Dual<T> operator-() const {
return {-_real, -_dual};
}
@ -118,7 +118,7 @@ template<class T> class Dual {
* \hat a - \hat b = a_0 - b_0 + \epsilon (a_\epsilon - b_\epsilon)
* @f]
*/
inline Dual<T>& operator-=(const Dual<T>& other) {
Dual<T>& operator-=(const Dual<T>& other) {
_real -= other._real;
_dual -= other._dual;
return *this;
@ -129,7 +129,7 @@ template<class T> class Dual {
*
* @see operator-=()
*/
inline Dual<T> operator-(const Dual<T>& other) const {
Dual<T> operator-(const Dual<T>& other) const {
return Dual<T>(*this)-=other;
}
@ -140,7 +140,7 @@ template<class T> class Dual {
* \hat a \hat b = a_0 b_0 + \epsilon (a_0 b_\epsilon + a_\epsilon b_0)
* @f]
*/
template<class U> inline Dual<T> operator*(const Dual<U>& other) const {
template<class U> Dual<T> operator*(const Dual<U>& other) const {
return {_real*other._real, _real*other._dual + _dual*other._real};
}
@ -151,7 +151,7 @@ template<class T> class Dual {
* \frac{\hat a}{\hat b} = \frac{a_0}{b_0} + \epsilon \frac{a_\epsilon b_0 - a_0 b_\epsilon}{b_0^2}
* @f]
*/
template<class U> inline Dual<T> operator/(const Dual<U>& other) const {
template<class U> Dual<T> operator/(const Dual<U>& other) const {
return {_real/other._real, (_dual*other._real - _real*other._dual)/(other._real*other._real)};
}
@ -162,7 +162,7 @@ template<class T> class Dual {
* \overline{\hat a} = a_0 - \epsilon a_\epsilon
* @f]
*/
inline Dual<T> conjugated() const {
Dual<T> conjugated() const {
return {_real, -_dual};
}
@ -172,27 +172,27 @@ template<class T> class Dual {
#ifndef DOXYGEN_GENERATING_OUTPUT
#define MAGNUM_DUAL_SUBCLASS_IMPLEMENTATION(Type, Underlying) \
inline Type<T> operator-() const { \
Type<T> operator-() const { \
return Dual<Underlying<T>>::operator-(); \
} \
inline Type<T>& operator+=(const Dual<Underlying<T>>& other) { \
Type<T>& operator+=(const Dual<Underlying<T>>& other) { \
Dual<Underlying<T>>::operator+=(other); \
return *this; \
} \
inline Type<T> operator+(const Dual<Underlying<T>>& other) const { \
Type<T> operator+(const Dual<Underlying<T>>& other) const { \
return Dual<Underlying<T>>::operator+(other); \
} \
inline Type<T>& operator-=(const Dual<Underlying<T>>& other) { \
Type<T>& operator-=(const Dual<Underlying<T>>& other) { \
Dual<Underlying<T>>::operator-=(other); \
return *this; \
} \
inline Type<T> operator-(const Dual<Underlying<T>>& other) const { \
Type<T> operator-(const Dual<Underlying<T>>& other) const { \
return Dual<Underlying<T>>::operator-(other); \
} \
template<class U> inline Type<T> operator*(const Dual<U>& other) const { \
template<class U> Type<T> operator*(const Dual<U>& other) const { \
return Dual<Underlying<T>>::operator*(other); \
} \
template<class U> inline Type<T> operator/(const Dual<U>& other) const { \
template<class U> Type<T> operator/(const Dual<U>& other) const { \
return Dual<Underlying<T>>::operator/(other); \
}
#endif

36
src/Math/DualComplex.cpp

@ -1,36 +0,0 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 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 "DualComplex.h"
namespace Magnum { namespace Math {
#ifndef DOXYGEN_GENERATING_OUTPUT
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const DualComplex<Float>&);
#ifndef MAGNUM_TARGET_GLES
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const DualComplex<Double>&);
#endif
#endif
}}

56
src/Math/DualComplex.h

@ -58,7 +58,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @see angle(), Complex::rotation(), Matrix3::rotation(),
* DualQuaternion::rotation()
*/
inline static DualComplex<T> rotation(Rad<T> angle) {
static DualComplex<T> rotation(Rad<T> angle) {
return {Complex<T>::rotation(angle), {{}, {}}};
}
@ -72,7 +72,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @see translation() const, Matrix3::translation(const Vector2&),
* DualQuaternion::translation(), Vector2::xAxis(), Vector2::yAxis()
*/
inline static DualComplex<T> translation(const Vector2<T>& vector) {
static DualComplex<T> translation(const Vector2<T>& vector) {
return {{}, {vector.x(), vector.y()}};
}
@ -83,7 +83,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @see toMatrix(), Complex::fromMatrix(),
* Matrix3::isRigidTransformation()
*/
inline static DualComplex<T> fromMatrix(const Matrix3<T>& matrix) {
static DualComplex<T> fromMatrix(const Matrix3<T>& matrix) {
CORRADE_ASSERT(matrix.isRigidTransformation(),
"Math::DualComplex::fromMatrix(): the matrix doesn't represent rigid transformation", {});
return {Implementation::complexFromMatrix(matrix.rotationScaling()), Complex<T>(matrix.translation())};
@ -98,9 +98,9 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @todoc Remove workaround when Doxygen is predictable
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
inline constexpr /*implicit*/ DualComplex();
constexpr /*implicit*/ DualComplex();
#else
inline constexpr /*implicit*/ DualComplex(): Dual<Complex<T>>({}, {T(0), T(0)}) {}
constexpr /*implicit*/ DualComplex(): Dual<Complex<T>>({}, {T(0), T(0)}) {}
#endif
/**
@ -110,7 +110,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* \hat c = c_0 + \epsilon c_\epsilon
* @f]
*/
inline constexpr /*implicit*/ DualComplex(const Complex<T>& real, const Complex<T>& dual = Complex<T>(T(0), T(0))): Dual<Complex<T>>(real, dual) {}
constexpr /*implicit*/ DualComplex(const Complex<T>& real, const Complex<T>& dual = Complex<T>(T(0), T(0))): Dual<Complex<T>>(real, dual) {}
/**
* @brief Construct dual complex number from vector
@ -121,9 +121,9 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @todoc Remove workaround when Doxygen is predictable
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
inline constexpr explicit DualComplex(const Vector2<T>& vector);
constexpr explicit DualComplex(const Vector2<T>& vector);
#else
inline constexpr explicit DualComplex(const Vector2<T>& vector): Dual<Complex<T>>({}, Complex<T>(vector)) {}
constexpr explicit DualComplex(const Vector2<T>& vector): Dual<Complex<T>>({}, Complex<T>(vector)) {}
#endif
/**
@ -134,7 +134,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f]
* @see Complex::dot(), normalized()
*/
inline bool isNormalized() const {
bool isNormalized() const {
return Implementation::isNormalizedSquared(lengthSquared());
}
@ -143,7 +143,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
*
* @see Complex::angle()
*/
inline constexpr Complex<T> rotation() const {
constexpr Complex<T> rotation() const {
return this->real();
}
@ -155,7 +155,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f]
* @see translation(const Vector2&)
*/
inline Vector2<T> translation() const {
Vector2<T> translation() const {
return Vector2<T>(this->dual());
}
@ -164,7 +164,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
*
* @see fromMatrix(), Complex::toMatrix()
*/
inline Matrix3<T> toMatrix() const {
Matrix3<T> toMatrix() const {
return Matrix3<T>::from(this->real().toMatrix(), translation());
}
@ -176,7 +176,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f]
* @todo can this be done similarly to dual quaternions?
*/
inline DualComplex<T> operator*(const DualComplex<T>& other) const {
DualComplex<T> operator*(const DualComplex<T>& other) const {
return {this->real()*other.real(), this->real()*other.dual() + this->dual()};
}
@ -188,7 +188,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f]
* @see dualConjugated(), conjugated(), Complex::conjugated()
*/
inline DualComplex<T> complexConjugated() const {
DualComplex<T> complexConjugated() const {
return {this->real().conjugated(), this->dual().conjugated()};
}
@ -200,7 +200,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f]
* @see complexConjugated(), conjugated(), Dual::conjugated()
*/
inline DualComplex<T> dualConjugated() const {
DualComplex<T> dualConjugated() const {
return Dual<Complex<T>>::conjugated();
}
@ -213,7 +213,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @see complexConjugated(), dualConjugated(), Complex::conjugated(),
* Dual::conjugated()
*/
inline DualComplex<T> conjugated() const {
DualComplex<T> conjugated() const {
return {this->real().conjugated(), {-this->dual().real(), this->dual().imaginary()}};
}
@ -226,7 +226,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f]
* @todo Can this be done similarly to dual quaternins?
*/
inline T lengthSquared() const {
T lengthSquared() const {
return this->real().dot();
}
@ -239,7 +239,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f]
* @todo can this be done similarly to dual quaternions?
*/
inline T length() const {
T length() const {
return this->real().length();
}
@ -252,7 +252,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @see isNormalized()
* @todo can this be done similarly to dual quaternions?
*/
inline DualComplex<T> normalized() const {
DualComplex<T> normalized() const {
return {this->real()/length(), this->dual()};
}
@ -265,7 +265,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f]
* @todo can this be done similarly to dual quaternions?
*/
inline DualComplex<T> inverted() const {
DualComplex<T> inverted() const {
return DualComplex<T>(this->real().inverted(), {{}, {}})*DualComplex<T>({}, -this->dual());
}
@ -278,7 +278,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @see isNormalized(), inverted()
* @todo can this be done similarly to dual quaternions?
*/
inline DualComplex<T> invertedNormalized() const {
DualComplex<T> invertedNormalized() const {
return DualComplex<T>(this->real().invertedNormalized(), {{}, {}})*DualComplex<T>({}, -this->dual());
}
@ -292,35 +292,35 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @see DualComplex(const Vector2&), dual(), Matrix3::transformPoint(),
* Complex::transformVector(), DualQuaternion::transformPoint()
*/
inline Vector2<T> transformPoint(const Vector2<T>& vector) const {
Vector2<T> transformPoint(const Vector2<T>& vector) const {
return Vector2<T>(((*this)*DualComplex<T>(vector)).dual());
}
/* Verbatim copy of DUAL_SUBCLASS_IMPLEMENTATION(), as we need to hide
Dual's operator*() and operator/() */
#ifndef DOXYGEN_GENERATING_OUTPUT
inline DualComplex<T> operator-() const {
DualComplex<T> operator-() const {
return Dual<Complex<T>>::operator-();
}
inline DualComplex<T>& operator+=(const Dual<Complex<T>>& other) {
DualComplex<T>& operator+=(const Dual<Complex<T>>& other) {
Dual<Complex<T>>::operator+=(other);
return *this;
}
inline DualComplex<T> operator+(const Dual<Complex<T>>& other) const {
DualComplex<T> operator+(const Dual<Complex<T>>& other) const {
return Dual<Complex<T>>::operator+(other);
}
inline DualComplex<T>& operator-=(const Dual<Complex<T>>& other) {
DualComplex<T>& operator-=(const Dual<Complex<T>>& other) {
Dual<Complex<T>>::operator-=(other);
return *this;
}
inline DualComplex<T> operator-(const Dual<Complex<T>>& other) const {
DualComplex<T> operator-(const Dual<Complex<T>>& other) const {
return Dual<Complex<T>>::operator-(other);
}
#endif
private:
/* Used by Dual operators and dualConjugated() */
inline constexpr DualComplex(const Dual<Complex<T>>& other): Dual<Complex<T>>(other) {}
constexpr DualComplex(const Dual<Complex<T>>& other): Dual<Complex<T>>(other) {}
/* Just to be sure nobody uses this, as it wouldn't probably work with
our operator*() */

36
src/Math/DualQuaternion.cpp

@ -1,36 +0,0 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 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 "DualQuaternion.h"
namespace Magnum { namespace Math {
#ifndef DOXYGEN_GENERATING_OUTPUT
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const DualQuaternion<Float>&);
#ifndef MAGNUM_TARGET_GLES
template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug, const DualQuaternion<Double>&);
#endif
#endif
}}

44
src/Math/DualQuaternion.h

@ -58,7 +58,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* DualComplex::rotation(), Vector3::xAxis(), Vector3::yAxis(),
* Vector3::zAxis(), Vector::isNormalized()
*/
inline static DualQuaternion<T> rotation(Rad<T> angle, const Vector3<T>& normalizedAxis) {
static DualQuaternion<T> rotation(Rad<T> angle, const Vector3<T>& normalizedAxis) {
return {Quaternion<T>::rotation(angle, normalizedAxis), {{}, T(0)}};
}
@ -75,7 +75,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* DualComplex::translation(), Vector3::xAxis(), Vector3::yAxis(),
* Vector3::zAxis()
*/
inline static DualQuaternion<T> translation(const Vector3<T>& vector) {
static DualQuaternion<T> translation(const Vector3<T>& vector) {
return {{}, {vector/T(2), T(0)}};
}
@ -86,7 +86,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* @see toMatrix(), Quaternion::fromMatrix(),
* Matrix4::isRigidTransformation()
*/
inline static DualQuaternion<T> fromMatrix(const Matrix4<T>& matrix) {
static DualQuaternion<T> fromMatrix(const Matrix4<T>& matrix) {
CORRADE_ASSERT(matrix.isRigidTransformation(),
"Math::DualQuaternion::fromMatrix(): the matrix doesn't represent rigid transformation", {});
@ -103,9 +103,9 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* @todoc Remove workaround when Doxygen is predictable
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
inline constexpr /*implicit*/ DualQuaternion();
constexpr /*implicit*/ DualQuaternion();
#else
inline constexpr /*implicit*/ DualQuaternion(): Dual<Quaternion<T>>({}, {{}, T(0)}) {}
constexpr /*implicit*/ DualQuaternion(): Dual<Quaternion<T>>({}, {{}, T(0)}) {}
#endif
/**
@ -115,7 +115,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* \hat q = q_0 + \epsilon q_\epsilon
* @f]
*/
inline constexpr /*implicit*/ DualQuaternion(const Quaternion<T>& real, const Quaternion<T>& dual = Quaternion<T>({}, T(0))): Dual<Quaternion<T>>(real, dual) {}
constexpr /*implicit*/ DualQuaternion(const Quaternion<T>& real, const Quaternion<T>& dual = Quaternion<T>({}, T(0))): Dual<Quaternion<T>>(real, dual) {}
/**
* @brief Construct dual quaternion from vector
@ -127,9 +127,9 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* @todoc Remove workaround when Doxygen is predictable
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
inline constexpr explicit DualQuaternion(const Vector3<T>& vector);
constexpr explicit DualQuaternion(const Vector3<T>& vector);
#else
inline constexpr explicit DualQuaternion(const Vector3<T>& vector): Dual<Quaternion<T>>({}, {vector, T(0)}) {}
constexpr explicit DualQuaternion(const Vector3<T>& vector): Dual<Quaternion<T>>({}, {vector, T(0)}) {}
#endif
/**
@ -140,7 +140,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* @f]
* @see lengthSquared(), normalized()
*/
inline bool isNormalized() const {
bool isNormalized() const {
/* Comparing dual part classically, as comparing sqrt() of it would
lead to overly strict precision */
Dual<T> a = lengthSquared();
@ -153,7 +153,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
*
* @see Quaternion::angle(), Quaternion::axis()
*/
inline constexpr Quaternion<T> rotation() const {
constexpr Quaternion<T> rotation() const {
return this->real();
}
@ -165,7 +165,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* @f]
* @see translation(const Vector3&)
*/
inline Vector3<T> translation() const {
Vector3<T> translation() const {
return (this->dual()*this->real().conjugated()).vector()*T(2);
}
@ -186,7 +186,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* @f]
* @see dualConjugated(), conjugated(), Quaternion::conjugated()
*/
inline DualQuaternion<T> quaternionConjugated() const {
DualQuaternion<T> quaternionConjugated() const {
return {this->real().conjugated(), this->dual().conjugated()};
}
@ -198,7 +198,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* @f]
* @see quaternionConjugated(), conjugated(), Dual::conjugated()
*/
inline DualQuaternion<T> dualConjugated() const {
DualQuaternion<T> dualConjugated() const {
return Dual<Quaternion<T>>::conjugated();
}
@ -211,7 +211,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* @see quaternionConjugated(), dualConjugated(), Quaternion::conjugated(),
* Dual::conjugated()
*/
inline DualQuaternion<T> conjugated() const {
DualQuaternion<T> conjugated() const {
return {this->real().conjugated(), {this->dual().vector(), -this->dual().scalar()}};
}
@ -223,7 +223,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* |\hat q|^2 = \sqrt{\hat q^* \hat q}^2 = q_0 \cdot q_0 + \epsilon 2 (q_0 \cdot q_\epsilon)
* @f]
*/
inline Dual<T> lengthSquared() const {
Dual<T> lengthSquared() const {
return {this->real().dot(), T(2)*Quaternion<T>::dot(this->real(), this->dual())};
}
@ -235,7 +235,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* |\hat q| = \sqrt{\hat q^* \hat q} = |q_0| + \epsilon \frac{q_0 \cdot q_\epsilon}{|q_0|}
* @f]
*/
inline Dual<T> length() const {
Dual<T> length() const {
return Math::sqrt(lengthSquared());
}
@ -244,7 +244,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
*
* @see isNormalized()
*/
inline DualQuaternion<T> normalized() const {
DualQuaternion<T> normalized() const {
return (*this)/length();
}
@ -256,7 +256,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* \hat q^{-1} = \frac{\hat q^*}{|\hat q|^2}
* @f]
*/
inline DualQuaternion<T> inverted() const {
DualQuaternion<T> inverted() const {
return quaternionConjugated()/lengthSquared();
}
@ -269,7 +269,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* @f]
* @see isNormalized(), inverted()
*/
inline DualQuaternion<T> invertedNormalized() const {
DualQuaternion<T> invertedNormalized() const {
CORRADE_ASSERT(isNormalized(),
"Math::DualQuaternion::invertedNormalized(): dual quaternion must be normalized", {});
return quaternionConjugated();
@ -285,7 +285,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* @see DualQuaternion(const Vector3&), dual(), Matrix4::transformPoint(),
* Quaternion::transformVector(), DualComplex::transformPoint()
*/
inline Vector3<T> transformPoint(const Vector3<T>& vector) const {
Vector3<T> transformPoint(const Vector3<T>& vector) const {
return ((*this)*DualQuaternion<T>(vector)*inverted().dualConjugated()).dual().vector();
}
@ -300,7 +300,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* Matrix4::transformPoint(), Quaternion::transformVectorNormalized(),
* DualComplex::transformPointNormalized()
*/
inline Vector3<T> transformPointNormalized(const Vector3<T>& vector) const {
Vector3<T> transformPointNormalized(const Vector3<T>& vector) const {
CORRADE_ASSERT(isNormalized(),
"Math::DualQuaternion::transformPointNormalized(): dual quaternion must be normalized",
Vector3<T>(std::numeric_limits<T>::quiet_NaN()));
@ -311,7 +311,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
private:
/* Used by Dual operators and dualConjugated() */
inline constexpr DualQuaternion(const Dual<Quaternion<T>>& other): Dual<Quaternion<T>>(other) {}
constexpr DualQuaternion(const Dual<Quaternion<T>>& other): Dual<Quaternion<T>>(other) {}
};
/** @debugoperator{Magnum::Math::DualQuaternion} */

24
src/Math/Functions.h

@ -38,29 +38,27 @@
namespace Magnum { namespace Math {
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
template<UnsignedInt exponent> struct Pow {
Pow() = delete;
template<class T> inline constexpr static T pow(T base) {
template<class T> constexpr static T pow(T base) {
return base*Pow<exponent-1>::pow(base);
}
};
template<> struct Pow<0> {
Pow() = delete;
template<class T> inline constexpr static T pow(T) { return 1; }
template<class T> constexpr static T pow(T) { return 1; }
};
}
#endif
/**
* @brief Integral power
*
* Returns integral power of base to the exponent.
*/
template<UnsignedInt exponent, class T> inline constexpr T pow(T base) {
template<UnsignedInt exponent, class T> constexpr T pow(T base) {
return Implementation::Pow<exponent>::pow(base);
}
@ -142,6 +140,14 @@ template<std::size_t size, class T> inline Vector<size, T> min(const Vector<size
}
#endif
/** @overload */
template<class T> inline T min(std::initializer_list<T> list) {
T out(*list.begin());
for(auto it = list.begin()+1; it != list.end(); ++it)
out = min(out, *it);
return out;
}
/**
@brief Maximum
@ -161,6 +167,14 @@ template<std::size_t size, class T> Vector<size, T> max(const Vector<size, T>& a
}
#endif
/** @overload */
template<class T> inline T max(std::initializer_list<T> list) {
T out(*list.begin());
for(auto it = list.begin()+1; it != list.end(); ++it)
out = max(out, *it);
return out;
}
/**
@brief Sign

156
src/Math/Geometry/Distance.h

@ -29,7 +29,6 @@
*/
#include "Math/Functions.h"
#include "Math/Matrix.h"
#include "Math/Vector3.h"
namespace Magnum { namespace Math { namespace Geometry {
@ -46,14 +45,15 @@ class Distance {
* @param point Point
*
* The distance *d* is computed from point **p** and line defined by **a**
* and **b** using @ref Matrix::determinant() "determinant": @f[
* d = \frac{|det(b - a a - point)|} {|b - a|}
* and **b** using @ref Vector2::cross() "perp-dot product": @f[
* d = \frac{|(\boldsymbol b - \boldsymbol a)_\bot \cdot (\boldsymbol a - \boldsymbol p)|} {|\boldsymbol b - \boldsymbol a|}
* @f]
* Source: http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html
* @see linePointSquared(const Vector2&, const Vector2&, const Vector2&)
*/
template<class T> inline static T linePoint(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point) {
return std::abs(Matrix<2, T>(b - a, a - point).determinant())/(b - a).length();
template<class T> static T linePoint(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point) {
const Vector2<T> bMinusA = b - a;
return std::abs(Vector2<T>::cross(bMinusA, a - point))/bMinusA.length();
}
/**
@ -66,9 +66,9 @@ class Distance {
* for comparing distance with other values, because it doesn't
* compute the square root.
*/
template<class T> inline static T linePointSquared(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point) {
Vector2<T> bMinusA = b - a;
return Math::pow<2>(Matrix<2, T>(bMinusA, a - point).determinant())/bMinusA.dot();
template<class T> static T linePointSquared(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point) {
const Vector2<T> bMinusA = b - a;
return Math::pow<2>(Vector2<T>::cross(bMinusA, a - point))/bMinusA.dot();
}
/**
@ -85,7 +85,7 @@ class Distance {
* Source: http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
* @see linePointSquared(const Vector3&, const Vector3&, const Vector3&)
*/
template<class T> inline static T linePoint(const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& point) {
template<class T> static T linePoint(const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& point) {
return std::sqrt(linePointSquared(a, b, point));
}
@ -126,25 +126,7 @@ class Distance {
*
* @see lineSegmentPointSquared()
*/
template<class T> inline static T lineSegmentPoint(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point) {
Vector2<T> pointMinusA = point - a;
Vector2<T> pointMinusB = point - b;
Vector2<T> bMinusA = b - a;
T pointDistanceA = pointMinusA.dot();
T pointDistanceB = pointMinusB.dot();
T bDistanceA = bMinusA.dot();
/* Point is before A */
if(pointDistanceB > bDistanceA + pointDistanceA)
return std::sqrt(pointDistanceA);
/* Point is after B */
if(pointDistanceA > bDistanceA + pointDistanceB)
return std::sqrt(pointDistanceB);
/* Between A and B */
return std::abs(Matrix<2, T>(bMinusA, -pointMinusA).determinant())/std::sqrt(bDistanceA);
}
template<class T> static T lineSegmentPoint(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point);
/**
* @brief %Distance of point from line segment in 2D, squared
@ -152,25 +134,7 @@ class Distance {
* More efficient than lineSegmentPoint() for comparing distance with
* other values, because it doesn't compute the square root.
*/
template<class T> static T lineSegmentPointSquared(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point) {
Vector2<T> pointMinusA = point - a;
Vector2<T> pointMinusB = point - b;
Vector2<T> bMinusA = b - a;
T pointDistanceA = pointMinusA.dot();
T pointDistanceB = pointMinusB.dot();
T bDistanceA = bMinusA.dot();
/* Point is before A */
if(pointDistanceB > bDistanceA + pointDistanceA)
return pointDistanceA;
/* Point is after B */
if(pointDistanceA > bDistanceA + pointDistanceB)
return pointDistanceB;
/* Between A and B */
return Math::pow<2>(Matrix<2, T>(bMinusA, -pointMinusA).determinant())/bDistanceA;
}
template<class T> static T lineSegmentPointSquared(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point);
/**
* @brief %Dístance of point from line segment in 3D
@ -183,7 +147,7 @@ class Distance {
*
* @see lineSegmentPointSquared(const Vector3&, const Vector3&, const Vector3&)
*/
template<class T> inline static T lineSegmentPoint(const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& point) {
template<class T> static T lineSegmentPoint(const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& point) {
return std::sqrt(lineSegmentPointSquared(a, b, point));
}
@ -193,26 +157,86 @@ class Distance {
* More efficient than lineSegmentPoint(const Vector3&, const Vector3&, const Vector3&) for comparing distance with
* other values, because it doesn't compute the square root.
*/
template<class T> static T lineSegmentPointSquared(const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& point) {
Vector3<T> pointMinusA = point - a;
Vector3<T> pointMinusB = point - b;
T pointDistanceA = pointMinusA.dot();
T pointDistanceB = pointMinusB.dot();
T bDistanceA = (b - a).dot();
/* Point is before A */
if(pointDistanceB > bDistanceA + pointDistanceA)
return pointDistanceA;
/* Point is after B */
if(pointDistanceA > bDistanceA + pointDistanceB)
return pointDistanceB;
/* Between A and B */
return Vector3<T>::cross(pointMinusA, pointMinusB).dot()/bDistanceA;
}
template<class T> static T lineSegmentPointSquared(const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& point);
};
/** @todoc Remove workaround when Doxygen is sane */
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> static
#else
template<class T>
#endif
T Distance::lineSegmentPoint(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point) {
const Vector2<T> pointMinusA = point - a;
const Vector2<T> pointMinusB = point - b;
const Vector2<T> bMinusA = b - a;
const T pointDistanceA = pointMinusA.dot();
const T pointDistanceB = pointMinusB.dot();
const T bDistanceA = bMinusA.dot();
/* Point is before A */
if(pointDistanceB > bDistanceA + pointDistanceA)
return std::sqrt(pointDistanceA);
/* Point is after B */
if(pointDistanceA > bDistanceA + pointDistanceB)
return std::sqrt(pointDistanceB);
/* Between A and B */
return std::abs(Vector2<T>::cross(bMinusA, -pointMinusA))/std::sqrt(bDistanceA);
}
/** @todoc Remove workaround when Doxygen is sane */
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> static
#else
template<class T>
#endif
T Distance::lineSegmentPointSquared(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& point) {
const Vector2<T> pointMinusA = point - a;
const Vector2<T> pointMinusB = point - b;
const Vector2<T> bMinusA = b - a;
const T pointDistanceA = pointMinusA.dot();
const T pointDistanceB = pointMinusB.dot();
const T bDistanceA = bMinusA.dot();
/* Point is before A */
if(pointDistanceB > bDistanceA + pointDistanceA)
return pointDistanceA;
/* Point is after B */
if(pointDistanceA > bDistanceA + pointDistanceB)
return pointDistanceB;
/* Between A and B */
return Math::pow<2>(Vector2<T>::cross(bMinusA, -pointMinusA))/bDistanceA;
}
/** @todoc Remove workaround when Doxygen is sane */
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> static
#else
template<class T>
#endif
T Distance::lineSegmentPointSquared(const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& point) {
const Vector3<T> pointMinusA = point - a;
const Vector3<T> pointMinusB = point - b;
const T pointDistanceA = pointMinusA.dot();
const T pointDistanceB = pointMinusB.dot();
const T bDistanceA = (b - a).dot();
/* Point is before A */
if(pointDistanceB > bDistanceA + pointDistanceA)
return pointDistanceA;
/* Point is after B */
if(pointDistanceA > bDistanceA + pointDistanceB)
return pointDistanceB;
/* Between A and B */
return Vector3<T>::cross(pointMinusA, pointMinusB).dot()/bDistanceA;
}
}}}
#endif

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

Loading…
Cancel
Save