Browse Source

Merge branch 'master' into compatibility

Conflicts:
	src/CMakeLists.txt
	src/Context.cpp
	src/DebugTools/Profiler.h
	src/DimensionTraits.h
	src/Magnum.h
	src/Math/Math.h
	src/Math/MathTypeTraits.h
	src/Math/Matrix4.h
	src/Mesh.cpp
	src/Mesh.h
	src/MeshTools/CMakeLists.txt
	src/MeshTools/CompressIndices.cpp
	src/MeshTools/FlipNormals.cpp
	src/MeshTools/Test/TipsifyTest.h
	src/MeshTools/Tipsify.cpp
	src/MeshTools/Transform.h
	src/Physics/Implementation/DebugRenderer.h
	src/Profiler.cpp
	src/SceneGraph/FeatureGroup.h
	src/SceneGraph/Object.hpp
	src/SceneGraph/SceneGraph.h
	src/SizeTraits.h
	src/Test/SwizzleTest.cpp
Vladimír Vondruš 13 years ago
parent
commit
5190ff74e6
  1. 2
      .gitignore
  2. 74
      CMakeLists.txt
  3. 72
      CONTRIBUTING.md
  4. 693
      COPYING
  5. 165
      COPYING.LESSER
  6. 7
      Doxyfile
  7. 6
      PKGBUILD
  8. 2
      PKGBUILD-mingw32
  9. 2
      PKGBUILD-nacl
  10. 2
      PKGBUILD-release
  11. 96
      README.md
  12. 28
      doc/best-practices.dox
  13. 110
      doc/building.dox
  14. 86
      doc/coding-style.dox
  15. 24
      doc/collision-detection.dox
  16. 36
      doc/compilation-speedup.dox
  17. 79
      doc/debug-tools.dox
  18. 33
      doc/features.dox
  19. 142
      doc/mainpage.dox
  20. 151
      doc/matrix-vector.dox
  21. 90
      doc/method-chaining.dox
  22. 51
      doc/namespaces.dox
  23. 51
      doc/portability.dox
  24. 24
      doc/required-extensions.dox
  25. 36
      doc/scenegraph.dox
  26. 31
      doc/tips.dox
  27. 314
      doc/transformations.dox
  28. 99
      doc/types.dox
  29. 24
      doc/unsupported.dox
  30. 24
      external/CMakeLists.txt
  31. 24
      external/GL/CMakeLists.txt
  32. 3
      external/GLES2/gl2ext.h
  33. 24
      external/GLES3/CMakeLists.txt
  34. 4
      external/GLES3/gl3.h
  35. 24
      external/KHR/CMakeLists.txt
  36. 24
      modules/CMakeLists.txt
  37. 97
      modules/FindCorrade.cmake
  38. 24
      modules/FindEGL.cmake
  39. 70
      modules/FindGLEW.cmake
  40. 57
      modules/FindHarfBuzz.cmake
  41. 128
      modules/FindMagnum.cmake
  42. 24
      modules/FindOpenGLES2.cmake
  43. 24
      modules/FindSDL2.cmake
  44. 2
      package/archlinux/magnum-git/PKGBUILD
  45. 250
      src/AbstractFramebuffer.cpp
  46. 310
      src/AbstractFramebuffer.h
  47. 233
      src/AbstractImage.cpp
  48. 465
      src/AbstractImage.h
  49. 101
      src/AbstractResourceLoader.h
  50. 303
      src/AbstractShaderProgram.cpp
  51. 801
      src/AbstractShaderProgram.h
  52. 344
      src/AbstractTexture.cpp
  53. 1255
      src/AbstractTexture.h
  54. 221
      src/Array.h
  55. 127
      src/Buffer.cpp
  56. 369
      src/Buffer.h
  57. 42
      src/BufferImage.cpp
  58. 103
      src/BufferImage.h
  59. 66
      src/BufferTexture.cpp
  60. 261
      src/BufferTexture.h
  61. 33
      src/BufferedImage.cpp
  62. 127
      src/BufferedImage.h
  63. 77
      src/BufferedTexture.cpp
  64. 175
      src/BufferedTexture.h
  65. 159
      src/CMakeLists.txt
  66. 163
      src/Color.h
  67. 218
      src/Context.cpp
  68. 63
      src/Context.h
  69. 149
      src/CubeMapTexture.h
  70. 178
      src/CubeMapTextureArray.h
  71. 27
      src/DebugMarker.cpp
  72. 29
      src/DebugMarker.h
  73. 62
      src/DebugTools/CMakeLists.txt
  74. 58
      src/DebugTools/DebugTools.h
  75. 98
      src/DebugTools/ForceRenderer.cpp
  76. 145
      src/DebugTools/ForceRenderer.h
  77. 45
      src/DebugTools/Implementation/AbstractBoxRenderer.cpp
  78. 50
      src/DebugTools/Implementation/AbstractBoxRenderer.h
  79. 111
      src/DebugTools/Implementation/AbstractShapeRenderer.cpp
  80. 61
      src/DebugTools/Implementation/AbstractShapeRenderer.h
  81. 50
      src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp
  82. 47
      src/DebugTools/Implementation/AxisAlignedBoxRenderer.h
  83. 48
      src/DebugTools/Implementation/BoxRenderer.cpp
  84. 47
      src/DebugTools/Implementation/BoxRenderer.h
  85. 70
      src/DebugTools/Implementation/ForceRendererTransformation.h
  86. 68
      src/DebugTools/Implementation/PointRenderer.cpp
  87. 47
      src/DebugTools/Implementation/PointRenderer.h
  88. 186
      src/DebugTools/ObjectRenderer.cpp
  89. 120
      src/DebugTools/ObjectRenderer.h
  90. 131
      src/DebugTools/Profiler.cpp
  91. 58
      src/DebugTools/Profiler.h
  92. 49
      src/DebugTools/ResourceManager.cpp
  93. 64
      src/DebugTools/ResourceManager.h
  94. 109
      src/DebugTools/ShapeRenderer.cpp
  95. 157
      src/DebugTools/ShapeRenderer.h
  96. 25
      src/DebugTools/Test/CMakeLists.txt
  97. 123
      src/DebugTools/Test/ForceRendererTest.cpp
  98. 37
      src/DebugTools/magnumDebugToolsVisibility.h
  99. 93
      src/DefaultFramebuffer.cpp
  100. 384
      src/DefaultFramebuffer.h
  101. Some files were not shown because too many files have changed in this diff Show More

2
.gitignore vendored

@ -2,4 +2,6 @@ build*
pkg
*.kdev4
*~
*.kate-swp
*.pkg.tar.xz
CMakeLists.txt.user*

74
CMakeLists.txt

@ -1,3 +1,27 @@
#
# 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.
#
# CMake 2.8.8 required for OBJECT library target
cmake_minimum_required(VERSION 2.8)
project(Magnum)
@ -6,29 +30,39 @@ include(CMakeDependentOption)
option(TARGET_GLES "Build for OpenGL ES instead of desktop OpenGL" OFF)
cmake_dependent_option(TARGET_GLES2 "Build for OpenGL ES 2" ON "TARGET_GLES" OFF)
cmake_dependent_option(TARGET_DESKTOP_GLES "Build for OpenGL ES on desktop" OFF "TARGET_GLES" OFF)
# Parts of the library
option(WITH_EVERYTHING "Build everything (doesn't include contexts)" ON)
cmake_dependent_option(WITH_MESHTOOLS "Build MeshTools library" OFF "NOT WITH_EVERYTHING" ON)
cmake_dependent_option(WITH_PHYSICS "Build Physics library" OFF "NOT WITH_EVERYTHING" ON)
cmake_dependent_option(WITH_PRIMITIVES "Builf Primitives library" OFF "NOT WITH_EVERYTHING" ON)
cmake_dependent_option(WITH_SCENEGRAPH "Build SceneGraph library" OFF "NOT WITH_EVERYTHING;NOT WITH_PHYSICS" ON)
cmake_dependent_option(WITH_SHADERS "Build Shaders library" OFF "NOT WITH_EVERYTHING;NOT WITH_PHYSICS" ON)
option(WITH_GLXAPPLICATION "Build GlxApplication library" OFF)
cmake_dependent_option(WITH_XEGLAPPLICATION "Build XEglApplication library" OFF "TARGET_GLES" OFF)
cmake_dependent_option(WITH_GLUTAPPLICATION "Build GlutApplication library" OFF "NOT TARGET_GLES" OFF)
option(WITH_SDL2APPLICATION "Build Sdl2Application library" OFF)
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_SHADERS "Build Shaders 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)
# Library features
cmake_dependent_option(USE_HARFBUZZ "Use HarfBuzz in Text library" ON "WITH_TEXT" OFF)
# Application libraries
if(${CMAKE_SYSTEM_NAME} STREQUAL NaCl)
option(WITH_NACLAPPLICATION "Build NaClApplication library" OFF)
else()
option(WITH_GLXAPPLICATION "Build GlxApplication library" OFF)
cmake_dependent_option(WITH_WINDOWLESSGLXAPPLICATION "Build WindowlessGlxApplication library" OFF "NOT WITH_MAGNUMINFO" ON)
cmake_dependent_option(WITH_XEGLAPPLICATION "Build XEglApplication library" OFF "TARGET_GLES" OFF)
cmake_dependent_option(WITH_GLUTAPPLICATION "Build GlutApplication library" OFF "NOT TARGET_GLES" OFF)
option(WITH_SDL2APPLICATION "Build Sdl2Application library" OFF)
endif()
option(BUILD_TESTS "Build unit tests." OFF)
option(BUILD_TESTS "Build unit tests." OFF)
if(BUILD_TESTS)
enable_testing()
endif()
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${Magnum_SOURCE_DIR}/modules/")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/modules/")
if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION} VERSION_LESS 2.8.8)
set(CMAKE_NO_OBJECT_TARGET 1)
@ -47,12 +81,14 @@ endif()
# Check dependencies
find_package(Corrade REQUIRED)
if(NOT TARGET_GLES)
if(NOT TARGET_GLES OR TARGET_DESKTOP_GLES)
find_package(OpenGL REQUIRED)
find_package(GLEW REQUIRED)
else()
find_package(OpenGLES2 REQUIRED)
endif()
if(NOT TARGET_GLES)
find_package(GLEW REQUIRED)
endif()
# Configuration variables (saved later to corradeConfigure.h)
if(TARGET_GLES)
@ -61,8 +97,16 @@ endif()
if(TARGET_GLES2)
set(MAGNUM_TARGET_GLES2 1)
endif()
if(TARGET_DESKTOP_GLES)
set(MAGNUM_TARGET_DESKTOP_GLES 1)
endif()
if(USE_HARFBUZZ)
set(MAGNUM_USE_HARFBUZZ 1)
endif()
# Installation paths
include(CorradeLibSuffix)
set(MAGNUM_BINARY_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/bin)
set(MAGNUM_LIBRARY_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX})
set(MAGNUM_CMAKE_MODULE_INSTALL_DIR ${CMAKE_ROOT}/Modules)
set(MAGNUM_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/Magnum)

72
CONTRIBUTING.md

@ -4,41 +4,51 @@ To make things easier, here are a few tips:
Reporting bugs, requesting features
-----------------------------------
- Best way to report bugs and request new features is to use GitHub
[issues](https://github.com/mosra/magnum/issues), but you can contact me
also any other way.
* Best way to report bugs and request new features is to use GitHub
[issues](https://github.com/mosra/magnum/issues), but you can contact me
also any other way.
Code contribution
-----------------
- Building and installing Magnum is described in the
[documentation](http://mosra.cz/blog/magnum-doc/building.html).
- Follow the project coding guidelines. In short - try to match style of
surrounding code and avoid any trailing whitespace. When in doubt, consult
coding guidelines, which are available also
[online](http://mosra.cz/blog/magnum-doc/coding-style.html).
- Document your code. When updating or adding new API, make sure that Doxygen
documentation is up to date. Run
doxygen
in project root to generate the documentation and check that your
modifications didn't add any warnings.
- Build unit tests (`-DBUILD_TESTS=ON` parameter to CMake) and run them
using
ctest --output-on-failure
in build directory. All tests should always pass. Add new tests or modify
the existing to make sure new code is properly covered (if possible). Here
is a [short tutorial](http://mosra.cz/blog/corrade-doc/unit-testing.html) to
help you with creating unit tests.
- Best way to contribute is by using GitHub
[pull requests](https://github.com/mosra/magnum/pulls) - fork the repository
and make pull request from feature branch. You can also send patches via
e-mail or contact me any other way.
- All your code will be released under license of the project, so make sure
you (or your employers) have no problems with it.
* Building and installing Magnum is described in the [documentation](http://mosra.cz/blog/magnum-doc/building.html).
* Follow the project coding guidelines. In short -- try to match style of the
surrounding code and avoid any trailing whitespace. When in doubt, consult
coding guidelines, which are available also [online](http://mosra.cz/blog/magnum-doc/coding-style.html).
* Document your code. When updating or adding new API, make sure that Doxygen
documentation is up to date. Run
doxygen
in project root to generate the documentation and check that your
modifications didn't add any warnings.
* Build unit tests (`-DBUILD_TESTS=ON` parameter to CMake) and run them
using
ctest --output-on-failure
in build directory. All tests should *always* pass. Add new tests or modify
the existing to make sure new code is properly covered (if possible). Here
is a [short tutorial](http://mosra.cz/blog/corrade-doc/unit-testing.html)
to help you with creating unit tests.
* Best way to contribute is by using GitHub [pull requests](https://github.com/mosra/magnum/pulls)
-- fork the repository and make pull request from feature branch. You can
also send patches via e-mail or contact me any other way.
* All your code will be released under license of the project (see [COPYING](COPYING)
file for details), so make sure you and your collaborators (or employers)
have no problems with it. If you create new files, don't forget to add
license header (verbatim copied from other files) and don't forget to add
yourself to license header of files you added or significantly modified,
for example:
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
Copyright © YEAR YOUR_NAME <your@mail.com>
Permission is hereby granted, free of charge, to any person obtaining a
...
Contact
-------

693
COPYING

@ -1,674 +1,19 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
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.

165
COPYING.LESSER

@ -1,165 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

7
Doxyfile

@ -202,6 +202,7 @@ ALIASES = \
"todoc=@xrefitem todoc \"Documentation todo\" \"Documentation-related todo list\"" \
"fn_gl{1}=<a href=\"http://www.opengl.org/sdk/docs/man4/xhtml/gl\1.xml\">gl\1()</a>" \
"fn_gl_extension{3}=<a href=\"http://www.opengl.org/registry/specs/\2/\3.txt\">gl\1<b></b>\2()</a>" \
"fn_gles_extension{3}=<a href=\"http://www.khronos.org/registry/gles/extensions/\2/\2_\3.txt\">gl\1<b></b>\2()</a>" \
"def_gl{1}=`GL_\1`" \
"requires_gl30=@xrefitem requires-gl30 \"Requires OpenGL 3.0\" \"Functionality requiring OpenGL 3.0\"" \
"requires_gl31=@xrefitem requires-gl31 \"Requires OpenGL 3.1\" \"Functionality requiring OpenGL 3.1\"" \
@ -1189,7 +1190,7 @@ EXT_LINKS_IN_WINDOW = NO
# to manually remove any form_*.png images from the HTML output directory
# to force them to be regenerated.
FORMULA_FONTSIZE = 10
FORMULA_FONTSIZE = 12
# Use the FORMULA_TRANPARENT tag to determine whether or not the images
# generated for formulas are transparent PNGs. Transparent PNGs are
@ -1670,7 +1671,7 @@ DOT_FONTPATH =
# indirect inheritance relations. Setting this tag to YES will force the
# CLASS_DIAGRAMS tag to NO.
CLASS_GRAPH = YES
CLASS_GRAPH = NO
# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
@ -1737,7 +1738,7 @@ CALLER_GRAPH = NO
# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
# will generate a graphical hierarchy of all classes instead of a textual one.
GRAPHICAL_HIERARCHY = YES
GRAPHICAL_HIERARCHY = NO
# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES
# then doxygen will show the dependencies a directory has on other directories

6
PKGBUILD

@ -5,7 +5,7 @@ pkgrel=1
pkgdesc="OpenGL 3 graphics engine"
arch=('i686' 'x86_64')
url="https://github.com/mosra/magnum"
license=('LGPLv3')
license=('MIT')
depends=('corrade' 'glew')
makedepends=('cmake')
options=(!strip)
@ -15,6 +15,10 @@ build() {
mkdir -p "$startdir/build"
cd "$startdir/build/"
# Disable optimization (saves A LOT of compilation time)
newcxxflags=$(echo $CXXFLAGS | sed s/-O.//g | sed s/-D_FORTIFY_SOURCE=.//g)
export CXXFLAGS="$newcxxflags"
if [ "$CXX" = clang++ ] ; then
newcxxflags=$(echo $CXXFLAGS | sed s/--param=ssp-buffer-size=4//g)
export CXXFLAGS="$newcxxflags"

2
PKGBUILD-mingw32

@ -5,7 +5,7 @@ pkgrel=1
pkgdesc="OpenGL 3 graphics engine (mingw32)"
arch=('any')
url="https://github.com/mosra/magnum"
license=('LGPLv3')
license=('MIT')
depends=('mingw32-runtime' 'mingw32-corrade' 'mingw32-glew')
makedepends=('mingw32-gcc' 'cmake' 'corrade')
options=(!buildflags !strip)

2
PKGBUILD-nacl

@ -5,7 +5,7 @@ pkgrel=1
pkgdesc="OpenGL 3 graphics engine (NaCl x86-64 version)"
arch=('any')
url="https://github.com/mosra/magnum"
license=('LGPLv3')
license=('MIT')
depends=('nacl-corrade')
makedepends=('nacl-sdk' 'cmake')
options=(!buildflags !strip)

2
PKGBUILD-release

@ -5,7 +5,7 @@ pkgrel=1
pkgdesc="OpenGL 3 graphics engine"
arch=('i686' 'x86_64')
url="https://github.com/mosra/magnum"
license=('LGPLv3')
license=('MIT')
depends=('corrade' 'glew')
makedepends=('cmake' 'qt')
provides=('magnum-git')

96
README.md

@ -1,30 +1,60 @@
Magnum is 3D graphics engine written in C++11 and OpenGL 3 Core Profile.
Features:
* Easy-to-use templated mathematical library for matrix/vector calculations
and geometry.
* Classes wrapping OpenGL objects and simplifying their usage - shaders,
buffers, meshes and textures. Access to framebuffer and occlusion queries.
* Mesh tools for cleaning, optimizing and generating meshes, utility classes
for color conversion, timeline and profiling.
* Hierarchical scene graph which supports transformation caching for better
performance, physics library for collision detection and rigid body
dynamics.
* Plugin-based data exchange framework for importing image, mesh, material
and scene data in various formats.
* Collection of pre-made graphic primitives and shaders for testing purposes.
* Classes for creating OpenGL-enabled applications with various toolkits,
methods for querying supported OpenGL version and available extensions.
* Comprehensive use of C++11 features for safety, performance and ease of
development. All code which doesn't directly interact with OpenGL is
covered with unit tests.
* Actively maintained Doxygen documentation. Occasionally updated snapshot is
also available online at http://mosra.cz/blog/magnum-doc/ .
Magnum is 2D/3D graphics engine written in C++11 and OpenGL 3 Core Profile.
DESIGN GOALS
============
* **2D is not an ugly stepchild**
Many engines out there are either purely 2D or 3D and if you want to do
your next project in 2D only, you have to either relearn another engine
from scratch or emulate it in 3D, leaving many things overly complicated.
Magnum treats 2D equivalently to 3D so you can reuse what you already
learned for 3D and even combine 2D and 3D in one project.
* **Forward compatibility**
If newer technology makes things faster, simpler or more intuitive, it is
the way to go. If you then really need to, you can selectively backport
some features and it will be easier than maintaining full backward
compatibility by default. Magnum by default relies on decent C++11 support
and modern OpenGL features, but compatibility functions for older hardware
and compatibility branch for older compilers are available if you need
them.
* **Intuitive, but not restrictive API**
Scripting languages are often preferred to C/C++ because they tend to do
more with less -- less complicated APIs, nicer syntax and less boilerplate
code. Magnum is designed with scripting language intuitivity in mind, but
also with speed and static checks that native code and strong typing
offers. Usually the most common way is the most simple, but if you need
full control, you can have it.
* **Extensible and replaceable components**
If you want to use different mathematical library for specific purposes,
that new windowing toolkit, your own file formats or another physics
library, you can. Conversion of data between different libraries can be
done on top of pre-made skeleton classes, support for file formats is done
using plugins and platform support is done by writing simple wrapper class.
FEATURES
========
* Actively maintained Doxygen documentation with tutorials and examples.
Snapshot is available at http://mosra.cz/blog/magnum-doc/.
* Vector and matrix library with implementation of complex numbers,
quaternions and their dual counterparts for representing transformations.
* Classes wrapping OpenGL and simplifying its usage with direct state access
and automatic fallback for unavailable features.
* Extensible scene graph which can be modified for each specific usage.
* Plugin-based data exchange framework, tools for manipulating meshes,
textures and images.
* Integration with various windowing toolkits and also ability to create
windowless contexts.
* Pre-made shaders, primitives and other tools for easy prototyping and
debugging.
INSTALLATION
============
You can either use packaging scripts, which are stored in package/
You can either use packaging scripts, which are stored in `package/`
subdirectory, or compile and install everything manually. Note that Doxygen
documentation (see above or build your own using instructions below) contains
more comprehensive guide for building, packaging and crosscompiling.
@ -38,7 +68,7 @@ Minimal dependencies
* **CMake** >= 2.8.8 (needed for `OBJECT` library target)
* **GLEW** - OpenGL extension wrangler (only if targeting desktop OpenGL)
* **Corrade** - Plugin management and utility library. You can get it at
http://github.com/mosra/corrade or at http://mosra.cz/blog/corrade.php.
https://github.com/mosra/corrade.
Compilation, installation
-------------------------
@ -53,6 +83,9 @@ installed using these four commands:
make
make install
See Doxygen documentation for more information about enabling or disabling
additional features and targeting different platforms such as OpenGL ES.
Building and running unit tests
-------------------------------
@ -82,12 +115,11 @@ PLUGINS AND EXAMPLES
====================
Various importer plugins for image and 3D model formats are maintained in
separate repository, which can be found at
http://github.com/mosra/magnum-plugins .
separate repository, which can be found at https://github.com/mosra/magnum-plugins.
There are also examples of engine usage, varying from simple *Hello
World*-like example to more advanced applications, such as viewer for complex
3D models. Example repository is at http://github.com/mosra/magnum-examples .
There are also examples of engine usage, varying from simple *Hello World*-like
example to more advanced applications, such as viewer for complex 3D models.
Example repository is at https://github.com/mosra/magnum-examples.
CONTACT
=======
@ -99,3 +131,9 @@ awesome idea? Feel free to visit my website or contact me at:
* GitHub - https://github.com/mosra/magnum
* E-mail - mosra@centrum.cz
* Jabber - mosra@jabbim.cz
LICENSE
=======
Magnum is licensed under MIT/Expat license, see [COPYING](COPYING) file for
details.

28
doc/best-practices.dox

@ -1,3 +1,27 @@
/*
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 {
/** @page best-practices Best practices and platform-specific information
@ -38,5 +62,9 @@ cannot be later rebound to @ref Buffer::Target "Target::Element". However,
internally (e.g. for setting data or copying). To avoid this, set target hint
to desired target, either in constructor or using Buffer::setTargetHint().
@subsection best-practices-powervr PowerVR hardware
- [PowerVR Performance Recommendations](http://www.imgtec.com/powervr/insider/docs/PowerVR.Performance%20Recommendations.1.0.28.External.pdf) [PDF]
*/
}

110
doc/building.dox

@ -1,3 +1,27 @@
/*
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 {
/** @page building Downloading and building
@brief Guide how to download and build %Magnum on different platforms.
@ -55,33 +79,60 @@ If you want to build with another compiler (e.g. Clang), pass
@subsection building-optional Enabling or disabling features
By default the engine is built for desktop OpenGL. If you want to target
OpenGL ES, set `TARGET_GLES` to `ON` or pass `-DTARGET_GLES=ON` to CMake. Note
that some features are available for desktop OpenGL only, see @ref requires-gl.
By default the engine is built with everything except
@ref Platform "application libraries". Using `WITH_*` CMake parameters you can
specify which parts will be built and which not:
- `WITH_EVERYTHING` - Defaults to `ON`, builds everything except window
contexts. If set to `OFF`, only the main library is built and you can
select additional libraries with the following:
- `WITH_MESHTOOLS` - MeshTools library.
- `WITH_PHYSICS` - Physics library.
- `WITH_PRIMITIVES` - Primitives library.
- `WITH_SCENEGRAPH` - SceneGraph library.
- `WITH_SHADERS` - Shaders library.
None of the application libraries is built by default, regardless to
`WITH_EVERYTHING` is enabled or not:
- `WITH_XEGLAPPLICATION` - X/EGL application, available only if targeting
OpenGL ES (see above). Requires **X11** and **EGL** libraries.
- `WITH_GLXAPPLICATION` - GLX application. Requires **X11** and **GLX**
libraries.
- `WITH_GLUTAPPLICATION` - GLUT application, available only if targeting
desktop OpenGL. Requires **GLUT** library.
- `WITH_SDL2APPLICATION` - SDL2 application. Requires **SDL2** library.
By default the engine is built for desktop OpenGL. Using `TARGET_*` CMake
parameters you can target other platforms. Note that some features are available
for desktop OpenGL only, see @ref requires-gl.
- `TARGET_GLES` - Target OpenGL ES.
- `TARGET_GLES2` - Target OpenGL ES 2.0. Currently enabled by default when
`TARGET_GLES` is set, as no customer OpenGL ES 3.0 platform exists yet.
- `TARGET_DESKTOP_GLES` - Target OpenGL ES on desktop, i.e. use OpenGL ES
emulation in desktop OpenGL library. Might not be supported in all drivers.
By default the engine is built with everything except application libraries (see
below). Using `WITH_*` CMake parameters you can specify which parts will be built
and which not:
- `WITH_DEBUGTOOLS` - DebugTools library. Enables also building of MeshTools,
Physics, Primitives, SceneGraph and Shaders 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.
- `WITH_SHADERS` - Shaders library. Enabled automatically if `WITH_DEBUGTOOLS`
is enabled.
- `WITH_TEXT` - Text library. Enables also building of TextureTools library.
Requires **FreeType** and possibly **HarfBuzz** library (see below).
- `WITH_TEXTURETOOLS` - TextureTools library. Enabled automatically if `WITH_TEXT`
is enabled.
- `WITH_MAGNUMINFO` - `magnum-info` executable, provides information about the
engine and OpenGL capabilities.
Some dependencies are optional, although disabling them might reduce some
functionality:
- `USE_HARFBUZZ` - Defaults to `ON`, disabling it will result in worse text
rendering (no kerning & ligatures) and possible issues with non-Latin text.
None of the @ref Platform "application libraries" is built by default (and you
need at least one). Choose the one which suits your requirements and your
platform best:
- `WITH_XEGLAPPLICATION` - @ref Platform::XEglApplication "XEglApplication",
available only if targeting OpenGL ES (see above). Requires **X11** and
**EGL** libraries.
- `WITH_GLXAPPLICATION` - @ref Platform::GlxApplication "GlxApplication".
Requires **X11** and **GLX** libraries.
- `WITH_WINDOWLESSGLXAPPLICATION` - @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication".
Requires **X11** and **GLX** libraries.
- `WITH_GLUTAPPLICATION` - @ref Platform::GlutApplication "GlutApplication",
available only if targeting desktop OpenGL. Requires **GLUT** library.
- `WITH_SDL2APPLICATION` - @ref Platform::Sdl2Application "Sdl2Application".
Requires **SDL2** library.
@subsection building-tests Building and running unit tests
@ -159,9 +210,10 @@ You will need [Native Client SDK](https://developers.google.com/native-client/be
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
@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`.
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.
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

86
doc/coding-style.dox

@ -1,3 +1,27 @@
/*
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 {
/** @page coding-style Coding style
@brief Coding style and best practices to preserve maintainability and
@ -27,6 +51,15 @@ have `*.hpp` extension (hinting that they are something between `*.h` and
@subsection cpp-format Code format
@subsubsection cpp-types Builtin types
Use %Magnum's own type aliases for public API (e.g. @ref UnsignedInt, see
@ref types for more information), but use specific types when interacting with
third party libraries and OpenGL (e.g. `GLuint`) and rely only on implicit
conversions when converting between them. This helps avoiding sign, truncation
and other issues, e.g. `%Math::%Vector2<GLsizei>` will implicitly convert to
@ref Vector2i if and only if @ref Int is the same type as `GLsizei`.
@subsubsection cpp-naming Naming
When writing wrappers for OpenGL functions and defines, try to match the
@ -35,12 +68,30 @@ removing redundant prefixes) is encouraged.
@subsubsection cpp-forward-declarations Forward declarations and forward declaration headers
Use forward declarations in headers as much as possible, as it can
significantly reduce time of incremental compilation. When an namespace has
classes which are commonly forward-declared, consider making a forward
declaration header - it should have the same name as the namespace itself and
contain foward declarations for all classes, enums and copies of all
meaningful typedefs. See SceneGraph/SceneGraph.h for an example.
When a namespace has classes which are commonly forward-declared, consider
making a forward declaration header - it should have the same name as the
namespace itself and contain foward declarations for all classes, enums and
copies of all meaningful typedefs. See @ref compilation-forward-declarations
for more information.
@section compatibility Compatibility with various OpenGL editions
If any class, function or part of code depends on particular OpenGL edition
(e.g. only for desktop), use conditional compilation to avoid erors on other
platforms (see @ref portability-target for more information). Put related
documentation also into the conditional compilation block and don't forget to
appropriately mark the class/function (@ref documentation-commands-requires "see below").
Example:
@code
#ifndef MAGNUM_TARGET_GLES
//
// @brief Set polygon mode
//
// @requires_gl Polygon mode is not available in OpenGL ES.
//
void setPolygonMode(PolygonMode mode);
#endif
@endcode
@section documentation Doxygen documentation
@ -69,15 +120,17 @@ with @c \@extension command:
@code
@extension{ARB,timer_query}
@endcode
It produces link to the specification of the extension in OpenGL registry,
e.g. @extension{ARB,timer_query}. Similarly for OpenGL ES extensions there is
@c \@es_extension command. Some extensions have slightly different URL,
with command @c \@es_extension2 you can specify extension filename, if the
previous command gives 404 error. The following produces link to
@es_extension2{NV,read_buffer_front,GL_NV_read_buffer} extension:
It produces link to the specification of the extension in OpenGL registry:
> @extension{ARB,timer_query}
Similarly for OpenGL ES extensions there is @c \@es_extension command. Some
extensions have slightly different URL, with command @c \@es_extension2 you can
specify extension filename, if the previous command gives 404 error. For example
@code
@es_extension2{NV,read_buffer_front,GL_NV_read_buffer}
@endcode
produces this link:
> @es_extension2{NV,read_buffer_front,GL_NV_read_buffer}
@subsubsection documentation-commands-ref_gl Links to related OpenGL functions and definitions
@ -90,9 +143,8 @@ inline static void setSeamless(bool enabled) {
enabled ? glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS) : glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
}
@endcode
It produces link to the online manual, in this case @fn_gl{Enable}/@fn_gl{Disable}
with @def_gl{TEXTURE_CUBE_MAP_SEAMLESS}.
It produces link to the online manual:
> @fn_gl{Enable}/@fn_gl{Disable} with @def_gl{TEXTURE_CUBE_MAP_SEAMLESS}.
For functions which are not part of OpenGL core specification, but only as
extensions, use @c \@fn_gl_extension command, e.g.
@ -101,8 +153,8 @@ extensions, use @c \@fn_gl_extension command, e.g.
@endcode
First parameter is function name without the suffix, the second two parameters
are the same as in @c \@extension command. It produced link to extension
specification, with function name as link text, in this case
@fn_gl_extension{NamedCopyBufferSubData,EXT,direct_state_access}.
specification, with function name as link text:
> @fn_gl_extension{NamedCopyBufferSubData,EXT,direct_state_access}.
@subsubsection documentation-commands-requires Classes and functions requiring specific OpenGL version or extensions

24
doc/collision-detection.dox

@ -1,3 +1,27 @@
/*
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.

36
doc/compilation-speedup.dox

@ -1,3 +1,27 @@
/*
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 {
/** @page compilation-speedup Speeding up compilation
@brief Techniques for reducing compilation times.
@ -19,16 +43,20 @@ some types it can be too cumbersome -- e.g. too many template parameters,
typedefs etc. In this case a header with forward declarations is usually
available, each namespace has its own:
- Math/Math.h
- Magnum.h
- DebugTools/DebugTools.h
- Physics/Physics.h
- SceneGraph/SceneGraph.h
- Shaders/Shaders.h
- Text/Text.h
- Trade/Trade.h
@section compilation-speedup-templates Templates
Many things in %Magnum are templated to allow handling of various types and
sizes of data, for example whole Scene graph can operate either with `float`s
or with `double`s. However, having templated classes and function usually
sizes of data, for example whole Scene graph can operate either with @ref Float
or @ref Double data type. However, having templated classes and function usually
means that the compiler compiles the whole templated code again in each
compilation unit (i.e. source file). In linking stage of the application or
library the duplicates are just thrown out, which is a waste of compilation
@ -60,7 +88,7 @@ Sometimes you however need to use your own specialization and that's why
template implementation files are included in the library. For example we want
to use @ref SceneGraph::Object "Object" from SceneGraph with
@ref SceneGraph::MatrixTransformation3D "MatrixTransformation3D" with
`GLdouble` as underlying type, because our scene will span the whole universe.
@ref Double as underlying type, because our scene will span the whole universe.
We include the implementation file in dedicated source file and explicitly
instantiate the template:
@code
@ -69,7 +97,7 @@ instantiate the template:
using namespace Magnum::SceneGraph;
template class Object<MatrixTransformation3D<GLdouble>>;
template class Object<MatrixTransformation3D<Double>>;
@endcode
All other files using the same object specialization now need to include only
SceneGraph/Object.h header. Thus the Object specialization will be compiled

79
doc/debug-tools.dox

@ -0,0 +1,79 @@
/*
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 {
/** @page debug-tools Debugging helpers
@brief Convenience classes to help you during development.
@tableofcontents
DebugTools library provides various helper classes to help you with
prototyping and debugging applications without the need to write too much
common code. They probably have no usage in production code, but can be useful
in development.
@section debug-tools-renderers Debug renderers
%Debug renderers provide a way to visualize objects and object features in
@ref scenegraph "scene graph" without the need to mess around with meshes and
shaders. They are implemented as object features, so you can attach any number
of them to any object.
Basic usage involves instancing DebugTools::ResourceManager and keeping it for
for the whole lifetime of debug renderers. Next you need some SceneGraph::DrawableGroup
instance. You can use the same group as for the rest of your scene, but
preferrably use dedicated one for debug renderers, so you can easily enable or
disable debug rendering.
Next step is to create configuration for your debug renderers and create
particular debug renderer. The configuration is managed using the resource
manager - you create configuration instance, add it to the manager and then
reference it using particular resource key. This way you can easily share the
same options with more renderers. If no options are specified or resource with
given key doesn't exist, default fallback is used.
Example usage: visualizing object position, rotation and scaling using
DebugTools::ObjectRenderer:
@code
// Global instance of debug resource manager, drawable group for the renderers
DebugTools::ResourceManager manager;
SceneGraph::DrawableGroup3D debugDrawables;
// Create renderer options which will be referenced later by "my" resource key
DebugTools::ResourceManager::instance()->set("my",
(new DebugTools::ObjectRendererOptions())->setSize(0.3f));
// Create debug renderer for given object, use "my" options for it. The
// renderer is automatically added to the object features and also to
// specified drawable group.
Object3D* object;
new DebugTools::ObjectRenderer2D(object, "my", debugDrawables);
@endcode
See DebugTools::ObjectRenderer and DebugTools::ShapeRenderer for more
information.
*/
}

33
doc/features.dox

@ -1,9 +1,36 @@
/*
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 {
/** @page features Feature overview
@brief Fundamental principles and design goals
- @subpage matrix-vector - @copybrief matrix-vector
- @subpage scenegraph - @copybrief scenegraph
- @subpage collision-detection - @copybrief collision-detection
- @subpage types -- @copybrief types
- @subpage matrix-vector -- @copybrief matrix-vector
- @subpage transformations -- @copybrief transformations
- @subpage scenegraph -- @copybrief scenegraph
- @subpage collision-detection -- @copybrief collision-detection
- @subpage debug-tools -- @copybrief debug-tools
*/
}

142
doc/mainpage.dox

@ -1,59 +1,91 @@
/*
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 {
/** @mainpage
%Magnum is 3D graphics engine written in C++11 and OpenGL 3 Core Profile.
Features:
- Easy-to-use templated @ref Math "mathematical library" for
@ref matrix-vector "matrix/vector calculations" and
@ref Math::Geometry "geometry".
- Classes wrapping OpenGL objects and simplifying their usage -
@ref AbstractShaderProgram "shaders", @ref Buffer "buffers",
@ref Mesh "meshes" and @ref AbstractTexture "textures". Access to
@ref Framebuffer "framebuffer" and @ref AbstractQuery "occlusion queries".
- @ref MeshTools "Mesh tools" for cleaning, optimizing and generating meshes,
utility classes for @ref Color.h "color conversion", @ref Timeline "timeline"
and @ref Profiler "profiling".
- Hierarchical @ref SceneGraph "scene graph" which supports transformation
caching for better performance, @ref Physics "physics library" for collision
detection and rigid body dynamics.
- Plugin-based @ref Trade "data exchange framework" for importing image, mesh,
material and scene data in various formats.
- Collection of pre-made @ref Primitives "graphic primitives" and
@ref Shaders "shaders" for testing purposes.
- Classes for creating OpenGL-enabled applications with @ref Platform
"various toolkits", methods for querying
@ref Context "supported OpenGL version and available extensions".
- Comprehensive use of C++11 features for safety, performance and ease of
development. All code which doesn't directly interact with OpenGL is
covered with unit tests.
The engine is meant to be run on OpenGL 3 capable hardware, but most of the
functionality is working on OpenGL 2.1 hardware too. The engine can be built
also for OpenGL ES with limited functionality. See also @ref required-extensions.
@section download-build Downloading and building Magnum
%Magnum is 2D/3D graphics engine written in C++11 and OpenGL 3 Core Profile.
Guide @ref building "how to download and build Magnum" on different platforms.
@section mainpage-design-goals Design goals
- **2D is not an ugly stepchild**
Many engines out there are either purely 2D or 3D and if you want to do
your next project in 2D only, you have to either relearn another engine
from scratch or emulate it in 3D, leaving many things overly complicated.
%Magnum treats 2D equivalently to 3D so you can reuse what you already
learned for 3D and even combine 2D and 3D in one project.
@section getting-started Getting started
- **Forward compatibility**
If newer technology makes things faster, simpler or more intuitive, it is
the way to go. If you then really need to, you can selectively backport
some features and it will be easier than maintaining full backward
compatibility by default. %Magnum by default relies on decent C++11 support
and modern OpenGL features, but compatibility functions for older hardware
and compatibility branch for older compilers are available if you need
them.
To get up and running, you must first subclass one of the provided window
context classes and implement required functions. %Magnum provides
implementations for the most common toolkits (such as GLUT, Xlib, or SDL2) in
Platform namespace.
- **Intuitive, but not restrictive API**
Scripting languages are often preferred to C/C++ because they tend to do
more with less -- less complicated APIs, nicer syntax and less boilerplate
code. %Magnum is designed with scripting language intuitivity in mind, but
also with speed and static checks that native code and strong typing
offers. Usually the most common way is the most simple, but if you need
full control, you can have it.
Then you can either draw your meshes directly or use SceneGraph which will
help you with object hierarchy, transformations and resource management.
- **Extensible and replaceable components**
If you want to use different mathematical library for specific purposes,
that new windowing toolkit, your own file formats or another physics
library, you can. Conversion of data between different libraries can be
done on top of pre-made skeleton classes, support for file formats is done
using plugins and platform support is done by writing simple wrapper class.
@subsection getting-started-examples Tutorials and examples
@section mainpage-features Features
- Vector and matrix library with implementation of complex numbers,
quaternions and their dual counterparts for representing transformations.
- Classes wrapping OpenGL and simplifying its usage with direct state access
and automatic fallback for unavailable features.
- Extensible scene graph which can be modified for each specific usage.
- Plugin-based data exchange framework, tools for manipulating meshes,
textures and images.
- Integration with various windowing toolkits and also ability to create
windowless contexts. Ported to OpenGL ES and various platforms.
- Pre-made shaders, primitives and other tools for easy prototyping and
debugging.
@section mainpage-download-build Downloading and building Magnum
Guide @ref building "how to download and build Magnum" on different platforms.
@section mainpage-getting-started Getting started
The best way to get started is to render your first triangle in
@ref example-index "step-by-step tutorial". Then you can dig deeper and try
other examples, read about @ref features "fundamental principles" in the
documentation or start experimenting on your own!
@subsection getting-started-hacking Hacking Magnum
@section mainpage-hacking Hacking Magnum
If you want to hack on this engine, if you spotted a bug, need an feature or
have an awesome idea, you can get a copy of the sources from GitHub and start
@ -69,5 +101,31 @@ Feel free to get more information or contact the author at:
- E-mail - mosra@centrum.cz
- Jabber - mosra@jabbim.cz
@section mainpage-license License
%Magnum is licensed under MIT/Expat license:
>
> Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš &lt;mosra@centrum.cz&gt;
>
> 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.
>
*/
}

151
doc/matrix-vector.dox

@ -1,3 +1,27 @@
/*
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 Math {
/** @page matrix-vector Operations with matrices and vectors
@ -14,9 +38,9 @@ easier.
%Magnum has three main matrix and vector classes: RectangularMatrix, (square)
Matrix and Vector. To achieve greatest code reuse, %Matrix is internally
square %RectangularMatrix and %Vector is internally one-column
%RectangularMatrix. Both vectors and matrices can have arbitrary size (known
at compile time) and can store any meaningful type.
square %RectangularMatrix and %RectangularMatrix is internally array of one or
more %Vector instances. Both vectors and matrices can have arbitrary size
(known at compile time) and can store any arithmetic type.
Each subclass brings some specialization to its superclass and for most common
vector and matrix sizes there are specialized classes Matrix3 and Matrix4,
@ -26,38 +50,34 @@ return the most specialized type known to make subsequent operations more
convenient - columns of %RectangularMatrix are returned as %Vector, but when
accessing columns of e.g. %Matrix3, they are returned as %Vector3.
There are also even more specialized subclasses - Point2D, Point3D for
creating points with homogeneous coordinates and Color3, Color4 for color
handling and conversion.
There are also even more specialized subclasses, e.g. Color3 and Color4 for
color handling and conversion.
@section matrix-vector-construction Constructing matrices and vectors
Default constructors of RectangularMatrix and Vector (and Vector2, Vector3,
Vector4, Color3) create zero-filled objects. Matrix (and Matrix3, Matrix4) is
by default constructed as identity matrix. Point2D and Point3D have
homogeneous component set to one, Color4 has alpha value set to opaque.
by default constructed as identity matrix. Color4 has alpha value set to opaque.
@code
RectangularMatrix<2, 3, int> a; // zero-filled
Vector<3, int> b; // zero-filled
Matrix<3, int> identity; // diagonal set to 1
Matrix<3, int> zero(Matrix<3, int>::Zero); // zero-filled
RectangularMatrix<2, 3, Int> a; // zero-filled
Vector<3, Int> b; // zero-filled
Point2D<int> c; // {0, 0, 1}
Point3D<int> d; // {0, 0, 0, 1}
Matrix<3, Int> identity; // diagonal set to 1
Matrix<3, Int> zero(Matrix<3, Int>::Zero); // zero-filled
Color4<float> black1; // {0.0f, 0.0f, 0.0f, 1.0f}
Color4<Float> black1; // {0.0f, 0.0f, 0.0f, 1.0f}
Color4<unsigned char> black2; // {0, 0, 0, 255}
@endcode
Most common and most efficient way to create matrix or vector is to pass
values of all components to the constructor.
Most common and most efficient way to create vector is to pass all values to
constructor, matrix is created by passing all column vectors to the
constructor.
@code
Matrix3<int> mat(0, 1, 2,
3, 4, 5,
6, 7, 8); // column-major (see explanation why below)
Vector3<Int> vec(0, 1, 2);
Vector3<int> vec(0, 1, 2);
Matrix3<Int> mat({0, 1, 2},
{3, 4, 5},
{6, 7, 8});
@endcode
All constructors check number of passed arguments and the errors are catched
at compile time.
@ -65,43 +85,34 @@ at compile time.
You can specify all components of vector or whole diagonal of square matrix at
once:
@code
Matrix3<int> diag(Matrix3<int>::Identity, 2); // diagonal set to 2, zeros elsewhere
Vector3<int> fill(10); // {10, 10, 10}
@endcode
Vectors are commonly used to specify various axes and scaling coefficients in
transformations, you can use convenience functions instead of typing out all
other elements:
@code
Matrix4::rotation(deg(5.0f), Vector3::xAxis()); // {1.0f, 0.0f, 0.0f}
Matrix3::translation(Vector2::yAxis(2.0f)); // {0.0f, 2.0f}
Matrix4::scaling(Vector3::zScale(-10.0f)); // {1.0f, 1.0f, -10.0f}
Matrix3<Int> diag(Matrix3<Int>::Identity, 2); // diagonal set to 2, zeros elsewhere
Vector3<Int> fill(10); // {10, 10, 10}
@endcode
It is possible to create matrices from other matrices and vectors with the
same row count; vectors from vector and scalar:
@code
RectangularMatrix<2, 3, int> a;
Vector3<int> b, c;
Matrix3<int> mat = Matrix3<int>::from(b, a, c);
Vector<8, int> vec = Vector<8, int>::from(1, b, 2, c);
RectangularMatrix<2, 3, Int> a;
Vector3<Int> b, c;
Matrix3<Int> mat(a, b);
Vector<8, Int> vec(1, b, 2, c);
@endcode
It is also possible to create them from an C-style array. The function does
simple type cast without any copying, so it's possible to conveniently operate
on the array itself:
@code
int[] mat = { 2, 4, 6,
Int[] mat = { 2, 4, 6,
1, 3, 5 };
RectangularMatrix<2, 3, int>::from(mat) *= 2; // mat == { 4, 8, 12, 2, 6, 10 }
RectangularMatrix<2, 3, Int>::from(mat) *= 2; // mat == { 4, 8, 12, 2, 6, 10 }
@endcode
Note that unlike constructors, this function has no way to check whether the
array is long enough to contain all elements, so use with caution.
You can also convert between data types:
You can also *explicitly* convert between data types:
@code
Vector4<float> floating(1.3f, 2.7f, -15.0f, 7.0f);
Vector4<int> integral(Vector4<int>::from(floating)); // {1, 2, -15, 7}
Vector4<Float> floating(1.3f, 2.7f, -15.0f, 7.0f);
Vector4<Int> integral(floating); // {1, 2, -15, 7}
@endcode
@section matrix-vector-component-access Accessing matrix and vector components
@ -110,37 +121,37 @@ Column vectors of matrices and vector components can be accessed using square
brackets, there is also round bracket operator for accessing matrix components
directly:
@code
RectangularMatrix<3, 2, int> a;
RectangularMatrix<3, 2, Int> a;
a[2] /= 2; // third column (column major indexing, see explanation below)
a[0][1] = 5; // first column, second element
a(0, 1) += 3; // first column, second element (preferred)
Vector<3, int> b;
Vector<3, Int> b;
b[1] = 1; // second element
@endcode
For accessing matrix element prefer round bracket operator, as it is possibly
faster than the double square brackets (but never slower) and isn't prone to
compiler mis-optimizations.
Row vectors can be accessed too, but only for reading, and the access is slower
due to the way the matrix is stored (see explanation below):
@code
Vector<2, Int> c = a.row(2); // third row
@endcode
Fixed-size vector subclasses have functions for accessing named components
and subparts:
@code
Vector4<int> a;
int x = a.x();
Vector4<Int> a;
Int x = a.x();
a.y() += 5;
Vector3<int> xyz = a.xyz();
Vector3<Int> xyz = a.xyz();
xyz.xy() *= 5;
@endcode
Color3 and Color4 name their components `rgba` instead of `xyzw`.
For more involved operations with components there are two swizzle() functions,
they have the same features, but one is guaranteed to do most of the work at
compile-time, while the second has more convenient syntax:
For more involved operations with components there is the swizzle() function:
@code
Vector4<int> original(-1, 2, 3, 4);
Vector4<int> bgra = swizzle<'b', 'g', 'r', 'a'>(original); // { 3, 2, -1, 4 }
Vector<6, int> a10rgb = swizzle(original, "a10rgb"); // { 4, 1, 0, -1, 2, 3 }
Vector<4, Int> original(-1, 2, 3, 4);
Vector<4, Int> bgra = swizzle<'b', 'g', 'r', 'a'>(original); // { 3, 2, -1, 4 }
Vector<6, Int> w10xyz = swizzle<'w', '1', '0', 'x', 'y', 'z'>(original); // { 4, 1, 0, -1, 2, 3 }
@endcode
@section matrix-vector-column-major Matrices are column-major and vectors are columns
@ -152,28 +163,24 @@ implications and it may differ from what is common in mathematics:
- Order of template arguments in specification of RectangularMatrix is also
column-major:
@code
RectangularMatrix<2, 3, int> mat; // two columns, three rows
RectangularMatrix<2, 3, Int> mat; // two columns, three rows
@endcode
- Order of components in matrix constructors is also column-major, so the
elements passed in constructor doesn't need to be reordered internally
before putting them into data array:
- Order of components in matrix constructors is also column-major, further
emphasized by requirement that you have to pass directly column vectors:
@code
Matrix3<int> mat(0, 1, 2,
3, 4, 5,
6, 7, 8); // first column is {0, 1, 2}
Matrix3<Int> mat({0, 1, 2},
{3, 4, 5},
{6, 7, 8}); // first column is {0, 1, 2}
@endcode
- Element accessing order is also column-major. It costs virtually no time to
return reference to portion of data array as column vector, thus the bracket
operator is accessing columns. Returned vector has also its own bracket
operator, which is indexing rows. To avoid confusion, first parameter of
round bracket operator is thus also column index.
- Element accessing order is also column-major, thus the bracket operator is
accessing columns. Returned vector has also its own bracket operator, which
is then indexing rows.
@code
mat[0] *= 2; // first column
mat[2][0] = 5; // first element of first column vector
mat(2, 0) += 3; // first element of first column
mat[2][0] = 5; // first element of first column
@endcode
- Various algorithms which commonly operate on matrix rows (such as
@ref Algorithms::GaussJordan "Gauss-Jordan elimination") have faster
@ref Algorithms::gaussJordanInPlace() "Gauss-Jordan elimination") have faster
alternatives which operate on columns. It's then up to user decision to
operate with transposed matrices or use the slower non-transposed
alternative of the algorithm.

90
doc/method-chaining.dox

@ -0,0 +1,90 @@
/*
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 {
/** @page method-chaining Method chaining
@brief Little feature helping to reduce typing and encourage best practices.
Method chaining ([Wikipedia](http://en.wikipedia.org/wiki/Method_chaining)) is a
feature which allows you to chain method calls one after another without
repeatedly specifying variable the method is called on. Its primary goal is to
reduce unnecessary repeated names, improving code readability.
%Magnum uses this feature for configuring OpenGL objects (such as various mesh
and framebuffer options, shader uniforms etc.). Because OpenGL was designed with
"bind-to-modify" approach, most configuration calls need to bind the object
first and only after that change the parameters (unless @extension{EXT,direct_state_access}
extension is available to avoid this). To reduce unneeded bind calls, %Magnum
binds the object only if it is not already bound somewhere. Method chaining
encourages you to configure whole object in one run, effectively reducing the
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->setSubImage(0, {}, diffuse);
carSpecularTexture->setSubImage(0, {}, specular;
carBumpTexture->setSubImage(0, {}, bump);
carDiffuseTexture->generateMipmap();
carSpecularTexture->generateMipmap();
carBumpTexture->generateMipmap();
@endcode
This code is written that similar configuration steps are grouped together,
which might be good when somebody needs to change something for all three
textures at once, but on the other hand the code is cluttered with repeated
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)
->setSubImage(0, {}, diffuse)
->generateMipmap();
carSpecularTexture->setStorage(3, Texture2D::InternalFormat::R8)
->setSubImage(0, {}, diffuse)
->generateMipmap();
carBumpTexture->setStorage(5, Texture2D::InternalFormat::RGB8)
->setSubImage(0, {}, bump)
->generateMipmap();
@endcode
Method chaining is not used on non-configuring functions, such as Framebuffer::clear()
or Mesh::draw(), as these won't be commonly used in conjunction with other
functions anyway.
Method chaining is also used in SceneGraph and other libraries and in some cases
it allows you to just "configure and forget" without even saving the created
object to some variable, for example when adding static object to an scene:
@code
Scene3D scene;
(new MyObject(&scene))
->rotateX(90.0_degf)
->translate({-1.5f, 0.5f, 7.0f});
@endcode
*/
}

51
doc/namespaces.dox

@ -1,3 +1,27 @@
/*
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.
*/
/** @dir magnum
* @brief %Magnum library
*/
@ -47,6 +71,15 @@ Various matrix and vector algorithms.
Functions for computing intersections, distances, areas and volumes.
*/
/** @dir DebugTools
* @brief Namespace Magnum::DebugTools
*/
/** @namespace Magnum::DebugTools
@brief %Debug tools
Debugging helpers, renderers and profilers.
*/
/** @dir MeshTools
* @brief Namespace Magnum::MeshTools
*/
@ -95,6 +128,24 @@ Collision detection system and rigid body objects. See @ref collision-detection
for introduction.
*/
/** @dir Text
* @brief Namespace Magnum::Text
*/
/** @namespace Magnum::Text
@brief %Text rendering
Font texture creation and text layouting.
*/
/** @dir TextureTools
* @brief Namespace Magnum::TextureTools
*/
/** @namespace Magnum::TextureTools
@brief %Texture tools
Tools for generating, compressing and optimizing textures.
*/
/** @dir Trade
* @brief Namespace Magnum::Trade
*/

51
doc/portability.dox

@ -1,3 +1,27 @@
/*
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 {
/** @page portability Writing portable applications
@brief How to support different platforms and different OpenGL capabilities within one codebase.
@ -71,10 +95,20 @@ You can also decide on particular OpenGL version using Context::isVersionSupport
but remember that some features from that version might be available even if
the drivers don't expose that version.
Each feature is marked accordingly if it needs specific extension or specific
OpenGL version. Various classes in %Magnum are taking advantage of some
extensions and enable faster code paths if given extension is available, for
example @ref AbstractShaderProgram-performance-optimization "AbstractShaderProgram",
On the other hand, if you don't want to write fallback code for unsupported
extensions, you can use macros MAGNUM_ASSERT_EXTENSION_SUPPORTED() or
MAGNUM_ASSERT_VERSION_SUPPORTED() to add mandatory requirement of given
extension or version:
@code
MAGNUM_ASSERT_EXTENSION_SUPPORTED(GL::ARB::geometry_shader4);
// just use geometry shader and don't care about old hardware
@endcode
Each class, function or enum value is marked accordingly if it needs specific
extension or specific OpenGL version. Various classes in %Magnum are taking
advantage of some extensions and enable faster code paths if given extension is
available, but also have proper fallback when it's not, for example
@ref AbstractShaderProgram-performance-optimization "AbstractShaderProgram",
@ref AbstractTexture-performance-optimization "AbstractTexture" or
@ref Mesh-performance-optimization "Mesh". See also @ref required-extensions.
@ -121,7 +155,7 @@ Your application might run on Windows box, on some embedded Linux or even in
browser - each platform has different requirements how to create entry point
to the application, how to handle input events, how to create window and
OpenGL context etc. Namespace Platform contains base classes for applications
which are abstracting most of it for your convenience.
which are abstracting out most of it for your convenience.
All the classes support limited form of static polymorphism, which means you
can switch to another base class and probably don't need to change any other
@ -136,7 +170,8 @@ macro is also aliased to MAGNUM_APPLICATION_MAIN() to save you typing.
Example application, which targets both embedded Linux (using plain X and EGL)
and desktop (using SDL2 toolkit). Thanks to static polymorphism most of the
functions will work on both without changes:
functions will work on both without changes, the main difference will be in
particular *Event class implementations:
@code
#ifndef MAGNUM_TARGET_GLES
#include <Platform/Sdl2Application.h>
@ -157,7 +192,7 @@ class MyApplication: public ApplicationBase {
}
protected:
void viewportEvent(const Math::Vector2<GLsizei>& size) override {
void viewportEvent(const Vector2i& size) override {
// ...
}
@ -165,7 +200,7 @@ class MyApplication: public ApplicationBase {
// ...
}
void keyPressEvent(Key key, Modifiers modifiers, const Math::Vector2<int>& position) {
void keyPressEvent(KeyEvent& event) override {
// ...
}
};

24
doc/required-extensions.dox

@ -1,3 +1,27 @@
/*
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.
*/
/** @page required-extensions Functionality requiring specific OpenGL version or extensions
@brief List of functions not available on OpenGL 2.1 / OpenGL ES 2.

36
doc/scenegraph.dox

@ -1,3 +1,27 @@
/*
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 SceneGraph {
/** @page scenegraph Using scene graph
@brief Overview of scene management capabilities.
@ -22,12 +46,12 @@ main components:
Transformation handles object position, rotation etc. and its basic property
is dimension count (2D or 3D) and underlying floating-point type (by default
`float`s are used everywhere, but you can use `double`s too).
@ref Float type is used everywhere, but you can use @ref Double too).
@note All classes in SceneGraph have `GLfloat` as default underlying
floating-point type, which means that you can omit that template parameter
and write just <tt>%AbstractObject<2></tt> or <tt>%MatrixTransformation3D<></tt>
instead of <tt>%AbstractObject<2, GLfloat></tt> and <tt>%MatrixTransformation3D&lt;GLfloat&gt;</tt>.
@note All classes in SceneGraph have Float as default underlying floating-point
type, which means that you can omit that template parameter and write just
<tt>%AbstractObject<2></tt> or <tt>%MatrixTransformation3D<></tt> instead of
<tt>%AbstractObject<2, Float></tt> and <tt>%MatrixTransformation3D&lt;Float&gt;</tt>.
%Scene graph has implementation of transformations in both 2D and 3D, using
either matrices or combination of position and rotation. Each implementation
@ -88,7 +112,7 @@ transformation. For convenience you can use method chaining:
Object3D* next = new Object3D;
next->setParent(another)
->translate(Vector3::yAxis(3.0f))
->rotateY(deg(35.0f));
->rotateY(35.0_degf);
@endcode
@section scenegraph-features Object features

31
doc/tips.dox

@ -1,9 +1,34 @@
/*
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 {
/** @page tips Tips and tricks
@brief Hints for better productivity and performance.
- @subpage portability - @copybrief portability
- @subpage best-practices - @copybrief best-practices
- @subpage compilation-speedup - @copybrief compilation-speedup
- @subpage method-chaining -- @copybrief method-chaining
- @subpage portability -- @copybrief portability
- @subpage best-practices -- @copybrief best-practices
- @subpage compilation-speedup -- @copybrief compilation-speedup
*/
}

314
doc/transformations.dox

@ -0,0 +1,314 @@
/*
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 Math {
/** @page transformations 2D and 3D transformations
@brief Introduction to essential operations on vectors and points.
@tableofcontents
Transformations are essential operations involved in scene management -- object
relations, hierarchies, animations etc. %Magnum provides classes for
transformations in both 2D and 3D. Each class is suited for different purposes,
but their usage is nearly the same to make your life simpler. This page will
explain the basic operation and differences between various representations.
@section transformations-representation Representing transformations
The first and most straightforward way to represent transformations is to use
homogeneous transformation matrix, i.e. Matrix3 for 2D and Matrix4 for 3D. The
matrices are able to represent all possible types of transformations -- rotation,
translation, scaling, reflection etc. and also projective transformation, thus
they are used at the very core of graphics pipeline and are supported natively
in OpenGL.
On the other hand, matrices need 9 or 16 floats to represent the transformation,
which has implications on both memory usage and performance (relatively slow
matrix multiplication). It is also relatively hard to extract transformation
properties (such as rotation angle/axis) from them, interpolate between them or
compute inverse transformation. They suffer badly from so-called floating-point
drift -- e.g. after a few combined rotations the transformation won't be pure
rotation anymore, but will involve also a bit of scaling, shearing and whatnot.
However, you can trade some transformation features for improved performance and
better behavior -- for just a rotation you can use Complex in 2D and Quaternion
in 3D, or DualComplex and DualQuaternion if you want also translation. It is not
possible to represent scaling, reflection or other transformations with them,
but they occupy only 2 or 4 floats (4 or 8 floats in dual versions), can be
easily inverted and interpolated and have many other awesome properties. However,
they are not magic so they also suffer slightly from floating-point drift, but
not too much and the drift can be accounted for more easily than with matrices.
@section transformations-types Transformation types
Transformation matrices and (dual) complex numbers or quaternions have completely
different internals, but they share the same API to achieve the same things,
greatly simplifying their usage. In many cases it is even possible to hot-swap
the transformation class type without changing any function calls.
@subsection transformations-default Default (identity) transformation
Default-constructed Matrix3, Matrix4, Complex, Quaternion, DualComplex and
DualQuaternion represent identity transformation, so you don't need to worry
about them in initialization.
@subsection transformations-rotation Rotation
2D rotation is represented solely by its angle in counterclockwise direction and
rotation transformation can be created by calling Matrix3::rotation(),
Complex::rotation() or DualComplex::rotation(), for example:
@code
auto a = Matrix3::rotation(23.0_degf);
auto b = Complex::rotation(Rad(Constants::pi()/2));
auto c = DualComplex::rotation(-1.57_radf);
@endcode
3D rotation is represented by angle and (three-dimensional) axis. The rotation
can be created by calling Matrix4::rotation(), Quaternion::rotation() or
DualQuaternion::rotation(). The axis must be always of unit length to avoid
redundant normalization. Shortcuts Vector3::xAxis(), Vector3::yAxis() and
Vector3::zAxis() are provided for convenience. %Matrix representation has also
Matrix4::rotationX(), Matrix4::rotationY() and Matrix4::rotationZ() which are
faster than using the generic function for rotation around primary axes.
Examples:
@code
auto a = Quaternion::rotation(60.0_degf, Vector3::xAxis());
auto b = DualQuaternion::rotation(-1.0_degf, Vector3(1.0f, 0.5f, 3.0f).normalized());
auto c = Matrix4::rotationZ(angle);
@endcode
Rotations are always around origin. Rotation about arbitrary point can be done
by applying translation to have the point at origin, performing the rotation and
then translating back. Read below for more information.
@todo DualQuaternion and rotation around arbitrary axis
@subsection transformations-translation Translation
2D translation is defined by two-dimensional vector and can be created with
Matrix3::translation() or DualComplex::translation(). You can use Vector2::xAxis()
or Vector2::yAxis() to translate only along given axis. Examples:
@code
auto a = Matrix3::translation(Vector2::xAxis(-5.0f));
auto b = DualComplex::translation({-1.0f, 0.5f});
@endcode
3D translation is defined by three-dimensional vector and can be created with
Matrix4::translation() or DualQuaternion::translation(). You can use
Vector3::xAxis() and friends also here. Examples:
@code
auto a = Matrix4::translation(vector);
auto b = DualQuaternion::translation(Vector3::zAxis(1.3f));
@endcode
@subsection transformations-scaling Scaling and reflection
Scaling is defined by two- or three-dimensional vector and is represented by
matrices. You can create it with Matrix3::scaling() or Matrix4::scaling(). You
can use Vector3::xScale(), Vector3::yScale(), Vector3::zScale() or their 2D
counterparts to scale along one axis and leave the rest unchanged or call
explicit one-parameter vector constructor to scale uniformly on all axes.
Examples:
@code
auto a = Matrix3::scaling(Vector2::xScale(2.0f));
auto b = Matrix4::scaling({2.0f, -2.0f, 1.5f});
auto c = Matrix4::scaling(Vector3(10.0f));
@endcode
Reflections are defined by normal along which to reflect (i.e., two- or
three-dimensional vector of unit length) and they are also represented by
matrices. Reflection is created with Matrix3::reflection() or Matrix4::reflection().
You can use Vector3::xAxis() and friends also here. Examples:
@code
auto a = Matrix3::reflection(Vector2::yAxis());
auto b = Matrix4::reflection(axis.normalized());
@endcode
Scaling and reflection is also done relative to origin, you can use method
mentioned above to scale or reflect around arbitrary point.
Sscaling and reflection can be (to some extent) also represented by complex
numbers and quaternions, but it has some bad properties and would make some
operations more expensive, so it's not implemented.
@subsection transformations-projective Projective transformations
Projective transformations eploit the full potential of transformation matrices.
In 2D there is only one projection type, which can be created with Matrix3::projection()
and it is defined by area which will be projected into unit rectangle. In 3D
there is orthographic projection, created with Matrix4::orthographicProjection()
and defined by volume to project into unit cube, and perspective projection.
Perspective projection is created with Matrix4::perspectiveProjection() and is
defined either by field-of-view, aspect ratio and distance to near and far plane
of view frustum or by size of near plane, its distance and distance to far
plane. Some examples:
@code
auto a = Matrix3::projection({4.0f, 3.0f});
auto b = Matrix4::orthographicProjection({4.0f, 3.0f, 100.0f});
auto c = Matrix4::perspectiveProjection(35.0_degf, 1.333f, 0.001f, 100.0f);
@endcode
@section transformations-composing Composing and inverting transformations
Transformations (of the same representation) can be composed simply by
multiplying them, it works the same for matrices, complex numbers, quaternions
and their dual counterparts. Order of multiplication matters -- the
transformation on the right-hand side of multiplication is applied first, the
transformation on the left-hand side is applied second. For example, rotation
followed by translation is done like this:
@code
auto a = DualComplex::translation(Vector2::yAxis(2.0f))*
DualComplex::rotation(25.0_degf);
auto b = Matrix4::translation(Vector3::yAxis(5.0f))*
Matrix4::rotationY(25.0_degf);
@endcode
Inverse transformation can be computed using Matrix3::inverted(), Matrix4::inverted(),
Complex::inverted(), Quaternion::inverted(), DualComplex::inverted() or
DualQuaternion::inverted(). %Matrix inversion is quite costly, so if your
transformation involves only translation and rotation, you can use faster
alternatives Matrix3::invertedRigid() and Matrix4::invertedRigid(). If you are
sure that the (dual) complex number or (dual) quaternion is of unit length, you
can use Complex::invertedNormalized(), Quaternion::invertedNormalized(),
DualComplex::invertedNormalized() or DualQuaternion::invertedNormalized() which
is a little bit faster, because it doesn't need to renormalize the result.
@section transformations-transforming Transforming vectors and points
Transformations can be used directly for transforming vectors and points. %Vector
transformation does not involve translation, in 2D can be done using
Matrix3::transformVector() and Complex::transformVector(), in 3D using
Matrix4::transformVector() and Quaternion::transformVector(). For transformation
with normalized quaternion you can use faster alternative Quaternion::transformVectorNormalized().
Example:
@code
auto transformation = Matrix3::rotation(-30.0_degf)*Matrix3::scaling(Vector2(3.0f));
Vector2 transformed = transformation.transformVector({1.5f, -7.9f});
@endcode
Point transformation involves also translation, in 2D is done with
Matrix3::transformPoint() and DualComplex::transformPoint(), in 3D with
Matrix4::transformPoint() and DualQuaternion::transformPoint(). Also here you
can use faster alternative Quaternion::transformPointNormalized():
@code
auto transformation = DualQuaternion::rotation(-30.0_degf, Vector3::xAxis())*
DualQuaternion::translation(Vector3::yAxis(3.0f));
Vector3 transformed = transformation.transformPointNormalized({1.5f, 3.0f, -7.9f});
@endcode
@section transformations-properties Transformation properties and conversion
It is possible to extract some transformation properties from transformation
matrices, particularly translation vector, rotation/scaling part of the matrix
(or pure rotation if the matrix has uniform scaling) and also base vectors:
@code
Matrix4 a;
auto rotationScaling = transformation.rotationScaling();
Vector3 up = transformation.up();
Vector3 right = transformation.right();
Matrix3 b;
auto rotation = b.rotation();
Float xTranslation = b.translation().x();
@endcode
Extracting scaling and rotation from arbitrary transformation matrices is harder
and can be done using Algorithms::svd(). Extracting rotation angle (and axis in
3D) from rotation part is possible using by converting it to complex number or
quaternion, see below.
You can also recreate transformation matrix from rotation and translation parts:
@code
Matrix3 c = Matrix3::from(rotation, {1.0f, 3.0f});
@endcode
%Complex numbers and quaternions are far better in this regard and they allow
you to extract rotation angle using Complex::angle() or Quaternion::angle() or
rotation axis in 3D using Quaternion::axis(). Their dual versions allow to
extract both rotation and translation part using DualComplex::rotation() const,
DualQuaternion::rotation() const, DualComplex::translation() const and
DualQuaternion::translation() const.
@code
DualComplex a;
Rad rotationAngle = a.rotation().angle();
Vector2 translation = a.translation();
Quaternion b;
Vector3 rotationAxis = b.axis();
@endcode
You can convert Complex and Quaternion to rotation matrix using Complex::toMatrix()
and Quaternion::toMatrix() or their dual version to rotation and translation
matrix using DualComplex::toMatrix() and DualQuaternion::toMatrix():
@code
Quaternion a;
auto rotation = Matrix4::from(a.toMatrix(), {});
DualComplex b;
Matrix3 transformation = b.toMatrix();
@endcode
Conversion the other way around is possible only from rotation matrices using
Complex::fromMatrix() or Quaternion::fromMatrix() and from rotation and
translation matrices using DualComplex::fromMatrix() and
DualQuaternion::fromMatrix():
@code
Matrix3 rotation;
auto a = Complex::fromMatrix(rotation.rotationScaling());
Matrix4 transformation;
auto b = DualQuaternion::fromMatrix(transformation);
@endcode
@section transformations-interpolation Transformation interpolation
@todoc Write this when interpolation is done also for (dual) complex numbers and
dual quaternions
@section transformations-normalization Normalizing transformations
When doing multiplicative transformations, e.g. adding rotating to an
transformation many times during an animation, the resulting transformation will
accumulate rounding errors and behave strangely. For transformation matrices
this can't always be fixed, because they can represent any transformation (and
thus no algorithm can't tell if the transformation is in expected form or not).
If you restrict yourselves (e.g. only uniform scaling and no skew), the matrix
can be reorthogonalized using Algorithms::gramSchmidtOrthogonalize() (or
Algorithms::gramSchmidtOrthonormalize(), if you don't have any scaling). You can
also use Algorithms::svd() to more precisely (but way more slowly) account for
the drift. Example:
@code
Matrix4 transformation;
Math::Algorithms::gramSchmidtOrthonormalizeInPlace(transformation);
@endcode
For quaternions and complex number this problem can be solved far more easily
using Complex::normalized(), Quaternion::normalized(), DualComplex::normalized()
and DualQuaternion::normalized(). Transformation quaternions and complex numbers
are always of unit length, thus normalizing them reduces the drift.
@code
DualQuaternion transformation;
transformation = transformation.normalized();
@endcode
*/
}}

99
doc/types.dox

@ -0,0 +1,99 @@
/*
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 {
/** @page types Type system
@brief Type aliases, naming and compatibility with OpenGL and GLSL types
@section types-builtin Builtin types
%Magnum provides typedefs for builtin integral and floating-point arithmetic
types to ensure portability (e.g. Int is *always* 32bit), maintain consistency
and reduce confusion (e.g. `std::int32_t`, `int` and `GLint` all refer to the
same type).
| %Magnum type | Size | Equivalent GLSL type |
| ------------------ | -------------- | -------------------- |
| @ref UnsignedByte | 8bit unsigned | |
| @ref Byte | 8bit signed | |
| @ref UnsignedShort | 16bit unsigned | |
| @ref Short | 16bit signed | |
| @ref UnsignedInt | 32bit unsigned | `uint` |
| @ref Int | 32bit signed | `int` |
| @ref UnsignedLong | 64bit unsigned | |
| @ref Long | 64bit signed | |
| @ref Float | 32bit | `float` |
| @ref Double | 64bit | `double` |
Types not meant to be used in arithmetic (such as `bool` or `std::size_t`) or
types which cannot be directly passed to GLSL shaders (such as `long double`)
have no typedefs.
Types from the above table are then used to define other types. All following
types are aliases of corresponding types in Math namespace. No suffix after type
name means @ref Float underlying type, `ui` means @ref UnsignedInt underlying
type, `i` is @ref Int underlying type and `d` is for @ref Double underlying type.
@section types-matrix Matrix/vector types
| %Magnum vector type | Equivalent GLSL type |
| ---------------------------------------------- | ------------------------- |
| @ref Vector2, @ref Vector3, @ref Vector4 | `vec2`, `vec3`, `vec4` |
| @ref Vector2ui, @ref Vector3ui, @ref Vector4ui | `uvec2`, `uvec3`, `uvec4` |
| @ref Vector2i, @ref Vector3i, @ref Vector4i | `ivec2`, `ivec3`, `ivec4` |
| @ref Vector2d, @ref Vector3d, @ref Vector4d | `dvec2`, `dvec3`, `dvec4` |
| %Magnum matrix type | Equivalent GLSL type |
| --------------------------------- | ------------------------------------ |
| @ref Matrix2 or @ref Matrix2d | `mat2`/`mat2x2` or `dmat2`/`dmat2x2` |
| @ref Matrix3 or @ref Matrix3d | `mat3`/`mat3x3` or `dmat3`/`dmat3x3` |
| @ref Matrix4 or @ref Matrix4d | `mat4`/`mat4x4` or `dmat3`/`dmat4x4` |
| @ref Matrix2x3 or @ref Matrix2x3d | `mat2x3` or `dmat2x3` |
| @ref Matrix3x2 or @ref Matrix3x2d | `mat3x2` or `dmat3x2` |
| @ref Matrix2x4 or @ref Matrix2x4d | `mat2x4` or `dmat2x4` |
| @ref Matrix4x2 or @ref Matrix4x2d | `mat4x2` or `dmat4x2` |
| @ref Matrix3x4 or @ref Matrix3x4d | `mat3x4` or `dmat3x4` |
| @ref Matrix4x3 or @ref Matrix4x3d | `mat4x3` or `dmat4x3` |
Any super- or sub-class of the same size and underlying type can be used
equivalently (e.g. Math::Vector or Color3 instead of @ref Vector3).
@section types-other Other types
Other types, which don't have their GLSL equivalent, are:
- @ref Rectangle, @ref Rectanglei or @ref Rectangled
- @ref Complex or @ref Complexd, @ref DualComplex or @ref DualComplexd
- @ref Quaternion or @ref Quaterniond, @ref DualQuaternion or @ref DualQuaterniond
These types can be used in GLSL either by extracting values from their
underlying structure or converting them to types supported by GLSL (e.g.
quaternion to matrix).
For your convenience, there is also alias for class with often used constants --
@ref Constants or @ref Constantsd.
*/
}

24
doc/unsupported.dox

@ -1,3 +1,27 @@
/*
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.
*/
/** @page unsupported Unsupported OpenGL features
Some functionality, which is either soon-to-be deprecated or isn't proven to

24
external/CMakeLists.txt vendored

@ -1,3 +1,27 @@
#
# 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.
#
if(NOT TARGET_GLES)
add_subdirectory(GL)
else()

24
external/GL/CMakeLists.txt vendored

@ -1 +1,25 @@
#
# 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.
#
install(FILES glcorearb.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/external/GL)

3
external/GLES2/gl2ext.h vendored

@ -1,7 +1,7 @@
#ifndef __gl2ext_h_
#define __gl2ext_h_
/* $Revision: 19436 $ on $Date:: 2012-10-10 10:37:04 -0700 #$ */
/* $Revision: 20040 $ on $Date:: 2013-01-03 01:43:00 -0800 #$ */
#ifdef __cplusplus
extern "C" {
@ -1167,6 +1167,7 @@ typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum
#endif
#ifndef GL_ANGLE_instanced_arrays
#define GL_ANGLE_instanced_arrays 1
#ifdef GL_GLEXT_PROTOTYPES
GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
GL_APICALL void GL_APIENTRY glDrawElementsInstancedANGLE (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);

24
external/GLES3/CMakeLists.txt vendored

@ -1 +1,25 @@
#
# 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.
#
install(FILES gl3.h gl3platform.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/external/GLES3)

4
external/GLES3/gl3.h vendored

@ -2,7 +2,7 @@
#define __gl3_h_
/*
* gl3.h last updated on $Date: 2012-09-12 10:13:02 -0700 (Wed, 12 Sep 2012) $
* gl3.h last updated on $Date: 2012-10-03 07:52:40 -0700 (Wed, 03 Oct 2012) $
*/
#include <GLES3/gl3platform.h>
@ -796,7 +796,7 @@ typedef struct __GLsync *GLsync;
#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F
#define GL_MAX_ELEMENT_INDEX 0x8D6B
#define GL_NUM_SAMPLE_COUNTS 0x9380
#define GL_TEXTURE_IMMUTABLE_LEVELS 0x8D63
#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
/*-------------------------------------------------------------------------
* Entrypoint definitions

24
external/KHR/CMakeLists.txt vendored

@ -1 +1,25 @@
#
# 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.
#
install(FILES khrplatform.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/external/KHR)

24
modules/CMakeLists.txt

@ -1,3 +1,27 @@
#
# 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.
#
if(NOT CMAKE_CROSSCOMPILING)
install(FILES FindMagnum.cmake DESTINATION ${MAGNUM_CMAKE_MODULE_INSTALL_DIR})
endif()

97
modules/FindCorrade.cmake

@ -5,57 +5,41 @@
# This module tries to find Corrade library and then defines:
# CORRADE_FOUND - True if Corrade library is found
# CORRADE_INCLUDE_DIR - Include dir for Corrade
# CORRADE_UTILITY_LIBRARIES - Corrade Utility library and dependent
# libraries
# CORRADE_PLUGINMANAGER_LIBRARIES - Corrade Plugin manager library and
# CORRADE_INTERCONNECT_LIBRARIES - Corrade Interconnect library and
# dependent libraries
# CORRADE_UTILITY_LIBRARIES - Corrade Utility library and
# dependent libraries
# CORRADE_PLUGINMANAGER_LIBRARIES - Corrade PluginManager library and
# dependent libraries
# CORRADE_TESTSUITE_LIBRARIES - Corrade TestSuite library and
# dependent libraries
# CORRADE_TESTSUITE_LIBRARIES - Corrade TestSuite library and dependent
# libraries
# CORRADE_RC_EXECUTABLE - Corrade resource compiler executable
# Additionally these variables are defined for internal usage:
# CORRADE_INTERCONNECT_LIBRARY - Corrade Interconnect library (w/o
# dependencies)
# CORRADE_UTILITY_LIBRARY - Corrade Utility library (w/o
# dependencies)
# CORRADE_PLUGINMANAGER_LIBRARY - Corrade Plugin manager library (w/o
# dependencies)
# CORRADE_TESTSUITE_LIBRARY - Corrade TestSuite library (w/o
# dependencies)
# Corrade configures the compiler to use C++11 standard. Additionally you can
# use CORRADE_CXX_FLAGS to enable additional pedantic set of warnings and enable
# hidden visibility by default.
#
# If Corrade library is found, these macros and functions are defined:
#
#
# Add unit test using Corrade's TestSuite.
# corrade_add_test2(test_name
# sources...
# [LIBRARIES libraries...])
# corrade_add_test(test_name
# sources...
# [LIBRARIES libraries...])
# Test name is also executable name. You can also specify libraries to link
# with instead of using target_link_libraries(). CORRADE_TESTSUITE_LIBRARIES
# are linked atuomatically to each test. Note that the enable_testing()
# function must be called explicitly.
#
#
# Add QtTest unit test.
# corrade_add_test(test_name moc_header source_file
# [libraries...])
# These tests contain mainly from one source file and one header, which is
# processed by Qt meta-object compiler. The executable is then linked to QtCore
# and QtTest library, more libraries can be specified as another parameters.
# Test name is also executable name. Header file is processed with Qt's moc.
#
# Note: Before using this function you must find package Qt4. The
# enable_testing() function must be also called explicitly.
#
#
# Add QtTest unit test with multiple source files.
# corrade_add_multifile_test(test_name
# moc_header_variable
# source_files_variable)
# Useful when there is need to compile more than one cpp/h file into the test.
#
# Example usage:
# set(test_headers ComplexTest.h MyObject.h)
# set(test_sources ComplexTest.cpp MyObject.cpp)
# corrade_add_test(MyComplexTest test_headers test_sources
# CoreLibrary AnotherLibrary)
#
# Compile data resources into application binary.
# corrade_add_resource(name group_name
# file [ALIAS alias]
@ -64,9 +48,7 @@
# generates resource file with group group_name from given files in current
# build directory. Argument name is name under which the resources can be
# explicitly loaded. Variable 'name' contains compiled resource filename,
# which is then used for compiling library / executable.
#
# Example usage:
# which is then used for compiling library / executable. Example usage:
# corrade_add_resource(name group_name file1 ALIAS alias1 file2 file3)
# add_executable(app source1 source2 ... ${name})
#
@ -84,13 +66,10 @@
# plugin_name metadata_file
# sources...)
# The macro adds preprocessor directive CORRADE_STATIC_PLUGIN. Additional
# libraries can be linked in via target_link_libraries(plugin_name ...).
#
# Plugin library name will be added at the end of static_plugins_variable and
# the variable is meant to be used for linking plugins to main
# executable/library, e.g:
# libraries can be linked in via target_link_libraries(plugin_name ...). Plugin
# library name will be appended to static_plugins_variable and the variable is
# meant to be used for linking plugins to main executable/library, e.g:
# target_link_libraries(app lib1 lib2 ... ${static_plugins_variable})
#
# This variable is set with parent scope to be available in parent directory.
# If there are more intermediate directories between plugin directory and main
# executable directory, the variable can be propagated to parent scope like
@ -106,7 +85,33 @@
# DLL is not found, fatal error message is printed.
#
#
# 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.
#
# Libraries
find_library(CORRADE_INTERCONNECT_LIBRARY CorradeInterconnect)
find_library(CORRADE_UTILITY_LIBRARY CorradeUtility)
find_library(CORRADE_PLUGINMANAGER_LIBRARY CorradePluginManager)
find_library(CORRADE_TESTSUITE_LIBRARY CorradeTestSuite)
@ -122,6 +127,7 @@ find_path(CORRADE_INCLUDE_DIR
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Corrade DEFAULT_MSG
CORRADE_UTILITY_LIBRARY
CORRADE_INTERCONNECT_LIBRARY
CORRADE_PLUGINMANAGER_LIBRARY
CORRADE_TESTSUITE_LIBRARY
CORRADE_INCLUDE_DIR
@ -149,9 +155,12 @@ if(NOT _GCC46_COMPATIBILITY EQUAL -1)
endif()
set(CORRADE_UTILITY_LIBRARIES ${CORRADE_UTILITY_LIBRARY})
set(CORRADE_INTERCONNECT_LIBRARIES ${CORRADE_INTERCONNECT_LIBRARY} ${CORRADE_UTILITY_LIBRARIES})
set(CORRADE_PLUGINMANAGER_LIBRARIES ${CORRADE_PLUGINMANAGER_LIBRARY} ${CORRADE_UTILITY_LIBRARIES})
set(CORRADE_TESTSUITE_LIBRARIES ${CORRADE_TESTSUITE_LIBRARY} ${CORRADE_UTILITY_LIBRARIES})
mark_as_advanced(CORRADE_UTILITY_LIBRARY CORRADE_PLUGINMANAGER_LIBRARY CORRADE_TESTSUITE_LIBRARY)
mark_as_advanced(CORRADE_UTILITY_LIBRARY
CORRADE_INTERCONNECT_LIBRARY
CORRADE_PLUGINMANAGER_LIBRARY
CORRADE_TESTSUITE_LIBRARY)
include(CorradeMacros)
include(CorradeLibSuffix)
include(UseCorrade)

24
modules/FindEGL.cmake

@ -7,6 +7,30 @@
# EGL_INCLUDE_DIR - Include dir
#
#
# 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.
#
# Library
find_library(EGL_LIBRARY EGL)

70
modules/FindGLEW.cmake

@ -3,33 +3,65 @@
# This module defines:
#
# GLEW_FOUND - True if GLEW library is found
# GLEW_LIBRARY - GLEW dynamic library
# GLEW_LIBRARIES - GLEW libraries
# GLEW_INCLUDE_DIR - Include dir
#
if(GLEW_LIBRARY AND GLEW_INCLUDE_DIR)
#
# 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.
#
set(GLEW_FOUND TRUE)
# Include dir
find_path(GLEW_INCLUDE_DIR
NAMES GL/glew.h)
# Library
if(NOT WIN32)
find_library(GLEW_LIBRARY GLEW)
set(GLEW_LIBRARIES_ GLEW_LIBRARY)
mark_as_advanced(GLEW_LIBRARY)
else()
find_library(GLEW_LIBRARY_DLL glew32)
find_library(GLEW_LIBRARY_LIB glew32)
set(GLEW_LIBRARIES_ GLEW_LIBRARY_DLL GLEW_LIBRARY_LIB)
mark_as_advanced(GLEW_LIBRARY_DLL GLEW_LIBRARY_LIB)
endif()
# Library
if(NOT WIN32)
find_library(GLEW_LIBRARY GLEW)
else()
find_library(GLEW_LIBRARY glew32)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args("GLEW" DEFAULT_MSG
${GLEW_LIBRARIES_}
GLEW_INCLUDE_DIR)
# Include dir
find_path(GLEW_INCLUDE_DIR
NAMES glew.h
PATH_SUFFIXES GL
)
if(NOT GLEW_FOUND)
return()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args("GLEW" DEFAULT_MSG
GLEW_LIBRARY
GLEW_INCLUDE_DIR
)
unset(GLEW_LIBRARIES_)
if(NOT WIN32)
set(GLEW_LIBRARIES ${GLEW_LIBRARY})
mark_as_advanced(GLEW_LIBRARY)
else()
set(GLEW_LIBRARIES ${GLEW_LIBRARY_DLL} ${GLEW_LIBRARY_LIB})
mark_as_advanced(GLEW_LIBRARY_DLL GLEW_LIBRARY_LIB)
endif()

57
modules/FindHarfBuzz.cmake

@ -0,0 +1,57 @@
# - Find HarfBuzz
#
# This module tries to find HarfBuzz library and then defines:
# HARFBUZZ_FOUND - True if HarfBuzz library is found
# HARFBUZZ_INCLUDE_DIRS - Include dirs
# HARFBUZZ_LIBRARIES - HarfBuzz libraries
#
# Additionally these variables are defined for internal usage:
# HARFBUZZ_INCLUDE_DIR - Include dir (w/o dependencies)
# HARFBUZZ_LIBRARY - HarfBuzz library (w/o dependencies)
#
#
# 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.
#
# Library
find_library(HARFBUZZ_LIBRARY NAMES harfbuzz)
# Include dir
find_path(HARFBUZZ_INCLUDE_DIR
NAMES hb.h
PATH_SUFFIXES harfbuzz
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args("HarfBuzz" DEFAULT_MSG
HARFBUZZ_LIBRARY
HARFBUZZ_INCLUDE_DIR
)
set(HARFBUZZ_INCLUDE_DIRS ${HARFBUZZ_INCLUDE_DIR})
set(HARFBUZZ_LIBRARIES ${HARFBUZZ_LIBRARY})
mark_as_advanced(FORCE
HARFBUZZ_LIBRARY
HARFBUZZ_INCLUDE_DIR)

128
modules/FindMagnum.cmake

@ -15,18 +15,25 @@
# components. The base library depends on Corrade, OpenGL and GLEW
# libraries. Additional dependencies are specified by the components. The
# optional components are:
# MeshTools - MeshTools library
# Physics - Physics library (depends on Primitives, SceneGraph and
# Shaders components)
# Primitives - Library with stock geometric primitives (static)
# SceneGraph - Scene graph library
# Shaders - Library with stock shaders
# GlxApplication - GLX application (depends on X11 libraries)
# XEglApplication - X/EGL application (depends on EGL and X11 libraries)
# GlutApplication - GLUT application (depends on GLUT library)
# Sdl2Application - SDL2 application (depends on SDL2 library)
# NaClApplication - NaCl application (only if targetting Google Chrome
# Native Client)
# DebugTools - DebugTools library (depends on MeshTools, Physics,
# Primitives, SceneGraph and Shaders components)
# MeshTools - MeshTools library
# Physics - Physics library
# Primitives - Library with stock geometric primitives (static)
# SceneGraph - Scene graph library
# Shaders - Library with stock shaders
# Text - Text rendering library (depends on TextureTools
# component, FreeType library and possibly HarfBuzz
# library, see below)
# TextureTools - TextureTools library
# GlxApplication - GLX application (depends on X11 libraries)
# XEglApplication - X/EGL application (depends on EGL and X11 libraries)
# WindowlessGlxApplication - Windowless GLX application (depends on X11
# libraries)
# GlutApplication - GLUT application (depends on GLUT library)
# Sdl2Application - SDL2 application (depends on SDL2 library)
# NaClApplication - NaCl application (only if targetting Google Chrome
# Native Client)
# Example usage with specifying additional components is:
# find_package(Magnum [REQUIRED|COMPONENTS]
# MeshTools Primitives GlutApplication)
@ -35,6 +42,16 @@
# MAGNUM_*_LIBRARIES - Component library and dependent libraries
# MAGNUM_*_INCLUDE_DIRS - Include dirs of module dependencies
#
# Features of found Magnum library are exposed in these variables:
# MAGNUM_TARGET_GLES - Defined if compiled for OpenGL ES
# MAGNUM_TARGET_GLES2 - Defined if compiled for OpenGL ES 2.0
# MAGNUM_TARGET_DESKTOP_GLES - Defined if compiled with OpenGL ES
# emulation on desktop OpenGL
# MAGNUM_TARGET_NACL - Defined if compiled for Google Chrome Native
# Client
# MAGNUM_USE_HARFBUZZ - Defined if HarfBuzz library is used for text
# rendering
#
# Additionally these variables are defined for internal usage:
# MAGNUM_INCLUDE_DIR - Root include dir (w/o
# dependencies)
@ -53,6 +70,30 @@
# directory
#
#
# 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.
#
# Dependencies
find_package(Corrade REQUIRED)
@ -80,13 +121,23 @@ string(FIND "${_magnumConfigure}" "#define MAGNUM_TARGET_NACL" _TARGET_NACL)
if(NOT _TARGET_NACL EQUAL -1)
set(MAGNUM_TARGET_NACL 1)
endif()
string(FIND "${_magnumConfigure}" "#define MAGNUM_TARGET_DESKTOP_GLES" _TARGET_DESKTOP_GLES)
if(NOT _TARGET_DESKTOP_GLES EQUAL -1)
set(MAGNUM_TARGET_DESKTOP_GLES 1)
endif()
string(FIND "${_magnumConfigure}" "#define MAGNUM_USE_HARFBUZZ" _USE_HARFBUZZ)
if(NOT _USE_HARFBUZZ EQUAL -1)
set(MAGNUM_USE_HARFBUZZ 1)
endif()
if(NOT MAGNUM_TARGET_GLES)
if(NOT MAGNUM_TARGET_GLES OR MAGNUM_TARGET_DESKTOP_GLES)
find_package(OpenGL REQUIRED)
find_package(GLEW REQUIRED)
else()
find_package(OpenGLES2 REQUIRED)
endif()
if(NOT MAGNUM_TARGET_GLES)
find_package(GLEW REQUIRED)
endif()
# On Windows, *Application libraries need to have ${MAGNUM_LIBRARY} listed
# in dependencies also after *Application.lib static library name to avoid
@ -152,6 +203,21 @@ foreach(component ${Magnum_FIND_COMPONENTS})
unset(MAGNUM_${_COMPONENT}_LIBRARY)
endif()
endif()
# Windowless GLX application dependencies
if(${component} STREQUAL WindowlessGlxApplication)
find_package(X11)
if(X11_FOUND)
set(_MAGNUM_${_COMPONENT}_LIBRARIES ${X11_LIBRARIES} ${_WINDOWCONTEXT_MAGNUM_LIBRARY_DEPENDENCY})
else()
unset(MAGNUM_${_COMPONENT}_LIBRARY)
endif()
endif()
endif()
# DebugTools library
if(${component} STREQUAL DebugTools)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Profiler.h)
endif()
# Mesh tools library
@ -179,6 +245,28 @@ foreach(component ${Magnum_FIND_COMPONENTS})
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES PhongShader.h)
endif()
# Text library
if(${component} STREQUAL Text)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Font.h)
# Dependencies
find_package(Freetype)
if(NOT FREETYPE_FOUND)
unset(MAGNUM_${_COMPONENT}_LIBRARY)
endif()
if(MAGNUM_USE_HARFBUZZ)
find_package(HarfBuzz)
if(NOT HARFBUZZ_FOUND)
unset(MAGNUM_${_COMPONENT}_LIBRARY)
endif()
endif()
endif()
# TextureTools library
if(${component} STREQUAL TextureTools)
set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Atlas.h)
endif()
# Try to find the includes
if(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES)
find_path(_MAGNUM_${_COMPONENT}_INCLUDE_DIR
@ -212,13 +300,13 @@ set(MAGNUM_INCLUDE_DIRS ${MAGNUM_INCLUDE_DIR}
set(MAGNUM_LIBRARIES ${MAGNUM_LIBRARY}
${CORRADE_UTILITY_LIBRARY}
${CORRADE_PLUGINMANAGER_LIBRARY})
if(NOT MAGNUM_TARGET_GLES)
set(MAGNUM_LIBRARIES ${MAGNUM_LIBRARIES}
${OPENGL_gl_LIBRARY}
${GLEW_LIBRARY})
if(NOT MAGNUM_TARGET_GLES OR MAGNUM_TARGET_DESKTOP_GLES)
set(MAGNUM_LIBRARIES ${MAGNUM_LIBRARIES} ${OPENGL_gl_LIBRARY})
else()
set(MAGNUM_LIBRARIES ${MAGNUM_LIBRARIES}
${OPENGLES2_LIBRARY})
set(MAGNUM_LIBRARIES ${MAGNUM_LIBRARIES} ${OPENGLES2_LIBRARY})
endif()
if(NOT MAGNUM_TARGET_GLES)
set(MAGNUM_LIBRARIES ${MAGNUM_LIBRARIES} ${GLEW_LIBRARIES})
endif()
# Installation dirs

24
modules/FindOpenGLES2.cmake

@ -7,6 +7,30 @@
# OPENGLES2_INCLUDE_DIR - Include dir
#
#
# 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.
#
# Library
find_library(OPENGLES2_LIBRARY NAMES
GLESv2

24
modules/FindSDL2.cmake

@ -7,6 +7,30 @@
# SDL2_INCLUDE_DIR - Include dir
#
#
# 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.
#
# Library
find_library(SDL2_LIBRARY SDL2)

2
package/archlinux/magnum-git/PKGBUILD

@ -5,7 +5,7 @@ pkgrel=1
pkgdesc="OpenGL 3 graphics engine (Git version)"
arch=('i686' 'x86_64')
url="https://github.com/mosra/magnum"
license=('LGPLv3')
license=('MIT')
depends=('corrade-git' 'glew')
makedepends=('cmake' 'git')

250
src/AbstractFramebuffer.cpp

@ -0,0 +1,250 @@
/*
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 "AbstractFramebuffer.h"
#include "BufferImage.h"
#include "Context.h"
#include "Extensions.h"
#include "Image.h"
#include "Implementation/FramebufferState.h"
#include "Implementation/State.h"
namespace Magnum {
#ifndef DOXYGEN_GENERATING_OUTPUT
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
void AbstractFramebuffer::bind(Target target) {
bindInternal(target);
setViewportInternal();
}
#ifndef DOXYGEN_GENERATING_OUTPUT
void AbstractFramebuffer::bindInternal(Target target) {
Implementation::FramebufferState* state = Context::current()->state()->framebuffer;
/* If already bound, done, otherwise update tracked state */
if(target == Target::Read) {
if(state->readBinding == _id) return;
state->readBinding = _id;
} else if(target == Target::Draw) {
if(state->drawBinding == _id) return;
state->drawBinding = _id;
} else if(target == Target::ReadDraw) {
if(state->readBinding == _id && state->drawBinding == _id) return;
state->readBinding = state->drawBinding = _id;
} else CORRADE_INTERNAL_ASSERT(false);
glBindFramebuffer(static_cast<GLenum>(target), _id);
}
AbstractFramebuffer::Target 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;
if(state->readBinding == _id)
return Target::Read;
if(state->drawBinding == _id)
return Target::Draw;
/* Or bind it, if not already */
state->readBinding = _id;
if(readTarget == Target::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);
/** @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));
#else
static_cast<void>(sourceRectangle);
static_cast<void>(destinationRectangle);
static_cast<void>(mask);
static_cast<void>(filter);
#endif
}
AbstractFramebuffer* AbstractFramebuffer::setViewport(const Rectanglei& rectangle) {
_viewport = rectangle;
/* Update the viewport if the framebuffer is currently bound */
if(Context::current()->state()->framebuffer->drawBinding == _id)
setViewportInternal();
return this;
}
#ifndef DOXYGEN_GENERATING_OUTPUT
void AbstractFramebuffer::setViewportInternal() {
Implementation::FramebufferState* state = Context::current()->state()->framebuffer;
CORRADE_INTERNAL_ASSERT(state->drawBinding == _id);
/* Already up-to-date, nothing to do */
if(state->viewport == _viewport)
return;
/* Update the state and viewport */
state->viewport = _viewport;
glViewport(_viewport.left(), _viewport.bottom(), _viewport.width(), _viewport.height());
}
#endif
void AbstractFramebuffer::clear(ClearMask 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) {
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);
}
#ifndef MAGNUM_TARGET_GLES2
void AbstractFramebuffer::read(const Vector2i& offset, const Vector2i& size, AbstractImage::Format format, AbstractImage::Type type, 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);
image->buffer()->bind(Buffer::Target::PixelPack);
glReadPixels(offset.x(), offset.y(), size.x(), size.y(), static_cast<GLenum>(format), static_cast<GLenum>(type), 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
glInvalidateFramebuffer(GLenum(bindInternal()), count, attachments);
#else
//glDiscardFramebufferEXT(GLenum(bindInternal()), count, attachments);
static_cast<void>(count);
static_cast<void>(attachments);
#endif
}
void AbstractFramebuffer::invalidateImplementation(GLsizei count, GLenum* attachments, const Rectanglei& rectangle) {
/** @todo Re-enable when extension wrangler is available for ES2 */
#ifndef MAGNUM_TARGET_GLES2
glInvalidateSubFramebuffer(GLenum(bindInternal()), count, attachments, rectangle.left(), rectangle.bottom(), rectangle.width(), rectangle.height());
#else
//glDiscardSubFramebufferEXT(GLenum(bindInternal()), count, attachments, rectangle.left(), rectangle.bottom(), rectangle.width(), rectangle.height());
static_cast<void>(count);
static_cast<void>(attachments);
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;
}
if(context->isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
Debug() << "AbstractFramebuffer: using" << Extensions::GL::EXT::direct_state_access::string() << "features";
drawBuffersImplementation = &AbstractFramebuffer::drawBuffersImplementationDSA;
drawBufferImplementation = &AbstractFramebuffer::drawBufferImplementationDSA;
readBufferImplementation = &AbstractFramebuffer::readBufferImplementationDSA;
}
#else
static_cast<void>(context);
#endif
}
void AbstractFramebuffer::drawBuffersImplementationDefault(GLsizei count, const GLenum* buffers) {
/** @todo Re-enable when extension wrangler is available for ES2 */
#ifndef MAGNUM_TARGET_GLES2
bindInternal(drawTarget);
glDrawBuffers(count, buffers);
#else
static_cast<void>(count);
static_cast<void>(buffers);
#endif
}
#ifndef MAGNUM_TARGET_GLES
void AbstractFramebuffer::drawBuffersImplementationDSA(GLsizei count, const GLenum* buffers) {
glFramebufferDrawBuffersEXT(_id, count, buffers);
}
#endif
void AbstractFramebuffer::drawBufferImplementationDefault(GLenum buffer) {
/** @todo Re-enable when extension wrangler is available for ES2 */
#ifndef MAGNUM_TARGET_GLES2
bindInternal(drawTarget);
glDrawBuffer(buffer);
#else
static_cast<void>(buffer);
#endif
}
#ifndef MAGNUM_TARGET_GLES
void AbstractFramebuffer::drawBufferImplementationDSA(GLenum buffer) {
glFramebufferDrawBufferEXT(_id, buffer);
}
#endif
void AbstractFramebuffer::readBufferImplementationDefault(GLenum buffer) {
/** @todo Get some extension wrangler instead to avoid undeclared glReadBuffer() on ES2 */
#ifndef MAGNUM_TARGET_GLES2
bindInternal(readTarget);
glReadBuffer(buffer);
#else
static_cast<void>(buffer);
#endif
}
#ifndef MAGNUM_TARGET_GLES
void AbstractFramebuffer::readBufferImplementationDSA(GLenum buffer) {
glFramebufferReadBufferEXT(_id, buffer);
}
#endif
}

310
src/AbstractFramebuffer.h

@ -0,0 +1,310 @@
#ifndef Magnum_AbstractFramebuffer_h
#define Magnum_AbstractFramebuffer_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 Class Magnum::AbstractFramebuffer
*/
#include <Containers/EnumSet.h>
#include "Math/Geometry/Rectangle.h"
#include "AbstractImage.h"
#include "Buffer.h"
namespace Magnum {
/**
@brief Base for default and named framebuffers
See DefaultFramebuffer and Framebuffer for more information.
@section AbstractFramebuffer-performance-optimization Performance optimizations
The engine tracks currently bound framebuffer and current viewport to avoid
unnecessary calls to @fn_gl{BindFramebuffer} and @fn_gl{Viewport} when
switching framebuffers.
@todo @extension{ARB,viewport_array}
*/
class MAGNUM_EXPORT AbstractFramebuffer {
friend class Context;
AbstractFramebuffer(const AbstractFramebuffer& other) = delete;
AbstractFramebuffer(AbstractFramebuffer&& other) = delete;
AbstractFramebuffer& operator=(const AbstractFramebuffer& other) = delete;
AbstractFramebuffer& operator=(AbstractFramebuffer&& other) = 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}
*/
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}
*/
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}
* or @es_extension{ANGLE,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}
* or @es_extension{ANGLE,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
* @param destination Destination framebuffer
* @param sourceRectangle Source rectangle
* @param destinationRectangle Destination rectangle
* @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(),
* Framebuffer::mapForRead(), DefaultFramebuffer::mapForDraw() and
* Framebuffer::mapForDraw() for specifying particular buffers for
* blitting operation.
* @see @fn_gl{BlitFramebuffer}
* @requires_gl30 %Extension @extension{EXT,framebuffer_blit}
* @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit}
*/
static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Rectanglei& sourceRectangle, const Rectanglei& destinationRectangle, BlitMask mask, BlitFilter filter);
/**
* @brief Copy block of pixels
* @param source Source framebuffer
* @param destination Destination framebuffer
* @param rectangle Source and destination rectangle
* @param mask Which buffers to perform blit operation on
*
* 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.
* @see @fn_gl{BlitFramebuffer}
* @requires_gl30 %Extension @extension{EXT,framebuffer_blit}
* @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit}
*/
inline static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Rectanglei& rectangle, BlitMask mask) {
blit(source, destination, rectangle, rectangle, mask, BlitFilter::Nearest);
}
explicit AbstractFramebuffer() = default;
virtual ~AbstractFramebuffer() = 0;
/**
* @brief Bind framebuffer for rendering
*
* Binds the framebuffer and updates viewport to saved dimensions.
* @see setViewport(), DefaultFramebuffer::mapForRead(),
* Framebuffer::mapForRead(), DefaultFramebuffer::mapForDraw(),
* Framebuffer::mapForDraw(), @fn_gl{BindFramebuffer},
* @fn_gl{Viewport}
*/
void bind(Target target);
/** @brief Viewport rectangle */
inline Rectanglei viewport() const { return _viewport; }
/**
* @brief Set viewport
* @return Pointer to self (for method chaining)
*
* Saves the viewport to be used at later time in bind(). If the
* framebuffer is currently bound, updates the viewport to given
* rectangle.
* @see @fn_gl{Viewport}
*/
AbstractFramebuffer* setViewport(const Rectanglei& rectangle);
/**
* @brief Clear specified buffers in framebuffer
* @param mask Which buffers to clear
*
* To improve performance you can also use
* DefaultFramebuffer::invalidate() / Framebuffer::invalidate() instead
* of clearing given buffer if you will not use it anymore or fully
* overwrite it later.
* @see Renderer::setClearColor(), Renderer::setClearDepth(),
* Renderer::setClearStencil(), @fn_gl{BindFramebuffer},
* @fn_gl{Clear}
*/
void clear(ClearMask 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?
*/
void read(const Vector2i& offset, const Vector2i& size, AbstractImage::Format format, AbstractImage::Type type, 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}
* @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);
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
protected:
void MAGNUM_LOCAL bindInternal(Target target);
Target MAGNUM_LOCAL bindInternal();
void MAGNUM_LOCAL setViewportInternal();
static MAGNUM_LOCAL Target readTarget;
static MAGNUM_LOCAL Target drawTarget;
typedef void(AbstractFramebuffer::*DrawBuffersImplementation)(GLsizei, const GLenum*);
static MAGNUM_LOCAL DrawBuffersImplementation drawBuffersImplementation;
typedef void(AbstractFramebuffer::*DrawBufferImplementation)(GLenum);
static DrawBufferImplementation drawBufferImplementation;
typedef void(AbstractFramebuffer::*ReadBufferImplementation)(GLenum);
static ReadBufferImplementation readBufferImplementation;
void MAGNUM_LOCAL invalidateImplementation(GLsizei count, GLenum* attachments);
void MAGNUM_LOCAL invalidateImplementation(GLsizei count, GLenum* attachments, const Rectanglei& rectangle);
GLuint _id;
Rectanglei _viewport;
#endif
private:
static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context);
void MAGNUM_LOCAL drawBuffersImplementationDefault(GLsizei count, const GLenum* buffers);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL drawBuffersImplementationDSA(GLsizei count, const GLenum* buffers);
#endif
void MAGNUM_LOCAL drawBufferImplementationDefault(GLenum buffer);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL drawBufferImplementationDSA(GLenum buffer);
#endif
void MAGNUM_LOCAL readBufferImplementationDefault(GLenum buffer);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL readBufferImplementationDSA(GLenum buffer);
#endif
};
inline AbstractFramebuffer::~AbstractFramebuffer() {}
CORRADE_ENUMSET_OPERATORS(AbstractFramebuffer::ClearMask)
CORRADE_ENUMSET_OPERATORS(AbstractFramebuffer::BlitMask)
}
#endif

233
src/AbstractImage.cpp

@ -1,105 +1,216 @@
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
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:
#include "AbstractImage.h"
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
#include <Utility/Debug.h>
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 "TypeTraits.h"
#include "AbstractImage.h"
using namespace std;
#include <Utility/Assert.h>
namespace Magnum {
size_t AbstractImage::pixelSize(Components format, ComponentType type) {
size_t size = 0;
std::size_t AbstractImage::pixelSize(Format format, Type type) {
std::size_t size = 0;
switch(type) {
#ifndef MAGNUM_TARGET_GLES
case ComponentType::RGB332:
case ComponentType::BGR233:
return 1;
case Type::UnsignedByte:
#ifndef MAGNUM_TARGET_GLES2
case Type::Byte:
#endif
case ComponentType::RGB565:
#ifndef MAGNUM_TARGET_GLES
case ComponentType::BGR565:
size = 1; break;
case Type::UnsignedShort:
#ifndef MAGNUM_TARGET_GLES2
case Type::Short:
#endif
case Type::HalfFloat:
size = 2; break;
case Type::UnsignedInt:
#ifndef MAGNUM_TARGET_GLES2
case Type::Int:
#endif
case ComponentType::RGBA4:
case Type::Float:
size = 4; break;
#ifndef MAGNUM_TARGET_GLES
case ComponentType::ABGR4:
case Type::UnsignedByte332:
case Type::UnsignedByte233Rev:
return 1;
#endif
case ComponentType::RGB5Alpha1:
case Type::UnsignedShort565:
#ifndef MAGNUM_TARGET_GLES
case ComponentType::Alpha1BGR5:
case Type::UnsignedShort565Rev:
#endif
case Type::UnsignedShort4444:
case Type::UnsignedShort4444Rev:
case Type::UnsignedShort5551:
case Type::UnsignedShort1555Rev:
return 2;
#ifndef MAGNUM_TARGET_GLES
case ComponentType::RGBA8:
case ComponentType::ABGR8:
case ComponentType::RGB10Alpha2:
case ComponentType::Alpha2RGB10:
case ComponentType::Depth24Stencil8:
case ComponentType::B10GR11Float:
case ComponentType::Exponent5RGB9:
case Type::UnsignedInt8888:
case Type::UnsignedInt8888Rev:
case Type::UnsignedInt1010102:
#endif
case Type::UnsignedInt2101010Rev:
#ifndef MAGNUM_TARGET_GLES2
case Type::UnsignedInt10F11F11FRev:
case Type::UnsignedInt5999Rev:
#endif
case Type::UnsignedInt248:
return 4;
case ComponentType::Depth32FloatStencil8:
#ifndef MAGNUM_TARGET_GLES2
case Type::Float32UnsignedInt248Rev:
return 8;
#endif
case ComponentType::UnsignedByte:
case ComponentType::Byte:
size = 1; break;
case ComponentType::UnsignedShort:
case ComponentType::Short:
#ifndef MAGNUM_TARGET_GLES
case ComponentType::HalfFloat:
size = 2; break;
#endif
case ComponentType::UnsignedInt:
case ComponentType::Int:
case ComponentType::Float:
size = 4; break;
}
switch(format) {
case Format::Red:
#ifndef MAGNUM_TARGET_GLES2
case Format::RedInteger:
#endif
#ifndef MAGNUM_TARGET_GLES
case Components::Red:
case Components::Green:
case Components::Blue:
case Format::Green:
case Format::Blue:
case Format::GreenInteger:
case Format::BlueInteger:
#endif
return 1*size;
case Components::RedGreen:
case Format::RG:
#ifndef MAGNUM_TARGET_GLES2
case Format::RGInteger:
#endif
return 2*size;
case Format::RGB:
#ifndef MAGNUM_TARGET_GLES2
case Format::RGBInteger:
#endif
case Components::RGB:
#ifndef MAGNUM_TARGET_GLES
case Components::BGR:
case Format::BGR:
case Format::BGRInteger:
#endif
return 3*size;
case Components::RGBA:
case Format::RGBA:
#ifndef MAGNUM_TARGET_GLES2
case Format::RGBAInteger:
#endif
case Format::BGRA:
#ifndef MAGNUM_TARGET_GLES
case Components::BGRA:
case Format::BGRAInteger:
#endif
return 4*size;
#ifndef MAGNUM_TARGET_GLES
case Components::Depth:
case Components::StencilIndex:
case Components::DepthStencil:
/* Handled above */
case Format::DepthComponent:
case Format::StencilIndex:
case Format::DepthStencil:
CORRADE_INTERNAL_ASSERT(false);
#endif
}
CORRADE_INTERNAL_ASSERT(false);
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
_c(BGRA)
#ifndef MAGNUM_TARGET_GLES2
_c(RedInteger)
_c(GreenInteger)
_c(BlueInteger)
_c(RGInteger)
_c(RGBInteger)
_c(RGBAInteger)
_c(BGRInteger)
_c(BGRAInteger)
#endif
_c(DepthComponent)
_c(StencilIndex)
_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_GLES2
_c(UnsignedByte332)
_c(UnsignedByte233Rev)
#endif
_c(UnsignedShort565)
#ifndef MAGNUM_TARGET_GLES
_c(UnsignedShort565Rev)
#endif
_c(UnsignedShort4444)
_c(UnsignedShort4444Rev)
_c(UnsignedShort5551)
_c(UnsignedShort1555Rev)
#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
}

465
src/AbstractImage.h

@ -1,18 +1,27 @@
#ifndef Magnum_AbstractImage_h
#define Magnum_AbstractImage_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
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
@ -22,7 +31,7 @@
#include <cstddef>
#include "Magnum.h"
#include "OpenGL.h"
#include "magnumVisibility.h"
namespace Magnum {
@ -30,7 +39,12 @@ namespace Magnum {
/**
@brief Non-templated base for one-, two- or three-dimensional images
See Image, BufferedImage, Trade::ImageData documentation for more information.
See Image, ImageWrapper, BufferImage, Trade::ImageData documentation for
more information.
@todo Where to put glClampColor() and glPixelStore() encapsulation? It is
needed in AbstractFramebuffer::read(), Texture::setImage() etc (i.e. all
functions operating with images). It also possibly needs to be "stackable" to
easily revert the state back.
*/
class MAGNUM_EXPORT AbstractImage {
AbstractImage(const AbstractImage& other) = delete;
@ -44,220 +58,391 @@ class MAGNUM_EXPORT AbstractImage {
*
* Note that some formats can be used only for framebuffer reading
* (using Framebuffer::read()) and some only for texture data (using
* Texture::setData() and others).
* Texture::setImage() and others).
*/
/** @brief Color components */
/** @todo Support *_INTEGER types */
enum class Components: GLenum {
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Format of pixel data
*
* @todo What is allowed for FB reading and what for image
* specification?
* @see pixelSize()
*/
enum class Format: GLenum {
/**
* One-component (red channel)
* @requires_gl
* Floating-point red channel.
* @requires_gles30 %Extension @es_extension{EXT,texture_rg}
*/
#ifndef MAGNUM_TARGET_GLES2
Red = GL_RED,
#else
Red = GL_RED_EXT,
#endif
#ifndef MAGNUM_TARGET_GLES
/**
* One-component (green channel). For framebuffer reading only.
* @requires_gl
* Floating-point green channel. For framebuffer reading only.
* @requires_gl Only @ref Magnum::AbstractImage::Format "Format::Red"
* is available in OpenGL ES.
*/
Green = GL_GREEN,
/**
* One-component (green channel). For framebuffer reading only.
* @requires_gl
* Floating-point blue channel. For framebuffer reading only.
* @requires_gl Only @ref Magnum::AbstractImage::Format "Format::Red"
* is available in OpenGL ES.
*/
Blue = GL_BLUE,
/** @todo GL_ALPHA? */
#endif
/**
* Two-component (red and green channel). For texture data only.
* @requires_gl
* Floating-point red and green channel. For texture data only.
* @requires_gl30 %Extension @extension{ARB,texture_rg} and
* @extension{EXT,texture_integer}
* @requires_gles30 %Extension @es_extension{EXT,texture_rg}
*/
RedGreen = GL_RG,
#ifndef MAGNUM_TARGET_GLES2
RG = GL_RG,
#else
RG = GL_RG_EXT,
#endif
RGB = GL_RGB, /**< Three-component RGB */
RGBA = GL_RGBA /**< Four-component RGBA */
/** Floating-point RGB. */
RGB = GL_RGB,
#ifndef MAGNUM_TARGET_GLES
,
/** Floating-point RGBA. */
RGBA = GL_RGBA,
#ifndef MAGNUM_TARGET_GLES
/**
* Three-component BGR
* @requires_gl
* Floating-point BGR.
* @requires_gl Only RGB component ordering is available in OpenGL
* ES.
*/
BGR = GL_BGR,
#endif
/**
* Four-component BGRA
* @requires_gl
* 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
#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_gles30 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_gles30 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. For framebuffer reading only.
* @requires_gl
* @requires_gles30 %Extension @es_extension2{NV,read_depth,GL_NV_read_depth_stencil}
*/
Depth = GL_DEPTH_COMPONENT,
DepthComponent = GL_DEPTH_COMPONENT,
/**
* Stencil index. For framebuffer reading only.
* @requires_gl
* @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
/**
* Depth and stencil component. For framebuffer reading only.
* @requires_gl
* @requires_gl30 Extension @extension{EXT,packed_depth_stencil}
* Depth and stencil. For framebuffer reading only.
* @requires_gl30 %Extension @extension{EXT,packed_depth_stencil}
* @requires_gles30 %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 */
enum class ComponentType: GLenum {
UnsignedByte = GL_UNSIGNED_BYTE, /**< Each component unsigned byte */
Byte = GL_BYTE, /**< Each component byte */
UnsignedShort = GL_UNSIGNED_SHORT, /**< Each component unsigned short */
Short = GL_SHORT, /**< Each component short */
UnsignedInt = GL_UNSIGNED_INT, /**< Each component unsigned int */
Int = GL_INT, /**< Each component int */
/**
* @brief Data type of pixel data
*
* @see pixelSize()
*/
enum class Type: GLenum {
/** Each component unsigned byte. */
UnsignedByte = GL_UNSIGNED_BYTE,
#ifndef MAGNUM_TARGET_GLES
#ifndef MAGNUM_TARGET_GLES2
/**
* Each component half float (16bit). For framebuffer reading only.
*
* @requires_gl
* @requires_gl30 Extension @extension{NV,half_float} / @extension{ARB,half_float_pixel}
* Each component signed byte.
* @requires_gles30 Only @ref Magnum::AbstractImage::Type "Type::UnsignedByte"
* is available in OpenGL ES 2.0.
*/
HalfFloat = GL_HALF_FLOAT,
Byte = GL_BYTE,
#endif
Float = GL_FLOAT, /**< Each component float (32bit) */
#ifndef MAGNUM_TARGET_GLES
/**
* Three-component RGB, unsigned normalized, red and green 3bit,
* blue 2bit, 8bit total.
* @requires_gl
* Each component unsigned short.
* @requires_gles30 %Extension @es_extension{OES,depth_texture}
*/
RGB332 = GL_UNSIGNED_BYTE_3_3_2,
UnsignedShort = GL_UNSIGNED_SHORT,
#ifndef MAGNUM_TARGET_GLES2
/**
* Three-component BGR, unsigned normalized, red and green 3bit,
* blue 2bit, 8bit total.
* @requires_gl
* Each component signed short.
* @requires_gles30 Only @ref Magnum::AbstractImage::Type "Type::UnsignedShort"
* is available in OpenGL ES 2.0.
*/
BGR233 = GL_UNSIGNED_BYTE_2_3_3_REV,
Short = GL_SHORT,
#endif
/**
* Three-component RGB, unsigned normalized, red and blue 5bit,
* green 6bit, 16bit total.
* Each component unsigned int.
* @requires_gles30 %Extension @es_extension{OES,depth_texture}
*/
RGB565 = GL_UNSIGNED_SHORT_5_6_5,
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
#ifndef MAGNUM_TARGET_GLES
/**
* Three-component BGR, unsigned normalized, red and blue 5bit,
* green 6bit, 16bit total.
* @requires_gl
* Each component half float. For framebuffer reading only.
* @requires_gl30 %Extension @extension{NV,half_float} / @extension{ARB,half_float_pixel}
* @requires_gles30 %Extension @es_extension2{OES,texture_half_float,OES_texture_float},
* for texture data only.
*/
BGR565 = GL_UNSIGNED_SHORT_5_6_5_REV,
#ifndef MAGNUM_TARGET_GLES2
HalfFloat = GL_HALF_FLOAT,
#else
HalfFloat = GL_HALF_FLOAT_OES,
#endif
/**
* Four-component RGBA, unsigned normalized, each component 4bit,
* 16bit total.
* Each component float.
* @requires_gles30 %Extension @es_extension{OES,texture_float}
*/
RGBA4 = GL_UNSIGNED_SHORT_4_4_4_4,
Float = GL_FLOAT,
#ifndef MAGNUM_TARGET_GLES
/**
* Four-component ABGR, unsigned normalized, each component 4bit,
* 16bit total.
* @requires_gl
* RGB, unsigned byte, red and green component 3bit, blue
* component 2bit.
* @requires_gl Packed 12bit types are not available in OpenGL ES.
*/
ABGR4 = GL_UNSIGNED_SHORT_4_4_4_4_REV,
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. */
UnsignedShort565 = GL_UNSIGNED_SHORT_5_6_5,
#ifndef MAGNUM_TARGET_GLES
/**
* Four-component RGBA, unsigned normalized, each RGB component
* 5bit, alpha 1bit, 16bit total.
* BGR, unsigned short, red and blue 5bit, green 6bit.
* @requires_gl Only @ref Magnum::AbstractImage::Type "Type::RGB565"
* is available in OpenGL ES.
*/
RGB5Alpha1 = GL_UNSIGNED_SHORT_5_5_5_1
UnsignedShort565Rev = GL_UNSIGNED_SHORT_5_6_5_REV,
#endif
/** RGBA, unsigned short, each component 4bit. */
UnsignedShort4444 = GL_UNSIGNED_SHORT_4_4_4_4,
/**
* ABGR, unsigned short, each component 4bit.
* @requires_es_extension %Extension @es_extension{EXT,read_format_bgra},
* for framebuffer reading only.
*/
#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
/**
* RGBA, unsigned short, each RGB component 5bit, alpha component
* 1bit.
*/
UnsignedShort5551 = GL_UNSIGNED_SHORT_5_5_5_1,
/**
* Four-component ABGR, unsigned normalized, each RGB component
* 5bit, alpha 1bit, 16bit total.
* @requires_gl
* ABGR, unsigned short, each RGB component 5bit, alpha component
* 1bit.
* @requires_es_extension %Extension @es_extension{EXT,read_format_bgra},
* for framebuffer reading only.
*/
Alpha1BGR5 = GL_UNSIGNED_SHORT_1_5_5_5_REV,
#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
#ifndef MAGNUM_TARGET_GLES
/**
* Four-component RGBA, unsigned normalized, each component 8bit,
* 32bit total.
* @requires_gl
* RGBA, unsigned int, each component 8bit.
* @requires_gl Use @ref Magnum::AbstractImage::Type "Type::UnsignedByte"
* in OpenGL ES instead.
*/
RGBA8 = GL_UNSIGNED_INT_8_8_8_8,
UnsignedInt8888 = GL_UNSIGNED_INT_8_8_8_8,
/**
* Four-component ABGR, unsigned normalized, each component 8bit,
* 32bit total.
* @requires_gl
* 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.
*/
ABGR8 = GL_UNSIGNED_INT_8_8_8_8_REV,
UnsignedInt8888Rev = GL_UNSIGNED_INT_8_8_8_8_REV,
/**
* Four-component RGBA, unsigned normalized, each RGB component
* 10bit, alpha 2bit, 32bit total.
* @requires_gl
* RGBA, unsigned int, each RGB component 10bit, alpha component
* 2bit.
* @requires_gl Only @ref Magnum::AbstractImage::Type "Type::UnsignedInt2101010Rev"
* is available in OpenGL ES.
*/
RGB10Alpha2 = GL_UNSIGNED_INT_10_10_10_2,
UnsignedInt1010102 = GL_UNSIGNED_INT_10_10_10_2,
#endif
/**
* Four-component ABGR, unsigned normalized, each RGB component
* 10bit, alpha 2bit, 32bit total.
* @requires_gl
* ABGR, unsigned int, each RGB component 10bit, alpha component
* 2bit.
* @requires_gles30 %Extension @es_extension{EXT,texture_type_2_10_10_10_REV},
* for texture data only.
*/
Alpha2RGB10 = GL_UNSIGNED_INT_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
/**
* Three-component BGR, float, red and green 11bit, blue 10bit,
* 32bit total. For framebuffer reading only.
* @requires_gl
* @requires_gl30 Extension @extension{EXT,packed_float}
* BGR, unsigned int, red and green 11bit float, blue 10bit float.
* For framebuffer reading only.
* @requires_gl30 %Extension @extension{EXT,packed_float}
* @requires_gles30 Floating-point types are not available in
* OpenGL ES 2.0.
*/
B10GR11Float = GL_UNSIGNED_INT_10F_11F_11F_REV,
UnsignedInt10F11F11FRev = GL_UNSIGNED_INT_10F_11F_11F_REV,
/**
* Three-component BGR, unsigned integers with exponent, each
* component 9bit, exponent 5bit, 32bit total. For framebuffer
* reading only.
* @requires_gl
* @requires_gl30 Extension @extension{EXT,texture_shared_exponent}
* BGR, unsigned int, each component 9bit + 5bit exponent. For
* framebuffer reading only.
* @requires_gl30 %Extension @extension{EXT,texture_shared_exponent}
* @requires_gles30 Only 8bit and 16bit types are available in
* OpenGL ES 2.0.
*/
Exponent5RGB9 = GL_UNSIGNED_INT_5_9_9_9_REV,
UnsignedInt5999Rev = GL_UNSIGNED_INT_5_9_9_9_REV,
#endif
/**
* 24bit depth and 8bit stencil component, 32bit total. For
* Unsigned int, depth component 24bit, stencil index 8bit. For
* framebuffer reading only.
* @requires_gl
* @requires_gl30 Extension @extension{EXT,packed_depth_stencil}
* @requires_gl30 %Extension @extension{EXT,packed_depth_stencil}
* @requires_gles30 %Extension @es_extension{OES,packed_depth_stencil}
*/
Depth24Stencil8 = GL_UNSIGNED_INT_24_8,
#ifdef MAGNUM_TARGET_GLES2
UnsignedInt248 = GL_UNSIGNED_INT_24_8_OES,
#else
UnsignedInt248 = GL_UNSIGNED_INT_24_8,
/**
* 32bit float depth component and 8bit stencil component, 64bit
* total. For framebuffer reading only.
* @requires_gl
* @requires_gl30 Extension @extension{ARB,depth_buffer_float}
* Float + unsigned int, depth component 32bit float, 24bit gap,
* stencil index 8bit. For framebuffer reading only.
* @requires_gl30 %Extension @extension{ARB,depth_buffer_float}
* @requires_gles30 Only @ref Magnum::AbstractImage::Type "Type::UnsignedInt248"
* is available in OpenGL ES 2.0.
*/
Depth32FloatStencil8 = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
Float32UnsignedInt248Rev = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
#endif
};
@ -265,34 +450,42 @@ class MAGNUM_EXPORT AbstractImage {
/**
* @brief Pixel size (in bytes)
* @param components Color components
* @param type Data type
* @param format Format of the pixel
* @param type Data type of the pixel
*/
static std::size_t pixelSize(Components components, ComponentType type);
static std::size_t pixelSize(Format format, Type type);
/**
* @brief Constructor
* @param components Color components of passed data
* @param type %Image data type
* @param format Format of pixel data
* @param type Data type of pixel data
*/
inline AbstractImage(Components components, ComponentType type): _components(components), _type(type) {}
inline explicit AbstractImage(Format format, Type type): _format(format), _type(type) {}
/** @brief Destructor */
virtual ~AbstractImage() = 0;
/** @brief Color components */
inline Components components() const { return _components; }
/** @brief Format of pixel data */
inline Format format() const { return _format; }
/** @brief Data type */
inline ComponentType type() const { return _type; }
/** @brief Data type of pixel data */
inline Type type() const { return _type; }
#ifndef DOXYGEN_GENERATING_OUTPUT
protected:
Components _components; /**< @brief Color components */
ComponentType _type; /**< @brief Data type */
Format _format;
Type _type;
#endif
};
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

101
src/AbstractResourceLoader.h

@ -1,26 +1,33 @@
#ifndef Magnum_AbstractResourceLoader_h
#define Magnum_AbstractResourceLoader_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
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 Class Magnum::AbstractResourceLoader
*/
#include "Magnum.h"
#include <string>
#include "ResourceManager.h"
@ -30,13 +37,68 @@ namespace Magnum {
/**
@brief Base for resource loaders
Provides asynchronous resource loading for ResourceManager.
Provides (a)synchronous resource loading for ResourceManager.
@section AbstractResourceLoader-usage Usage and subclassing
Usage is done by subclassing. Subclass instances can be added to
ResourceManager using ResourceManager::setLoader(). After adding the loader,
each call to ResourceManager::get() will call load() implementation unless the
resource is already loaded (or loading is in progress). Note that resources
requested before the loader was added are not be affected by the loader.
Subclassing is done by implementing at least load() function. The loading can
be done synchronously or asynchronously (i.e., in another thread). The base
implementation provides interface to ResourceManager and manages loading
progress (which is then available through functions requestedCount(),
loadedCount() and notFoundCount()). You shouldn't access the ResourceManager
directly when loading the data.
Your load() implementation must call the base implementation at the beginning
so ResourceManager is informed about loading state. Then, after your resources
are loaded, call set() to pass them to ResourceManager or call setNotFound()
to indicate that the resource was not found.
You can also implement name() to provide meaningful names for resource keys.
Example implementation for synchronous mesh loader:
@code
class MeshResourceLoader: public AbstractResourceLoader<Mesh> {
public:
void load(ResourceKey key) {
// Indicate that loading has begun
AbstractResourceLoader<Mesh>::load(key);
// Load the mesh...
// Not found
if(!found) {
setNotFound(key);
return;
}
// Found, pass it to resource manager
set(key, mesh, state, policy);
}
};
@endcode
You can then add it to resource manager instance like this:
@code
MyResourceManager manager;
MeshResourceLoader loader;
manager->setLoader(loader);
// This will now automatically request the mesh from loader by calling load()
Resource<Mesh> myMesh = manager->get<Mesh>("my-mesh");
@endcode
*/
template<class T> class AbstractResourceLoader {
friend class Implementation::ResourceManagerData<T>;
public:
inline AbstractResourceLoader(): manager(nullptr), _requestedCount(0), _loadedCount(0), _notFoundCount(0) {}
inline explicit AbstractResourceLoader(): manager(nullptr), _requestedCount(0), _loadedCount(0), _notFoundCount(0) {}
inline virtual ~AbstractResourceLoader() {
if(manager) manager->_loader = nullptr;
@ -55,7 +117,7 @@ template<class T> class AbstractResourceLoader {
* Count of resources requested by calling load(), but not found by
* the loader.
*/
inline std::size_t notFountCount() const { return _notFoundCount; }
inline std::size_t notFoundCount() const { return _notFoundCount; }
/**
* @brief Count of loaded resources
@ -78,11 +140,12 @@ template<class T> class AbstractResourceLoader {
*
* If the resource isn't yet loaded or loading, state of the resource
* is set to @ref Resource::ResourceState "ResourceState::Loading" and count of
* requested features is incremented.
* requested features is incremented. Depending on implementation the
* resource might be loaded synchronously or asynchronously.
*
* See class documentation for reimplementation guide.
*
* The resource might be loaded asynchronously and added to
* ResourceManager when loading is done.
* @see ResourceManager::state(), requestedCount(), notFountCount(),
* @see ResourceManager::state(), requestedCount(), notFoundCount(),
* loadedCount()
*/
virtual void load(ResourceKey key) = 0;

303
src/AbstractShaderProgram.cpp

@ -1,21 +1,31 @@
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
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 "AbstractShaderProgram.h"
#include <fstream>
#include <type_traits>
#include "Math/Matrix.h"
#include "Shader.h"
@ -25,8 +35,6 @@
#define LINKER_MESSAGE_MAX_LENGTH 1024
using namespace std;
namespace Magnum {
AbstractShaderProgram::Uniform1fImplementation AbstractShaderProgram::uniform1fImplementation = &AbstractShaderProgram::uniformImplementationDefault;
@ -73,7 +81,7 @@ AbstractShaderProgram::UniformMatrix3x4dvImplementation AbstractShaderProgram::u
AbstractShaderProgram::UniformMatrix4x3dvImplementation AbstractShaderProgram::uniformMatrix4x3dvImplementation = &AbstractShaderProgram::uniformImplementationDefault;
#endif
GLint AbstractShaderProgram::maxSupportedVertexAttributeCount() {
Int AbstractShaderProgram::maxSupportedVertexAttributeCount() {
GLint& value = Context::current()->state()->shaderProgram->maxSupportedVertexAttributeCount;
/* Get the value, if not already cached */
@ -108,19 +116,19 @@ bool AbstractShaderProgram::attachShader(Shader& shader) {
return true;
}
void AbstractShaderProgram::bindAttributeLocation(GLuint location, const string& name) {
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(GLuint location, const std::string& name) {
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(GLuint location, GLuint index, const std::string& name) {
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());
@ -156,7 +164,7 @@ void AbstractShaderProgram::link() {
state = status == GL_FALSE ? Failed : Linked;
}
GLint AbstractShaderProgram::uniformLocation(const std::string& name) {
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);
@ -570,4 +578,265 @@ void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math:
}
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
std::size_t FloatAttribute::size(GLint components, DataType dataType) {
switch(dataType) {
case DataType::UnsignedByte:
case DataType::Byte:
return components;
case DataType::UnsignedShort:
case DataType::Short:
case DataType::HalfFloat:
return 2*components;
case DataType::UnsignedInt:
case DataType::Int:
case DataType::Float:
return 4*components;
#ifndef MAGNUM_TARGET_GLES
case DataType::Double:
return 8*components;
#endif
}
CORRADE_INTERNAL_ASSERT(false);
return 0;
}
#ifndef MAGNUM_TARGET_GLES2
std::size_t IntAttribute::size(GLint components, DataType dataType) {
switch(dataType) {
case DataType::UnsignedByte:
case DataType::Byte:
return components;
case DataType::UnsignedShort:
case DataType::Short:
return 2*components;
case DataType::UnsignedInt:
case DataType::Int:
return 4*components;
}
CORRADE_INTERNAL_ASSERT(false);
return 0;
}
#endif
#ifndef MAGNUM_TARGET_GLES
std::size_t DoubleAttribute::size(GLint components, DataType dataType) {
switch(dataType) {
case DataType::Double:
return 8*components;
}
CORRADE_INTERNAL_ASSERT(false);
return 0;
}
#endif
std::size_t Attribute<Math::Vector<4, Float>>::size(GLint components, DataType dataType) {
#ifndef MAGNUM_TARGET_GLES
if(components == GL_BGRA) components = 4;
#endif
switch(dataType) {
case DataType::UnsignedByte:
case DataType::Byte:
return components;
case DataType::UnsignedShort:
case DataType::Short:
case DataType::HalfFloat:
return 2*components;
case DataType::UnsignedInt:
case DataType::Int:
case DataType::Float:
return 4*components;
#ifndef MAGNUM_TARGET_GLES
case DataType::Double:
return 8*components;
#endif
#ifndef MAGNUM_TARGET_GLES2
case DataType::UnsignedInt2101010Rev:
case DataType::Int2101010Rev:
CORRADE_INTERNAL_ASSERT(components == 4);
return 4;
#endif
}
CORRADE_INTERNAL_ASSERT(false);
return 0;
}
Debug operator<<(Debug debug, SizedAttribute<1, 1>::Components value) {
switch(value) {
case SizedAttribute<1, 1>::Components::One:
return debug << "AbstractShaderProgram::Attribute::Components::One";
}
return debug << "AbstractShaderProgram::Attribute::Components::(invalid)";
}
Debug operator<<(Debug debug, SizedAttribute<1, 2>::Components value) {
switch(value) {
case SizedAttribute<1, 2>::Components::One:
return debug << "AbstractShaderProgram::Attribute::Components::One";
case SizedAttribute<1, 2>::Components::Two:
return debug << "AbstractShaderProgram::Attribute::Components::Two";
}
return debug << "AbstractShaderProgram::Attribute::Components::(invalid)";
}
Debug operator<<(Debug debug, SizedAttribute<1, 3>::Components value) {
switch(value) {
case SizedAttribute<1, 3>::Components::One:
return debug << "AbstractShaderProgram::Attribute::Components::One";
case SizedAttribute<1, 3>::Components::Two:
return debug << "AbstractShaderProgram::Attribute::Components::Two";
case SizedAttribute<1, 3>::Components::Three:
return debug << "AbstractShaderProgram::Attribute::Components::Three";
}
return debug << "AbstractShaderProgram::Attribute::Components::(invalid)";
}
Debug operator<<(Debug debug, SizedAttribute<1, 4>::Components value) {
switch(value) {
case SizedAttribute<1, 4>::Components::One:
return debug << "AbstractShaderProgram::Attribute::Components::One";
case SizedAttribute<1, 4>::Components::Two:
return debug << "AbstractShaderProgram::Attribute::Components::Two";
case SizedAttribute<1, 4>::Components::Three:
return debug << "AbstractShaderProgram::Attribute::Components::Three";
case SizedAttribute<1, 4>::Components::Four:
return debug << "AbstractShaderProgram::Attribute::Components::Four";
}
return debug << "AbstractShaderProgram::Attribute::Components::(invalid)";
}
Debug operator<<(Debug debug, SizedMatrixAttribute<2>::Components value) {
switch(value) {
case SizedMatrixAttribute<2>::Components::Two:
return debug << "AbstractShaderProgram::Attribute::Components::Two";
}
return debug << "AbstractShaderProgram::Attribute::Components::(invalid)";
}
Debug operator<<(Debug debug, SizedMatrixAttribute<3>::Components value) {
switch(value) {
case SizedMatrixAttribute<3>::Components::Three:
return debug << "AbstractShaderProgram::Attribute::Components::Three";
}
return debug << "AbstractShaderProgram::Attribute::Components::(invalid)";
}
Debug operator<<(Debug debug, SizedMatrixAttribute<4>::Components value) {
switch(value) {
case SizedMatrixAttribute<4>::Components::Four:
return debug << "AbstractShaderProgram::Attribute::Components::Four";
}
return debug << "AbstractShaderProgram::Attribute::Components::(invalid)";
}
Debug operator<<(Debug debug, Attribute<Math::Vector<4, Float>>::Components value) {
switch(value) {
case Attribute<Math::Vector<4, Float>>::Components::One:
return debug << "AbstractShaderProgram::Attribute::Components::One";
case Attribute<Math::Vector<4, Float>>::Components::Two:
return debug << "AbstractShaderProgram::Attribute::Components::Two";
case Attribute<Math::Vector<4, Float>>::Components::Three:
return debug << "AbstractShaderProgram::Attribute::Components::Three";
case Attribute<Math::Vector<4, Float>>::Components::Four:
return debug << "AbstractShaderProgram::Attribute::Components::Four";
#ifndef MAGNUM_TARGET_GLES
case Attribute<Math::Vector<4, Float>>::Components::BGRA:
return debug << "AbstractShaderProgram::Attribute::Components::BGRA";
#endif
}
return debug << "AbstractShaderProgram::Attribute::Components::(invalid)";
}
Debug operator<<(Debug debug, FloatAttribute::DataType value) {
switch(value) {
#define _c(value) case FloatAttribute::DataType::value: return debug << "AbstractShaderProgram::Attribute::DataType::" #value;
_c(UnsignedByte)
_c(Byte)
_c(UnsignedShort)
_c(Short)
_c(UnsignedInt)
_c(Int)
_c(HalfFloat)
_c(Float)
#ifndef MAGNUM_TARGET_GLES
_c(Double)
#endif
#undef _c
}
return debug << "AbstractShaderProgram::Attribute::DataType::(invalid)";
}
#ifndef MAGNUM_TARGET_GLES2
Debug operator<<(Debug debug, IntAttribute::DataType value) {
switch(value) {
#define _c(value) case IntAttribute::DataType::value: return debug << "AbstractShaderProgram::Attribute::DataType::" #value;
_c(UnsignedByte)
_c(Byte)
_c(UnsignedShort)
_c(Short)
_c(UnsignedInt)
_c(Int)
#undef _c
}
return debug << "AbstractShaderProgram::Attribute::DataType::(invalid)";
}
#endif
#ifndef MAGNUM_TARGET_GLES
Debug operator<<(Debug debug, DoubleAttribute::DataType value) {
switch(value) {
#define _c(value) case DoubleAttribute::DataType::value: return debug << "AbstractShaderProgram::Attribute::DataType::" #value;
_c(Double)
#undef _c
}
return debug << "AbstractShaderProgram::Attribute::DataType::(invalid)";
}
#endif
Debug operator<<(Debug debug, Attribute<Math::Vector<4, Float>>::DataType value) {
switch(value) {
#define _c(value) case Attribute<Math::Vector<4, Float>>::DataType::value: return debug << "AbstractShaderProgram::Attribute::DataType::" #value;
_c(UnsignedByte)
_c(Byte)
_c(UnsignedShort)
_c(Short)
_c(UnsignedInt)
_c(Int)
_c(HalfFloat)
_c(Float)
#ifndef MAGNUM_TARGET_GLES
_c(Double)
#endif
#ifndef MAGNUM_TARGET_GLES2
_c(UnsignedInt2101010Rev)
_c(Int2101010Rev)
#endif
#undef _c
}
return debug << "AbstractShaderProgram::Attribute::DataType::(invalid)";
}
}
#endif
}

801
src/AbstractShaderProgram.h

File diff suppressed because it is too large Load Diff

344
src/AbstractTexture.cpp

@ -1,20 +1,31 @@
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
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 "AbstractTexture.h"
#include "Buffer.h"
#include "BufferImage.h"
#include "Context.h"
#include "Extensions.h"
#include "Implementation/State.h"
@ -30,9 +41,21 @@ AbstractTexture::ParameterfImplementation AbstractTexture::parameterfImplementat
&AbstractTexture::parameterImplementationDefault;
AbstractTexture::ParameterfvImplementation AbstractTexture::parameterfvImplementation =
&AbstractTexture::parameterImplementationDefault;
#ifndef MAGNUM_TARGET_GLES
AbstractTexture::GetLevelParameterivImplementation AbstractTexture::getLevelParameterivImplementation =
&AbstractTexture::getLevelParameterImplementationDefault;
#endif
AbstractTexture::MipmapImplementation AbstractTexture::mipmapImplementation =
&AbstractTexture::mipmapImplementationDefault;
#ifndef MAGNUM_TARGET_GLES
AbstractTexture::Storage1DImplementation AbstractTexture::storage1DImplementation =
&AbstractTexture::storageImplementationDefault;
#endif
AbstractTexture::Storage2DImplementation AbstractTexture::storage2DImplementation =
&AbstractTexture::storageImplementationDefault;
AbstractTexture::Storage3DImplementation AbstractTexture::storage3DImplementation =
&AbstractTexture::storageImplementationDefault;
#ifndef MAGNUM_TARGET_GLES
AbstractTexture::Image1DImplementation AbstractTexture::image1DImplementation =
&AbstractTexture::imageImplementationDefault;
#endif
@ -49,6 +72,9 @@ 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
@ -56,21 +82,21 @@ AbstractTexture::SubImage3DImplementation AbstractTexture::subImage3DImplementat
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(NearestNeighbor, BaseLevel) == GL_NEAREST) &&
(filter_or(NearestNeighbor, NearestLevel) == GL_NEAREST_MIPMAP_NEAREST) &&
(filter_or(NearestNeighbor, LinearInterpolation) == GL_NEAREST_MIPMAP_LINEAR) &&
(filter_or(LinearInterpolation, BaseLevel) == GL_LINEAR) &&
(filter_or(LinearInterpolation, NearestLevel) == GL_LINEAR_MIPMAP_NEAREST) &&
(filter_or(LinearInterpolation, LinearInterpolation) == GL_LINEAR_MIPMAP_LINEAR),
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
GLint AbstractTexture::maxSupportedLayerCount() {
Int AbstractTexture::maxSupportedLayerCount() {
return Context::current()->state()->texture->maxSupportedLayerCount;
}
GLfloat AbstractTexture::maxSupportedAnisotropy() {
Float AbstractTexture::maxSupportedAnisotropy() {
GLfloat& value = Context::current()->state()->texture->maxSupportedAnisotropy;
/** @todo Re-enable when extension header is available */
@ -83,7 +109,10 @@ GLfloat AbstractTexture::maxSupportedAnisotropy() {
return value;
}
AbstractTexture::~AbstractTexture() {
void AbstractTexture::destroy() {
/* Moved out */
if(!_id) return;
/* Remove all bindings */
std::vector<GLuint>& bindings = Context::current()->state()->texture->bindings;
for(auto it = bindings.begin(); it != bindings.end(); ++it)
@ -92,7 +121,27 @@ AbstractTexture::~AbstractTexture() {
glDeleteTextures(1, &_id);
}
void AbstractTexture::bind(GLint layer) {
void AbstractTexture::move() {
_id = 0;
}
AbstractTexture::~AbstractTexture() { destroy(); }
AbstractTexture::AbstractTexture(AbstractTexture&& other): _target(other._target), _id(other._id) {
other.move();
}
AbstractTexture& AbstractTexture::operator=(AbstractTexture&& other) {
destroy();
_target = other._target;
_id = other._id;
other.move();
return *this;
}
void AbstractTexture::bind(Int layer) {
Implementation::TextureState* const textureState = Context::current()->state()->texture;
/* If already bound in given layer, nothing to do */
@ -120,7 +169,7 @@ void AbstractTexture::bindImplementationDSA(GLint layer) {
AbstractTexture* AbstractTexture::setMinificationFilter(Filter filter, Mipmap mipmap) {
#ifndef MAGNUM_TARGET_GLES
CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE || mipmap == Mipmap::BaseLevel, "AbstractTexture: rectangle textures cannot have mipmaps", this);
CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE || mipmap == Mipmap::Base, "AbstractTexture: rectangle textures cannot have mipmaps", this);
#endif
(this->*parameteriImplementation)(GL_TEXTURE_MIN_FILTER,
@ -183,7 +232,11 @@ void AbstractTexture::initializeContextBasedFunctionality(Context* context) {
parameteriImplementation = &AbstractTexture::parameterImplementationDSA;
parameterfImplementation = &AbstractTexture::parameterImplementationDSA;
parameterfvImplementation = &AbstractTexture::parameterImplementationDSA;
getLevelParameterivImplementation = &AbstractTexture::getLevelParameterImplementationDSA;
mipmapImplementation = &AbstractTexture::mipmapImplementationDSA;
storage1DImplementation = &AbstractTexture::storageImplementationDSA;
storage2DImplementation = &AbstractTexture::storageImplementationDSA;
storage3DImplementation = &AbstractTexture::storageImplementationDSA;
image1DImplementation = &AbstractTexture::imageImplementationDSA;
image2DImplementation = &AbstractTexture::imageImplementationDSA;
image3DImplementation = &AbstractTexture::imageImplementationDSA;
@ -191,6 +244,13 @@ void AbstractTexture::initializeContextBasedFunctionality(Context* context) {
subImage2DImplementation = &AbstractTexture::subImageImplementationDSA;
subImage3DImplementation = &AbstractTexture::subImageImplementationDSA;
}
if(context->isExtensionSupported<Extensions::GL::ARB::invalidate_subdata>()) {
Debug() << "AbstractTexture: using" << Extensions::GL::ARB::invalidate_subdata::string() << "features";
invalidateImplementation = &AbstractTexture::invalidateImplementationARB;
invalidateSubImplementation = &AbstractTexture::invalidateSubImplementationARB;
}
#endif
}
@ -225,170 +285,228 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, const GLf
void AbstractTexture::parameterImplementationDSA(GLenum parameter, const GLfloat* values) {
glTextureParameterfvEXT(_id, _target, parameter, values);
}
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::getLevelParameterImplementationDefault(GLenum target, GLint level, GLenum parameter, GLint* values) {
bindInternal();
glGetTexLevelParameteriv(target, level, parameter, values);
}
void AbstractTexture::getLevelParameterImplementationDSA(GLenum target, GLint level, GLenum parameter, GLint* values) {
glGetTextureLevelParameterivEXT(_id, target, level, parameter, values);
}
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels, AbstractTexture::InternalFormat internalFormat, const Math::Vector< 1, GLsizei >& size) {
bindInternal();
/** @todo Re-enable when extension wrangler is available for ES2 */
#ifndef MAGNUM_TARGET_GLES2
glTexStorage1D(target, levels, GLenum(internalFormat), size[0]);
#else
//glTexStorage2DEXT(target, levels, GLenum(internalFormat), size.x(), size.y());
static_cast<void>(target);
static_cast<void>(levels);
static_cast<void>(internalFormat);
static_cast<void>(size);
#endif
}
void AbstractTexture::storageImplementationDSA(GLenum target, GLsizei levels, AbstractTexture::InternalFormat 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) {
bindInternal();
/** @todo Re-enable when extension wrangler is available for ES2 */
#ifndef MAGNUM_TARGET_GLES2
glTexStorage2D(target, levels, GLenum(internalFormat), size.x(), size.y());
#else
//glTexStorage2DEXT(target, levels, GLenum(internalFormat), size.x(), size.y());
static_cast<void>(target);
static_cast<void>(levels);
static_cast<void>(internalFormat);
static_cast<void>(size);
#endif
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::storageImplementationDSA(GLenum target, GLsizei levels, AbstractTexture::InternalFormat 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) {
bindInternal();
/** @todo Re-enable when extension wrangler is available for ES2 */
#ifndef MAGNUM_TARGET_GLES2
glTexStorage3D(target, levels, GLenum(internalFormat), size.x(), size.y(), size.z());
#else
//glTexStorage3DEXT(target, levels, GLenum(internalFormat), size.x(), size.y(), size.z());
static_cast<void>(target);
static_cast<void>(levels);
static_cast<void>(internalFormat);
static_cast<void>(size);
#endif
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::storageImplementationDSA(GLenum target, GLsizei levels, AbstractTexture::InternalFormat internalFormat, const Vector3i& size) {
glTextureStorage3DEXT(_id, target, levels, GLenum(internalFormat), size.x(), size.y(), size.z());
}
void AbstractTexture::imageImplementationDefault(GLenum target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector<1, GLsizei>& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* 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) {
bindInternal();
glTexImage1D(target, mipLevel, internalFormat, size[0], 0, static_cast<GLenum>(components), static_cast<GLenum>(type), data);
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 mipLevel, InternalFormat internalFormat, const Math::Vector<1, GLsizei>& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) {
glTextureImage1DEXT(_id, target, mipLevel, internalFormat, size[0], 0, static_cast<GLenum>(components), 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) {
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 mipLevel, InternalFormat internalFormat, const Math::Vector2<GLsizei>& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) {
void AbstractTexture::imageImplementationDefault(GLenum target, GLint level, InternalFormat internalFormat, const Vector2i& size, AbstractImage::Format format, AbstractImage::Type type, const GLvoid* data) {
bindInternal();
glTexImage2D(target, mipLevel, internalFormat, size.x(), size.y(), 0, static_cast<GLenum>(components), static_cast<GLenum>(type), data);
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 mipLevel, InternalFormat internalFormat, const Math::Vector2<GLsizei>& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) {
glTextureImage2DEXT(_id, target, mipLevel, internalFormat, size.x(), size.y(), 0, static_cast<GLenum>(components), static_cast<GLenum>(type), data);
void AbstractTexture::imageImplementationDSA(GLenum target, GLint level, InternalFormat internalFormat, const Vector2i& size, AbstractImage::Format format, AbstractImage::Type 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 mipLevel, InternalFormat internalFormat, const Math::Vector3<GLsizei>& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) {
void AbstractTexture::imageImplementationDefault(GLenum target, GLint level, InternalFormat internalFormat, const Vector3i& size, AbstractImage::Format format, AbstractImage::Type type, const GLvoid* data) {
bindInternal();
/** @todo Get some extension wrangler instead to avoid linker errors to glTexImage3D() on ES2 */
#ifndef MAGNUM_TARGET_GLES2
glTexImage3D(target, mipLevel, internalFormat, size.x(), size.y(), size.z(), 0, static_cast<GLenum>(components), static_cast<GLenum>(type), data);
glTexImage3D(target, level, GLint(internalFormat), size.x(), size.y(), size.z(), 0, static_cast<GLenum>(format), static_cast<GLenum>(type), data);
#else
static_cast<void>(target);
static_cast<void>(mipLevel);
static_cast<void>(level);
static_cast<void>(internalFormat);
static_cast<void>(size);
static_cast<void>(components);
static_cast<void>(format);
static_cast<void>(type);
static_cast<void>(data);
#endif
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::imageImplementationDSA(GLenum target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector3<GLsizei>& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) {
glTextureImage3DEXT(_id, target, mipLevel, internalFormat, size.x(), size.y(), size.z(), 0, static_cast<GLenum>(components), static_cast<GLenum>(type), data);
void AbstractTexture::imageImplementationDSA(GLenum target, GLint level, InternalFormat internalFormat, const Vector3i& size, AbstractImage::Format format, AbstractImage::Type 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 mipLevel, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) {
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) {
bindInternal();
glTexSubImage1D(target, mipLevel, offset[0], size[0], static_cast<GLenum>(components), static_cast<GLenum>(type), data);
glTexSubImage1D(target, level, offset[0], size[0], static_cast<GLenum>(format), static_cast<GLenum>(type), data);
}
void AbstractTexture::subImageImplementationDSA(GLenum target, GLint mipLevel, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) {
glTextureSubImage1DEXT(_id, target, mipLevel, offset[0], size[0], static_cast<GLenum>(components), 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) {
glTextureSubImage1DEXT(_id, target, level, offset[0], size[0], static_cast<GLenum>(format), static_cast<GLenum>(type), data);
}
#endif
void AbstractTexture::subImageImplementationDefault(GLenum target, GLint mipLevel, const Math::Vector2<GLint>& offset, const Math::Vector2<GLsizei>& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) {
void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, AbstractImage::Format format, AbstractImage::Type type, const GLvoid* data) {
bindInternal();
glTexSubImage2D(target, mipLevel, offset.x(), offset.y(), size.x(), size.y(), static_cast<GLenum>(components), static_cast<GLenum>(type), data);
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 mipLevel, const Math::Vector2<GLint>& offset, const Math::Vector2<GLsizei>& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) {
glTextureSubImage2DEXT(_id, target, mipLevel, offset.x(), offset.y(), size.x(), size.y(), static_cast<GLenum>(components), static_cast<GLenum>(type), data);
void AbstractTexture::subImageImplementationDSA(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, AbstractImage::Format format, AbstractImage::Type 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 mipLevel, const Math::Vector3<GLint>& offset, const Math::Vector3<GLsizei>& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) {
void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, AbstractImage::Format format, AbstractImage::Type type, const GLvoid* data) {
bindInternal();
/** @todo Get some extension wrangler instead to avoid linker errors to glTexSubImage3D() on ES2 */
#ifndef MAGNUM_TARGET_GLES2
glTexSubImage3D(target, mipLevel, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), static_cast<GLenum>(components), static_cast<GLenum>(type), data);
glTexSubImage3D(target, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), static_cast<GLenum>(format), static_cast<GLenum>(type), data);
#else
static_cast<void>(target);
static_cast<void>(mipLevel);
static_cast<void>(level);
static_cast<void>(offset);
static_cast<void>(size);
static_cast<void>(components);
static_cast<void>(format);
static_cast<void>(type);
static_cast<void>(data);
#endif
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::subImageImplementationDSA(GLenum target, GLint mipLevel, const Math::Vector3<GLint>& offset, const Math::Vector3<GLsizei>& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) {
glTextureSubImage3DEXT(_id, target, mipLevel, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), static_cast<GLenum>(components), static_cast<GLenum>(type), data);
void AbstractTexture::subImageImplementationDSA(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, AbstractImage::Format format, AbstractImage::Type 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) {}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::invalidateImplementationARB(GLint level) {
glInvalidateTexImage(_id, level);
}
#endif
void AbstractTexture::invalidateSubImplementationNoOp(GLint, const Vector3i&, const Vector3i&) {}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::invalidateSubImplementationARB(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_GLES2
AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Components components, AbstractTexture::ComponentType type) {
#ifndef MAGNUM_TARGET_GLES
#define internalFormatSwitch(c) switch(type) { \
case ComponentType::UnsignedByte: \
internalFormat = GL_##c##8UI; break; \
case ComponentType::Byte: \
internalFormat = GL_##c##8I; break; \
case ComponentType::UnsignedShort: \
internalFormat = GL_##c##16UI; break; \
case ComponentType::Short: \
internalFormat = GL_##c##16I; break; \
case ComponentType::UnsignedInt: \
internalFormat = GL_##c##32UI; break; \
case ComponentType::Int: \
internalFormat = GL_##c##32I; break; \
case ComponentType::Half: \
internalFormat = GL_##c##16F; break; \
case ComponentType::Float: \
internalFormat = GL_##c##32F; break; \
case ComponentType::NormalizedUnsignedByte: \
internalFormat = GL_##c##8; break; \
case ComponentType::NormalizedByte: \
internalFormat = GL_##c##8_SNORM; break; \
case ComponentType::NormalizedUnsignedShort: \
internalFormat = GL_##c##16; break; \
case ComponentType::NormalizedShort: \
internalFormat = GL_##c##16_SNORM; break; \
}
#else
#define internalFormatSwitch(c) switch(type) { \
case ComponentType::UnsignedByte: \
internalFormat = GL_##c##8UI; break; \
case ComponentType::Byte: \
internalFormat = GL_##c##8I; break; \
case ComponentType::UnsignedShort: \
internalFormat = GL_##c##16UI; break; \
case ComponentType::Short: \
internalFormat = GL_##c##16I; break; \
case ComponentType::UnsignedInt: \
internalFormat = GL_##c##32UI; break; \
case ComponentType::Int: \
internalFormat = GL_##c##32I; break; \
case ComponentType::Half: \
internalFormat = GL_##c##16F; break; \
case ComponentType::Float: \
internalFormat = GL_##c##32F; break; \
case ComponentType::NormalizedUnsignedByte: \
internalFormat = GL_##c##8; break; \
case ComponentType::NormalizedByte: \
internalFormat = GL_##c##8_SNORM; break; \
namespace Implementation {
template<UnsignedInt dimensions> const GLvoid* ImageHelper<BufferImage<dimensions>>::dataOrPixelUnpackBuffer(BufferImage<dimensions>* image) {
image->buffer()->bind(Buffer::Target::PixelUnpack);
return nullptr;
}
#endif
if(components == Components::Red)
internalFormatSwitch(R)
else if(components == Components::RedGreen)
internalFormatSwitch(RG)
else if(components == Components::RGB)
internalFormatSwitch(RGB)
else if(components == Components::RGBA)
internalFormatSwitch(RGBA)
#undef internalFormatSwitch
template struct ImageHelper<BufferImage1D>;
template struct ImageHelper<BufferImage2D>;
template struct ImageHelper<BufferImage3D>;
}
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
void AbstractTexture::DataHelper<2>::setWrapping(AbstractTexture* texture, const Math::Vector2<Wrapping>& wrapping) {
#ifndef MAGNUM_TARGET_GLES
Math::Vector<1, GLint> AbstractTexture::DataHelper<1>::imageSize(AbstractTexture* texture, GLenum target, GLint level) {
Math::Vector<1, GLint> value;
(texture->*getLevelParameterivImplementation)(target, level, GL_TEXTURE_WIDTH, &value[0]);
return value;
}
Vector2i AbstractTexture::DataHelper<2>::imageSize(AbstractTexture* texture, GLenum target, GLint level) {
Vector2i value;
(texture->*getLevelParameterivImplementation)(target, level, GL_TEXTURE_WIDTH, &value[0]);
(texture->*getLevelParameterivImplementation)(target, level, GL_TEXTURE_HEIGHT, &value[1]);
return value;
}
Vector3i AbstractTexture::DataHelper<3>::imageSize(AbstractTexture* texture, GLenum target, GLint level) {
Vector3i value;
(texture->*getLevelParameterivImplementation)(target, level, GL_TEXTURE_WIDTH, &value[0]);
(texture->*getLevelParameterivImplementation)(target, level, GL_TEXTURE_HEIGHT, &value[1]);
(texture->*getLevelParameterivImplementation)(target, level, GL_TEXTURE_DEPTH, &value[2]);
return value;
}
#endif
void AbstractTexture::DataHelper<2>::setWrapping(AbstractTexture* texture, const Array2D<Wrapping>& wrapping) {
#ifndef MAGNUM_TARGET_GLES
CORRADE_ASSERT(texture->_target != GL_TEXTURE_RECTANGLE || ((wrapping[0] == Wrapping::ClampToEdge || wrapping[0] == Wrapping::ClampToBorder) && (wrapping[0] == Wrapping::ClampToEdge || wrapping[1] == Wrapping::ClampToEdge)), "AbstractTexture: rectangle texture wrapping must either clamp to border or to edge", );
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", );
#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 Math::Vector3<Wrapping>& wrapping) {
void AbstractTexture::DataHelper<3>::setWrapping(AbstractTexture* texture, const Array3D<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

1255
src/AbstractTexture.h

File diff suppressed because it is too large Load Diff

221
src/Array.h

@ -0,0 +1,221 @@
#ifndef Magnum_Array_h
#define Magnum_Array_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 Class Magnum::Array, Magnum::Array1D, Magnum::Array2D, Magnum::Array3D
*/
#include <type_traits>
#include <Utility/Debug.h>
#include "Magnum.h"
namespace Magnum {
/**
@brief %Array
@tparam dimensions Dimension count
@tparam T Data type
Similar to Math::Vector, but more suitable for storing enum values which don't
need any math operations and fuzzy comparison (e.g. enum values). Unlike
Math::Vector this class has non-explicit constructor from one value.
@see Array1D, Array2D, Array3D
*/
template<UnsignedInt dimensions, class T> class Array {
public:
typedef T Type; /**< @brief Data type */
const static UnsignedInt Dimensions = dimensions; /**< @brief Dimension count */
/**
* @brief Default constructor
*
* Sets all components to their default-constructed values
*/
inline constexpr /*implicit*/ Array(): _data() {}
/**
* @brief Initializer-list constructor
* @param first First value
* @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...} {
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} {}
#else
template<class ...U> inline 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) {
for(UnsignedInt i = 0; i != dimensions; ++i)
_data[i] = value;
}
/** @brief Equality */
inline 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 {
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 */
/**
* @brief Raw data
* @return One-dimensional array of `dimensions` length
*/
inline T* data() { return _data; }
inline constexpr const T* data() const { return _data; } /**< @overload */
private:
T _data[dimensions];
};
/**
@brief One-dimensional array
@tparam T Data type
*/
template<class T> class Array1D: public Array<1, T> {
public:
/** @copydoc Array::Array() */
inline constexpr /*implicit*/ Array1D() = default;
/**
* @brief Constructor
* @param x X component
*/
inline constexpr /*implicit*/ Array1D(T x): Array<1, T>(x) {}
/** @brief Copy constructor */
inline 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 */
};
/**
@brief Two-dimensional array
@tparam T Data type
*/
template<class T> class Array2D: public Array<2, T> {
public:
/** @copydoc Array::Array() */
inline 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) {}
/** @copydoc Array::Array(U) */
inline 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) {}
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 */
};
/**
@brief Three-dimensional array
@tparam T Data type
*/
template<class T> class Array3D: public Array<3, T> {
public:
/** @copydoc Array::Array() */
inline constexpr /*implicit*/ Array3D() {}
/**
* @brief Constructor
* @param x X component
* @param y Y component
* @param z Z component
*/
inline 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) {}
/** @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 */
};
/** @debugoperator{Magnum::Array} */
template<UnsignedInt dimensions, class T> Debug operator<<(Debug debug, const Array<dimensions, T>& value) {
debug << "Array(";
debug.setFlag(Debug::SpaceAfterEachValue, false);
for(UnsignedInt i = 0; i != dimensions; ++i) {
if(i != 0) debug << ", ";
debug << value[i];
}
debug << ")";
debug.setFlag(Debug::SpaceAfterEachValue, true);
return debug;
}
/** @debugoperator{Magnum::Array1D} */
template<class T> inline Debug operator<<(Debug debug, const Array1D<T>& value) {
return debug << static_cast<const Array<1, T>&>(value);
}
/** @debugoperator{Magnum::Array2D} */
template<class T> inline Debug operator<<(Debug debug, const Array2D<T>& value) {
return debug << static_cast<const Array<2, T>&>(value);
}
/** @debugoperator{Magnum::Array3D} */
template<class T> inline Debug operator<<(Debug debug, const Array3D<T>& value) {
return debug << static_cast<const Array<3, T>&>(value);
}
}
#endif

127
src/Buffer.cpp

@ -1,16 +1,25 @@
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
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 "Buffer.h"
@ -29,6 +38,12 @@ Buffer::CopyImplementation Buffer::copyImplementation = &Buffer::copyImplementat
#endif
Buffer::SetDataImplementation Buffer::setDataImplementation = &Buffer::setDataImplementationDefault;
Buffer::SetSubDataImplementation Buffer::setSubDataImplementation = &Buffer::setSubDataImplementationDefault;
Buffer::InvalidateImplementation Buffer::invalidateImplementation = &Buffer::invalidateImplementationNoOp;
Buffer::InvalidateSubImplementation Buffer::invalidateSubImplementation = &Buffer::invalidateSubImplementationNoOp;
Buffer::MapImplementation Buffer::mapImplementation = &Buffer::mapImplementationDefault;
Buffer::MapRangeImplementation Buffer::mapRangeImplementation = &Buffer::mapRangeImplementationDefault;
Buffer::FlushMappedRangeImplementation Buffer::flushMappedRangeImplementation = &Buffer::flushMappedRangeImplementationDefault;
Buffer::UnmapImplementation Buffer::unmapImplementation = &Buffer::unmapImplementationDefault;
void Buffer::initializeContextBasedFunctionality(Context* context) {
#ifndef MAGNUM_TARGET_GLES
@ -38,6 +53,17 @@ void Buffer::initializeContextBasedFunctionality(Context* context) {
copyImplementation = &Buffer::copyImplementationDSA;
setDataImplementation = &Buffer::setDataImplementationDSA;
setSubDataImplementation = &Buffer::setSubDataImplementationDSA;
mapImplementation = &Buffer::mapImplementationDSA;
mapRangeImplementation = &Buffer::mapRangeImplementationDSA;
flushMappedRangeImplementation = &Buffer::flushMappedRangeImplementationDSA;
unmapImplementation = &Buffer::unmapImplementationDSA;
}
if(context->isExtensionSupported<Extensions::GL::ARB::invalidate_subdata>()) {
Debug() << "Buffer: using" << Extensions::GL::ARB::invalidate_subdata::string() << "features";
invalidateImplementation = &Buffer::invalidateImplementationARB;
invalidateSubImplementation = &Buffer::invalidateSubImplementationARB;
}
#else
static_cast<void>(context);
@ -114,4 +140,85 @@ void Buffer::setSubDataImplementationDSA(GLintptr offset, GLsizeiptr size, const
}
#endif
void Buffer::invalidateImplementationNoOp() {}
#ifndef MAGNUM_TARGET_GLES
void Buffer::invalidateImplementationARB() {
glInvalidateBufferData(_id);
}
#endif
void Buffer::invalidateSubImplementationNoOp(GLintptr, GLsizeiptr) {}
#ifndef MAGNUM_TARGET_GLES
void Buffer::invalidateSubImplementationARB(GLintptr offset, GLsizeiptr length) {
glInvalidateBufferSubData(_id, offset, length);
}
#endif
void* Buffer::mapImplementationDefault(MapAccess access) {
/** @todo Re-enable when extension wrangler is available for ES */
#ifndef MAGNUM_TARGET_GLES
return glMapBuffer(static_cast<GLenum>(bindInternal(_targetHint)), GLenum(access));
#else
static_cast<void>(access);
return nullptr;
#endif
}
#ifndef MAGNUM_TARGET_GLES
void* Buffer::mapImplementationDSA(MapAccess access) {
return glMapNamedBufferEXT(_id, GLenum(access));
}
#endif
void* Buffer::mapRangeImplementationDefault(GLintptr offset, GLsizeiptr length, MapFlags access) {
/** @todo Re-enable when extension wrangler is available for ES */
#ifndef MAGNUM_TARGET_GLES2
return glMapBufferRange(static_cast<GLenum>(bindInternal(_targetHint)), offset, length, GLenum(access));
#else
static_cast<void>(offset);
static_cast<void>(length);
static_cast<void>(access);
return nullptr;
#endif
}
#ifndef MAGNUM_TARGET_GLES
void* Buffer::mapRangeImplementationDSA(GLintptr offset, GLsizeiptr length, MapFlags access) {
return glMapNamedBufferRangeEXT(_id, offset, length, GLenum(access));
}
#endif
void Buffer::flushMappedRangeImplementationDefault(GLintptr offset, GLsizeiptr length) {
/** @todo Re-enable when extension wrangler is available for ES */
#ifndef MAGNUM_TARGET_GLES2
glFlushMappedBufferRange(static_cast<GLenum>(bindInternal(_targetHint)), offset, length);
#else
static_cast<void>(offset);
static_cast<void>(length);
#endif
}
#ifndef MAGNUM_TARGET_GLES
void Buffer::flushMappedRangeImplementationDSA(GLintptr offset, GLsizeiptr length) {
glFlushMappedNamedBufferRangeEXT(_id, offset, length);
}
#endif
bool Buffer::unmapImplementationDefault() {
/** @todo Re-enable when extension wrangler is available for ES */
#ifndef MAGNUM_TARGET_GLES2
return glUnmapBuffer(static_cast<GLenum>(bindInternal(_targetHint)));
#else
return false;
#endif
}
#ifndef MAGNUM_TARGET_GLES
bool Buffer::unmapImplementationDSA() {
return glUnmapNamedBufferEXT(_id);
}
#endif
}

369
src/Buffer.h

@ -1,18 +1,27 @@
#ifndef Magnum_Buffer_h
#define Magnum_Buffer_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
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
@ -22,9 +31,10 @@
#include <cstddef>
#include <array>
#include <vector>
#include <Containers/EnumSet.h>
#include "Magnum.h"
#include "OpenGL.h"
#include "magnumVisibility.h"
namespace Magnum {
@ -40,6 +50,7 @@ data updates.
Default way to set or update buffer data with setData() or setSubData() is to
explicitly specify data size and pass the pointer to it:
@code
Buffer buffer;
Vector3* data = new Vector3[200];
buffer.setData(200*sizeof(Vector3), data, Buffer::Usage::StaticDraw);
@endcode
@ -59,19 +70,52 @@ std::vector<Vector3> data;
buffer.setData(data, Buffer::Usage::StaticDraw);
@endcode
@subsection Buffer-data-mapping Memory mapping
%Buffer data can be also updated asynchronously. First you need to allocate
the buffer to desired size by passing `nullptr` to setData(), e.g.:
@code
buffer.setData(200*sizeof(Vector3)), nullptr, Buffer::Usage::StaticDraw);
@endcode
Then you can map the buffer to client memory and operate with the memory
directly. After you are done with the operation, call unmap() to unmap the
buffer again.
@code
Vector3* data = static_cast<Vector3*>(buffer.map(0, 200*sizeof(Vector3), Buffer::MapFlag::Write|Buffer::MapFlag::InvalidateBuffer));
for(std::size_t i = 0; i != 200; ++i)
data[i] = ...;
CORRADE_INTERNAL_ASSERT_OUTPUT(buffer.unmap());
@endcode
If you are updating only a few discrete portions of the buffer, you can use
@ref MapFlag "MapFlag::FlushExplicit" and flushMappedRange() to reduce number
of memory operations performed by OpenGL on unmapping. Example:
@code
Vector3* data = static_cast<Vector3*>(buffer.map(0, 200*sizeof(Vector3), Buffer::MapFlag::Write|Buffer::MapFlag::FlushExplicit));
for(std::size_t i: {7, 27, 56, 128}) {
data[i] = ...;
buffer.flushMappedRange(i*sizeof(Vector3), sizeof(Vector3));
}
CORRADE_INTERNAL_ASSERT_OUTPUT(buffer.unmap());
@endcode
@section Buffer-performance-optimization Performance optimizations
The engine tracks currently bound buffers to avoid unnecessary calls to
@fn_gl{BindBuffer}. If the buffer is already bound to some target,
functions copy(), setData() and setSubData() use that target in
@fn_gl{CopyBufferSubData}, @fn_gl{BufferData} and @fn_gl{BufferSubData}
functions instead of binding the buffer to some specific target. You can also
use setTargetHint() to possibly reduce unnecessary rebinding.
@fn_gl{BindBuffer}. If the buffer is already bound to some target, functions
copy(), setData(), setSubData(), map(), flushMappedRange() and unmap() use
that target instead of binding the buffer to some specific target. You can
also use setTargetHint() to possibly reduce unnecessary rebinding.
If extension @extension{EXT,direct_state_access} is available, functions
copy(), setData() and setSubData() use DSA functions to avoid unnecessary
calls to @fn_gl{BindBuffer}. See their respective documentation for more
information.
copy(), setData(), setSubData(), map(), flushMappedRange() and unmap() use DSA
functions to avoid unnecessary calls to @fn_gl{BindBuffer}. See their
respective documentation for more information.
You can use functions invalidateData() and invalidateSubData() if you don't
need buffer data anymore to avoid unnecessary memory operations performed by
OpenGL in order to preserve the data. If running on OpenGL ES or extension
@extension{ARB,invalidate_subdata} is not available, these functions do
nothing.
@todo Support for AMD's query buffer (@extension{AMD,query_buffer_object})
@todo BindBufferRange/BindBufferOffset/BindBufferBase for transform feedback (3.0, @extension{EXT,transform_feedback})
@ -97,7 +141,7 @@ class MAGNUM_EXPORT Buffer {
#ifndef MAGNUM_TARGET_GLES
/**
* Used for storing atomic counters.
* @requires_gl42 Extension @extension{ARB,shader_atomic_counters}
* @requires_gl42 %Extension @extension{ARB,shader_atomic_counters}
* @requires_gl Atomic counters are not available in OpenGL ES.
*/
AtomicCounter = GL_ATOMIC_COUNTER_BUFFER,
@ -106,7 +150,7 @@ class MAGNUM_EXPORT Buffer {
#ifndef MAGNUM_TARGET_GLES2
/**
* Source for copies. See copy().
* @requires_gl31 Extension @extension{ARB,copy_buffer}
* @requires_gl31 %Extension @extension{ARB,copy_buffer}
* @requires_gles30 Buffer copying is not available in OpenGL ES
* 2.0.
*/
@ -114,7 +158,7 @@ class MAGNUM_EXPORT Buffer {
/**
* Target for copies. See copy().
* @requires_gl31 Extension @extension{ARB,copy_buffer}
* @requires_gl31 %Extension @extension{ARB,copy_buffer}
* @requires_gles30 Buffer copying is not available in OpenGL ES
* 2.0.
*/
@ -124,14 +168,14 @@ class MAGNUM_EXPORT Buffer {
#ifndef MAGNUM_TARGET_GLES
/**
* Indirect compute dispatch commands.
* @requires_gl43 Extension @extension{ARB,compute_shader}
* @requires_gl43 %Extension @extension{ARB,compute_shader}
* @requires_gl Compute shaders are not available in OpenGL ES.
*/
DispatchIndirect = GL_DISPATCH_INDIRECT_BUFFER,
/**
* Used for supplying arguments for indirect drawing.
* @requires_gl40 Extension @extension{ARB,draw_indirect}
* @requires_gl40 %Extension @extension{ARB,draw_indirect}
* @requires_gl Indirect drawing not available in OpenGL ES.
*/
DrawIndirect = GL_DRAW_INDIRECT_BUFFER,
@ -161,14 +205,14 @@ class MAGNUM_EXPORT Buffer {
#ifndef MAGNUM_TARGET_GLES
/**
* Used for shader storage.
* @requires_gl43 Extension @extension{ARB,shader_storage_buffer_object}
* @requires_gl43 %Extension @extension{ARB,shader_storage_buffer_object}
* @requires_gl Shader storage is not available in OpenGL ES.
*/
ShaderStorage = GL_SHADER_STORAGE_BUFFER,
/**
* Source for texel fetches. See BufferedTexture.
* @requires_gl31 Extension @extension{ARB,texture_buffer_object}
* Source for texel fetches. See BufferTexture.
* @requires_gl31 %Extension @extension{ARB,texture_buffer_object}
* @requires_gl Texture buffers are not available in OpenGL ES.
*/
Texture = GL_TEXTURE_BUFFER,
@ -177,7 +221,7 @@ class MAGNUM_EXPORT Buffer {
#ifndef MAGNUM_TARGET_GLES2
/**
* Target for transform feedback.
* @requires_gl30 Extension @extension{EXT,transform_feedback}
* @requires_gl30 %Extension @extension{EXT,transform_feedback}
* @requires_gles30 Transform feedback is not available in OpenGL
* ES 2.0.
*/
@ -185,7 +229,7 @@ class MAGNUM_EXPORT Buffer {
/**
* Used for storing uniforms.
* @requires_gl31 Extension @extension{ARB,uniform_buffer_object}
* @requires_gl31 %Extension @extension{ARB,uniform_buffer_object}
* @requires_gles30 Uniform buffers are not available in OpenGL ES
* 2.0.
*/
@ -265,13 +309,123 @@ class MAGNUM_EXPORT Buffer {
/**
* Updated frequently as output from OpenGL command and used
* frequently for drawing or copying to other images.
* @requires_gles30 Only @ref Magnum::Buffer::Usage "Usage::DynamicCopy"
* @requires_gles30 Only @ref Magnum::Buffer::Usage "Usage::DynamicDraw"
* is available in OpenGL ES 2.0.
*/
DynamicCopy = GL_DYNAMIC_COPY
#endif
};
/**
* @brief Memory mapping access
*
* @deprecated Prefer to use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)"
* instead, as it has more complete set of features.
* @see map(MapAccess)
* @requires_es_extension %Extension @es_extension{OES,mapbuffer} in
* OpenGL ES 2.0, use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)"
* in OpenGL ES 3.0 instead.
*/
enum class MapAccess: GLenum {
#ifndef MAGNUM_TARGET_GLES
/**
* Map buffer for reading only.
* @requires_gl Only @ref Magnum::Buffer::MapAccess "MapAccess::WriteOnly"
* is available in OpenGL ES 2.0.
*/
ReadOnly = GL_READ_ONLY,
#endif
/**
* Map buffer for writing only.
*/
#ifdef MAGNUM_TARGET_GLES
WriteOnly = GL_WRITE_ONLY_OES
#else
WriteOnly = GL_WRITE_ONLY,
/**
* Map buffer for both reading and writing.
* @requires_gl Only @ref Magnum::Buffer::MapAccess "MapAccess::WriteOnly"
* is available in OpenGL ES 2.0.
*/
ReadWrite = GL_READ_WRITE
#endif
};
/**
* @brief Memory mapping flag
*
* @see MapFlags, map(GLintptr, GLsizeiptr, MapFlags)
* @requires_gl30 %Extension @extension{ARB,map_buffer_range}
* @requires_gles30 %Extension @es_extension{EXT,map_buffer_range}
*/
enum class MapFlag: GLbitfield {
/** Map buffer for reading. */
#ifndef MAGNUM_TARGET_GLES2
Read = GL_MAP_READ_BIT,
#else
Read = GL_MAP_READ_BIT_EXT,
#endif
/** Map buffer for writing. */
#ifndef MAGNUM_TARGET_GLES2
Write = GL_MAP_WRITE_BIT,
#else
Write = GL_MAP_WRITE_BIT_EXT,
#endif
/**
* Previous contents of the entire buffer may be discarded. May
* not be used in combination with @ref MapFlag "MapFlag::Read".
* @see invalidateData()
*/
#ifndef MAGNUM_TARGET_GLES2
InvalidateBuffer = GL_MAP_INVALIDATE_BUFFER_BIT,
#else
InvalidateBuffer = GL_MAP_INVALIDATE_BUFFER_BIT_EXT,
#endif
/**
* Previous contents of mapped range may be discarded. May not
* be used in combination with @ref MapFlag "MapFlag::Read".
* @see invalidateSubData()
*/
#ifndef MAGNUM_TARGET_GLES2
InvalidateRange = GL_MAP_INVALIDATE_RANGE_BIT,
#else
InvalidateRange = GL_MAP_INVALIDATE_RANGE_BIT_EXT,
#endif
/**
* Only one or more discrete subranges of the mapping will be
* modified. See flushMappedRange() for more information. May only
* be used in conjuction with @ref MapFlag "MapFlag::Write".
*/
#ifndef MAGNUM_TARGET_GLES2
FlushExplicit = GL_MAP_FLUSH_EXPLICIT_BIT,
#else
FlushExplicit = GL_MAP_FLUSH_EXPLICIT_BIT_EXT,
#endif
/**
* No pending operations on the buffer should be synchronized
* before mapping.
*/
#ifndef MAGNUM_TARGET_GLES2
Unsynchronized = GL_MAP_UNSYNCHRONIZED_BIT
#else
Unsynchronized = GL_MAP_UNSYNCHRONIZED_BIT_EXT
#endif
};
/**
* @brief Memory mapping flags
*
* @see map(GLintptr, GLsizeiptr, MapFlags)
*/
typedef Corrade::Containers::EnumSet<MapFlag, GLbitfield> MapFlags;
/**
* @brief Unbind any buffer from given target
* @param target %Target
@ -293,10 +447,10 @@ class MAGNUM_EXPORT Buffer {
* buffers aren't already bound somewhere, they are bound to
* `Target::CopyRead` and `Target::CopyWrite` before the copy is
* performed.
* @requires_gl31 Extension @extension{ARB,copy_buffer}
* @requires_gles30 Buffer copying is not available in OpenGL ES 2.0.
* @see @fn_gl{BindBuffer} and @fn_gl{CopyBufferSubData} or
* @fn_gl_extension{NamedCopyBufferSubData,EXT,direct_state_access}
* @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) {
copyImplementation(read, write, readOffset, writeOffset, size);
@ -311,7 +465,7 @@ class MAGNUM_EXPORT Buffer {
* Generates new OpenGL buffer.
* @see @fn_gl{GenBuffers}
*/
inline Buffer(Target targetHint = Target::Array): _targetHint(targetHint) {
inline explicit Buffer(Target targetHint = Target::Array): _targetHint(targetHint) {
glGenBuffers(1, &_id);
}
@ -443,6 +597,111 @@ class MAGNUM_EXPORT Buffer {
setSubData(offset, data.size()*sizeof(T), data.data());
}
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Invalidate buffer data
*
* 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() {
(this->*invalidateImplementation)();
}
/**
* @brief Invalidate buffer subdata
* @param offset Offset into the buffer
* @param length Length of the invalidated range
*
* 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) {
(this->*invalidateSubImplementation)(offset, length);
}
#endif
/**
* @brief Map buffer to client memory
* @param access Access
* @return Pointer to buffer data
*
* 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.
* @deprecated Prefer to use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)"
* instead, as it has more complete set of features.
* @see unmap(), setTargetHint(), @fn_gl{BindBuffer} and @fn_gl{MapBuffer}
* or @fn_gl_extension{MapNamedBuffer,EXT,direct_state_access}
* @requires_es_extension %Extension @es_extension{OES,mapbuffer} in
* 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) {
return (this->*mapImplementation)(access);
}
/**
* @brief Map buffer to client memory
* @param offset Offset into the buffer
* @param length Length of the mapped memory
* @param flags Flags. At least @ref MapFlag "MapFlag::Read" or
* @ref MapFlag "MapFlag::Write" must be specified.
* @return Pointer to buffer data
*
* 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 flushMappedRange(), unmap(), map(MapAccess), setTargetHint(), @fn_gl{BindBuffer}
* and @fn_gl{MapBufferRange} or @fn_gl_extension{MapNamedBufferRange,EXT,direct_state_access}
* @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) {
return (this->*mapRangeImplementation)(offset, length, flags);
}
/**
* @brief Flush mapped range
* @param offset Offset relative to start of mapped range
* @param length Length of the flushed memory
*
* Flushes specified subsection of mapped range. Use only if you called
* map() with @ref MapFlag "MapFlag::FlushExplicit" flag. See
* @ref Buffer-data-mapping "class documentation" for usage example.
*
* 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 setTargetHint(), @fn_gl{BindBuffer} and @fn_gl{FlushMappedBufferRange}
* or @fn_gl_extension{FlushMappedNamedBufferRange,EXT,direct_state_access}
* @requires_gl30 %Extension @extension{ARB,map_buffer_range}
* @requires_gles30 %Extension @es_extension{EXT,map_buffer_range}
*/
inline void flushMappedRange(GLintptr offset, GLsizeiptr length) {
(this->*flushMappedRangeImplementation)(offset, length);
}
/**
* @brief Unmap buffer
* @return `False` if the data have become corrupt during the time
* the buffer was mapped (e.g. after screen was resized), `true`
* otherwise.
*
* Unmaps buffer previously mapped with map(), invalidating the
* pointer returned by these functions. 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 setTargetHint(), @fn_gl{BindBuffer} and @fn_gl{UnmapBuffer} or
* @fn_gl_extension{UnmapNamedBuffer,EXT,direct_state_access}
* @requires_gles30 %Extension @es_extension{OES,mapbuffer}
*/
inline bool unmap() {
return (this->*unmapImplementation)();
}
private:
static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context);
@ -472,10 +731,54 @@ class MAGNUM_EXPORT Buffer {
#endif
static SetSubDataImplementation setSubDataImplementation;
typedef void(Buffer::*InvalidateImplementation)();
void MAGNUM_LOCAL invalidateImplementationNoOp();
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL invalidateImplementationARB();
#endif
static InvalidateImplementation invalidateImplementation;
typedef void(Buffer::*InvalidateSubImplementation)(GLintptr, GLsizeiptr);
void MAGNUM_LOCAL invalidateSubImplementationNoOp(GLintptr offset, GLsizeiptr length);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL invalidateSubImplementationARB(GLintptr offset, GLsizeiptr length);
#endif
static InvalidateSubImplementation invalidateSubImplementation;
typedef void*(Buffer::*MapImplementation)(MapAccess);
void MAGNUM_LOCAL * mapImplementationDefault(MapAccess access);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL * mapImplementationDSA(MapAccess access);
#endif
static MapImplementation mapImplementation;
typedef void*(Buffer::*MapRangeImplementation)(GLintptr, GLsizeiptr, MapFlags);
void MAGNUM_LOCAL * mapRangeImplementationDefault(GLintptr offset, GLsizeiptr length, MapFlags access);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL * mapRangeImplementationDSA(GLintptr offset, GLsizeiptr length, MapFlags access);
#endif
static MapRangeImplementation mapRangeImplementation;
typedef void(Buffer::*FlushMappedRangeImplementation)(GLintptr, GLsizeiptr);
void MAGNUM_LOCAL flushMappedRangeImplementationDefault(GLintptr offset, GLsizeiptr length);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL flushMappedRangeImplementationDSA(GLintptr offset, GLsizeiptr length);
#endif
static FlushMappedRangeImplementation flushMappedRangeImplementation;
typedef bool(Buffer::*UnmapImplementation)();
bool MAGNUM_LOCAL unmapImplementationDefault();
#ifndef MAGNUM_TARGET_GLES
bool MAGNUM_LOCAL unmapImplementationDSA();
#endif
static UnmapImplementation unmapImplementation;
GLuint _id;
Target _targetHint;
};
CORRADE_ENUMSET_OPERATORS(Buffer::MapFlags)
}
#endif

42
src/BufferImage.cpp

@ -0,0 +1,42 @@
/*
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 "BufferImage.h"
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) {
_format = format;
_type = type;
_size = size;
_buffer.setData(pixelSize(format, type)*size.product(), data, usage);
}
template class BufferImage<1>;
template class BufferImage<2>;
template class BufferImage<3>;
#endif
}

103
src/BufferImage.h

@ -0,0 +1,103 @@
#ifndef Magnum_BufferImage_h
#define Magnum_BufferImage_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.
*/
#ifndef MAGNUM_TARGET_GLES2
/** @file
* @brief Class Magnum::BufferImage, typedef Magnum::BufferImage1D, Magnum::BufferImage2D, Magnum::BufferImage3D
*/
#endif
#include "Math/Vector3.h"
#include "AbstractImage.h"
#include "Buffer.h"
#include "DimensionTraits.h"
namespace Magnum {
#ifndef MAGNUM_TARGET_GLES2
/**
@brief %Buffer image
Stores image data in GPU memory. Interchangeable with Image, ImageWrapper or
Trade::ImageData.
@see BufferImage1D, BufferImage2D, BufferImage3D, Buffer
@requires_gles30 Pixel buffer objects are not available in OpenGL ES 2.0.
*/
template<UnsignedInt dimensions> class MAGNUM_EXPORT BufferImage: public AbstractImage {
public:
const static UnsignedInt Dimensions = dimensions; /**< @brief %Image dimension count */
/**
* @brief Constructor
* @param format Format of pixel data
* @param type Data type of pixel data
*
* Dimensions and buffer are empty, call setData() to fill the image
* with data.
*/
inline explicit BufferImage(Format format, Type type): AbstractImage(format, type) {
_buffer.setTargetHint(Buffer::Target::PixelPack);
}
/** @brief %Image size */
inline typename DimensionTraits<Dimensions, Int>::VectorType size() const { return _size; }
/** @brief %Image buffer */
inline Buffer* buffer() { return &_buffer; }
/**
* @brief Set image data
* @param size %Image size
* @param format Format of pixel data
* @param type Data type of pixel data
* @param data %Image data
* @param usage %Image buffer usage
*
* Updates the image buffer with given data. The data are not deleted
* after filling the buffer.
*
* @see Buffer::setData()
*/
void setData(const typename DimensionTraits<Dimensions, Int>::VectorType& size, Format format, Type type, const GLvoid* data, Buffer::Usage usage);
private:
Math::Vector<Dimensions, Int> _size;
Buffer _buffer;
};
/** @brief One-dimensional buffer image */
typedef BufferImage<1> BufferImage1D;
/** @brief Two-dimensional buffer image */
typedef BufferImage<2> BufferImage2D;
/** @brief Three-dimensional buffer image */
typedef BufferImage<3> BufferImage3D;
#endif
}
#endif

66
src/BufferTexture.cpp

@ -0,0 +1,66 @@
/*
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 "BufferTexture.h"
#ifndef MAGNUM_TARGET_GLES
#include "Buffer.h"
#include "Context.h"
#include "Extensions.h"
namespace Magnum {
BufferTexture::SetBufferImplementation BufferTexture::setBufferImplementation = &BufferTexture::setBufferImplementationDefault;
BufferTexture::SetBufferRangeImplementation BufferTexture::setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDefault;
void BufferTexture::initializeContextBasedFunctionality(Context* context) {
if(context->isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
Debug() << "BufferTexture: using" << Extensions::GL::EXT::direct_state_access::string() << "features";
setBufferImplementation = &BufferTexture::setBufferImplementationDSA;
setBufferRangeImplementation = &BufferTexture::setBufferRangeImplementationDSA;
}
}
void BufferTexture::setBufferImplementationDefault(InternalFormat internalFormat, Buffer* buffer) {
bindInternal();
glTexBuffer(GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer->id());
}
void BufferTexture::setBufferImplementationDSA(InternalFormat internalFormat, Buffer* buffer) {
glTextureBufferEXT(id(), GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer->id());
}
void BufferTexture::setBufferRangeImplementationDefault(InternalFormat 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) {
glTextureBufferRangeEXT(id(), GL_TEXTURE_BUFFER, GLenum(internalFormat), buffer->id(), offset, size);
}
}
#endif

261
src/BufferTexture.h

@ -0,0 +1,261 @@
#ifndef Magnum_BufferTexture_h
#define Magnum_BufferTexture_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.
*/
#ifndef MAGNUM_TARGET_GLES
/** @file
* @brief Class Magnum::BufferTexture
*/
#endif
#include "AbstractTexture.h"
#ifndef MAGNUM_TARGET_GLES
namespace Magnum {
/**
@brief %Buffer texture
This texture is, unlike classic textures such as Texture or CubeMapTexture,
used as simple data source, without any unnecessary interpolation and
wrapping methods.
@section BufferTexture-usage Usage
%Texture data are stored in buffer and after binding the buffer to the texture
using setBuffer(), you can fill the buffer at any time using data setting
functions in Buffer itself.
Note that the buffer is not managed (e.g. deleted on destruction) by the
texture, so you have to manage it on your own. On the other hand it allows you
to use one buffer for more textures or store more than one data in it.
Example usage:
@code
Buffer* buffer;
BufferTexture texture;
texture.setBuffer(buffer);
constexpr static Vector3 data[] = {
// ...
};
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.
@section BufferTexture-performance-optimization Performance optimizations
If extension @extension{EXT,direct_state_access} is available, setBuffer()
functions use DSA to avoid unnecessary calls to @fn_gl{ActiveTexture} and
@fn_gl{BindTexture}. See @ref AbstractTexture-performance-optimization
"relevant section in AbstractTexture documentation" and respective function
documentation for more information.
@requires_gl31 %Extension @extension{ARB,texture_buffer_object}
@requires_gl Texture buffers are not available in OpenGL ES.
*/
class MAGNUM_EXPORT BufferTexture: private AbstractTexture {
friend class Context;
BufferTexture(const BufferTexture& other) = delete;
BufferTexture(BufferTexture&& other) = delete;
BufferTexture& operator=(const BufferTexture& other) = delete;
BufferTexture& operator=(BufferTexture&& other) = delete;
public:
/**
* @brief Internal format
*
* @see setBuffer()
*/
enum class InternalFormat: GLenum {
/** Red component, normalized unsigned byte. */
R8 = GL_R8,
/** Red and green component, each normalized unsigned byte. */
RG8 = GL_RG8,
/** RGBA, each component normalized unsigned byte. */
RGBA8 = GL_RGBA8,
/** Red component, normalized unsigned short. */
R16 = GL_R16,
/** Red and green component, each normalized unsigned short. */
RG16 = GL_RG16,
/** RGBA, each component normalized unsigned short. */
RGBA16 = GL_RGBA16,
/** Red component, non-normalized unsigned byte. */
R8UI = GL_R8UI,
/** Red and green component, each non-normalized unsigned byte. */
RG8UI = GL_RG8UI,
/** RGBA, each component non-normalized unsigned byte. */
RGBA8UI = GL_RGBA8UI,
/** Red component, non-normalized signed byte. */
R8I = GL_R8I,
/** Red and green component, each non-normalized signed byte. */
RG8I = GL_RG8I,
/** RGBA, each component non-normalized signed byte. */
RGBA8I = GL_RGBA8I,
/** Red component, non-normalized unsigned short. */
R16UI = GL_R16UI,
/** Red and green component, each non-normalized unsigned short. */
RG16UI = GL_RG16UI,
/** RGBA, each component non-normalized unsigned short. */
RGBA16UI = GL_RGBA16UI,
/** Red component, non-normalized signed short. */
R16I = GL_R16I,
/** Red and green component, each non-normalized signed short. */
RG16I = GL_RG16I,
/** RGBA, each component non-normalized signed short. */
RGBA16I = GL_RGBA16I,
/** Red component, non-normalized unsigned int. */
R32UI = GL_R32UI,
/** Red and green component, each non-normalized unsigned int. */
RG32UI = GL_RG32UI,
/**
* RGB, each component non-normalized unsigned int.
* @requires_gl40 %Extension @extension{ARB,texture_buffer_object_rgb32}
*/
RGB32UI = GL_RGB32UI,
/** RGBA, each component non-normalized unsigned int. */
RGBA32UI = GL_RGBA32UI,
/** Red component, non-normalized signed int. */
R32I = GL_R32I,
/** Red and green component, each non-normalized signed int. */
RG32I = GL_RG32I,
/**
* 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 int. */
RGBA32I = GL_RGBA32I,
/** Red component, half float. */
R16F = GL_R16F,
/** Red and green component, each half float. */
RG16F = GL_RG16F,
/** RGBA, each component half float. */
RGBA16F = GL_RGBA16F,
/** Red component, float. */
R32F = GL_R32F,
/** Red and green component, each float. */
RG32F = GL_RG32F,
/**
* RGB, each component float.
* @requires_gl40 %Extension @extension{ARB,texture_buffer_object_rgb32}
*/
RGB32F = GL_RGB32F,
/** RGBA, each component float. */
RGBA32F = GL_RGBA32F
};
inline explicit BufferTexture(): AbstractTexture(GL_TEXTURE_BUFFER) {}
/** @copydoc AbstractTexture::bind() */
inline void bind(Int layer) { AbstractTexture::bind(layer); }
/**
* @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);
}
/**
* @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);
}
private:
static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context);
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;
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;
};
}
#endif
#endif

33
src/BufferedImage.cpp

@ -1,33 +0,0 @@
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
#include "BufferedImage.h"
namespace Magnum {
#ifndef MAGNUM_TARGET_GLES2
template<std::uint8_t dimensions> void BufferedImage<dimensions>::setData(const typename DimensionTraits<Dimensions, GLsizei>::VectorType& size, Components components, ComponentType type, const GLvoid* data, Buffer::Usage usage) {
_components = components;
_type = type;
_size = size;
_buffer.setData(pixelSize(_components, _type)*size.product(), data, usage);
}
template class BufferedImage<1>;
template class BufferedImage<2>;
template class BufferedImage<3>;
#endif
}

127
src/BufferedImage.h

@ -1,127 +0,0 @@
#ifndef Magnum_BufferedImage_h
#define Magnum_BufferedImage_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
#ifndef MAGNUM_TARGET_GLES2
/** @file
* @brief Class Magnum::BufferedImage, typedef Magnum::BufferedImage1D, Magnum::BufferedImage2D, Magnum::BufferedImage3D
*/
#endif
#include "Math/Vector3.h"
#include "AbstractImage.h"
#include "Buffer.h"
#include "DimensionTraits.h"
#include "TypeTraits.h"
namespace Magnum {
#ifndef MAGNUM_TARGET_GLES2
/**
@brief %Buffered image
Class for storing image data in GPU memory. Can be replaced with Image, which
stores image data in client memory, ImageWrapper, or for example with
Trade::ImageData.
@see BufferedImage1D, BufferedImage2D, BufferedImage3D, Buffer
@requires_gles30 Pixel buffer objects are not available in OpenGL ES 2.0.
*/
template<std::uint8_t dimensions> class MAGNUM_EXPORT BufferedImage: public AbstractImage {
public:
const static std::uint8_t Dimensions = dimensions; /**< @brief %Image dimension count */
/**
* @brief Constructor
* @param components Color components
* @param type Data type
*
* Dimensions and buffer are empty, call setData() to fill the image
* with data.
*/
inline BufferedImage(Components components, ComponentType type): AbstractImage(components, type) {
_buffer.setTargetHint(Buffer::Target::PixelPack);
}
/** @brief %Image size */
inline typename DimensionTraits<Dimensions, GLsizei>::VectorType size() const { return _size; }
/**
* @brief Data
*
* Binds the buffer to @ref Buffer::Target "pixel unpack
* target" and returns nullptr, so it can be used for texture updating
* functions the same way as Image::data().
*
* @see Buffer::bind(Target)
*/
inline void* data() {
_buffer.bind(Buffer::Target::PixelUnpack);
return nullptr;
}
/** @brief %Image buffer */
inline Buffer* buffer() { return &_buffer; }
/**
* @brief Set image data
* @param size %Image size
* @param components Color components. Data type is detected
* from passed data array.
* @param data %Image data
* @param usage %Image buffer usage
*
* Updates the image buffer with given data. The data are not deleted
* after filling the buffer.
*
* @see setData(const Math::Vector<Dimensions, GLsizei>&, Components, ComponentType, const GLvoid*, Buffer::Usage)
*/
template<class T> inline void setData(const typename DimensionTraits<Dimensions, GLsizei>::VectorType& size, Components components, const T* data, Buffer::Usage usage) {
setData(size, components, TypeTraits<T>::imageType(), data, usage);
}
/**
* @brief Set image data
* @param size %Image size
* @param components Color components
* @param type Data type
* @param data %Image data
* @param usage %Image buffer usage
*
* Updates the image buffer with given data. The data are not deleted
* after filling the buffer.
*
* @see Buffer::setData()
*/
void setData(const typename DimensionTraits<Dimensions, GLsizei>::VectorType& size, Components components, ComponentType type, const GLvoid* data, Buffer::Usage usage);
protected:
Math::Vector<Dimensions, GLsizei> _size; /**< @brief %Image size */
Buffer _buffer; /**< @brief %Image buffer */
};
/** @brief One-dimensional buffered image */
typedef BufferedImage<1> BufferedImage1D;
/** @brief Two-dimensional buffered image */
typedef BufferedImage<2> BufferedImage2D;
/** @brief Three-dimensional buffered image */
typedef BufferedImage<3> BufferedImage3D;
#endif
}
#endif

77
src/BufferedTexture.cpp

@ -1,77 +0,0 @@
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
#include "BufferedTexture.h"
#ifndef MAGNUM_TARGET_GLES
#include "Buffer.h"
#include "Context.h"
#include "Extensions.h"
namespace Magnum {
BufferedTexture::SetBufferImplementation BufferedTexture::setBufferImplementation = &BufferedTexture::setBufferImplementationDefault;
void BufferedTexture::initializeContextBasedFunctionality(Context* context) {
if(context->isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
Debug() << "BufferedTexture: using" << Extensions::GL::EXT::direct_state_access::string() << "features";
setBufferImplementation = &BufferedTexture::setBufferImplementationDSA;
}
}
void BufferedTexture::setBufferImplementationDefault(BufferedTexture::InternalFormat internalFormat, Buffer* buffer) {
bindInternal();
glTexBuffer(GL_TEXTURE_BUFFER, internalFormat, buffer->id());
}
void BufferedTexture::setBufferImplementationDSA(BufferedTexture::InternalFormat internalFormat, Buffer* buffer) {
glTextureBufferEXT(id(), GL_TEXTURE_BUFFER, internalFormat, buffer->id());
}
BufferedTexture::InternalFormat::InternalFormat(Components components, ComponentType type) {
#define internalFormatSwitch(c) switch(type) { \
case ComponentType::UnsignedByte: \
internalFormat = GL_##c##8UI; break; \
case ComponentType::Byte: \
internalFormat = GL_##c##8I; break; \
case ComponentType::UnsignedShort: \
internalFormat = GL_##c##16UI; break; \
case ComponentType::Short: \
internalFormat = GL_##c##16I; break; \
case ComponentType::UnsignedInt: \
internalFormat = GL_##c##32UI; break; \
case ComponentType::Int: \
internalFormat = GL_##c##32I; break; \
case ComponentType::Half: \
internalFormat = GL_##c##16F; break; \
case ComponentType::Float: \
internalFormat = GL_##c##32F; break; \
case ComponentType::NormalizedUnsignedByte: \
internalFormat = GL_##c##8; break; \
case ComponentType::NormalizedUnsignedShort: \
internalFormat = GL_##c##16; break; \
}
if(components == Components::Red)
internalFormatSwitch(R)
else if(components == Components::RedGreen)
internalFormatSwitch(RG)
else if(components == Components::RGBA)
internalFormatSwitch(RGBA)
#undef internalFormatSwitch
}
}
#endif

175
src/BufferedTexture.h

@ -1,175 +0,0 @@
#ifndef Magnum_BufferedTexture_h
#define Magnum_BufferedTexture_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
#ifndef MAGNUM_TARGET_GLES
/** @file
* @brief Class Magnum::BufferedTexture
*/
#endif
#include "AbstractTexture.h"
#ifndef MAGNUM_TARGET_GLES
namespace Magnum {
/**
@brief Buffered texture
This texture is, unlike classic textures such as Texture or CubeMapTexture,
used as simple data source, without any unneccessary interpolation and
wrapping methods. Texture data are stored in buffer and after binding the
buffer to the texture using setBuffer(), you can fill the buffer at any time
using data setting functions in Buffer itself.
When using buffered texture in the shader, use `samplerBuffer` and fetch the
data using integer coordinates in `texelFetch()`.
@section BufferedTexture-performance-optimization Performance optimizations
If extension @extension{EXT,direct_state_access} is available, setBuffer()
uses DSA function to avoid unnecessary calls to @fn_gl{ActiveTexture} and
@fn_gl{BindTexture}. See @ref AbstractTexture-performance-optimization
"relevant section in AbstractTexture documentation" and respective function
documentation for more information.
@requires_gl31 Extension @extension{ARB,texture_buffer_object}
@requires_gl Texture buffers are not available in OpenGL ES.
*/
class MAGNUM_EXPORT BufferedTexture: private AbstractTexture {
friend class Context;
BufferedTexture(const BufferedTexture& other) = delete;
BufferedTexture(BufferedTexture&& other) = delete;
BufferedTexture& operator=(const BufferedTexture& other) = delete;
BufferedTexture& operator=(BufferedTexture&& other) = delete;
public:
/** @{ @name Internal buffered texture formats */
/**
* @copybrief AbstractTexture::Components
*
* Like AbstractTexture::Components, without three-component RGB.
*/
enum class Components {
Red, RedGreen, RGBA
};
/**
* @copybrief AbstractTexture::ComponentType
*
* Like AbstractTexture::ComponentType, without normalized signed
* types.
*/
enum class ComponentType {
UnsignedByte, Byte, UnsignedShort, Short, UnsignedInt, Int, Half,
Float, NormalizedUnsignedByte, NormalizedUnsignedShort
};
/** @copybrief AbstractTexture::Format */
enum class Format: GLenum {
/**
* Three-component RGB, float, each component 32bit, 96bit total.
*
* @requires_gl40 Extension @extension{ARB,texture_buffer_object_rgb32}
*/
RGB32Float = GL_RGB32F,
/**
* Three-component RGB, unsigned non-normalized, each component
* 32bit, 96bit total.
*
* @requires_gl40 Extension @extension{ARB,texture_buffer_object_rgb32}
*/
RGB32UnsignedInt = GL_RGB32UI,
/**
* Three-component RGB, signed non-normalized, each component
* 32bit, 96bit total.
*
* @requires_gl40 Extension @extension{ARB,texture_buffer_object_rgb32}
*/
RGB32Int = GL_RGB32I
};
/** @copydoc AbstractTexture::InternalFormat */
class MAGNUM_EXPORT InternalFormat {
public:
/** @copybrief AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Components, AbstractTexture::ComponentType) */
InternalFormat(Components components, ComponentType type);
/** @copydoc AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Format) */
inline constexpr InternalFormat(Format format): internalFormat(static_cast<GLenum>(format)) {}
/**
* @brief OpenGL internal format ID
*
* @todoc Remove workaround when Doxygen supports \@copydoc for conversion operators
*/
inline constexpr operator GLint() const { return internalFormat; }
private:
GLint internalFormat;
};
/*@}*/
inline BufferedTexture(): AbstractTexture(GL_TEXTURE_BUFFER) {}
/** @copydoc AbstractTexture::bind() */
inline void bind(GLint layer) { AbstractTexture::bind(layer); }
/**
* @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);
}
private:
static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context);
typedef void(BufferedTexture::*SetBufferImplementation)(InternalFormat, Buffer*);
void MAGNUM_LOCAL setBufferImplementationDefault(InternalFormat internalFormat, Buffer* buffer);
void MAGNUM_LOCAL setBufferImplementationDSA(InternalFormat internalFormat, Buffer* buffer);
static SetBufferImplementation setBufferImplementation;
};
/** @relates BufferedTexture
@brief Convertor of component count and data type to InternalFormat
*/
inline BufferedTexture::InternalFormat operator|(BufferedTexture::Components components, BufferedTexture::ComponentType type) {
return BufferedTexture::InternalFormat(components, type);
}
/** @relates BufferedTexture
* @overload
*/
inline BufferedTexture::InternalFormat operator|(BufferedTexture::ComponentType type, BufferedTexture::Components components) {
return BufferedTexture::InternalFormat(components, type);
}
}
#endif
#endif

159
src/CMakeLists.txt

@ -1,159 +1,167 @@
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wold-style-cast -Winit-self -pedantic -std=c++0x -fvisibility=hidden")
# Disable strict aliasing for GCC 4.4, as it breaks RectangularMatrix::from()
# (and I have no better solution for that yet)
if(CORRADE_GCC44_COMPATIBILITY)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing")
endif()
# -Wdouble-promotion is supported from GCC 4.6
# TODO: do this with check_c_compiler_flags()
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND NOT "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "4.6.0")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wdouble-promotion")
endif()
#
# 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.
#
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CORRADE_CXX_FLAGS}")
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CORRADE_INCLUDE_DIR})
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/magnumConfigure.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/magnumConfigure.h)
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CORRADE_INCLUDE_DIR})
# Files shared between main library and unit test library
set(Magnum_SRCS
AbstractFramebuffer.cpp
AbstractImage.cpp
AbstractTexture.cpp
AbstractShaderProgram.cpp
Buffer.cpp
Context.cpp
DebugMarker.cpp
DefaultFramebuffer.cpp
Framebuffer.cpp
Image.cpp
IndexedMesh.cpp
Mesh.cpp
Profiler.cpp
OpenGL.cpp
Query.cpp
Renderbuffer.cpp
Resource.cpp
Shader.cpp
SizeTraits.cpp
Timeline.cpp
TypeTraits.cpp
Implementation/BufferState.cpp
Implementation/State.cpp
Trade/AbstractImporter.cpp
Trade/MeshData2D.cpp
Trade/MeshData3D.cpp)
Trade/MeshData3D.cpp
Trade/ObjectData2D.cpp
Trade/ObjectData3D.cpp)
# Desktop-only code
if(NOT TARGET_GLES)
set(Magnum_SRCS ${Magnum_SRCS}
BufferedTexture.cpp)
BufferTexture.cpp)
endif()
# Not-ES2 code
if(NOT TARGET_GLES2)
set(Magnum_SRCS ${Magnum_SRCS}
BufferedImage.cpp)
BufferImage.cpp)
endif()
set(Magnum_HEADERS
AbstractFramebuffer.h
AbstractImage.h
AbstractResourceLoader.h
AbstractShaderProgram.h
AbstractTexture.h
Array.h
Buffer.h
Color.h
Context.h
CubeMapTexture.h
DebugMarker.h
DefaultFramebuffer.h
DimensionTraits.h
Extensions.h
Framebuffer.h
Image.h
ImageWrapper.h
IndexedMesh.h
Magnum.h
Mesh.h
Profiler.h
OpenGL.h
Query.h
Renderbuffer.h
Renderer.h
Resource.h
ResourceManager.h
Shader.h
SizeTraits.h
Swizzle.h
Texture.h
Timeline.h
TypeTraits.h
Types.h
magnumVisibility.h)
# Desktop-only headers
if(NOT TARGET_GLES)
set(Magnum_HEADERS ${Magnum_HEADERS}
BufferedTexture.h
BufferTexture.h
CubeMapTextureArray.h)
endif()
# Not-ES2 headers
if(NOT TARGET_GLES2)
set(Magnum_HEADERS ${Magnum_HEADERS}
BufferedImage.h)
endif()
if(NOT CMAKE_NO_OBJECT_TARGET)
add_library(MagnumObjects OBJECT ${Magnum_SRCS})
BufferImage.h)
endif()
# Files shared between main library and math unit test library
set(MagnumMath_SRCS
Math/Math.cpp
Math/Angle.cpp
Math/Complex.cpp
Math/DualComplex.cpp
Math/DualQuaternion.cpp
Math/Functions.cpp
Math/Quaternion.cpp
Math/RectangularMatrix.cpp
Math/Vector.cpp)
if(NOT CMAKE_NO_OBJECT_TARGET)
add_library(MagnumMathObjects OBJECT ${MagnumMath_SRCS})
endif()
# 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
if(NOT CMAKE_NO_OBJECT_TARGET)
set_target_properties(MagnumObjects MagnumMathObjects PROPERTIES COMPILE_FLAGS "-DMagnumObjects_EXPORTS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}")
endif()
add_library(MagnumMathObjects OBJECT ${MagnumMath_SRCS})
add_library(MagnumObjects OBJECT ${Magnum_SRCS})
set_target_properties(MagnumObjects MagnumMathObjects PROPERTIES COMPILE_FLAGS "-DMagnumObjects_EXPORTS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}")
# Main library
if(NOT CMAKE_NO_OBJECT_TARGET)
add_library(Magnum SHARED
$<TARGET_OBJECTS:MagnumObjects>
$<TARGET_OBJECTS:MagnumMathObjects>)
else()
add_library(Magnum SHARED
${Magnum_SRCS}
${MagnumMath_SRCS})
endif()
add_library(Magnum SHARED
$<TARGET_OBJECTS:MagnumObjects>
$<TARGET_OBJECTS:MagnumMathObjects>)
set(Magnum_LIBS
${CORRADE_UTILITY_LIBRARY}
${CORRADE_PLUGINMANAGER_LIBRARY})
if(NOT TARGET_GLES)
set(Magnum_LIBS ${Magnum_LIBS}
${OPENGL_gl_LIBRARY}
${GLEW_LIBRARY})
if(NOT TARGET_GLES OR TARGET_DESKTOP_GLES)
set(Magnum_LIBS ${Magnum_LIBS} ${OPENGL_gl_LIBRARY})
else()
set(Magnum_LIBS ${Magnum_LIBS}
${OPENGLES2_LIBRARY})
set(Magnum_LIBS ${Magnum_LIBS} ${OPENGLES2_LIBRARY})
endif()
if(NOT TARGET_GLES)
set(Magnum_LIBS ${Magnum_LIBS} ${GLEW_LIBRARIES})
endif()
target_link_libraries(Magnum ${Magnum_LIBS})
install(TARGETS Magnum DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR})
install(FILES ${Magnum_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR})
# Install also configure file
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/magnumConfigure.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR})
add_subdirectory(Platform)
add_subdirectory(Math)
add_subdirectory(Platform)
add_subdirectory(Trade)
if(WITH_DEBUGTOOLS)
add_subdirectory(DebugTools)
endif()
if(WITH_MESHTOOLS)
add_subdirectory(MeshTools)
endif()
@ -174,26 +182,27 @@ if(WITH_SHADERS)
add_subdirectory(Shaders)
endif()
if(WITH_TEXT)
add_subdirectory(Text)
endif()
if(WITH_TEXTURETOOLS)
add_subdirectory(TextureTools)
endif()
if(BUILD_TESTS)
enable_testing()
# Library with graceful assert for testing
if(NOT CMAKE_NO_OBJECT_TARGET)
add_library(MagnumMathTestLib SHARED
$<TARGET_OBJECTS:MagnumMathObjects>)
add_library(MagnumTestLib SHARED
$<TARGET_OBJECTS:MagnumObjects>
$<TARGET_OBJECTS:MagnumMathObjects>)
else()
add_library(MagnumMathTestLib SHARED
${MagnumMath_SRCS})
add_library(MagnumTestLib SHARED
${Magnum_SRCS}
${MagnumMath_SRCS})
# Libraries with graceful assert for testing
add_library(MagnumMathTestLib SHARED
$<TARGET_OBJECTS:MagnumMathObjects>)
set_target_properties(MagnumMathTestLib PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT)
if(WIN32)
target_link_libraries(MagnumMathTestLib ${CORRADE_UTILITY_LIBRARY})
endif()
set_target_properties(MagnumTestLib MagnumMathTestLib PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT)
add_library(MagnumTestLib SHARED
$<TARGET_OBJECTS:MagnumObjects>
$<TARGET_OBJECTS:MagnumMathObjects>)
set_target_properties(MagnumTestLib PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT)
target_link_libraries(MagnumTestLib ${Magnum_LIBS})
add_subdirectory(Test)

163
src/Color.h

@ -1,18 +1,27 @@
#ifndef Magnum_Color_h
#define Magnum_Color_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
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
@ -21,8 +30,7 @@
#include <tuple>
#include "Math/MathTypeTraits.h"
#include "Math/Math.h"
#include "Math/Functions.h"
#include "Math/Vector4.h"
#include "Magnum.h"
@ -33,15 +41,16 @@ 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) {
T hue, saturation, value;
Math::Deg<T> hue;
T saturation, value;
std::tie(hue, saturation, value) = hsv;
/* Remove repeats */
hue -= int(hue/T(360))*T(360);
if(hue < T(0)) hue += T(360);
hue -= int(T(hue)/T(360))*Math::Deg<T>(360);
if(hue < Math::Deg<T>(0)) hue += Math::Deg<T>(360);
int h = int(hue/T(60)) % 6;
T f = hue/T(60) - h;
int h = int(T(hue)/T(60)) % 6;
T f = T(hue)/T(60) - h;
T p = value * (T(1) - saturation);
T q = value * (T(1) - f*saturation);
@ -54,16 +63,15 @@ template<class T> inline typename std::enable_if<std::is_floating_point<T>::valu
case 3: return {p, q, value};
case 4: return {t, p, value};
case 5: return {value, p, q};
default:
CORRADE_ASSERT(false, "It shouldn't get here.", {});
default: CORRADE_INTERNAL_ASSERT(false);
}
}
template<class T> inline typename std::enable_if<std::is_integral<T>::value, Color3<T>>::type fromHSV(typename Color3<T>::HSV hsv) {
return Color3<T>::fromNormalized(fromHSV<typename Color3<T>::FloatingPointType>(hsv));
return Math::denormalize<Color3<T>>(fromHSV<typename Color3<T>::FloatingPointType>(hsv));
}
/* Internal hue computing function */
template<class T> T hue(const Color3<T>& color, T max, T delta) {
template<class T> Math::Deg<T> hue(const Color3<T>& color, T max, T delta) {
T deltaInv60 = T(60)/delta;
T hue(0);
@ -76,11 +84,11 @@ template<class T> T hue(const Color3<T>& color, T max, T delta) {
hue = (color.r()-color.g())*deltaInv60 + T(240);
}
return hue;
return Math::Deg<T>(hue);
}
/* Hue, saturation, value for floating-point types */
template<class T> inline T hue(typename std::enable_if<std::is_floating_point<T>::value, const Color3<T>&>::type color) {
template<class T> inline Math::Deg<T> hue(typename std::enable_if<std::is_floating_point<T>::value, const Color3<T>&>::type color) {
T max = color.max();
T delta = max - color.min();
return hue(color, max, delta);
@ -95,11 +103,11 @@ template<class T> inline T value(typename std::enable_if<std::is_floating_point<
}
/* Hue, saturation, value for integral types */
template<class T> inline typename Color3<T>::FloatingPointType hue(typename std::enable_if<std::is_integral<T>::value, const Color3<T>&>::type color) {
return hue<typename Color3<T>::FloatingPointType>(Color3<typename Color3<T>::FloatingPointType>::fromDenormalized(color));
template<class T> inline Math::Deg<typename Color3<T>::FloatingPointType> hue(typename std::enable_if<std::is_integral<T>::value, const Color3<T>&>::type color) {
return hue<typename Color3<T>::FloatingPointType>(Math::normalize<Color3<typename Color3<T>::FloatingPointType>>(color));
}
template<class T> inline typename Color3<T>::FloatingPointType saturation(typename std::enable_if<std::is_integral<T>::value, const Color3<T>&>::type& color) {
return saturation<typename Color3<T>::FloatingPointType>(Color3<typename Color3<T>::FloatingPointType>::fromDenormalized(color));
return saturation<typename Color3<T>::FloatingPointType>(Math::normalize<Color3<typename Color3<T>::FloatingPointType>>(color));
}
template<class T> inline typename Color3<T>::FloatingPointType value(typename std::enable_if<std::is_integral<T>::value, const Color3<T>&>::type color) {
return Math::normalize<typename Color3<T>::FloatingPointType>(color.max());
@ -113,7 +121,7 @@ template<class T> inline typename Color3<T>::HSV toHSV(typename std::enable_if<s
return typename Color3<T>::HSV(hue<typename Color3<T>::FloatingPointType>(color, max, delta), max != T(0) ? delta/max : T(0), max);
}
template<class T> inline typename Color3<T>::HSV toHSV(typename std::enable_if<std::is_integral<T>::value, const Color3<T>&>::type color) {
return toHSV<typename Color3<T>::FloatingPointType>(Color3<typename Color3<T>::FloatingPointType>::fromDenormalized(color));
return toHSV<typename Color3<T>::FloatingPointType>(Math::normalize<Color3<typename Color3<T>::FloatingPointType>>(color));
}
/* Default alpha value */
@ -139,21 +147,18 @@ is always in range in range @f$ [0.0, 360.0] @f$, saturation and value in
range @f$ [0.0, 1.0] @f$.
@see Color4
@todo Hue in degrees so users can use deg()
@todo Signed normalization to [-1.0, 1.0] like in OpenGL?
*/
/* Not using template specialization because some internal functions are
impossible to explicitly instantiate */
#ifndef DOXYGEN_GENERATING_OUTPUT
template<class T>
#else
template<class T = GLfloat>
template<class T = Float>
#endif
class Color3: public Math::Vector3<T> {
public:
/** @brief Corresponding floating-point type for HSV computation */
typedef typename Math::MathTypeTraits<T>::FloatingPointType FloatingPointType;
typedef typename Math::TypeTraits<T>::FloatingPointType FloatingPointType;
/**
* @brief Type for storing HSV values
@ -161,37 +166,7 @@ class Color3: public Math::Vector3<T> {
* Hue in range @f$ [0.0, 360.0] @f$, saturation and value in
* range @f$ [0.0, 1.0] @f$.
*/
typedef std::tuple<FloatingPointType, FloatingPointType, FloatingPointType> HSV;
/**
* @brief Create integral color from floating-point color
*
* E.g. `{0.294118, 0.45098, 0.878431}` is converted to
* `{75, 115, 224}`, if resulting type is `uint8_t`.
*
* @note This function is enabled only if source type is floating-point
* and destination type is integral.
*/
template<class U> inline constexpr static typename std::enable_if<std::is_integral<T>::value && std::is_floating_point<U>::value, Color3<T>>::type fromNormalized(const Color3<U>& color) {
return Color3<T>(Math::denormalize<T>(color.r()),
Math::denormalize<T>(color.g()),
Math::denormalize<T>(color.b()));
}
/**
* @brief Create floating-point color from integral color
*
* E.g. `{75, 115, 224}` is converted to
* `{0.294118, 0.45098, 0.878431}`, if source type is `uint8_t`.
*
* @note This function is enabled only if source type is integral
* and destination type is floating-point.
*/
template<class U> inline constexpr static typename std::enable_if<std::is_floating_point<T>::value && std::is_integral<U>::value, Color3<T>>::type fromDenormalized(const Color3<U>& color) {
return Color3<T>(Math::normalize<T>(color.r()),
Math::normalize<T>(color.g()),
Math::normalize<T>(color.b()));
}
typedef std::tuple<Math::Deg<FloatingPointType>, FloatingPointType, FloatingPointType> HSV;
/**
* @brief Create RGB color from HSV representation
@ -203,7 +178,7 @@ class Color3: public Math::Vector3<T> {
return Implementation::fromHSV<T>(hsv);
}
/** @overload */
inline constexpr static Color3<T> fromHSV(FloatingPointType hue, FloatingPointType saturation, FloatingPointType value) {
inline constexpr static Color3<T> fromHSV(Math::Deg<FloatingPointType> hue, FloatingPointType saturation, FloatingPointType value) {
return fromHSV(std::make_tuple(hue, saturation, value));
}
@ -212,7 +187,7 @@ class Color3: public Math::Vector3<T> {
*
* All components are set to zero.
*/
inline constexpr Color3() {}
inline constexpr /*implicit*/ Color3() {}
/**
* @brief Gray constructor
@ -220,16 +195,19 @@ class Color3: public Math::Vector3<T> {
*/
inline constexpr explicit Color3(T rgb): Math::Vector3<T>(rgb) {}
/** @brief Copy constructor */
inline constexpr Color3(const Math::RectangularMatrix<1, 3, T>& other): Math::Vector3<T>(other) {}
/**
* @brief Constructor
* @param r R value
* @param g G value
* @param b B value
*/
inline constexpr Color3(T r, T g, T b): Math::Vector3<T>(r, g, b) {}
inline 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) {}
/** @brief Copy constructor */
inline 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 */
@ -259,8 +237,8 @@ class Color3: public Math::Vector3<T> {
*
* @see saturation(), value(), toHSV(), fromHSV()
*/
inline constexpr FloatingPointType hue() const {
return Implementation::hue<T>(*this);
inline constexpr Math::Deg<FloatingPointType> hue() const {
return Math::Deg<FloatingPointType>(Implementation::hue<T>(*this));
}
/**
@ -284,7 +262,6 @@ class Color3: public Math::Vector3<T> {
}
MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(Color3, 3)
MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(1, 3, Color3<T>)
};
MAGNUM_VECTOR_SUBCLASS_OPERATOR_IMPLEMENTATION(Color3, 3)
@ -299,7 +276,7 @@ See Color3 for more information.
#ifndef DOXYGEN_GENERATING_OUTPUT
template<class T>
#else
template<class T = GLfloat>
template<class T = Float>
#endif
class Color4: public Math::Vector4<T> {
public:
@ -309,22 +286,6 @@ class Color4: public Math::Vector4<T> {
/** @copydoc Color3::HSV */
typedef typename Color3<T>::HSV HSV;
/** @copydoc Color3::fromNormalized() */
template<class U> inline constexpr static typename std::enable_if<std::is_integral<T>::value && std::is_floating_point<U>::value, Color4<T>>::type fromNormalized(const Color4<U>& color) {
return Color4<T>(Math::denormalize<T>(color.r()),
Math::denormalize<T>(color.g()),
Math::denormalize<T>(color.b()),
Math::denormalize<T>(color.a()));
}
/** @copydoc Color3::fromDenormalized() */
template<class U> inline constexpr static typename std::enable_if<std::is_floating_point<T>::value && std::is_integral<U>::value, Color4<T>>::type fromDenormalized(const Color4<U>& color) {
return Color4<T>(Math::normalize<T>(color.r()),
Math::normalize<T>(color.g()),
Math::normalize<T>(color.b()),
Math::normalize<T>(color.a()));
}
/**
* @copydoc Color3::fromHSV()
* @param a Alpha value, defaults to 1.0 for floating-point types
@ -334,7 +295,7 @@ class Color4: public Math::Vector4<T> {
return Color4<T>(Implementation::fromHSV<T>(hsv), a);
}
/** @overload */
inline constexpr static Color4<T> fromHSV(FloatingPointType hue, FloatingPointType saturation, FloatingPointType value, T alpha) {
inline constexpr static Color4<T> fromHSV(Math::Deg<FloatingPointType> hue, FloatingPointType saturation, FloatingPointType value, T alpha) {
return fromHSV(std::make_tuple(hue, saturation, value), alpha);
}
@ -344,7 +305,7 @@ 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 Color4(): Math::Vector4<T>(T(0), T(0), T(0), Implementation::defaultAlpha<T>()) {}
inline constexpr /*implicit*/ Color4(): Math::Vector4<T>(T(0), T(0), T(0), Implementation::defaultAlpha<T>()) {}
/**
* @copydoc Color3::Color3(T)
@ -353,9 +314,6 @@ class Color4: public Math::Vector4<T> {
*/
inline constexpr explicit Color4(T rgb, T alpha = Implementation::defaultAlpha<T>()): Math::Vector4<T>(rgb, rgb, rgb, alpha) {}
/** @brief Copy constructor */
inline constexpr Color4(const Math::RectangularMatrix<1, 4, T>& other): Math::Vector4<T>(other) {}
/**
* @brief Constructor
* @param r R value
@ -364,7 +322,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 Color4(T r, T g, T b, T a = Implementation::defaultAlpha<T>()): Math::Vector4<T>(r, g, b, a) {}
inline constexpr /*implicit*/ Color4(T r, T g, T b, T a = Implementation::defaultAlpha<T>()): Math::Vector4<T>(r, g, b, a) {}
/**
* @brief Constructor
@ -373,7 +331,13 @@ 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 Color4(const Math::Vector3<T>& rgb, T a = Implementation::defaultAlpha<T>()): Math::Vector4<T>(rgb[0], rgb[1], rgb[2], a) {}
inline 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) {}
/** @brief Copy constructor */
inline 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 */
@ -399,7 +363,7 @@ class Color4: public Math::Vector4<T> {
}
/** @copydoc Color3::hue() */
inline constexpr FloatingPointType hue() const {
inline constexpr Math::Deg<FloatingPointType> hue() const {
return Implementation::hue<T>(rgb());
}
@ -414,18 +378,17 @@ class Color4: public Math::Vector4<T> {
}
MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(Color4, 4)
MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(1, 4, Color4<T>)
};
MAGNUM_VECTOR_SUBCLASS_OPERATOR_IMPLEMENTATION(Color4, 4)
/** @debugoperator{Magnum::Color3} */
template<class T> inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Color3<T>& value) {
template<class T> inline Debug operator<<(Debug debug, const Color3<T>& value) {
return debug << static_cast<const Math::Vector3<T>&>(value);
}
/** @debugoperator{Magnum::Color4} */
template<class T> inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Color4<T>& value) {
template<class T> inline Debug operator<<(Debug debug, const Color4<T>& value) {
return debug << static_cast<const Math::Vector4<T>&>(value);
}

218
src/Context.cpp

@ -1,16 +1,25 @@
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
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.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
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 "Context.h"
@ -20,17 +29,19 @@
#include <Utility/Debug.h>
#include <Utility/String.h>
#include "AbstractFramebuffer.h"
#include "AbstractShaderProgram.h"
#include "AbstractTexture.h"
#include "Buffer.h"
#include "BufferedTexture.h"
#include "BufferTexture.h"
#include "DebugMarker.h"
#include "DefaultFramebuffer.h"
#include "Extensions.h"
#include "IndexedMesh.h"
#include "Framebuffer.h"
#include "Mesh.h"
#include "Implementation/State.h"
#include "DebugMarker.h"
#include "Renderbuffer.h"
using namespace std;
#include "Implementation/State.h"
namespace Magnum {
@ -66,103 +77,173 @@ const std::vector<Extension>& Extension::extensions(Version version) {
static const std::vector<Extension> empty;
#ifndef MAGNUM_TARGET_GLES
static const std::vector<Extension> extensions{
_extension(GL,AMD,vertex_shader_layer),
_extension(GL,AMD,shader_trinary_minmax),
_extension(GL,EXT,texture_filter_anisotropic),
_extension(GL,AMD,vertex_shader_layer), // done
_extension(GL,AMD,shader_trinary_minmax), // done
_extension(GL,EXT,texture_filter_anisotropic), // done
_extension(GL,EXT,direct_state_access),
_extension(GL,GREMEDY,string_marker)};
_extension(GL,GREMEDY,string_marker)}; // done
static const std::vector<Extension> extensions300{
_extension(GL,APPLE,flush_buffer_range),
_extension(GL,APPLE,vertex_array_object),
/**
* @todo Remove as it doesn't have all functionality present in GL 3.0
* and leave only ARB_map_buffer_range?
*/
_extension(GL,APPLE,flush_buffer_range), // done
_extension(GL,APPLE,vertex_array_object), // done
_extension(GL,ARB,map_buffer_range), // done, replaces APPLE_flush_buffer_range
_extension(GL,ARB,color_buffer_float),
_extension(GL,ARB,half_float_pixel),
_extension(GL,ARB,texture_float),
_extension(GL,ARB,depth_buffer_float),
_extension(GL,ARB,texture_rg),
_extension(GL,ARB,half_float_pixel), // done
_extension(GL,ARB,texture_float), // done
_extension(GL,ARB,depth_buffer_float), // done
_extension(GL,ARB,texture_rg), // done
/**
* @todo Remove as it doesn't have the same functionality present in
* GL 3.0 and replace with ARB_framebuffer_object?
*/
_extension(GL,EXT,framebuffer_object),
_extension(GL,EXT,packed_depth_stencil),
_extension(GL,EXT,framebuffer_blit),
_extension(GL,EXT,packed_depth_stencil), // done
_extension(GL,EXT,framebuffer_blit), // done
_extension(GL,EXT,framebuffer_multisample),
_extension(GL,EXT,gpu_shader4),
_extension(GL,EXT,packed_float),
_extension(GL,EXT,packed_float), // done
_extension(GL,EXT,texture_array),
_extension(GL,EXT,texture_compression_rgtc),
_extension(GL,EXT,texture_shared_exponent),
_extension(GL,EXT,texture_compression_rgtc), // done
_extension(GL,EXT,texture_shared_exponent), // done
_extension(GL,EXT,framebuffer_sRGB),
_extension(GL,EXT,draw_buffers2),
_extension(GL,EXT,texture_integer),
_extension(GL,EXT,transform_feedback),
_extension(GL,NV,half_float),
_extension(GL,NV,half_float), // done
_extension(GL,NV,depth_buffer_float),
_extension(GL,NV,conditional_render)};
_extension(GL,NV,conditional_render)}; // done
static const std::vector<Extension> extensions310{
_extension(GL,ARB,texture_rectangle),
_extension(GL,ARB,draw_instanced),
_extension(GL,ARB,texture_buffer_object),
_extension(GL,ARB,uniform_buffer_object),
_extension(GL,ARB,copy_buffer),
_extension(GL,EXT,texture_snorm),
_extension(GL,ARB,copy_buffer), // done
_extension(GL,EXT,texture_snorm), // done
_extension(GL,NV,primitive_restart)};
static const std::vector<Extension> extensions320{
_extension(GL,ARB,geometry_shader4),
_extension(GL,ARB,depth_clamp),
_extension(GL,ARB,depth_clamp), // done
_extension(GL,ARB,draw_elements_base_vertex),
_extension(GL,ARB,fragment_coord_conventions),
_extension(GL,ARB,provoking_vertex),
_extension(GL,ARB,seamless_cube_map),
_extension(GL,ARB,fragment_coord_conventions), // done
_extension(GL,ARB,provoking_vertex), // done
_extension(GL,ARB,seamless_cube_map), // done
_extension(GL,ARB,sync),
_extension(GL,ARB,texture_multisample),
_extension(GL,ARB,vertex_array_bgra)};
_extension(GL,ARB,vertex_array_bgra)}; // done
static const std::vector<Extension> extensions330{
_extension(GL,ARB,instanced_arrays),
_extension(GL,ARB,blend_func_extended),
_extension(GL,ARB,explicit_attrib_location),
_extension(GL,ARB,occlusion_query2),
_extension(GL,ARB,explicit_attrib_location), // done
_extension(GL,ARB,occlusion_query2), // done
_extension(GL,ARB,sampler_objects),
_extension(GL,ARB,shader_bit_encoding),
_extension(GL,ARB,texture_rgb10_a2ui),
_extension(GL,ARB,shader_bit_encoding), // done
_extension(GL,ARB,texture_rgb10_a2ui), // done
_extension(GL,ARB,texture_swizzle),
_extension(GL,ARB,timer_query),
_extension(GL,ARB,vertex_type_2_10_10_10_rev)};
_extension(GL,ARB,vertex_type_2_10_10_10_rev)}; // done
static const std::vector<Extension> extensions400{
_extension(GL,ARB,draw_buffers_blend),
_extension(GL,ARB,sample_shading),
_extension(GL,ARB,texture_cube_map_array),
_extension(GL,ARB,texture_cube_map_array), // done
_extension(GL,ARB,texture_gather),
_extension(GL,ARB,texture_query_lod),
_extension(GL,ARB,texture_query_lod), // done
_extension(GL,ARB,draw_indirect),
_extension(GL,ARB,gpu_shader5),
_extension(GL,ARB,gpu_shader_fp64),
_extension(GL,ARB,gpu_shader_fp64), // done
_extension(GL,ARB,shader_subroutine),
_extension(GL,ARB,tessellation_shader),
_extension(GL,ARB,texture_buffer_object_rgb32),
_extension(GL,ARB,texture_buffer_object_rgb32), // done
_extension(GL,ARB,transform_feedback2),
_extension(GL,ARB,transform_feedback3)};
static const std::vector<Extension> extensions410{
_extension(GL,ARB,ES2_compatibility),
_extension(GL,ARB,get_program_binary),
_extension(GL,ARB,separate_shader_objects),
_extension(GL,ARB,shader_precision),
_extension(GL,ARB,vertex_attrib_64bit),
_extension(GL,ARB,shader_precision), // done
_extension(GL,ARB,vertex_attrib_64bit), // done
_extension(GL,ARB,viewport_array)};
static const std::vector<Extension> extensions420{
_extension(GL,ARB,texture_compression_bptc),
_extension(GL,ARB,texture_compression_bptc), // done
_extension(GL,ARB,base_instance),
_extension(GL,ARB,shading_language_420pack),
_extension(GL,ARB,shading_language_420pack), // done
_extension(GL,ARB,transform_feedback_instanced),
_extension(GL,ARB,compressed_texture_pixel_storage),
_extension(GL,ARB,conservative_depth),
_extension(GL,ARB,conservative_depth), // done
_extension(GL,ARB,internalformat_query),
_extension(GL,ARB,map_buffer_alignment),
_extension(GL,ARB,shader_atomic_counters),
_extension(GL,ARB,shader_image_load_store),
_extension(GL,ARB,texture_storage)};
static const std::vector<Extension> extensions430;
static const std::vector<Extension> extensions430{
_extension(GL,ARB,arrays_of_arrays), // done
_extension(GL,ARB,ES3_compatibility),
_extension(GL,ARB,clear_buffer_object),
_extension(GL,ARB,compute_shader),
_extension(GL,ARB,copy_image),
_extension(GL,KHR,debug),
_extension(GL,ARB,explicit_uniform_location),
_extension(GL,ARB,fragment_layer_viewport), // done
_extension(GL,ARB,framebuffer_no_attachments),
_extension(GL,ARB,internalformat_query2),
_extension(GL,ARB,invalidate_subdata), // done
_extension(GL,ARB,multi_draw_indirect),
_extension(GL,ARB,program_interface_query),
_extension(GL,ARB,robust_buffer_access_behavior), // done
_extension(GL,ARB,shader_image_size), // done
_extension(GL,ARB,shader_storage_buffer_object),
_extension(GL,ARB,stencil_texturing),
_extension(GL,ARB,texture_buffer_range), // done
_extension(GL,ARB,texture_query_levels), // done
_extension(GL,ARB,texture_storage_multisample),
_extension(GL,ARB,texture_view),
_extension(GL,ARB,vertex_attrib_binding)};
#undef _extension
#else
static const std::vector<Extension> extensions;
static const std::vector<Extension> extensionsES200;
static const std::vector<Extension> extensionsES300;
static const std::vector<Extension> extensions{
_extension(GL,APPLE,texture_format_BGRA8888),
_extension(GL,EXT,texture_filter_anisotropic),
_extension(GL,EXT,texture_format_BGRA8888),
_extension(GL,EXT,read_format_bgra),
_extension(GL,EXT,debug_marker),
_extension(GL,EXT,separate_shader_objects),
_extension(GL,EXT,sRGB),
_extension(GL,NV,read_buffer_front),
_extension(GL,NV,read_stencil),
_extension(GL,OES,depth32),
_extension(GL,OES,mapbuffer),
_extension(GL,OES,stencil1),
_extension(GL,OES,stencil4),
_extension(GL,OES,texture_3D)};
static const std::vector<Extension> extensionsES300{
_extension(GL,ANGLE,framebuffer_blit),
_extension(GL,APPLE,framebuffer_multisample),
_extension(GL,ARM,rgba8),
_extension(GL,EXT,texture_type_2_10_10_10_REV),
_extension(GL,EXT,discard_framebuffer),
_extension(GL,EXT,blend_minmax),
_extension(GL,EXT,occlusion_query_boolean),
_extension(GL,EXT,texture_rg),
_extension(GL,EXT,texture_storage),
_extension(GL,EXT,map_buffer_range),
_extension(GL,NV,draw_buffers),
_extension(GL,NV,read_buffer),
_extension(GL,NV,read_depth),
_extension(GL,NV,read_depth_stencil),
_extension(GL,OES,depth24),
_extension(GL,OES,element_index_uint),
_extension(GL,OES,rgb8_rgba8),
_extension(GL,OES,texture_half_float_linear),
_extension(GL,OES,texture_float_linear),
_extension(GL,OES,texture_half_float),
_extension(GL,OES,texture_float),
_extension(GL,OES,vertex_half_float),
_extension(GL,OES,packed_depth_stencil),
_extension(GL,OES,depth_texture),
_extension(GL,OES,vertex_array_object),
_extension(GL,OES,required_internalformat)};
#endif
switch(version) {
@ -180,7 +261,7 @@ const std::vector<Extension>& Extension::extensions(Version version) {
/* case Version::GLES300: */
case Version::GL430: return extensions430;
#else
case Version::GLES200: return extensionsES200;
case Version::GLES200: return empty;
case Version::GLES300: return extensionsES300;
#endif
}
@ -202,7 +283,7 @@ Context::Context() {
_version = static_cast<Version>(_majorVersion*100+_minorVersion*10);
/* Get first future (not supported) version */
vector<Version> versions{
std::vector<Version> versions{
#ifndef MAGNUM_TARGET_GLES
Version::GL300,
Version::GL310,
@ -218,18 +299,18 @@ Context::Context() {
#endif
Version::None
};
size_t future = 0;
while(versions[future] != Version::None && !isVersionSupported(_version))
std::size_t future = 0;
while(versions[future] != Version::None && isVersionSupported(versions[future]))
++future;
/* List of extensions from future versions (extensions from current and
previous versions should be supported automatically, so we don't need
to check for them) */
unordered_map<string, Extension> futureExtensions;
for(size_t i = future; i != versions.size(); ++i) {
std::unordered_map<std::string, Extension> futureExtensions;
for(std::size_t i = future; i != versions.size(); ++i) {
const std::vector<Extension>& extensions = Extension::extensions(versions[i]);
for(auto it = extensions.begin(); it != extensions.end(); ++it)
futureExtensions.insert(make_pair(it->_string, *it));
futureExtensions.insert(std::make_pair(it->_string, *it));
}
/* Check for presence of extensions in future versions */
@ -255,7 +336,7 @@ Context::Context() {
/* Don't crash when glGetString() returns nullptr */
const char* e = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
if(e) {
vector<string> extensions = Corrade::Utility::String::split(e, ' ');
std::vector<std::string> extensions = Corrade::Utility::String::split(e, ' ');
for(auto it = extensions.begin(); it != extensions.end(); ++it) {
auto found = futureExtensions.find(*it);
if(found != futureExtensions.end()) {
@ -274,15 +355,18 @@ Context::Context() {
_state = new Implementation::State;
/* Initialize functionality based on current OpenGL version and extensions */
AbstractFramebuffer::initializeContextBasedFunctionality(this);
AbstractShaderProgram::initializeContextBasedFunctionality(this);
AbstractTexture::initializeContextBasedFunctionality(this);
Buffer::initializeContextBasedFunctionality(this);
#ifndef MAGNUM_TARGET_GLES
BufferedTexture::initializeContextBasedFunctionality(this);
BufferTexture::initializeContextBasedFunctionality(this);
#endif
DebugMarker::initializeContextBasedFunctionality(this);
IndexedMesh::initializeContextBasedFunctionality(this);
DefaultFramebuffer::initializeContextBasedFunctionality(this);
Framebuffer::initializeContextBasedFunctionality(this);
Mesh::initializeContextBasedFunctionality(this);
Renderbuffer::initializeContextBasedFunctionality(this);
}
Context::~Context() {
@ -291,7 +375,7 @@ Context::~Context() {
_current = nullptr;
}
Version Context::supportedVersion(initializer_list<Version> versions) const {
Version Context::supportedVersion(std::initializer_list<Version> versions) const {
for(auto it = versions.begin(); it != versions.end(); ++it)
if(isVersionSupported(*it)) return *it;

63
src/Context.h

@ -1,36 +1,45 @@
#ifndef Magnum_Context_h
#define Magnum_Context_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
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 Version, class Magnum::Context, Magnum::Extension, macro MAGNUM_ASSERT_VERSION_SUPPORTED(), MAGNUM_ASSERT_EXTENSION_SUPPORTED()
* @brief Enum Magnum::Version, class Magnum::Context, Magnum::Extension, macro MAGNUM_ASSERT_VERSION_SUPPORTED(), MAGNUM_ASSERT_EXTENSION_SUPPORTED()
*/
#include <bitset>
#include <vector>
#include "Magnum.h"
#include "OpenGL.h"
#include "magnumVisibility.h"
namespace Magnum {
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
class State;
struct State;
}
#endif
@ -39,7 +48,7 @@ namespace Implementation {
@see Context, MAGNUM_ASSERT_VERSION_SUPPORTED()
*/
enum class Version: GLint {
enum class Version: Int {
None = 0xFFFF, /**< @brief Unspecified */
#ifndef MAGNUM_TARGET_GLES
GL210 = 210, /**< @brief OpenGL 2.1 / GLSL 1.20 */
@ -123,7 +132,12 @@ class MAGNUM_EXPORT Extension {
/**
@brief OpenGL context
Provides access to version and extension information.
Provides access to version and extension information. Instance available
through Context::current() is automatically created during construction of
*Application classes in Platform namespace so you can safely assume that the
instance is available during whole lifetime of *Application object.
@todo @extension{ATI,meminfo}, @extension{NVX,gpu_memory_info}, GPU temperature?
(here or where?)
*/
class MAGNUM_EXPORT Context {
Context(const Context&) = delete;
@ -135,10 +149,13 @@ class MAGNUM_EXPORT Context {
/**
* @brief Constructor
*
* Constructed automatically, see class documentation for more
* information.
* @see @fn_gl{Get} with @def_gl{MAJOR_VERSION}, @def_gl{MINOR_VERSION},
* @fn_gl{GetString} with @def_gl{EXTENSIONS}
*/
Context();
explicit Context();
~Context();
/** @brief Current context */
@ -158,7 +175,7 @@ class MAGNUM_EXPORT Context {
* @see minorVersion(), version(), versionString(),
* shadingLanguageVersionString()
*/
inline GLint majorVersion() const { return _majorVersion; }
inline Int majorVersion() const { return _majorVersion; }
/**
* @brief Minor OpenGL version (e.g. `3`)
@ -166,7 +183,7 @@ class MAGNUM_EXPORT Context {
* @see majorVersion(), version(), versionString(),
* shadingLanguageVersionString()
*/
inline GLint minorVersion() const { return _minorVersion; }
inline Int minorVersion() const { return _minorVersion; }
/**
* @brief Vendor string
@ -178,7 +195,7 @@ class MAGNUM_EXPORT Context {
}
/**
* @brief Renderer string
* @brief %Renderer string
*
* @see vendorString(), @fn_gl{GetString} with @def_gl{RENDERER}
*/
@ -289,8 +306,8 @@ class MAGNUM_EXPORT Context {
static Context* _current;
Version _version;
GLint _majorVersion;
GLint _minorVersion;
Int _majorVersion;
Int _minorVersion;
std::bitset<128> extensionStatus;
std::vector<Extension> _supportedExtensions;
@ -322,7 +339,7 @@ MAGNUM_ASSERT_VERSION_SUPPORTED(Version::GL330);
do { \
if(!Context::current()->isVersionSupported(version)) { \
Corrade::Utility::Error() << "Magnum: required version" << version << "is not supported"; \
exit(-3); \
std::exit(-3); \
} \
} while(0)
#endif
@ -352,7 +369,7 @@ MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::geometry_shader4);
do { \
if(!Context::current()->isExtensionSupported<extension>()) { \
Corrade::Utility::Error() << "Magnum: required extension" << extension::string() << "is not supported"; \
exit(-3); \
std::exit(-3); \
} \
} while(0)
#endif

149
src/CubeMapTexture.h

@ -1,35 +1,43 @@
#ifndef Magnum_CubeMapTexture_h
#define Magnum_CubeMapTexture_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
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 Class Magnum::CubeMapTexture
*/
#include "Texture.h"
#include "AbstractTexture.h"
namespace Magnum {
/**
@brief Cube map texture
%Texture used mainly for environemnt maps. See AbstractTexture documentation
for more information. It consists of 6 square textures generating 6 faces of
the cube as following. Note that all images must be turned upside down (+Y is
top):
%Texture used mainly for environment maps. It consists of 6 square textures
generating 6 faces of the cube as following. Note that all images must be
turned upside down (+Y is top):
+----+
| -Y |
@ -39,11 +47,30 @@ top):
| +Y |
+----+
When using cube map texture in the shader, use `samplerCube`. Unlike 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.
@section CubeMapTexture-usage Basic usage
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);
// ...
See AbstractTexture documentation for more information about usage.
CubeMapTexture texture;
texture.setMagnificationFilter(Texture2D::Filter::Linear)
// ...
->setStorage(Math::log2(256)+1, Texture2D::Format::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
*/
@ -65,7 +92,7 @@ class CubeMapTexture: public AbstractTexture {
*
* 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_gl32 %Extension @extension{ARB,seamless_cube_map}
* @requires_gl Not available in OpenGL ES 2.0, always enabled in
* OpenGL ES 3.0.
*/
@ -78,41 +105,95 @@ class CubeMapTexture: public AbstractTexture {
* @brief Constructor
*
* Creates one cube map OpenGL texture.
* @see @def_gl{TEXTURE_CUBE_MAP}
* @see @fn_gl{GenTextures} with @def_gl{TEXTURE_CUBE_MAP}
*/
inline CubeMapTexture(): AbstractTexture(GL_TEXTURE_CUBE_MAP) {}
inline explicit CubeMapTexture(): AbstractTexture(GL_TEXTURE_CUBE_MAP) {}
/**
* @copydoc Texture::setWrapping()
* @brief Set wrapping
*
* See Texture::setWrapping() for more information.
*/
inline CubeMapTexture* setWrapping(const Math::Vector<3, Wrapping>& wrapping) {
inline CubeMapTexture* setWrapping(const Array3D<Wrapping>& wrapping) {
DataHelper<3>::setWrapping(this, wrapping);
return this;
}
#ifndef MAGNUM_TARGET_GLES
/**
* @brief %Image size in given mip level
* @param coordinate Coordinate
* @param level Mip level
*
* See Texture::imageSize() for more information.
* @requires_gl %Texture image queries are not available in OpenGL ES.
*/
inline Vector2i imageSize(Coordinate coordinate, Int level) {
return DataHelper<2>::imageSize(this, static_cast<GLenum>(coordinate), level);
}
#endif
/**
* @copydoc Texture::setData(GLint, InternalFormat, Image*)
* @param coordinate Coordinate
* @brief Set storage
*
* See Texture::setStorage() for more information.
*/
inline CubeMapTexture* setStorage(Int levels, InternalFormat internalFormat, const Vector2i& size) {
DataHelper<2>::setStorage(this, _target, levels, internalFormat, size);
return this;
}
/**
* @brief Set image data
* @param coordinate Coordinate
* @param level Mip level
* @param internalFormat Internal format
* @param image Image, ImageWrapper, BufferImage or
* Trade::ImageData of the same dimension count
* @return Pointer to self (for method chaining)
*
* See Texture::setImage() for more information.
*/
template<class Image> inline CubeMapTexture* setData(Coordinate coordinate, GLint mipLevel, InternalFormat internalFormat, Image* image) {
DataHelper<2>::set(this, static_cast<GLenum>(coordinate), mipLevel, internalFormat, image);
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);
return this;
}
/**
* @copydoc Texture::setSubData(GLint, const typename DimensionTraits<Dimensions, GLint>::VectorType&, Image*)
* @param coordinate Coordinate
* @brief Set image subdata
* @param coordinate Coordinate
* @param level Mip level
* @param offset Offset where to put data in the texture
* @param image Image, ImageWrapper, BufferImage or
* Trade::ImageData of the same or one less dimension count
* @return Pointer to self (for method chaining)
*
* See Texture::setSubImage() for more information.
*/
template<class Image> inline CubeMapTexture* setSubData(Coordinate coordinate, GLint mipLevel, const Math::Vector2<GLint>& offset, const Image* image) {
DataHelper<2>::setSub(this, static_cast<GLenum>(coordinate), mipLevel, offset, image);
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);
return this;
}
/**
* @brief Invalidate texture subimage
* @param level Mip level
* @param offset Offset into the texture
* @param size Size of invalidated data
*
* Z coordinate is equivalent to number of texture face, i.e.
* @ref Coordinate "Coordinate::PositiveX" is `0` and so on, in the
* same order as in the enum.
*
* See Texture::invalidateSubImage() for more information.
*/
inline void invalidateSubImage(Int level, const Vector3i& offset, const Vector3i& size) {
DataHelper<3>::invalidateSub(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::BaseLevel) {
inline CubeMapTexture* setMinificationFilter(Filter filter, Mipmap mipmap = Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap);
return this;
}
@ -126,7 +207,7 @@ class CubeMapTexture: public AbstractTexture {
return this;
}
#endif
inline CubeMapTexture* setMaxAnisotropy(GLfloat anisotropy) {
inline CubeMapTexture* setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy);
return this;
}

178
src/CubeMapTextureArray.h

@ -1,18 +1,27 @@
#ifndef Magnum_CubeMapTextureArray_h
#define Magnum_CubeMapTextureArray_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
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.
*/
#ifndef MAGNUM_TARGET_GLES
@ -21,7 +30,7 @@
*/
#endif
#include "Texture.h"
#include "AbstractTexture.h"
#ifndef MAGNUM_TARGET_GLES
namespace Magnum {
@ -29,15 +38,44 @@ namespace Magnum {
/**
@brief Cube map texture array
For information, see CubeMapTexture and AbstractTexture documentation.
See CubeMapTexture documentation for introduction.
@section CubeMapTextureArray-usage Usage
Common usage is to specify each layer and face separately using setSubImage().
You have to allocate the memory for all layers and faces first either by
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);
CubeMapTextureArray texture;
texture.setMagnificationFilter(CubeMapTextureArray::Filter::Linear)
// ...
->setStorage(Math::log2(64)+1, CubeMapTextureArray::Format::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);
// ...
texture->setSubImage(i, CubeMapTextureArray::Coordinate::PositiveX, 0, {}, imagePositiveX);
texture->setSubImage(i, CubeMapTextureArray::Coordinate::NegativeX, 0, {}, imageNegativeX);
// ...
}
// ...
@endcode
When using cube map texture in the shader, use `samplerCubeArray`. Unlike
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.
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.
@see CubeMapTexture::setSeamless()
@requires_gl40 Extension @extension{ARB,texture_cube_map_array}
@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 {
@ -56,76 +94,122 @@ class CubeMapTextureArray: public AbstractTexture {
* @brief Constructor
*
* Creates one cube map OpenGL texture.
* @see @def_gl{TEXTURE_CUBE_MAP_ARRAY}
* @see @fn_gl{GenTextures} with @def_gl{TEXTURE_CUBE_MAP}
*/
inline CubeMapTextureArray(): AbstractTexture(GL_TEXTURE_CUBE_MAP_ARRAY) {}
inline explicit CubeMapTextureArray(): AbstractTexture(GL_TEXTURE_CUBE_MAP_ARRAY) {}
/**
* @copydoc Texture::setWrapping()
* @brief Set wrapping
*
* See Texture::setWrapping() for more information.
*/
inline CubeMapTextureArray* setWrapping(const Math::Vector3<Wrapping>& wrapping) {
inline CubeMapTextureArray* setWrapping(const Array3D<Wrapping>& wrapping) {
DataHelper<3>::setWrapping(this, wrapping);
return this;
}
/**
* @copydoc Texture::setData(GLint, InternalFormat, Image*)
* @brief %Image size in given mip level
* @param coordinate Coordinate
* @param level Mip level
*
* Sets texture data from three-dimensional image for all cube faces
* for all layers. Each group of 6 2D images is one cube map layer.
* The images are ordered the same way as Coordinate enum.
* See Texture::imageSize() for more information.
*/
template<class T> inline CubeMapTextureArray* setData(GLint mipLevel, InternalFormat internalFormat, T* image) {
DataHelper<3>::set(this, GL_TEXTURE_CUBE_MAP_ARRAY, mipLevel, internalFormat, image);
inline Vector3i imageSize(Coordinate coordinate, Int level) {
return DataHelper<3>::imageSize(this, GL_TEXTURE_CUBE_MAP_POSITIVE_X + static_cast<GLenum>(coordinate), level);
}
/**
* @brief Set storage
*
* See Texture::setStorage() for more information.
*/
inline CubeMapTextureArray* setStorage(Int levels, InternalFormat internalFormat, const Vector3i& size) {
DataHelper<3>::setStorage(this, _target, levels, internalFormat, size);
return this;
}
/**
* @brief Set texture subdata from 3D image
* @param mipLevel Mip level
* @brief Set image data
* @param level Mip level
* @param internalFormat Internal format
* @param image Image, ImageWrapper, BufferImage or
* Trade::ImageData of the same dimension count
* @return Pointer to self (for method chaining)
*
* Sets texture image data from three-dimensional image for all cube
* faces for all layers. Each group of 6 2D images is one cube map
* layer. The images are ordered the same way as Coordinate enum.
*
* 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);
return this;
}
/**
* @brief Set texture image 3D subdata
* @param level Mip level
* @param offset Offset where to put data in the texture
* @param image Three-dimensional Image, BufferedImage or for
* example Trade::ImageData
* @param image Image3D, ImageWrapper3D, BufferImage3D or
* Trade::ImageData3D
* @return Pointer to self (for method chaining)
*
* Sets texture subdata from given image. The image is not deleted
* afterwards.
* Sets texture image subdata for more than one level/face at once.
*
* Z coordinate of @p offset specifies layer and cube map face. If
* you want to start at given face in layer *n*, you have to specify
* Z coordinate as @f$ 6n + i @f$, where i is face index as specified
* in Coordinate enum.
*
* @see setSubData(GLsizei, Coordinate, GLint, const Math::Vector<2, GLint>&, const Image*)
* See Texture::setSubImage() for more information.
*
* @see setSubImage(Int, Coordinate, Int, const Math::Vector<2, Int>&, const Image*)
*/
template<class Image> inline CubeMapTextureArray* setSubData(GLint mipLevel, const Math::Vector3<GLint>& offset, const Image* image) {
DataHelper<3>::setSub(this, GL_TEXTURE_CUBE_MAP_ARRAY, mipLevel, offset, image, Math::Vector3<GLsizei>(Math::Vector<Image::Dimensions, GLsizei>()));
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>()));
return this;
}
/**
* @brief Set texture subdata from 2D image
* @brief Set texture image 2D subdata
* @param layer Array layer
* @param coordinate Coordinate
* @param mipLevel Mip level
* @param level Mip level
* @param offset Offset where to put data in the texture
* @param image Two-dimensional Image, BufferedImage or for
* example Trade::ImageData
* @param image Image2D, ImageWrapper2D, BufferImage2D or
* Trade::ImageData2D
* @return Pointer to self (for method chaining)
*
* Sets texture subdata from given image. The image is not deleted
* afterwards.
* See Texture::setSubImage() for more information.
*
* @see setSubData(GLint, const Math::Vector<3, GLint>&, const Image*)
* @see setSubImage(Int, const Math::Vector<3, Int>&, const Image*)
*/
template<class Image> inline CubeMapTextureArray* setSubData(GLsizei layer, Coordinate coordinate, GLint mipLevel, const Math::Vector2<GLint>& offset, const Image* image) {
DataHelper<3>::setSub(this, GL_TEXTURE_CUBE_MAP_ARRAY, mipLevel, Math::Vector3<GLint>(offset, layer*6+static_cast<GLsizei>(coordinate)), image, Math::Vector<2, GLsizei>(Math::Vector<Image::Dimensions, GLsizei>()));
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>()));
return this;
}
/**
* @brief Invalidate texture subimage
* @param level Mip level
* @param offset Offset into the texture
* @param size Size of invalidated data
*
* Z coordinate is equivalent to layer * 6 + number of texture face,
* i.e. @ref Coordinate "Coordinate::PositiveX" is `0` and so on, in
* the same order as in the enum.
*
* See Texture::invalidateSubImage() for more information.
*/
inline void invalidateSubImage(Int level, const Vector3i& offset, const Vector3i& size) {
DataHelper<3>::invalidateSub(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::BaseLevel) {
inline CubeMapTextureArray* setMinificationFilter(Filter filter, Mipmap mipmap = Mipmap::Base) {
AbstractTexture::setMinificationFilter(filter, mipmap);
return this;
}
@ -137,7 +221,7 @@ class CubeMapTextureArray: public AbstractTexture {
AbstractTexture::setBorderColor(color);
return this;
}
inline CubeMapTextureArray* setMaxAnisotropy(GLfloat anisotropy) {
inline CubeMapTextureArray* setMaxAnisotropy(Float anisotropy) {
AbstractTexture::setMaxAnisotropy(anisotropy);
return this;
}

27
src/DebugMarker.cpp

@ -1,16 +1,25 @@
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
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.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
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 "DebugMarker.h"

29
src/DebugMarker.h

@ -1,18 +1,27 @@
#ifndef Magnum_DebugMarker_h
#define Magnum_DebugMarker_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
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:
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
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
@ -41,6 +50,8 @@ class MAGNUM_EXPORT DebugMarker {
friend class Context;
public:
DebugMarker() = delete;
/** @brief Put string mark into OpenGL command stream */
inline static void mark(const std::string& string) {
markImplementation(string);

62
src/DebugTools/CMakeLists.txt

@ -0,0 +1,62 @@
#
# 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.
#
set(MagnumDebugTools_SRCS
ForceRenderer.cpp
ObjectRenderer.cpp
Profiler.cpp
ResourceManager.cpp
ShapeRenderer.cpp
Implementation/AbstractBoxRenderer.cpp
Implementation/AbstractShapeRenderer.cpp
Implementation/AxisAlignedBoxRenderer.cpp
Implementation/BoxRenderer.cpp
Implementation/PointRenderer.cpp)
set(MagnumDebugTools_HEADERS
ForceRenderer.h
DebugTools.h
ObjectRenderer.h
Profiler.h
ResourceManager.h
ShapeRenderer.h
magnumDebugToolsVisibility.h)
add_library(MagnumDebugTools SHARED ${MagnumDebugTools_SRCS})
target_link_libraries(MagnumDebugTools
Magnum
MagnumMeshTools
MagnumPhysics
MagnumPrimitives
MagnumSceneGraph
MagnumShaders)
install(TARGETS MagnumDebugTools DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR})
install(FILES ${MagnumDebugTools_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/DebugTools)
if(BUILD_TESTS)
add_subdirectory(Test)
endif()

58
src/DebugTools/DebugTools.h

@ -0,0 +1,58 @@
#ifndef Magnum_DebugTools_DebugTools_h
#define Magnum_DebugTools_DebugTools_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 Forward declarations for Magnum::DebugTools namespace
*/
#include "Types.h"
namespace Magnum { namespace DebugTools {
/** @todoc Remove `ifndef` when Doxygen is sane again */
#ifndef DOXYGEN_GENERATING_OUTPUT
template<UnsignedInt> class ForceRenderer;
typedef ForceRenderer<2> ForceRenderer2D;
typedef ForceRenderer<3> ForceRenderer3D;
class ForceRendererOptions;
template<UnsignedInt> class ObjectRenderer;
typedef ObjectRenderer<2> ObjectRenderer2D;
typedef ObjectRenderer<3> ObjectRenderer3D;
class ObjectRendererOptions;
class Profiler;
class ResourceManager;
template<UnsignedInt> class ShapeRenderer;
typedef ShapeRenderer<2> ShapeRenderer2D;
typedef ShapeRenderer<3> ShapeRenderer3D;
class ShapeRendererOptions;
#endif
}}
#endif

98
src/DebugTools/ForceRenderer.cpp

@ -0,0 +1,98 @@
/*
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 "ForceRenderer.h"
#include "Buffer.h"
#include "Mesh.h"
#include "DebugTools/ResourceManager.h"
#include "SceneGraph/AbstractCamera.h"
#include "Shaders/FlatShader.h"
#include "DebugTools/Implementation/ForceRendererTransformation.h"
namespace Magnum { namespace DebugTools {
namespace {
template<UnsignedInt dimensions> ResourceKey shaderKey();
template<> inline ResourceKey shaderKey<2>() { return ResourceKey("FlatShader2D"); }
template<> inline ResourceKey shaderKey<3>() { return ResourceKey("FlatShader3D"); }
constexpr std::array<Vector2, 4> positions{{
{0.0f, 0.0f},
{1.0f, 0.0f},
{0.9f, 0.1f},
{0.9f, -0.1f}
}};
constexpr std::array<UnsignedByte, 6> indices{{
0, 1,
1, 2,
1, 3
}};
}
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>);
/* Mesh and vertex buffer */
mesh = ResourceManager::instance()->get<Mesh>("force");
vertexBuffer = ResourceManager::instance()->get<Buffer>("force-vertices");
indexBuffer = ResourceManager::instance()->get<Buffer>("force-indices");
if(mesh) return;
/* Create the mesh */
Buffer* vertexBuffer = new Buffer(Buffer::Target::Array);
Buffer* indexBuffer = new Buffer(Buffer::Target::ElementArray);
vertexBuffer->setData(positions, Buffer::Usage::StaticDraw);
ResourceManager::instance()->set(this->vertexBuffer.key(), vertexBuffer, ResourceDataState::Final, ResourcePolicy::Manual);
indexBuffer->setData(indices, Buffer::Usage::StaticDraw);
ResourceManager::instance()->set(this->indexBuffer.key(), indexBuffer, ResourceDataState::Final, ResourcePolicy::Manual);
Mesh* mesh = new Mesh;
mesh->setPrimitive(Mesh::Primitive::Lines)
->setIndexCount(indices.size())
->addVertexBuffer(vertexBuffer, 0,
typename Shaders::FlatShader<dimensions>::Position(Shaders::FlatShader<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);
}
template<UnsignedInt dimensions> void ForceRenderer<dimensions>::draw(const typename DimensionTraits<dimensions>::MatrixType& transformationMatrix, SceneGraph::AbstractCamera<dimensions>* camera) {
shader->setTransformationProjectionMatrix(camera->projectionMatrix()*Implementation::forceRendererTransformation<dimensions>(transformationMatrix.translation()+forcePosition, *force)*DimensionTraits<dimensions>::MatrixType::scaling(typename DimensionTraits<dimensions>::VectorType(options->scale())))
->setColor(options->color())
->use();
mesh->draw();
}
template class ForceRenderer<2>;
template class ForceRenderer<3>;
}}

145
src/DebugTools/ForceRenderer.h

@ -0,0 +1,145 @@
#ifndef Magnum_DebugTools_ForceRenderer_h
#define Magnum_DebugTools_ForceRenderer_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 Class Magnum::DebugTools::ForceRenderer, Magnum::DebugTools::ForceRendererOptions, typedef Magnum::DebugTools::ForceRenderer2D, Magnum::DebugTools::ForceRenderer3D
*/
#include "Color.h"
#include "Resource.h"
#include "SceneGraph/Drawable.h"
#include "Shaders/Shaders.h"
#include "magnumDebugToolsVisibility.h"
namespace Magnum { namespace DebugTools {
/**
@brief Force renderer options
See ForceRenderer documentation for more information.
*/
class ForceRendererOptions {
public:
inline constexpr ForceRendererOptions(): _size(1.0f) {}
/** @brief Color of rendered arrow */
inline constexpr Color3<> color() const { return _color; }
/**
* @brief Set color of rendered arrow
* @return Pointer to self (for method chaining)
*
* Default is black.
*/
inline ForceRendererOptions* setColor(const Color3<>& color) {
_color = color;
return this;
}
/** @brief Scale of rendered arrow */
inline constexpr Float scale() const { return _size; }
/**
* @brief Set scale of rendered arrow
* @return Pointer to self (for method chaining)
*
* Default is `1.0f`.
*/
inline ForceRendererOptions* setSize(Float size) {
_size = size;
return this;
}
private:
Color3<> _color;
Float _size;
};
/**
@brief Force renderer
Visualizes force pushing on object by an arrow of the same direction and size.
See @ref debug-tools-renderers for more information.
@section ForceRenderer-usage Basic usage
Example code:
@code
// Create some options
DebugTools::ResourceManager::instance()->set("my", (new DebugTools::ForceRendererOptions()
->setScale(5.0f)
->setColor(Color3<>::fromHSV(120.0_degf, 1.0f, 0.7f)));
// Create debug renderer for given object, use "my" options for it
Object3D* object;
Vector3 force;
new DebugTools::ForceRenderer2D(object, {0.3f, 1.5f, -0.7f}, &force, "my", debugDrawables);
@endcode
@see ForceRenderer2D, ForceRenderer3D
*/
template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ForceRenderer: public SceneGraph::Drawable<dimensions> {
public:
/**
* @brief Constructor
* @param object Object for which to create debug renderer
* @param forcePosition Where to render the force, relative to object
* @param force Force vector
* @param options Options resource key. See
* @ref ForceRenderer-usage "class documentation" for more
* information.
* @param drawables Drawable group
*
* The renderer is automatically added to object's features, @p force is
* saved as reference to original vector and thus it must be available
* for the whole lifetime of the renderer.
*/
explicit ForceRenderer(SceneGraph::AbstractObject<dimensions>* object, const typename DimensionTraits<dimensions, Float>::VectorType& forcePosition, const typename DimensionTraits<dimensions, Float>::VectorType* force, ResourceKey options = ResourceKey(), SceneGraph::DrawableGroup<dimensions>* drawables = nullptr);
protected:
/** @todoc Remove Float when Doxygen properly treats this as override */
void draw(const typename DimensionTraits<dimensions, Float>::MatrixType& transformationMatrix, SceneGraph::AbstractCamera<dimensions, Float>* camera) override;
private:
const typename DimensionTraits<dimensions, Float>::VectorType forcePosition;
const typename DimensionTraits<dimensions, Float>::VectorType* const force;
Resource<ForceRendererOptions> options;
Resource<AbstractShaderProgram, Shaders::FlatShader<dimensions>> shader;
Resource<Mesh> mesh;
Resource<Buffer> vertexBuffer, indexBuffer;
};
/** @brief Two-dimensional force renderer */
typedef ForceRenderer<2> ForceRenderer2D;
/** @brief Three-dimensional force renderer */
typedef ForceRenderer<3> ForceRenderer3D;
}}
#endif

45
src/DebugTools/Implementation/AbstractBoxRenderer.cpp

@ -0,0 +1,45 @@
/*
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 "AbstractBoxRenderer.h"
#include "Primitives/Cube.h"
#include "Primitives/Square.h"
#include "Trade/MeshData2D.h"
#include "Trade/MeshData3D.h"
namespace Magnum { namespace DebugTools { namespace Implementation {
AbstractBoxRenderer<2>::AbstractBoxRenderer(): AbstractShapeRenderer<2>("box2d", "box2d-vertices", {}) {
if(!mesh) this->createResources(Primitives::Square::wireframe());
}
AbstractBoxRenderer<3>::AbstractBoxRenderer(): AbstractShapeRenderer<3>("box3d", "box3d-vertices", "box3d-indices") {
if(!mesh) this->createResources(Primitives::Cube::wireframe());
}
template class AbstractBoxRenderer<2>;
template class AbstractBoxRenderer<3>;
}}}

50
src/DebugTools/Implementation/AbstractBoxRenderer.h

@ -0,0 +1,50 @@
#ifndef Magnum_DebugTools_Implementation_AbstractBoxRenderer_h
#define Magnum_DebugTools_Implementation_AbstractBoxRenderer_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.
*/
#include "AbstractShapeRenderer.h"
#include "Resource.h"
#include "Shaders/Shaders.h"
#include "corradeCompatibility.h"
namespace Magnum { namespace DebugTools { namespace Implementation {
template<UnsignedInt dimensions> class AbstractBoxRenderer;
template<> class AbstractBoxRenderer<2>: public AbstractShapeRenderer<2> {
public:
AbstractBoxRenderer();
};
template<> class AbstractBoxRenderer<3>: public AbstractShapeRenderer<3> {
public:
AbstractBoxRenderer();
};
}}}
#endif

111
src/DebugTools/Implementation/AbstractShapeRenderer.cpp

@ -0,0 +1,111 @@
/*
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 "AbstractShapeRenderer.h"
#include "AbstractShaderProgram.h"
#include "Buffer.h"
#include "Mesh.h"
#include "DebugTools/ResourceManager.h"
#include "MeshTools/CompressIndices.h"
#include "Shaders/FlatShader.h"
#include "Trade/MeshData2D.h"
#include "Trade/MeshData3D.h"
namespace Magnum { namespace DebugTools { namespace Implementation {
namespace {
template<UnsignedInt dimensions> ResourceKey shaderKey();
template<> inline ResourceKey shaderKey<2>() { return ResourceKey("FlatShader2D"); }
template<> inline ResourceKey shaderKey<3>() { return ResourceKey("FlatShader3D"); }
template<UnsignedInt dimensions> void create(typename MeshData<dimensions>::Type&, Resource<Mesh>&, Resource<Buffer>&, Resource<Buffer>&);
template<> void create<2>(Trade::MeshData2D& data, Resource<Mesh>& meshResource, Resource<Buffer>& vertexBufferResource, Resource<Buffer>& indexBufferResource) {
/* Vertex buffer */
Buffer* buffer = new Buffer(Buffer::Target::Array);
buffer->setData(*data.positions(0), Buffer::Usage::StaticDraw);
ResourceManager::instance()->set(vertexBufferResource.key(), buffer, ResourceDataState::Final, ResourcePolicy::Manual);
/* Mesh configuration */
Mesh* mesh = new Mesh;
mesh->setPrimitive(data.primitive())
->setVertexCount(data.positions(0)->size())
->addVertexBuffer(buffer, 0, Shaders::FlatShader2D::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 */
if(data.indices()) {
CORRADE_INTERNAL_ASSERT(indexBufferResource.key() != ResourceKey());
Buffer* indexBuffer = new Buffer(Buffer::Target::ElementArray);
MeshTools::compressIndices(mesh, indexBuffer, Buffer::Usage::StaticDraw, *data.indices());
ResourceManager::instance()->set(indexBufferResource.key(), indexBuffer, ResourceDataState::Final, ResourcePolicy::Manual);
}
}
template<> void create<3>(Trade::MeshData3D& data, Resource<Mesh>& meshResource, Resource<Buffer>& vertexBufferResource, Resource<Buffer>& indexBufferResource) {
/* Vertex buffer */
Buffer* vertexBuffer = new Buffer(Buffer::Target::Array);
vertexBuffer->setData(*data.positions(0), Buffer::Usage::StaticDraw);
ResourceManager::instance()->set(vertexBufferResource.key(), vertexBuffer, ResourceDataState::Final, ResourcePolicy::Manual);
/* Mesh configuration */
Mesh* mesh = new Mesh;
mesh->setPrimitive(data.primitive())
->setVertexCount(data.positions(0)->size())
->addVertexBuffer(vertexBuffer, 0, Shaders::FlatShader3D::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 */
if(data.indices()) {
CORRADE_INTERNAL_ASSERT(indexBufferResource.key() != ResourceKey());
Buffer* indexBuffer = new Buffer(Buffer::Target::ElementArray);
MeshTools::compressIndices(mesh, indexBuffer, Buffer::Usage::StaticDraw, *data.indices());
ResourceManager::instance()->set(indexBufferResource.key(), indexBuffer, ResourceDataState::Final, ResourcePolicy::Manual);
}
}
}
template<UnsignedInt dimensions> AbstractShapeRenderer<dimensions>::AbstractShapeRenderer(ResourceKey meshKey, ResourceKey vertexBufferKey, ResourceKey indexBufferKey) {
shader = ResourceManager::instance()->get<AbstractShaderProgram, Shaders::FlatShader<dimensions>>(shaderKey<dimensions>());
mesh = ResourceManager::instance()->get<Mesh>(meshKey);
vertexBuffer = ResourceManager::instance()->get<Buffer>(vertexBufferKey);
indexBuffer = ResourceManager::instance()->get<Buffer>(indexBufferKey);
if(!shader) ResourceManager::instance()->set<AbstractShaderProgram>(shaderKey<dimensions>(),
new Shaders::FlatShader<dimensions>, ResourceDataState::Final, ResourcePolicy::Resident);
}
template<UnsignedInt dimensions> AbstractShapeRenderer<dimensions>::~AbstractShapeRenderer() {}
template<UnsignedInt dimensions> void AbstractShapeRenderer<dimensions>::createResources(typename MeshData<dimensions>::Type data) {
create<dimensions>(data, this->mesh, this->vertexBuffer, this->indexBuffer);
}
template class AbstractShapeRenderer<2>;
template class AbstractShapeRenderer<3>;
}}}

61
src/DebugTools/Implementation/AbstractShapeRenderer.h

@ -0,0 +1,61 @@
#ifndef Magnum_DebugTools_Implementation_AbstractShapeRenderer_h
#define Magnum_DebugTools_Implementation_AbstractShapeRenderer_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.
*/
#include "DimensionTraits.h"
#include "Resource.h"
#include "DebugTools/DebugTools.h"
#include "SceneGraph/SceneGraph.h"
#include "Shaders/Shaders.h"
#include "Trade/Trade.h"
namespace Magnum { namespace DebugTools { namespace Implementation {
template<UnsignedInt dimensions> struct MeshData;
template<> struct MeshData<2> { typedef Trade::MeshData2D Type; };
template<> struct MeshData<3> { typedef Trade::MeshData3D Type; };
template<UnsignedInt dimensions> class AbstractShapeRenderer {
public:
AbstractShapeRenderer(ResourceKey mesh, ResourceKey vertexBuffer, ResourceKey indexBuffer);
virtual ~AbstractShapeRenderer();
virtual void draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions>::MatrixType& projectionMatrix) = 0;
protected:
/* Call only if the mesh resource isn't already present */
void createResources(typename MeshData<dimensions>::Type data);
Resource<AbstractShaderProgram, Shaders::FlatShader<dimensions>> shader;
Resource<Mesh> mesh;
private:
Resource<Buffer> indexBuffer, vertexBuffer;
};
}}}
#endif

50
src/DebugTools/Implementation/AxisAlignedBoxRenderer.cpp

@ -0,0 +1,50 @@
/*
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 "AxisAlignedBoxRenderer.h"
#include "Mesh.h"
#include "DebugTools/ShapeRenderer.h"
#include "Physics/AxisAlignedBox.h"
#include "Shaders/FlatShader.h"
namespace Magnum { namespace DebugTools { namespace Implementation {
template<UnsignedInt dimensions> AxisAlignedBoxRenderer<dimensions>::AxisAlignedBoxRenderer(Physics::AxisAlignedBox<dimensions>& axisAlignedBox): axisAlignedBox(axisAlignedBox) {}
template<UnsignedInt dimensions> void AxisAlignedBoxRenderer<dimensions>::draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions>::MatrixType& projectionMatrix) {
/* Half scale, because the box is 2x2(x2) */
typename DimensionTraits<dimensions>::MatrixType transformation =
DimensionTraits<dimensions>::MatrixType::translation((axisAlignedBox.transformedMin()+axisAlignedBox.transformedMax())/2)*
DimensionTraits<dimensions>::MatrixType::scaling((axisAlignedBox.transformedMax()-axisAlignedBox.transformedMin())/2);
this->shader->setTransformationProjectionMatrix(projectionMatrix*transformation)
->setColor(options->color())
->use();
this->mesh->draw();
}
template class AxisAlignedBoxRenderer<2>;
template class AxisAlignedBoxRenderer<3>;
}}}

47
src/DebugTools/Implementation/AxisAlignedBoxRenderer.h

@ -0,0 +1,47 @@
#ifndef Magnum_DebugTools_Implementation_AxisAlignedBoxRenderer_h
#define Magnum_DebugTools_Implementation_AxisAlignedBoxRenderer_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.
*/
#include "AbstractBoxRenderer.h"
#include "Physics/Physics.h"
#include "corradeCompatibility.h"
namespace Magnum { namespace DebugTools { namespace Implementation {
template<UnsignedInt dimensions> class AxisAlignedBoxRenderer: public AbstractBoxRenderer<dimensions> {
public:
AxisAlignedBoxRenderer(Physics::AxisAlignedBox<dimensions>& axisAlignedBox);
void draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions>::MatrixType& projectionMatrix) override;
private:
Physics::AxisAlignedBox<dimensions>& axisAlignedBox;
};
}}}
#endif

48
src/DebugTools/Implementation/BoxRenderer.cpp

@ -0,0 +1,48 @@
/*
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 "BoxRenderer.h"
#include "Mesh.h"
#include "DebugTools/ShapeRenderer.h"
#include "Physics/Box.h"
#include "Shaders/FlatShader.h"
namespace Magnum { namespace DebugTools { namespace Implementation {
template<UnsignedInt dimensions> BoxRenderer<dimensions>::BoxRenderer(Physics::Box<dimensions>& box): box(box) {}
template<UnsignedInt dimensions> void BoxRenderer<dimensions>::draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions>::MatrixType& projectionMatrix) {
/* Half scale, because the box is 2x2(x2) */
this->shader->setTransformationProjectionMatrix(projectionMatrix*box.transformedTransformation()*
DimensionTraits<dimensions>::MatrixType::scaling(typename DimensionTraits<dimensions>::VectorType(0.5f)))
->setColor(options->color())
->use();
this->mesh->draw();
}
template class BoxRenderer<2>;
template class BoxRenderer<3>;
}}}

47
src/DebugTools/Implementation/BoxRenderer.h

@ -0,0 +1,47 @@
#ifndef Magnum_DebugTools_Implementation_BoxRenderer_h
#define Magnum_DebugTools_Implementation_BoxRenderer_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.
*/
#include "AbstractBoxRenderer.h"
#include "Physics/Physics.h"
#include "corradeCompatibility.h"
namespace Magnum { namespace DebugTools { namespace Implementation {
template<UnsignedInt dimensions> class BoxRenderer: public AbstractBoxRenderer<dimensions> {
public:
BoxRenderer(Physics::Box<dimensions>& box);
void draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions>::MatrixType& projectionMatrix) override;
private:
Physics::Box<dimensions>& box;
};
}}}
#endif

70
src/DebugTools/Implementation/ForceRendererTransformation.h

@ -0,0 +1,70 @@
#ifndef Magnum_DebugTools_Implementation_ForceRendererTransformation_h
#define Magnum_DebugTools_Implementation_ForceRendererTransformation_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.
*/
#include "Math/Matrix3.h"
#include "Math/Matrix4.h"
#include "Magnum.h"
#include "DimensionTraits.h"
namespace Magnum { namespace DebugTools { namespace Implementation {
template<UnsignedInt dimensions> typename DimensionTraits<dimensions>::MatrixType forceRendererTransformation(const typename DimensionTraits<dimensions>::VectorType& forcePosition, const typename DimensionTraits<dimensions>::VectorType& force);
template<> inline Matrix3 forceRendererTransformation<2>(const Vector2& forcePosition, const Vector2& force) {
return Matrix3::from({force, Vector2(-force.y(), force.x())}, forcePosition);
}
template<> inline Matrix4 forceRendererTransformation<3>(const Vector3& forcePosition, const Vector3& force) {
const Matrix4 translation = Matrix4::translation(forcePosition);
const Float forceLength = force.length();
/* Zero length, zero scaling */
if(forceLength < Math::TypeTraits<Float>::epsilon())
return translation*Matrix4::scaling(Vector3(0.0f));
const Float dot = Vector3::dot(force/forceLength, Vector3::xAxis());
/* Force is parallel to X axis, just scaling */
if(dot > 1.0f - Math::TypeTraits<Float>::epsilon())
return translation*Matrix4::scaling(Vector3(forceLength));
/* Force is antiparallel to X axis, scaling inverted on X */
if(-dot > 1.0f - Math::TypeTraits<Float>::epsilon())
return translation*Matrix4::scaling({-forceLength, forceLength, forceLength});
/* Normal of plane going through force vector and X axis vector */
const Vector3 normal = Vector3::cross(Vector3::xAxis(), force).normalized();
/* Third base vector, orthogonal to force and normal */
const Vector3 binormal = Vector3::cross(normal, force).normalized();
/* Transformation matrix from scaled base vectors and translation vector */
return Matrix4::from({force, normal*forceLength, binormal*forceLength}, forcePosition);
}
}}}
#endif

68
src/DebugTools/Implementation/PointRenderer.cpp

@ -0,0 +1,68 @@
/*
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 "PointRenderer.h"
#include "Mesh.h"
#include "DebugTools/ShapeRenderer.h"
#include "Physics/Point.h"
#include "Primitives/Crosshair.h"
#include "Shaders/FlatShader.h"
#include "Trade/MeshData2D.h"
#include "Trade/MeshData3D.h"
namespace Magnum { namespace DebugTools { namespace Implementation {
namespace {
template<UnsignedInt dimensions> ResourceKey meshKey();
template<> inline ResourceKey meshKey<2>() { return ResourceKey("point2d"); }
template<> inline ResourceKey meshKey<3>() { return ResourceKey("point3d"); }
template<UnsignedInt dimensions> ResourceKey vertexBufferKey();
template<> inline ResourceKey vertexBufferKey<2>() { return ResourceKey("point2d-vertices"); }
template<> inline ResourceKey vertexBufferKey<3>() { return ResourceKey("point3d-vertices"); }
template<UnsignedInt dimensions> typename MeshData<dimensions>::Type meshData();
template<> inline Trade::MeshData2D meshData<2>() { return Primitives::Crosshair2D::wireframe(); }
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) {
if(!this->mesh) 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->shader->setTransformationProjectionMatrix(projectionMatrix*
DimensionTraits<dimensions>::MatrixType::translation(point.transformedPosition())*
DimensionTraits<dimensions>::MatrixType::scaling(typename DimensionTraits<dimensions>::VectorType(options->pointSize()/2)))
->setColor(options->color())
->use();
this->mesh->draw();
}
template class PointRenderer<2>;
template class PointRenderer<3>;
}}}

47
src/DebugTools/Implementation/PointRenderer.h

@ -0,0 +1,47 @@
#ifndef Magnum_DebugTools_Implementation_PointRenderer_h
#define Magnum_DebugTools_Implementation_PointRenderer_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.
*/
#include "AbstractShapeRenderer.h"
#include "Physics/Physics.h"
#include "corradeCompatibility.h"
namespace Magnum { namespace DebugTools { namespace Implementation {
template<UnsignedInt dimensions> class PointRenderer: public AbstractShapeRenderer<dimensions> {
public:
PointRenderer(Physics::Point<dimensions>& point);
void draw(Resource<ShapeRendererOptions>& options, const typename DimensionTraits<dimensions>::MatrixType& projectionMatrix) override;
private:
Physics::Point<dimensions>& point;
};
}}}
#endif

186
src/DebugTools/ObjectRenderer.cpp

@ -0,0 +1,186 @@
/*
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 "ObjectRenderer.h"
#include "Buffer.h"
#include "DebugTools/ResourceManager.h"
#include "MeshTools/Interleave.h"
#include "SceneGraph/AbstractCamera.h"
#include "Shaders/VertexColorShader.h"
namespace Magnum { namespace DebugTools {
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 const std::array<Vector2, 8> positions;
static const std::array<Color3<>, 8> colors;
static const std::array<UnsignedByte, 12> indices;
};
const std::array<Vector2, 8> Renderer<2>::positions{{
{ 0.0f, 0.0f},
{ 1.0f, 0.0f}, /* X axis */
{ 0.9f, 0.1f},
{ 0.9f, -0.1f},
{ 0.0f, 0.0f},
{ 0.0f, 1.0f}, /* Y axis */
{ 0.1f, 0.9f},
{-0.1f, 0.9f}
}};
const std::array<Color3<>, 8> Renderer<2>::colors{{
{1.0f, 0.0f, 0.0f},
{1.0f, 0.0f, 0.0f}, /* X axis */
{1.0f, 0.0f, 0.0f},
{1.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f},
{0.0f, 1.0f, 0.0f}, /* Y axis */
{0.0f, 1.0f, 0.0f},
{0.0f, 1.0f, 0.0f},
}};
const std::array<UnsignedByte, 12> Renderer<2>::indices{{
0, 1,
1, 2, /* X axis */
1, 3,
4, 5,
5, 6, /* Y axis */
5, 7
}};
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 const std::array<Vector3, 12> positions;
static const std::array<Color3<>, 12> colors;
static const std::array<uint8_t, 18> indices;
};
const std::array<Vector3, 12> Renderer<3>::positions{{
{ 0.0f, 0.0f, 0.0f},
{ 1.0f, 0.0f, 0.0f}, /* X axis */
{ 0.9f, 0.1f, 0.0f},
{ 0.9f, -0.1f, 0.0f},
{ 0.0f, 0.0f, 0.0f},
{ 0.0f, 1.0f, 0.0f}, /* Y axis */
{ 0.1f, 0.9f, 0.0f},
{-0.1f, 0.9f, 0.0f},
{ 0.0f, 0.0f, 0.0f},
{ 0.0f, 0.0f, 1.0f}, /* Z axis */
{ 0.1f, 0.0f, 0.9f},
{-0.1f, 0.0f, 0.9f}
}};
const std::array<Color3<>, 12> Renderer<3>::colors{{
{1.0f, 0.0f, 0.0f},
{1.0f, 0.0f, 0.0f}, /* X axis */
{1.0f, 0.0f, 0.0f},
{1.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f},
{0.0f, 1.0f, 0.0f}, /* Y axis */
{0.0f, 1.0f, 0.0f},
{0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 1.0f},
{0.0f, 0.0f, 1.0f}, /* Z axis */
{0.0f, 0.0f, 1.0f},
{0.0f, 0.0f, 1.0f}
}};
const std::array<UnsignedByte, 18> Renderer<3>::indices{{
0, 1,
1, 2, /* X axis */
1, 3,
4, 5,
5, 6, /* Y axis */
5, 7,
8, 9,
9, 10, /* Z axis */
9, 11
}};
}
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>);
/* Mesh and vertex buffer */
mesh = ResourceManager::instance()->get<Mesh>(Renderer<dimensions>::mesh());
vertexBuffer = ResourceManager::instance()->get<Buffer>(Renderer<dimensions>::vertexBuffer());
indexBuffer = ResourceManager::instance()->get<Buffer>(Renderer<dimensions>::indexBuffer());
if(mesh) return;
/* Create the mesh */
Buffer* vertexBuffer = new Buffer(Buffer::Target::Array);
Buffer* indexBuffer = new Buffer(Buffer::Target::ElementArray);
Mesh* mesh = new Mesh;
MeshTools::interleave(mesh, vertexBuffer, Buffer::Usage::StaticDraw, Renderer<dimensions>::positions, Renderer<dimensions>::colors);
ResourceManager::instance()->set(this->vertexBuffer.key(), vertexBuffer, ResourceDataState::Final, ResourcePolicy::Manual);
indexBuffer->setData(Renderer<dimensions>::indices, Buffer::Usage::StaticDraw);
ResourceManager::instance()->set(this->indexBuffer.key(), indexBuffer, ResourceDataState::Final, ResourcePolicy::Manual);
mesh->setPrimitive(Mesh::Primitive::Lines)
->setIndexCount(Renderer<dimensions>::indices.size())
->addInterleavedVertexBuffer(vertexBuffer, 0,
typename Shaders::VertexColorShader<dimensions>::Position(),
typename Shaders::VertexColorShader<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);
}
template<UnsignedInt dimensions> void ObjectRenderer<dimensions>::draw(const typename DimensionTraits<dimensions>::MatrixType& transformationMatrix, SceneGraph::AbstractCamera<dimensions>* camera) {
shader->setTransformationProjectionMatrix(camera->projectionMatrix()*transformationMatrix*DimensionTraits<dimensions>::MatrixType::scaling(typename DimensionTraits<dimensions>::VectorType(options->size())))
->use();
mesh->draw();
}
template class ObjectRenderer<2>;
template class ObjectRenderer<3>;
}}

120
src/DebugTools/ObjectRenderer.h

@ -0,0 +1,120 @@
#ifndef Magnum_DebugTools_ObjectRenderer_h
#define Magnum_DebugTools_ObjectRenderer_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 Class Magnum::DebugTools::ObjectRenderer, Magnum::DebugTools::ObjectRendererOptions, typedef Magnum::DebugTools::ObjectRenderer2D, Magnum::DebugTools::ObjectRenderer3D
*/
#include "Resource.h"
#include "SceneGraph/Drawable.h"
#include "Shaders/Shaders.h"
#include "magnumDebugToolsVisibility.h"
namespace Magnum { namespace DebugTools {
/**
@brief Object renderer options
See ObjectRenderer documentation for more information.
*/
class ObjectRendererOptions {
public:
inline constexpr ObjectRendererOptions(): _size(1.0f) {}
/** @brief Size of the rendered axes */
inline constexpr Float size() const { return _size; }
/**
* @brief Set size of the rendered axes
* @return Pointer to self (for method chaining)
*
* Default is `1.0f`.
*/
inline ObjectRendererOptions* setSize(Float size) {
_size = size;
return this;
}
private:
Float _size;
};
/**
@brief Object renderer
Visualizes object position, rotation and scale using colored axes. See
@ref debug-tools-renderers for more information.
@section ObjectRenderer-usage Basic usage
Example code:
@code
// Create some options
DebugTools::ResourceManager::instance()->set("my",
(new DebugTools::ObjectRendererOptions())->setSize(0.3f));
// Create debug renderer for given object, use "my" options for it
Object3D* object;
new DebugTools::ObjectRenderer2D(object, "my", debugDrawables);
@endcode
@see ObjectRenderer2D, ObjectRenderer3D
*/
template<UnsignedInt dimensions> class MAGNUM_DEBUGTOOLS_EXPORT ObjectRenderer: public SceneGraph::Drawable<dimensions> {
public:
/**
* @brief Constructor
* @param object Object for which to create debug renderer
* @param options Options resource key. See
* @ref ObjectRenderer-usage "class documentation" for more
* information.
* @param drawables Drawable group
*
* The renderer is automatically added to object's features.
*/
explicit ObjectRenderer(SceneGraph::AbstractObject<dimensions>* object, ResourceKey options = ResourceKey(), SceneGraph::DrawableGroup<dimensions>* drawables = nullptr);
protected:
/** @todoc Remove Float when Doxygen properly treats this as override */
void draw(const typename DimensionTraits<dimensions, Float>::MatrixType& transformationMatrix, SceneGraph::AbstractCamera<dimensions, Float>* camera) override;
private:
Resource<ObjectRendererOptions> options;
Resource<AbstractShaderProgram, Shaders::VertexColorShader<dimensions>> shader;
Resource<Mesh> mesh;
Resource<Buffer> vertexBuffer, indexBuffer;
};
/** @brief Two-dimensional object renderer */
typedef ObjectRenderer<2> ObjectRenderer2D;
/** @brief Three-dimensional object renderer */
typedef ObjectRenderer<3> ObjectRenderer3D;
}}
#endif

131
src/DebugTools/Profiler.cpp

@ -0,0 +1,131 @@
/*
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 "Profiler.h"
#include <algorithm>
#include <numeric>
#include <Utility/Assert.h>
#include "Magnum.h"
using namespace std::chrono;
namespace Magnum { namespace DebugTools {
Profiler::Section Profiler::addSection(const std::string& name) {
CORRADE_ASSERT(!enabled, "Profiler: cannot add section when profiling is enabled", 0);
sections.push_back(name);
return sections.size()-1;
}
void Profiler::setMeasureDuration(std::size_t frames) {
CORRADE_ASSERT(!enabled, "Profiler: cannot set measure duration when profiling is enabled", );
measureDuration = frames;
}
void Profiler::enable() {
enabled = true;
frameData.assign(measureDuration*sections.size(), high_resolution_clock::duration::zero());
totalData.assign(sections.size(), high_resolution_clock::duration::zero());
frameCount = 0;
}
void Profiler::disable() {
enabled = false;
}
void Profiler::start(Section section) {
if(!enabled) return;
CORRADE_ASSERT(section < sections.size(), "Profiler: unknown section passed to start()", );
save();
currentSection = section;
}
void Profiler::stop() {
if(!enabled) return;
save();
previousTime = high_resolution_clock::time_point();
}
void Profiler::save() {
auto now = high_resolution_clock::now();
/* If the profiler is already running, add time to given section */
if(previousTime != high_resolution_clock::time_point())
frameData[currentFrame*sections.size()+currentSection] += now-previousTime;
/* Set current time as previous for next section */
previousTime = now;
}
void Profiler::nextFrame() {
if(!enabled) return;
/* Next frame index */
std::size_t nextFrame = (currentFrame+1) % measureDuration;
/* Add times of current frame to total */
for(std::size_t i = 0; i != sections.size(); ++i)
totalData[i] += frameData[currentFrame*sections.size()+i];
/* Subtract times of next frame from total and erase them */
for(std::size_t i = 0; i != sections.size(); ++i) {
totalData[i] -= frameData[nextFrame*sections.size()+i];
frameData[nextFrame*sections.size()+i] = high_resolution_clock::duration::zero();
}
/* Advance to next frame */
currentFrame = nextFrame;
if(frameCount < measureDuration) ++frameCount;
}
void Profiler::printStatistics() {
if(!enabled) return;
std::vector<std::size_t> totalSorted(sections.size());
std::iota(totalSorted.begin(), totalSorted.end(), 0);
#ifndef CORRADE_GCC44_COMPATIBILITY
std::sort(totalSorted.begin(), totalSorted.end(), [this](std::size_t i, std::size_t j){return totalData[i] > totalData[j];});
#else
std::sort(totalSorted.begin(), totalSorted.end(), Compare(this));
#endif
Debug() << "Statistics for last" << measureDuration << "frames:";
for(std::size_t i = 0; i != sections.size(); ++i)
Debug() << " " << sections[totalSorted[i]] << duration_cast<microseconds>(totalData[totalSorted[i]]).count()/frameCount
#ifndef CORRADE_GCC44_COMPATIBILITY
<< u8"µs";
#else
<< "µs";
#endif
}
}}

58
src/Profiler.h → src/DebugTools/Profiler.h

@ -1,46 +1,56 @@
#ifndef Magnum_Profiler_h
#define Magnum_Profiler_h
#ifndef Magnum_DebugTools_Profiler_h
#define Magnum_DebugTools_Profiler_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
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 Class Magnum::Profiler
* @brief Class Magnum::DebugTools::Profiler
*/
#include <chrono>
#include <initializer_list>
#include <string>
#include <vector>
#include <corradeCompatibility.h>
#include "corradeCompatibility.h"
#include "magnumVisibility.h"
#include "Types.h"
#include "magnumDebugToolsVisibility.h"
namespace Magnum {
namespace Magnum { namespace DebugTools {
/**
@brief Measuring elapsed time in each frame
@brief %Profiler
Measures time passed during specified sections of each frame. It's meant to be
used in rendering and event loops (e.g. Platform::GlutApplication::drawEvent()),
but it's possible to use it standalone elsewhere. Example usage:
@code
Profiler p;
DebugTools::Profiler p;
// Register named sections
struct {
Profiler::Section ai, physics, draw, bufferSwap;
DebugTools::Profiler::Section ai, physics, draw, bufferSwap;
} sections;
sections.ai = p.addSection("AI");
sections.physics = p.addSection("Physics");
@ -51,7 +61,7 @@ sections.bufferSwap = p.addSection("Buffer swap");
p.enable();
// Mark sections in draw function
void MyContext::drawEvent() {
void MyApplication::drawEvent() {
p.start();
// ... misc stuff belogning to "Other" section
@ -89,14 +99,14 @@ stop it again using stop(), if you are not interested in profiling the rest.
@todo Some unit testing
@todo More time intervals
*/
class MAGNUM_EXPORT Profiler {
class MAGNUM_DEBUGTOOLS_EXPORT Profiler {
public:
/**
* @brief Section ID
*
* @see otherSection, addSection(), start(Section)
*/
typedef std::uint32_t Section;
typedef UnsignedInt Section;
/**
* @brief Default section
@ -106,7 +116,7 @@ class MAGNUM_EXPORT Profiler {
static const Section otherSection = 0;
#ifndef DOXYGEN_GENERATING_OUTPUT
Profiler(): enabled(false), measureDuration(60), currentFrame(0), frameCount(0), sections{"Other"}, currentSection(otherSection) {}
explicit Profiler(): enabled(false), measureDuration(60), currentFrame(0), frameCount(0), sections{"Other"}, currentSection(otherSection) {}
#endif
/**
@ -215,6 +225,6 @@ class MAGNUM_EXPORT Profiler {
Section currentSection;
};
}
}}
#endif

49
src/DebugTools/ResourceManager.cpp

@ -0,0 +1,49 @@
/*
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.
*/
#define MAGNUM_RESOURCEMANAGER_DEFINE_INTERNALINSTANCE
#include "ResourceManager.h"
#include "Buffer.h"
#include "Mesh.h"
#include "DebugTools/ForceRenderer.h"
#include "DebugTools/ObjectRenderer.h"
#include "DebugTools/ShapeRenderer.h"
namespace Magnum {
template class ResourceManager<AbstractShaderProgram, Buffer, Mesh, DebugTools::ForceRendererOptions, DebugTools::ObjectRendererOptions, DebugTools::ShapeRendererOptions>;
namespace DebugTools {
ResourceManager::ResourceManager() {
setFallback(new ForceRendererOptions);
setFallback(new ObjectRendererOptions);
setFallback(new ShapeRendererOptions);
}
ResourceManager::~ResourceManager() {}
}}

64
src/DebugTools/ResourceManager.h

@ -0,0 +1,64 @@
#ifndef Magnum_DebugTools_ResourceManager_h
#define Magnum_DebugTools_ResourceManager_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 Class Magnum::DebugTools::ResourceManager
*/
#include "Magnum.h"
#ifndef MAGNUM_RESOURCEMANAGER_DEFINE_INTERNALINSTANCE
#define MAGNUM_RESOURCEMANAGER_DONT_DEFINE_INTERNALINSTANCE
#endif
#include "../ResourceManager.h"
#include "SceneGraph/SceneGraph.h"
#include "Physics/Physics.h"
#include "DebugTools.h"
#include "magnumDebugToolsVisibility.h"
namespace Magnum {
extern template ResourceManager<AbstractShaderProgram, Buffer, Mesh, DebugTools::ForceRendererOptions, DebugTools::ObjectRendererOptions, DebugTools::ShapeRendererOptions> MAGNUM_DEBUGTOOLS_EXPORT *& ResourceManager<AbstractShaderProgram, Buffer, Mesh, DebugTools::ForceRendererOptions, DebugTools::ObjectRendererOptions, DebugTools::ShapeRendererOptions>::internalInstance();
namespace DebugTools {
/**
@brief %Resource manager for debug tools
Stores various data used by debug renderers. See @ref debug-tools for more
information.
*/
class MAGNUM_DEBUGTOOLS_EXPORT ResourceManager: public Magnum::ResourceManager<AbstractShaderProgram, Buffer, Mesh, DebugTools::ForceRendererOptions, DebugTools::ObjectRendererOptions, DebugTools::ShapeRendererOptions> {
public:
explicit ResourceManager();
~ResourceManager();
};
}}
#endif

109
src/DebugTools/ShapeRenderer.cpp

@ -0,0 +1,109 @@
/*
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 "ShapeRenderer.h"
#include "ResourceManager.h"
#include "Physics/AbstractShape.h"
#include "Physics/AxisAlignedBox.h"
#include "Physics/Box.h"
#include "Physics/ObjectShape.h"
#include "Physics/Point.h"
#include "Physics/ShapeGroup.h"
#include "SceneGraph/AbstractCamera.h"
#include "Implementation/AxisAlignedBoxRenderer.h"
#include "Implementation/BoxRenderer.h"
#include "Implementation/PointRenderer.h"
namespace Magnum { namespace DebugTools {
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
template<> void createDebugMesh(ShapeRenderer<2>* renderer, Physics::AbstractShape<2>* shape) {
switch(shape->type()) {
case Physics::AbstractShape2D::Type::AxisAlignedBox:
renderer->renderers.push_back(new Implementation::AxisAlignedBoxRenderer<2>(*static_cast<Physics::AxisAlignedBox2D*>(shape)));
break;
case Physics::AbstractShape2D::Type::Box:
renderer->renderers.push_back(new Implementation::BoxRenderer<2>(*static_cast<Physics::Box2D*>(shape)));
break;
case Physics::AbstractShape2D::Type::Point:
renderer->renderers.push_back(new Implementation::PointRenderer<2>(*static_cast<Physics::Point2D*>(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());
} break;
default:
Warning() << "DebugTools::ShapeRenderer2D::createShapeRenderer(): type" << shape->type() << "not implemented";
}
}
template<> void createDebugMesh(ShapeRenderer<3>* renderer, Physics::AbstractShape<3>* shape) {
switch(shape->type()) {
case Physics::AbstractShape3D::Type::AxisAlignedBox:
renderer->renderers.push_back(new Implementation::AxisAlignedBoxRenderer<3>(*static_cast<Physics::AxisAlignedBox3D*>(shape)));
break;
case Physics::AbstractShape3D::Type::Box:
renderer->renderers.push_back(new Implementation::BoxRenderer<3>(*static_cast<Physics::Box3D*>(shape)));
break;
case Physics::AbstractShape3D::Type::Point:
renderer->renderers.push_back(new Implementation::PointRenderer<3>(*static_cast<Physics::Point3D*>(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());
} break;
default:
Warning() << "DebugTools::ShapeRenderer3D::createShapeRenderer(): type" << shape->type() << "not implemented";
}
}
}
#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() {
for(auto it = renderers.begin(); it != renderers.end(); ++it)
delete *it;
}
template<UnsignedInt dimensions> void ShapeRenderer<dimensions>::draw(const typename DimensionTraits<dimensions>::MatrixType&, SceneGraph::AbstractCamera<dimensions>* camera) {
typename DimensionTraits<dimensions>::MatrixType projectionMatrix = camera->projectionMatrix()*camera->cameraMatrix();
for(auto it = renderers.begin(); it != renderers.end(); ++it)
(*it)->draw(options, projectionMatrix);
}
template class ShapeRenderer<2>;
template class ShapeRenderer<3>;
}}

157
src/DebugTools/ShapeRenderer.h

@ -0,0 +1,157 @@
#ifndef Magnum_DebugTools_ShapeRenderer_h
#define Magnum_DebugTools_ShapeRenderer_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 Class Magnum::DebugTools::ShapeRenderer, Magnum::DebugTools::ShapeRendererOptions, typedef Magnum::DebugTools::ShapeRenderer2D, Magnum::DebugTools::ShapeRenderer3D
*/
#include "Color.h"
#include "Resource.h"
#include "SceneGraph/Drawable.h"
#include "Physics/Physics.h"
#include "magnumDebugToolsVisibility.h"
namespace Magnum { namespace DebugTools {
/** @todoc Remove `ifndef` when Doxygen is sane again */
#ifndef DOXYGEN_GENERATING_OUTPUT
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);
}
#endif
/**
@brief Shape renderer options
See ShapeRenderer documentation for more information.
*/
class ShapeRendererOptions {
public:
inline constexpr ShapeRendererOptions(): _pointSize(0.25f) {}
/** @brief Color of rendered shape */
inline constexpr Color3<> color() const { return _color; }
/**
* @brief Set color of rendered shape
* @return Pointer to self (for method chaining)
*
* Default is black.
*/
inline ShapeRendererOptions* setColor(const Color3<>& color) {
_color = color;
return this;
}
/** @brief Point size */
inline 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.
* Default is `0.25f`.
*/
inline ShapeRendererOptions* setPointSize(Float size) {
_pointSize = size;
return this;
}
private:
Color3<> _color;
Float _pointSize;
};
/**
@brief Shape renderer
Visualizes collision shapes using wireframe primitives. See
@ref debug-tools-renderers for more information.
@section ShapeRenderer-usage Basic usage
Example code:
@code
// Create some options
DebugTools::ResourceManager::instance()->set("red",
(new DebugTools::ShapeRendererOptions())->setColor({1.0f, 0.0f, 0.0f}));
// Create debug renderer for given shape, use "red" options for it
Physics::ObjectShape2D* 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
public:
/**
* @brief Constructor
* @param shape Object 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.
*/
explicit ShapeRenderer(Physics::ObjectShape<dimensions>* shape, ResourceKey options = ResourceKey(), SceneGraph::DrawableGroup<dimensions>* drawables = nullptr);
~ShapeRenderer();
protected:
/** @todoc Remove Float when Doxygen properly treats this as override */
void draw(const typename DimensionTraits<dimensions, Float>::MatrixType& transformationMatrix, SceneGraph::AbstractCamera<dimensions, Float>* camera) override;
private:
Resource<ShapeRendererOptions> options;
std::vector<Implementation::AbstractShapeRenderer<dimensions>*> renderers;
};
/** @brief Two-dimensional shape renderer */
typedef ShapeRenderer<2> ShapeRenderer2D;
/** @brief Three-dimensional shape renderer */
typedef ShapeRenderer<3> ShapeRenderer3D;
}}
#endif

25
src/DebugTools/Test/CMakeLists.txt

@ -0,0 +1,25 @@
#
# 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.
#
corrade_add_test(MagnumDebugToolsForceRendererTest ForceRendererTest.cpp LIBRARIES MagnumMathTestLib)

123
src/DebugTools/Test/ForceRendererTest.cpp

@ -0,0 +1,123 @@
/*
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 <TestSuite/Tester.h>
#include "DebugTools/Implementation/ForceRendererTransformation.h"
namespace Magnum { namespace DebugTools { namespace Implementation { namespace Test {
class ForceRendererTest: public Corrade::TestSuite::Tester {
public:
explicit ForceRendererTest();
void zero2D();
void parallel2D();
void antiParallel2D();
void arbitrary2D();
void zero3D();
void parallel3D();
void antiParallel3D();
void arbitrary3D();
};
ForceRendererTest::ForceRendererTest() {
addTests({&ForceRendererTest::zero2D,
&ForceRendererTest::parallel2D,
&ForceRendererTest::antiParallel2D,
&ForceRendererTest::arbitrary2D,
&ForceRendererTest::zero3D,
&ForceRendererTest::parallel3D,
&ForceRendererTest::antiParallel3D,
&ForceRendererTest::arbitrary3D});
}
void ForceRendererTest::zero2D() {
CORRADE_COMPARE(Implementation::forceRendererTransformation<2>({0.5f, -3.0f}, Vector2()),
Matrix3::translation({0.5f, -3.0f})*Matrix3::scaling(Vector2(0.0f)));
}
void ForceRendererTest::parallel2D() {
CORRADE_COMPARE(Implementation::forceRendererTransformation<2>({0.5f, -3.0f}, Vector2::xAxis(2.5f)),
Matrix3::translation({0.5f, -3.0f})*Matrix3::scaling(Vector2(2.5f)));
}
void ForceRendererTest::antiParallel2D() {
CORRADE_COMPARE(Implementation::forceRendererTransformation<2>({0.5f, -3.0f}, Vector2::xAxis(-2.5f)),
Matrix3::translation({0.5f, -3.0f})*Matrix3::scaling(Vector2(-2.5f)));
}
void ForceRendererTest::arbitrary2D() {
Vector2 force(2.7f, -11.5f);
Matrix3 m = Implementation::forceRendererTransformation<2>({0.5f, -3.0f}, force);
/* Translation, right-pointing base vector is the same as force */
CORRADE_COMPARE(m.translation(), Vector2(0.5f, -3.0f));
CORRADE_COMPARE(m.right(), force);
/* All vectors have the same length */
CORRADE_COMPARE(m.up().length(), force.length());
/* All vectors are parallel */
CORRADE_COMPARE(Vector2::dot(m.right(), m.up()), 0.0f);
}
void ForceRendererTest::zero3D() {
CORRADE_COMPARE(Implementation::forceRendererTransformation<3>({0.5f, -3.0f, 1.0f}, Vector3()),
Matrix4::translation({0.5f, -3.0f, 1.0f})*Matrix4::scaling(Vector3(0.0f)));
}
void ForceRendererTest::parallel3D() {
CORRADE_COMPARE(Implementation::forceRendererTransformation<3>({0.5f, -3.0f, 1.0f}, Vector3::xAxis(2.5f)),
Matrix4::translation({0.5f, -3.0f, 1.0f})*Matrix4::scaling(Vector3(2.5f)));
}
void ForceRendererTest::antiParallel3D() {
CORRADE_COMPARE(Implementation::forceRendererTransformation<3>({0.5f, -3.0f, 1.0f}, Vector3::xAxis(-2.5f)),
Matrix4::translation({0.5f, -3.0f, 1.0f})*Matrix4::scaling({-2.5f, 2.5f, 2.5f}));
}
void ForceRendererTest::arbitrary3D() {
Vector3 force(3.7f, -5.7f, -11.5f);
Matrix4 m = Implementation::forceRendererTransformation<3>({0.5f, -3.0f, 1.0f}, force);
/* Translation, right-pointing base vector is the same as force */
CORRADE_COMPARE(m.translation(), Vector3(0.5f, -3.0f, 1.0f));
CORRADE_COMPARE(m.right(), force);
/* All vectors have the same length */
CORRADE_COMPARE(m.up().length(), force.length());
CORRADE_COMPARE(m.backward().length(), force.length());
/* All vectors are parallel */
CORRADE_COMPARE(Vector3::dot(m.right(), m.up()), 0.0f);
CORRADE_COMPARE(Vector3::dot(m.right(), m.backward()), 0.0f);
CORRADE_COMPARE(Vector3::dot(m.up(), m.backward()), 0.0f);
}
}}}}
CORRADE_TEST_MAIN(Magnum::DebugTools::Implementation::Test::ForceRendererTest)

37
src/DebugTools/magnumDebugToolsVisibility.h

@ -0,0 +1,37 @@
#ifndef Magnum_DebugTools_magnumDebugToolsVisibility_h
#define Magnum_DebugTools_magnumDebugToolsVisibility_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.
*/
#ifdef _WIN32
#ifdef MagnumDebugTools_EXPORTS
#define MAGNUM_DEBUGTOOLS_EXPORT __declspec(dllexport)
#else
#define MAGNUM_DEBUGTOOLS_EXPORT __declspec(dllimport)
#endif
#else
#define MAGNUM_DEBUGTOOLS_EXPORT __attribute__ ((visibility ("default")))
#endif
#endif

93
src/DefaultFramebuffer.cpp

@ -0,0 +1,93 @@
/*
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 "DefaultFramebuffer.h"
#include "Context.h"
#include "Implementation/State.h"
#include "Implementation/FramebufferState.h"
#include "Extensions.h"
namespace Magnum {
DefaultFramebuffer defaultFramebuffer;
DefaultFramebuffer::DefaultFramebuffer() { _id = 0; }
#ifndef MAGNUM_TARGET_GLES2
DefaultFramebuffer* DefaultFramebuffer::mapForDraw(std::initializer_list<std::pair<UnsignedInt, DrawAttachment>> attachments) {
/* Max attachment location */
std::size_t max = 0;
for(const auto& attachment: attachments)
if(attachment.first > max) max = attachment.first;
/* Create linear array from associative */
GLenum* _attachments = new GLenum[max+1];
std::fill_n(_attachments, max, GL_NONE);
for(const auto& attachment: attachments)
_attachments[attachment.first] = static_cast<GLenum>(attachment.second);
(this->*drawBuffersImplementation)(max+1, _attachments);
delete[] _attachments;
return this;
}
#endif
void DefaultFramebuffer::invalidate(std::initializer_list<InvalidationAttachment> attachments) {
GLenum* _attachments = new GLenum[attachments.size()];
for(std::size_t i = 0; i != attachments.size(); ++i)
_attachments[i] = GLenum(*(attachments.begin()+i));
invalidateImplementation(attachments.size(), _attachments);
delete[] _attachments;
}
void DefaultFramebuffer::invalidate(std::initializer_list<InvalidationAttachment> attachments, const Rectanglei& rectangle) {
GLenum* _attachments = new GLenum[attachments.size()];
for(std::size_t i = 0; i != attachments.size(); ++i)
_attachments[i] = GLenum(*(attachments.begin()+i));
invalidateImplementation(attachments.size(), _attachments, rectangle);
delete[] _attachments;
}
void DefaultFramebuffer::initializeContextBasedFunctionality(Context* context) {
Implementation::FramebufferState* state = context->state()->framebuffer;
/* Initial framebuffer size */
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
defaultFramebuffer._viewport = state->viewport = Rectanglei::fromSize({viewport[0], viewport[1]}, {viewport[2], viewport[3]});
/* Fake initial glViewport() call for ApiTrace */
#ifndef MAGNUM_TARGET_GLES
if(context->isExtensionSupported<Extensions::GL::GREMEDY::string_marker>())
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
#endif
}
}

384
src/DefaultFramebuffer.h

@ -0,0 +1,384 @@
#ifndef Magnum_DefaultFramebuffer_h
#define Magnum_DefaultFramebuffer_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 Class Magnum::DefaultFramebuffer
*/
#include "AbstractFramebuffer.h"
namespace Magnum {
/**
@brief Default framebuffer
Default framebuffer, i.e. the actual screen surface. It is automatically
created when Context is created and it is available through global variable
@ref defaultFramebuffer. It is by default mapped to whole screen surface.
@section DefaultFramebuffer-usage Usage
When you are using only the default framebuffer, the usage is simple. You
must ensure that it is properly resized when application surface is resized,
i.e. you must pass the new size in your @ref Platform::GlutApplication::viewportEvent() "viewportEvent()"
implementation, for example:
@code
void viewportEvent(const Vector2i& size) {
defaultFramebuffer.setViewport({}, size);
// ...
}
@endcode
Next thing you probably want is to clear all used buffers before performing
any drawing in your @ref Platform::GlutApplication::drawEvent() "drawEvent()"
implementation, for example:
@code
void drawEvent() {
defaultFramebuffer.clear(AbstractFramebuffer::Clear::Color|AbstractFramebuffer::Clear::Depth);
// ...
}
@endcode
See Framebuffer documentation for more involved usage, usage of non-default or
multiple framebuffers.
@section DefaultFramebuffer-performance-optimization Performance optimizations
See also @ref AbstractFramebuffer-performance-optimization "relevant section in AbstractFramebuffer".
If extension @extension{EXT,direct_state_access} is available, functions
mapForDraw() and mapForRead() use DSA to avoid unnecessary calls to
@fn_gl{BindFramebuffer}. See their respective documentation for more
information.
*/
class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
friend class Context;
public:
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Draw attachment
*
* @see mapForDraw()
* @requires_gles30 Draw attachments for default framebuffer are
* available only in OpenGL ES 3.0.
*/
enum class DrawAttachment: GLenum {
/** Don't use the output. */
None = GL_NONE,
#ifndef MAGNUM_TARGET_GLES
/**
* Write output to front left buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
*/
FrontLeft = GL_FRONT_LEFT,
/**
* Write output to front right buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
*/
FrontRight = GL_FRONT_RIGHT,
/**
* Write output to back left buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
*/
BackLeft = GL_BACK_LEFT,
/**
* Write output to back right buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
*/
BackRight = GL_BACK_RIGHT,
#endif
/**
* Write output to back buffer.
*
* On desktop OpenGL, this is equal to @ref DrawAttachment "DrawAttachment::BackLeft".
*/
#ifdef MAGNUM_TARGET_GLES
Back = GL_BACK,
#else
Back = GL_BACK_LEFT,
#endif
/**
* Write output to front buffer.
*
* On desktop OpenGL, this is equal to @ref DrawAttachment "DrawAttachment::FrontLeft".
*/
#ifdef MAGNUM_TARGET_GLES
Front = GL_FRONT
#else
Front = GL_FRONT_LEFT
#endif
};
#endif
/**
* @brief Read attachment
*
* @see mapForRead()
* @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer}
*/
enum class ReadAttachment: GLenum {
/** Don't read from any buffer */
None = GL_NONE,
#ifndef MAGNUM_TARGET_GLES
/**
* Read from front left buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
*/
FrontLeft = GL_FRONT_LEFT,
/**
* Read from front right buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
*/
FrontRight = GL_FRONT_RIGHT,
/**
* Read from back left buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
*/
BackLeft = GL_BACK_LEFT,
/**
* Read from back right buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
*/
BackRight = GL_BACK_RIGHT,
/**
* Read from left buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
*/
Left = GL_LEFT,
/**
* Read from right buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
*/
Right = GL_RIGHT,
#endif
/** Read from back buffer. */
Back = GL_BACK,
/**
* Read from front buffer.
* @requires_es_extension %Extension @es_extension2{NV,read_buffer_front,GL_NV_read_buffer}
*/
Front = GL_FRONT
#ifndef MAGNUM_TARGET_GLES
,
/**
* Read from front and back buffer.
* @requires_gl In OpenGL ES you must specify either
* @ref Magnum::DefaultFramebuffer::ReadAttachment "ReadAttachment::Front"
* or @ref Magnum::DefaultFramebuffer::ReadAttachment "ReadAttachment::Back".
*/
FrontAndBack = GL_FRONT_AND_BACK
#endif
};
/**
* @brief Invalidation attachment
*
* @see invalidate()
* @requires_gl43 %Extension @extension{ARB,invalidate_subdata}
* @requires_gles30 %Extension @es_extension{EXT,discard_framebuffer}
*/
enum class InvalidationAttachment: GLenum {
#ifndef MAGNUM_TARGET_GLES
/**
* Invalidate front left buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
*/
FrontLeft = GL_FRONT_LEFT,
/**
* Invalidate front right buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
*/
FrontRight = GL_FRONT_RIGHT,
/**
* Invalidate back left buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
*/
BackLeft = GL_BACK_LEFT,
/**
* Invalidate back right buffer.
* @requires_gl Stereo rendering is not available in OpenGL ES.
*/
BackRight = GL_BACK_RIGHT,
#endif
/** Invalidate color buffer. */
#ifndef MAGNUM_TARGET_GLES2
Color = GL_COLOR,
#else
Color = GL_COLOR_EXT,
#endif
/** Invalidate depth bufer. */
#ifndef MAGNUM_TARGET_GLES2
Depth = GL_DEPTH,
#else
Depth = GL_DEPTH_EXT,
#endif
/** Invalidate stencil buffer. */
#ifndef MAGNUM_TARGET_GLES2
Stencil = GL_STENCIL
#else
Stencil = GL_STENCIL_EXT
#endif
};
explicit MAGNUM_LOCAL DefaultFramebuffer();
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Map shader outputs to buffer attachment
* @return Pointer to self (for method chaining)
*
* @p attachments is list of shader outputs mapped to buffer
* attachments. %Shader outputs which are not listed are not used, you
* can achieve the same by passing @ref DrawAttachment "DrawAttachment::None"
* as attachment. Example usage:
* @code
* framebuffer.mapForDraw({{MyShader::ColorOutput, DefaultFramebuffer::DrawAttachment::BackLeft},
* {MyShader::NormalOutput, DefaultFramebuffer::DrawAttachment::None}});
* @endcode
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
* operation.
* @see mapForRead(), @fn_gl{BindFramebuffer}, @fn_gl{DrawBuffers} or
* @fn_gl_extension{FramebufferDrawBuffers,EXT,direct_state_access}
* @requires_gles30 Draw attachments for default framebuffer are
* available only in OpenGL ES 3.0.
*/
DefaultFramebuffer* mapForDraw(std::initializer_list<std::pair<UnsignedInt, DrawAttachment>> attachments);
/**
* @brief Map shader output to buffer attachment
* @param attachment %Buffer attachment
* @return Pointer to self (for method chaining)
*
* Similar to above function, can be used in cases when shader has
* only one (unnamed) output.
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
* operation.
* @see mapForRead(), @fn_gl{BindFramebuffer}, @fn_gl{DrawBuffer} or
* @fn_gl_extension{FramebufferDrawBuffer,EXT,direct_state_access}
* @requires_gles30 Draw attachments for default framebuffer are
* available only in OpenGL ES 3.0.
*/
inline DefaultFramebuffer* mapForDraw(DrawAttachment attachment) {
(this->*drawBufferImplementation)(static_cast<GLenum>(attachment));
return this;
}
#endif
/**
* @brief Map given attachment for reading
* @param attachment %Buffer attachment
* @return Pointer to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
* operation.
* @see mapForDraw(), @fn_gl{BindFramebuffer}, @fn_gl{ReadBuffer} or
* @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) {
(this->*readBufferImplementation)(static_cast<GLenum>(attachment));
return this;
}
/**
* @brief Invalidate framebuffer
* @param attachments Attachments to invalidate
*
* The framebuffer is bound to some target before the operation, if
* not already.
* @see @fn_gl{InvalidateFramebuffer} or @fn_gles_extension{DiscardFramebuffer,EXT,discard_framebuffer}
* on OpenGL ES 2.0
* @requires_gl43 %Extension @extension{ARB,invalidate_subdata}. Use
* clear() instead where the extension is not supported.
* @requires_gles30 %Extension @es_extension{EXT,discard_framebuffer}.
* Use clear() instead where the extension is not supported.
*/
void invalidate(std::initializer_list<InvalidationAttachment> attachments);
/**
* @brief Invalidate framebuffer rectangle
* @param attachments Attachments to invalidate
* @param rectangle %Rectangle to invalidate
*
* The framebuffer is bound to some target before the operation, if
* not already.
* @see @fn_gl{InvalidateSubFramebuffer} or @fn_gles_extension{DiscardSubFramebuffer,EXT,discard_framebuffer}
* on OpenGL ES 2.0
* @requires_gl43 %Extension @extension{ARB,invalidate_subdata}. Use
* clear() instead where the extension is not supported.
* @requires_gles30 %Extension @es_extension{EXT,discard_framebuffer}.
* Use clear() instead where the extension is not supported.
*/
void invalidate(std::initializer_list<InvalidationAttachment> attachments, const Rectanglei& rectangle);
/* Overloads to remove WTF-factor from method chaining order */
#ifndef DOXYGEN_GENERATING_OUTPUT
inline DefaultFramebuffer* setViewport(const Rectanglei& rectangle) {
AbstractFramebuffer::setViewport(rectangle);
return this;
}
#endif
private:
static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context);
};
/** @brief Default framebuffer instance */
extern DefaultFramebuffer MAGNUM_EXPORT defaultFramebuffer;
}
#endif

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

Loading…
Cancel
Save