diff --git a/CMakeLists.txt b/CMakeLists.txt index ddca3741a..dc3435490 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,31 +4,26 @@ project(Magnum) include(CMakeDependentOption) -option(TARGET_GLES "Build for OpenGL ES 2 instead of desktop OpenGL" OFF) +option(GCC46_COMPATIBILITY "Enable compatibility mode for GCC 4.6 (might disable some features)" OFF) + +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) # Parts of the library option(WITH_EVERYTHING "Build everything (doesn't include contexts)" ON) -option(WITH_MESHTOOLS "Build MeshTools library" OFF) -option(WITH_PHYSICS "Build Physics library" OFF) -option(WITH_PRIMITIVES "Builf Primitives library" OFF) -option(WITH_SCENEGRAPH "Build SceneGraph library" OFF) -option(WITH_SHADERS "Build Shaders library" OFF) +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_GLXCONTEXT "Build GlxContext library" OFF) -cmake_dependent_option(WITH_XEGLCONTEXT "Build XEglContext library" OFF "TARGET_GLES" OFF) -cmake_dependent_option(WITH_GLUTCONTEXT "Build GlutContext library" OFF "NOT TARGET_GLES" OFF) -option(WITH_SDL2CONTEXT "Build Sdl2Context library" OFF) +option(WITH_GLXWINDOWCONTEXT "Build GlxWindowContext library" OFF) +cmake_dependent_option(WITH_XEGLWINDOWCONTEXT "Build XEglWindowContext library" OFF "TARGET_GLES" OFF) +cmake_dependent_option(WITH_GLUTWINDOWCONTEXT "Build GlutWindowContext library" OFF "NOT TARGET_GLES" OFF) +option(WITH_SDL2WINDOWCONTEXT "Build Sdl2WindowContext library" OFF) option(BUILD_TESTS "Build unit tests." OFF) -if(WITH_EVERYTHING) - set(WITH_MESHTOOLS ON) - set(WITH_PHYSICS ON) - set(WITH_PRIMITIVES ON) - set(WITH_SCENEGRAPH ON) - set(WITH_SHADERS ON) -endif() - if(BUILD_TESTS) enable_testing() endif() @@ -57,5 +52,8 @@ 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) +include_directories(${CMAKE_SOURCE_DIR}/external) + +add_subdirectory(external) add_subdirectory(modules) add_subdirectory(src) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..d55a03a71 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,49 @@ +Bug reports, feature requests or code contributions are always very welcome. +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. + +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. + +Contact +------- + +- Website - http://mosra.cz/blog/ +- GitHub - https://github.com/mosra/magnum +- E-mail - mosra@centrum.cz +- Jabber - mosra@jabbim.cz diff --git a/Doxyfile b/Doxyfile index a9b8a684f..2553d0c84 100644 --- a/Doxyfile +++ b/Doxyfile @@ -200,7 +200,9 @@ ALIASES = \ "configurationvalue{1}=@brief %Configuration value parser and writer @xrefitem configurationvalues \"Configuration value parser and writer\" \"Configuration value parsers and writers for custom types\" Allows parsing and writing \1 from and to Corrade::Utility::Configuration." \ "collisionoperator{2}=@relates \1\n@brief Collision of %\1 and %\2\n@see \2::operator%(const \1&) const" \ "todoc=@xrefitem todoc \"Documentation todo\" \"Documentation-related todo list\"" \ - "requires_gl=@xrefitem requires-gl \"Requires desktop OpenGL\" \"Functionality requiring desktop OpenGL (not available on OpenGL ES)\" Not available on OpenGL ES." \ + "fn_gl{1}=gl\1()" \ + "fn_gl_extension{3}=gl\1\2()" \ + "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\"" \ "requires_gl32=@xrefitem requires-gl32 \"Requires OpenGL 3.2\" \"Functionality requiring OpenGL 3.2\"" \ @@ -212,8 +214,10 @@ ALIASES = \ "requires_extension=@xrefitem requires-extension \"Requires OpenGL extension\" \"Functionality requiring specific OpenGL extension\"" \ "extension{2}=\1_\2" \ "requires_gles30=@xrefitem requires-gles30 \"Requires OpenGL ES 3.0\" \"Functionality requiring OpenGL ES 3.0\"" \ + "requires_gl=@xrefitem requires-gl \"Requires desktop OpenGL\" \"Functionality requiring desktop OpenGL (not available in OpenGL ES)\"" \ "requires_es_extension=@xrefitem requires-es-extension \"Requires OpenGL ES extension\" \"Functionality requiring specific OpenGL ES extension\"" \ - "es_extension{2}=\1_\2" + "es_extension{2}=\1_\2" \ + "es_extension2{3}=\1_\2" # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding @@ -396,7 +400,7 @@ EXTRACT_STATIC = NO # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. -EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in @@ -700,6 +704,7 @@ INPUT_ENCODING = UTF-8 FILE_PATTERNS = *.cpp \ *.h \ + *.hpp \ *.dox # The RECURSIVE tag can be used to turn specify whether or not subdirectories @@ -729,6 +734,7 @@ EXCLUDE_SYMLINKS = NO # for example use the pattern */test/* EXCLUDE_PATTERNS = */Test/* \ + */Implementation/* \ *Visibility.h # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names @@ -855,7 +861,7 @@ USE_HTAGS = NO # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. -VERBATIM_HEADERS = YES +VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index diff --git a/README.md b/README.md index 07fde48cf..9ed0bed4f 100644 --- a/README.md +++ b/README.md @@ -3,20 +3,23 @@ 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, classes for convenient usage of shaders, buffers and textures. - Access to framebuffer and occlusion queries. - * Physics library for collision detection and rigid body dynamics. Mesh tools - for cleaning, optimizing and generating meshes. + 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 easy creation of OpenGL context with various toolkits. + * Classes for easy creation of OpenGL context 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 . + also available online at http://mosra.cz/blog/magnum-doc/ . INSTALLATION ============ @@ -37,18 +40,18 @@ Minimal dependencies **OpenGL ES 2** headers, if targeting OpenGL ES. * **GLEW** - OpenGL extension wrangler * **Corrade** - Plugin management and utility library. You can get it at - http://mosra.cz/blog/corrade.php + http://github.com/mosra/corrade or at http://mosra.cz/blog/corrade.php. Compilation, installation ------------------------- -The library (for example with GLUT context) can be built and installed using -these four commands: +The library (for example with GLUT window context) can be built and installed +using these four commands: mkdir -p build && cd build cmake .. \ -DCMAKE_INSTALL_PREFIX=/usr \ - -DWITH_GLUTCONTEXT=ON + -DWITH_GLUTWINDOWCONTEXT=ON make make install @@ -59,7 +62,7 @@ If you want to build also unit tests (which are not built by default), pass `-DBUILD_TESTS=True` to CMake. Unit tests use Corrade's TestSuite framework and can be run using - ctest -V + ctest --output-on-failure in build directory. Everything should pass ;-) diff --git a/doc/building.dox b/doc/building.dox index 5153bf4b4..a3beb30d6 100644 --- a/doc/building.dox +++ b/doc/building.dox @@ -37,13 +37,14 @@ subdirectory: git submodule update @section building-compilation Compilation, installation -The library (for example with GLUT context) can be built and installed using -these four commands. See below for more information about optional features. +The library (for example with GLUT window context) can be built and installed +using these four commands. See below for more information about optional +features. mkdir -p build && cd build cmake .. \ -DCMAKE_INSTALL_PREFIX=/usr \ - -DWITH_GLUTCONTEXT=ON + -DWITH_GLUTWINDOWCONTEXT=ON make make install @@ -59,29 +60,31 @@ By default the engine is built with everything except @ref Contexts "context libraries". Using `WITH_*` CMake parameters you can specify which parts will be built and which not: - - `WITH_EVERYTHING` - Defaults to `ON`, builds everything except contexts. If - set to `OFF`, only the main library is built and you can select additional - libraries with the following: + - `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_SHADERS` - Shaders library. -None of the context libraries is built by default, regardless to +None of the window context libraries is built by default, regardless to `WITH_EVERYTHING` is enabled or not: - - `WITH_EGLCONTEXT` - X/EGL context, available only if targeting OpenGL ES - (see above). Requires **X11** and **EGL** libraries. - - `WITH_GLUTCONTEXT` - GLUT context, available only if targeting desktop - OpenGL. Requires **GLUT** library. - - `WITH_SDL2CONTEXT` - SDL2 context. Requires **SDL2** library. + - `WITH_XEGLWINDOWCONTEXT` - X/EGL window context, available only if + targeting OpenGL ES (see above). Requires **X11** and **EGL** libraries. + - `WITH_GLXWINDOWCONTEXT` - GLX window context. Requires **X11** and **GLX** + libraries. + - `WITH_GLUTWINDOWCONTEXT` - GLUT window context, available only if targeting + desktop OpenGL. Requires **GLUT** library. + - `WITH_SDL2WINDOWCONTEXT` - SDL2 window context. Requires **SDL2** library. @subsection building-tests Building and running unit tests If you want to build also unit tests (which are not built by default), pass `-DBUILD_TESTS=True` to CMake. Unit tests use Corrade's @ref Corrade::TestSuite "TestSuite" framework and can be run using - ctest -V + ctest --output-on-failure in build directory. Everything should pass ;-) diff --git a/doc/coding-style.dox b/doc/coding-style.dox index 09fbdcb80..74ea08d2b 100644 --- a/doc/coding-style.dox +++ b/doc/coding-style.dox @@ -57,7 +57,39 @@ with @c \@extension command: @extension{ARB,timer_query} @endcode It produces link to the specification of the extension in OpenGL registry, -e.g. @extension{ARB,timer_query}. +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: +@code +@es_extension2{NV,read_buffer_front,GL_NV_read_buffer} +@endcode + +@subsubsection documentation-commands-ref_gl Links to related OpenGL functions and definitions + +If an function touches OpenGL, related OpenGL functions should be documented +in @c \@see block with @c \@fn_gl command. If only specific definition is used +in the function, document it with @c \@def_gl command. Example usage: +@code +// @see @fn_gl{Enable}/@fn_gl{Disable} with @def_gl{TEXTURE_CUBE_MAP_SEAMLESS} +inline static void setSeamless(bool enabled) { + 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}. + +For functions which are not part of OpenGL core specification, but only as +extensions, use @c \@fn_gl_extension command, e.g. +@code +@fn_gl_extension{NamedCopyBufferSubData,EXT,direct_state_access} +@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}. @subsubsection documentation-commands-requires Classes and functions requiring specific OpenGL version or extensions @@ -77,6 +109,14 @@ function, only the function should be marked. If the extension is needed only for some functionality (not related to any member function), it should be noted in the description. +Similarly for OpenGL ES there is command @c \@requires_gl for functionality +not available in OpenGL ES at all, @c \@requires_gles30 for functionality +requiring OpenGL ES 3.0 (i.e. not part of OpenGL 2.0) and +@c \@requires_es_extension for specific extensions not part of OpenGL ES +specification. When there is both required desktop OpenGL version/extension +and OpenGL ES version/extension, first come desktop requirements, then ES +requirements. + All classes and functions using those commands are cross-referenced in page @ref required-extensions. diff --git a/doc/collision-detection.dox b/doc/collision-detection.dox index bde0bd606..033f7607d 100644 --- a/doc/collision-detection.dox +++ b/doc/collision-detection.dox @@ -5,56 +5,60 @@ namespace Magnum { namespace Physics { The essential thing in collision detection is to define a complex object with collection of simple shapes, for which it is easy to detect collisions. These shapes can be either one-, two- or three-dimensional and they can be grouped -together using five different set operations. +together using various operations. @tableofcontents -@section CollisionDetectionShapeCollection Available shapes +@section collision-detection-shape-collection Available shapes -@subsection CollisionDetectionShapes1D One-dimensional shapes +@subsection collision-detection-shapes1D One-dimensional shapes -- Physics::Point - @copybrief Physics::Point -- Physics::Line - @copybrief Physics::Line -- Physics::LineSegment - @copybrief Physics::LineSegment +- @ref Physics::Point "Physics::Point*D" - @copybrief Physics::Point +- @ref Physics::Line "Physics::Line*D" - @copybrief Physics::Line +- @ref Physics::LineSegment "Physics::LineSegment*D" - @copybrief Physics::LineSegment -One-dimensional shapes don't provide collision detection with each other -because of numerical instability. +Because of numerical instability it's not possible to detect collisions of +line and point. Collision of two lines can be detected only in 2D. -@subsection CollisionDetectionShapes2D Two-dimensional shapes +@subsection collision-detection-shapes2D Two-dimensional shapes - Physics::Plane - @copybrief Physics::Plane -@subsection CollisionDetectionShapes3D Three-dimensional shapes +@subsection collision-detection-shapes3D Three-dimensional shapes -- Physics::Sphere - @copybrief Physics::Sphere -- Physics::Capsule - @copybrief Physics::Capsule -- Physics::AxisAlignedBox - @copybrief Physics::AxisAlignedBox -- Physics::Box - @copybrief Physics::Box +- @ref Physics::Sphere "Physics::Sphere*D" - @copybrief Physics::Sphere +- @ref Physics::Capsule "Physics::Capsule*D" - @copybrief Physics::Capsule +- @ref Physics::AxisAlignedBox "Physics::AxisAlignedBox*D" - @copybrief Physics::AxisAlignedBox +- @ref Physics::Box "Physics::Box*D" - @copybrief Physics::Box The easiest (and most efficient) shape combination for detecting collisions is point and sphere, followed by two spheres. Computing collision of two boxes is least efficient. -@section CollisionDetectionShapeGroups Creating hierarchic groups of shapes +@section collision-detection-shape-groups Creating hierarchic groups of shapes -Shapes can be grouped together using one of five set operations: complement, -union, intersection, difference and XOR. These operations are mapped to -operator~(), operator|(), operator&(), operator-() and operator^(), so for -example creating complement of union of sphere and box is simple as this: +Shapes can be grouped together using one of three available logical +operations: AND, OR and NOT. These operations are mapped to operator&&(), +operator||() and operator!(), so for example creating negation of logical OR +of line segment and point is simple as this: @code -Physics::Sphere sphere; -Physics::Box box; +Physics::LineSegment3D segment; +Physics::Point3D point; -Physics::ShapeGroup group = ~(sphere|box); +Physics::ShapeGroup3D group = !(segment || point); @endcode +@note Logical operations are not the same as set operations -- intersection of + two spheres will not generate any collision if they are disjoint, but + logical AND will if the object collides with both of them. + The resulting object internally stores copies of both shapes, so the original instances can be destroyed. For simple combinations appropriate resulting -shape is generated (e.g. intersection of line and three-dimensional object -can be a line segment) and stored inside ShapeGroup instead of two original +shape is generated (e.g. logical OR of point and sphere can be only the sphere, +if the point lies inside) and stored inside ShapeGroup instead of two original objects. -@subsection CollisionDetectionShapeReference Referencing the shapes for later changes +@subsection collision-detection-shape-reference Referencing the shapes for later changes Sometimes you may want to modify the shape based on changes of the object itself. In previous example all the shapes were copied into ShapeGroup, so it @@ -62,40 +66,42 @@ was not possible to change their properties such as sphere radius without recreating the group again. You can, however, explicitly pass a reference to original object, so you can change it later: @code -Physics::Sphere sphere; -Physics::Box box; +Physics::LineSegment3D segment; +Physics::Point3D point; -Physics::ShapeGroup group = ~(std::ref(sphere)|box); +Physics::ShapeGroup3D group = !(segment || std::ref(point)); -sphere.setRadius(2.0f); +point.setPosition({1.0f, -6.0f, 0.5f}); @endcode Note that passing a reference implies that you must not destroy the original -instance (in this case the sphere). Also because the referenced instance could +instance (in this case the point). Also because the referenced instance could change, there are no shape optimizations done, unlike above. -@subsection CollisionDetectionShapeSimplification Providing simplified version of shape for better performance +@subsection collision-detection-shape-simplification Providing simplified version of shape for better performance If there are many shapes grouped together, it might hurt performance of collision detection, because it might be testing collision with more shapes than necessary. It's then good to specify simplified version of such shape, so the collision detection is done on the original if and only if collision -was detected with the simplified shape. It is in fact intersection group - -the collision is initially detected on first (simplified) shape and then on -the other: +was detected with the simplified shape. It is in fact logical AND using +operator&&() - the collision is initially detected on first (simplified) shape +and then on the other: @code -Physics::AxisAlignedBox simplified; +Physics::Sphere3D sphere; +Physics::Box3D box; +Physics::AxisAlignedBox3D simplified; -Physics::ShapeGroup object = simplified & (sphere|box); +Physics::ShapeGroup3D object = simplified && (sphere || box); @endcode -@section CollisionDetectionShapeCollisions Detecting shape collisions +@section collision-detection-shape-collisions Detecting shape collisions Shape pairs which have collision detection implemented can be tested for collision using operator%(), for example: @code -Physics::Point point; -Physics::Sphere sphere; +Physics::Point3D point; +Physics::Sphere3D sphere; bool collide = point % sphere; @endcode diff --git a/doc/features.dox b/doc/features.dox new file mode 100644 index 000000000..27da4a060 --- /dev/null +++ b/doc/features.dox @@ -0,0 +1,8 @@ +namespace Magnum { +/** @page features Feature overview +@brief Fundamental principles and design goals + +- @subpage matrix-vector - @copybrief matrix-vector +- @subpage collision-detection - @copybrief collision-detection +*/ +} diff --git a/doc/mainpage.dox b/doc/mainpage.dox index 093bcf0ce..3894d8a1f 100644 --- a/doc/mainpage.dox +++ b/doc/mainpage.dox @@ -4,22 +4,26 @@ namespace Magnum { %Magnum is 3D graphics engine written in C++11 and OpenGL 3 Core Profile. Features: -- Easy-to-use templated @ref Math "mathematical library" for matrix/vector - calculations and @ref Math::Geometry "geometry". +- 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, classes for convenient usage of - @ref AbstractShaderProgram "shaders", @ref Buffer "buffers" and - @ref AbstractTexture "textures". Access to @ref Framebuffer "framebuffer" - and @ref AbstractQuery "occlusion queries". -- @ref Physics "Physics library" for collision detection and rigid body - dynamics, @ref MeshTools "Mesh tools" for cleaning, optimizing and - generating meshes. + 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 easy creation of OpenGL context with @ref Contexts - "various toolkits". + "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. @@ -34,21 +38,20 @@ Guide @ref building "how to download and build Magnum" on different platforms. @section getting-started Getting started -Applications using %Magnum have at least two parts. One part manages OpenGL -context using some toolkit and takes care of window resizing, mouse and -keyboard input, while the other manages the scene and does the rendering. -While it is possible for you to manage the OpenGL context and events on your -own, %Magnum provides implementations for the most common toolkits (such as -GLUT, SDL or Qt) in Contexts namespace. %Scene in %Magnum is composed of -hierarchically connected object instances. To build the scene you need Scene -object with assigned camera and at least one Object instance. +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 +Contexts namespace. + +Then you can either draw your meshes directly or use SceneGraph which will +help you with object hierarchy, transformations and resource management. @subsection getting-started-examples Tutorials and examples -The best way to get started is to @ref examples-triangle "render your first triangle" -in step-by-step tutorial. Then you can dig deeper and try @ref example-index -"other examples", read about fundamental principles in the documentation or -start experimenting on your own! +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 diff --git a/doc/matrix-vector.dox b/doc/matrix-vector.dox new file mode 100644 index 000000000..6b05b00c3 --- /dev/null +++ b/doc/matrix-vector.dox @@ -0,0 +1,181 @@ +namespace Magnum { namespace Math { +/** @page matrix-vector Operations with matrices and vectors + +@brief Introduction to essential classes of the graphics pipeline. + +@tableofcontents + +Matrices and vectors are the most important part of graphics programming and +one of goals of %Magnum is to make their usage as intuitive as possible. This +page will overview their usage and introduce some tricks to make your life +easier. + +@section matrix-vector-hierarchy Matrix and vector classes + +%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. + +Each subclass brings some specialization to its superclass and for most common +vector and matrix sizes there are specialized classes Matrix3 and Matrix4, +implementing various transformation in 2D and 3D, Vector2, Vector3 and Vector4, +implementing direct access to named components. Functions of each class try to +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. + +@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. +@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 + +Point2D c; // {0, 0, 1} +Point3D d; // {0, 0, 0, 1} + +Color4 black1; // {0.0f, 0.0f, 0.0f, 1.0f} +Color4 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. +@code +Matrix3 mat(0, 1, 2, + 3, 4, 5, + 6, 7, 8); // column-major (see explanation why below) + +Vector3 vec(0, 1, 2); +@endcode +All constructors check number of passed arguments and the errors are catched +at compile time. + +You can specify all components of vector or whole diagonal of square matrix at +once: +@code +Matrix3 diag(Matrix3::Identity, 2); // diagonal set to 2, zeros elsewhere +Vector3 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} +@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 b, c; +Matrix3 mat = Matrix3::from(b, a, c); +Vector<8, int> vec = Vector<8, int>::from(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, + 1, 3, 5 }; +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: +@code +Vector4 floating(1.3f, 2.7f, -15.0f, 7.0f); +Vector4 integral(Vector4::from(floating)); // {1, 2, -15, 7} +@endcode + +@section matrix-vector-component-access Accessing matrix and vector components + +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; +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; +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. + +Fixed-size vector subclasses have functions for accessing named components +and subparts: +@code +Vector4 a; +int x = a.x(); +a.y() += 5; + +Vector3 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: +@code +Vector4 original(-1, 2, 3, 4); +Vector4 bgra = swizzle<'b', 'g', 'r', 'a'>(original); // { 3, 2, -1, 4 } +Vector<6, int> a10rgb = swizzle(original, "a10rgb"); // { 4, 1, 0, -1, 2, 3 } +@endcode + +@section matrix-vector-column-major Matrices are column-major and vectors are columns + +OpenGL matrices are column-major, thus it is reasonable to have matrices in +%Magnum also column major (and vectors as columns). This has naturally some +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 +@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: +@code +Matrix3 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. +@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 +@endcode +- Various algorithms which commonly operate on matrix rows (such as + @ref Algorithms::GaussJordan "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. +*/ +}} diff --git a/doc/namespaces.dox b/doc/namespaces.dox index faf2cb178..6c1ff042a 100644 --- a/doc/namespaces.dox +++ b/doc/namespaces.dox @@ -25,7 +25,8 @@ Base classes for creating OpenGL contexts with various toolkits. /** @namespace Magnum::Math @brief %Math library -Template classes for matrix and vector calculations. +Template classes for matrix and vector calculations. See @ref matrix-vector +for brief introduction. */ /** @dir Math/Algorithms @@ -89,7 +90,7 @@ Collection of shaders for testing purposes. /** @namespace Magnum::Physics @brief %Physics library -Collision detection system and rigid body objects. See @ref physics +Collision detection system and rigid body objects. See @ref collision-detection for introduction. */ diff --git a/doc/physics.dox b/doc/physics.dox deleted file mode 100644 index 6a914c457..000000000 --- a/doc/physics.dox +++ /dev/null @@ -1,7 +0,0 @@ -namespace Magnum { namespace Physics { -/** @page physics Physics library -@brief Collision detection and rigid body dynamics. - -@subpage collision-detection -*/ -}} diff --git a/doc/required-extensions.dox b/doc/required-extensions.dox index 443109d1a..58a47ebfc 100644 --- a/doc/required-extensions.dox +++ b/doc/required-extensions.dox @@ -12,7 +12,6 @@ functionality, so if given hardware supports required extension, it doesn't need to have required OpenGL version too (e.g. `APPLE_vertex_array_object` is supported on Intel GPUs even if they are capable of OpenGL 2.1 only). -- @subpage requires-gl - @subpage requires-gl30 - @subpage requires-gl31 - @subpage requires-gl32 @@ -22,8 +21,10 @@ supported on Intel GPUs even if they are capable of OpenGL 2.1 only). - @subpage requires-gl42 - @subpage requires-gl43 - @subpage requires-extension +- @subpage requires-gl - @subpage requires-gles30 - @subpage requires-es-extension +- @subpage unsupported @page requires-gl Functionality requiring desktop OpenGL (not available on OpenGL ES) @page requires-gl30 Functionality requiring OpenGL 3.0 diff --git a/doc/unsupported.dox b/doc/unsupported.dox new file mode 100644 index 000000000..4d6ae1232 --- /dev/null +++ b/doc/unsupported.dox @@ -0,0 +1,22 @@ +/** @page unsupported Unsupported OpenGL features + +Some functionality, which is either soon-to-be deprecated or isn't proven to +add any performance gains, is not supported in %Magnum. + +@section unsupported-features Unsupported features + +- Luminance texture formats (OpenGL ES) are not supported, as they are + deprecated in OpenGL ES 3.0 and not present in core desktop OpenGL. +- Fixed precision data types (OpenGL ES) are not supported, as they occupy the + same memory as floats and they aren't faster than floats on current hardware + anymore. + +@section unsupported-extensions Unsupported extensions + +- @extension{INTEL,map_texture} negatively affects texture access performance. + Combination of buffer mapping and pixel buffers might be of the same or + better performance, without affecting texture access speed. +- @extension{NV,draw_texture} can be done with framebuffer blitting and + doesn't make any full-screen postprocessing easier, as shaders are excluded. + +*/ diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt new file mode 100644 index 000000000..a24503e8b --- /dev/null +++ b/external/CMakeLists.txt @@ -0,0 +1,6 @@ +if(NOT TARGET_GLES) + add_subdirectory(GL) +else() + add_subdirectory(GLES3) + add_subdirectory(KHR) +endif() diff --git a/external/GL/CMakeLists.txt b/external/GL/CMakeLists.txt new file mode 100644 index 000000000..a24337831 --- /dev/null +++ b/external/GL/CMakeLists.txt @@ -0,0 +1 @@ +install(FILES glcorearb.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/external/GL) diff --git a/external/GL/glcorearb.h b/external/GL/glcorearb.h new file mode 100644 index 000000000..e8474135e --- /dev/null +++ b/external/GL/glcorearb.h @@ -0,0 +1,4552 @@ +#ifndef __glcorearb_h_ +#define __glcorearb_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2007-2012 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* glcorearb.h replaces gl3.h. It is for use with OpenGL core + * profile implementations. + * + * glcorearb.h last updated on $Date: 2012-08-13 16:18:01 -0700 (Mon, 13 Aug 2012) $ + * + * RELEASE NOTES - 2012/08/13 + * + * glcorearb.h should be placed in the same directory as gl.h and + * included as + * ''. + * + * gl3.h includes only APIs in the latest OpenGL core profile + * implementation together with APIs in newer ARB extensions which can be + * can be supported by the core profile. It does not, and never will + * include functionality removed from the core profile, such as + * fixed-function vertex and fragment processing. + * + * It is not possible to #include both and either of + * or in the same source file. + * + * Feedback can be given by register for the Khronos Bugzilla + * (www.khronos.org/bugzilla) and filing issues there under product + * "OpenGL", category "Registry". + */ + +/* Function declaration macros - to move into glplatform.h */ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) +#define WIN32_LEAN_AND_MEAN 1 +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif +#ifndef GLAPI +#define GLAPI extern +#endif + +/* Base GL types */ + +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef signed char GLbyte; +typedef short GLshort; +typedef int GLint; +typedef int GLsizei; +typedef unsigned char GLubyte; +typedef unsigned short GLushort; +typedef unsigned int GLuint; +typedef unsigned short GLhalf; +typedef float GLfloat; +typedef float GLclampf; +typedef double GLdouble; +typedef double GLclampd; +typedef void GLvoid; + +/*************************************************************/ + +#ifndef GL_VERSION_1_1 +/* AttribMask */ +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_COLOR_BUFFER_BIT 0x00004000 +/* Boolean */ +#define GL_FALSE 0 +#define GL_TRUE 1 +/* BeginMode */ +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +/* AlphaFunction */ +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 +/* BlendingFactorDest */ +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +/* BlendingFactorSrc */ +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +/* DrawBufferMode */ +#define GL_NONE 0 +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_RIGHT 0x0403 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_LEFT 0x0406 +#define GL_RIGHT 0x0407 +#define GL_FRONT_AND_BACK 0x0408 +/* ErrorCode */ +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_OUT_OF_MEMORY 0x0505 +/* FrontFaceDirection */ +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +/* GetPName */ +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_RANGE 0x0B12 +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINE_WIDTH_RANGE 0x0B22 +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_VIEWPORT 0x0BA2 +#define GL_DITHER 0x0BD0 +#define GL_BLEND_DST 0x0BE0 +#define GL_BLEND_SRC 0x0BE1 +#define GL_BLEND 0x0BE2 +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_READ_BUFFER 0x0C02 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_STEREO 0x0C33 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_2D 0x8069 +/* GetTextureParameter */ +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_ALPHA_SIZE 0x805F +/* HintMode */ +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 +/* DataType */ +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_DOUBLE 0x140A +/* ErrorCode */ +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +/* LogicOp */ +#define GL_CLEAR 0x1500 +#define GL_AND 0x1501 +#define GL_AND_REVERSE 0x1502 +#define GL_COPY 0x1503 +#define GL_AND_INVERTED 0x1504 +#define GL_NOOP 0x1505 +#define GL_XOR 0x1506 +#define GL_OR 0x1507 +#define GL_NOR 0x1508 +#define GL_EQUIV 0x1509 +#define GL_INVERT 0x150A +#define GL_OR_REVERSE 0x150B +#define GL_COPY_INVERTED 0x150C +#define GL_OR_INVERTED 0x150D +#define GL_NAND 0x150E +#define GL_SET 0x150F +/* MatrixMode (for gl3.h, FBO attachment type) */ +#define GL_TEXTURE 0x1702 +/* PixelCopyType */ +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +/* PixelFormat */ +#define GL_STENCIL_INDEX 0x1901 +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_RED 0x1903 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +/* PolygonMode */ +#define GL_POINT 0x1B00 +#define GL_LINE 0x1B01 +#define GL_FILL 0x1B02 +/* StencilOp */ +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +/* StringName */ +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 +/* TextureMagFilter */ +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 +/* TextureMinFilter */ +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +/* TextureParameterName */ +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +/* TextureTarget */ +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +/* TextureWrapMode */ +#define GL_REPEAT 0x2901 +/* PixelInternalFormat */ +#define GL_R3_G3_B2 0x2A10 +#define GL_RGB4 0x804F +#define GL_RGB5 0x8050 +#define GL_RGB8 0x8051 +#define GL_RGB10 0x8052 +#define GL_RGB12 0x8053 +#define GL_RGB16 0x8054 +#define GL_RGBA2 0x8055 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_RGBA12 0x805A +#define GL_RGBA16 0x805B +#endif + +#ifndef GL_VERSION_1_2 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#endif + +#ifndef GL_ARB_imaging +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_FUNC_ADD 0x8006 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_BLEND_EQUATION 0x8009 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#endif + +#ifndef GL_VERSION_1_3 +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_CLAMP_TO_BORDER 0x812D +#endif + +#ifndef GL_VERSION_1_4 +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_LOD_BIAS 0x8501 +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#endif + +#ifndef GL_VERSION_1_5 +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_SAMPLES_PASSED 0x8914 +#endif + +#ifndef GL_VERSION_2_0 +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_SHADER_TYPE 0x8B4F +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_DELETE_STATUS 0x8B80 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#endif + +#ifndef GL_VERSION_2_1 +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#endif + +#ifndef GL_VERSION_3_0 +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_CLIP_DISTANCE0 0x3000 +#define GL_CLIP_DISTANCE1 0x3001 +#define GL_CLIP_DISTANCE2 0x3002 +#define GL_CLIP_DISTANCE3 0x3003 +#define GL_CLIP_DISTANCE4 0x3004 +#define GL_CLIP_DISTANCE5 0x3005 +#define GL_CLIP_DISTANCE6 0x3006 +#define GL_CLIP_DISTANCE7 0x3007 +#define GL_MAX_CLIP_DISTANCES 0x0D32 +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_CONTEXT_FLAGS 0x821E +#define GL_COMPRESSED_RED 0x8225 +#define GL_COMPRESSED_RG 0x8226 +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_CLAMP_READ_COLOR 0x891C +#define GL_FIXED_ONLY 0x891D +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_TEXTURE_1D_ARRAY 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_RGB9_E5 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_RGBA32UI 0x8D70 +#define GL_RGB32UI 0x8D71 +#define GL_RGBA16UI 0x8D76 +#define GL_RGB16UI 0x8D77 +#define GL_RGBA8UI 0x8D7C +#define GL_RGB8UI 0x8D7D +#define GL_RGBA32I 0x8D82 +#define GL_RGB32I 0x8D83 +#define GL_RGBA16I 0x8D88 +#define GL_RGB16I 0x8D89 +#define GL_RGBA8I 0x8D8E +#define GL_RGB8I 0x8D8F +#define GL_RED_INTEGER 0x8D94 +#define GL_GREEN_INTEGER 0x8D95 +#define GL_BLUE_INTEGER 0x8D96 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_BGR_INTEGER 0x8D9A +#define GL_BGRA_INTEGER 0x8D9B +#define GL_SAMPLER_1D_ARRAY 0x8DC0 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_INT_SAMPLER_1D 0x8DC9 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_QUERY_WAIT 0x8E13 +#define GL_QUERY_NO_WAIT 0x8E14 +#define GL_QUERY_BY_REGION_WAIT 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +/* Reuse tokens from ARB_depth_buffer_float */ +/* reuse GL_DEPTH_COMPONENT32F */ +/* reuse GL_DEPTH32F_STENCIL8 */ +/* reuse GL_FLOAT_32_UNSIGNED_INT_24_8_REV */ +/* Reuse tokens from ARB_framebuffer_object */ +/* reuse GL_INVALID_FRAMEBUFFER_OPERATION */ +/* reuse GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING */ +/* reuse GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE */ +/* reuse GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */ +/* reuse GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE */ +/* reuse GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE */ +/* reuse GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE */ +/* reuse GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE */ +/* reuse GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */ +/* reuse GL_FRAMEBUFFER_DEFAULT */ +/* reuse GL_FRAMEBUFFER_UNDEFINED */ +/* reuse GL_DEPTH_STENCIL_ATTACHMENT */ +/* reuse GL_INDEX */ +/* reuse GL_MAX_RENDERBUFFER_SIZE */ +/* reuse GL_DEPTH_STENCIL */ +/* reuse GL_UNSIGNED_INT_24_8 */ +/* reuse GL_DEPTH24_STENCIL8 */ +/* reuse GL_TEXTURE_STENCIL_SIZE */ +/* reuse GL_TEXTURE_RED_TYPE */ +/* reuse GL_TEXTURE_GREEN_TYPE */ +/* reuse GL_TEXTURE_BLUE_TYPE */ +/* reuse GL_TEXTURE_ALPHA_TYPE */ +/* reuse GL_TEXTURE_DEPTH_TYPE */ +/* reuse GL_UNSIGNED_NORMALIZED */ +/* reuse GL_FRAMEBUFFER_BINDING */ +/* reuse GL_DRAW_FRAMEBUFFER_BINDING */ +/* reuse GL_RENDERBUFFER_BINDING */ +/* reuse GL_READ_FRAMEBUFFER */ +/* reuse GL_DRAW_FRAMEBUFFER */ +/* reuse GL_READ_FRAMEBUFFER_BINDING */ +/* reuse GL_RENDERBUFFER_SAMPLES */ +/* reuse GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */ +/* reuse GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */ +/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */ +/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */ +/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */ +/* reuse GL_FRAMEBUFFER_COMPLETE */ +/* reuse GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */ +/* reuse GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */ +/* reuse GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER */ +/* reuse GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER */ +/* reuse GL_FRAMEBUFFER_UNSUPPORTED */ +/* reuse GL_MAX_COLOR_ATTACHMENTS */ +/* reuse GL_COLOR_ATTACHMENT0 */ +/* reuse GL_COLOR_ATTACHMENT1 */ +/* reuse GL_COLOR_ATTACHMENT2 */ +/* reuse GL_COLOR_ATTACHMENT3 */ +/* reuse GL_COLOR_ATTACHMENT4 */ +/* reuse GL_COLOR_ATTACHMENT5 */ +/* reuse GL_COLOR_ATTACHMENT6 */ +/* reuse GL_COLOR_ATTACHMENT7 */ +/* reuse GL_COLOR_ATTACHMENT8 */ +/* reuse GL_COLOR_ATTACHMENT9 */ +/* reuse GL_COLOR_ATTACHMENT10 */ +/* reuse GL_COLOR_ATTACHMENT11 */ +/* reuse GL_COLOR_ATTACHMENT12 */ +/* reuse GL_COLOR_ATTACHMENT13 */ +/* reuse GL_COLOR_ATTACHMENT14 */ +/* reuse GL_COLOR_ATTACHMENT15 */ +/* reuse GL_DEPTH_ATTACHMENT */ +/* reuse GL_STENCIL_ATTACHMENT */ +/* reuse GL_FRAMEBUFFER */ +/* reuse GL_RENDERBUFFER */ +/* reuse GL_RENDERBUFFER_WIDTH */ +/* reuse GL_RENDERBUFFER_HEIGHT */ +/* reuse GL_RENDERBUFFER_INTERNAL_FORMAT */ +/* reuse GL_STENCIL_INDEX1 */ +/* reuse GL_STENCIL_INDEX4 */ +/* reuse GL_STENCIL_INDEX8 */ +/* reuse GL_STENCIL_INDEX16 */ +/* reuse GL_RENDERBUFFER_RED_SIZE */ +/* reuse GL_RENDERBUFFER_GREEN_SIZE */ +/* reuse GL_RENDERBUFFER_BLUE_SIZE */ +/* reuse GL_RENDERBUFFER_ALPHA_SIZE */ +/* reuse GL_RENDERBUFFER_DEPTH_SIZE */ +/* reuse GL_RENDERBUFFER_STENCIL_SIZE */ +/* reuse GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */ +/* reuse GL_MAX_SAMPLES */ +/* Reuse tokens from ARB_framebuffer_sRGB */ +/* reuse GL_FRAMEBUFFER_SRGB */ +/* Reuse tokens from ARB_half_float_vertex */ +/* reuse GL_HALF_FLOAT */ +/* Reuse tokens from ARB_map_buffer_range */ +/* reuse GL_MAP_READ_BIT */ +/* reuse GL_MAP_WRITE_BIT */ +/* reuse GL_MAP_INVALIDATE_RANGE_BIT */ +/* reuse GL_MAP_INVALIDATE_BUFFER_BIT */ +/* reuse GL_MAP_FLUSH_EXPLICIT_BIT */ +/* reuse GL_MAP_UNSYNCHRONIZED_BIT */ +/* Reuse tokens from ARB_texture_compression_rgtc */ +/* reuse GL_COMPRESSED_RED_RGTC1 */ +/* reuse GL_COMPRESSED_SIGNED_RED_RGTC1 */ +/* reuse GL_COMPRESSED_RG_RGTC2 */ +/* reuse GL_COMPRESSED_SIGNED_RG_RGTC2 */ +/* Reuse tokens from ARB_texture_rg */ +/* reuse GL_RG */ +/* reuse GL_RG_INTEGER */ +/* reuse GL_R8 */ +/* reuse GL_R16 */ +/* reuse GL_RG8 */ +/* reuse GL_RG16 */ +/* reuse GL_R16F */ +/* reuse GL_R32F */ +/* reuse GL_RG16F */ +/* reuse GL_RG32F */ +/* reuse GL_R8I */ +/* reuse GL_R8UI */ +/* reuse GL_R16I */ +/* reuse GL_R16UI */ +/* reuse GL_R32I */ +/* reuse GL_R32UI */ +/* reuse GL_RG8I */ +/* reuse GL_RG8UI */ +/* reuse GL_RG16I */ +/* reuse GL_RG16UI */ +/* reuse GL_RG32I */ +/* reuse GL_RG32UI */ +/* Reuse tokens from ARB_vertex_array_object */ +/* reuse GL_VERTEX_ARRAY_BINDING */ +#endif + +#ifndef GL_VERSION_3_1 +#define GL_SAMPLER_2D_RECT 0x8B63 +#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 +#define GL_SAMPLER_BUFFER 0x8DC2 +#define GL_INT_SAMPLER_2D_RECT 0x8DCD +#define GL_INT_SAMPLER_BUFFER 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +#define GL_TEXTURE_BUFFER 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT 0x8C2E +#define GL_TEXTURE_RECTANGLE 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 +#define GL_RED_SNORM 0x8F90 +#define GL_RG_SNORM 0x8F91 +#define GL_RGB_SNORM 0x8F92 +#define GL_RGBA_SNORM 0x8F93 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_R16_SNORM 0x8F98 +#define GL_RG16_SNORM 0x8F99 +#define GL_RGB16_SNORM 0x8F9A +#define GL_RGBA16_SNORM 0x8F9B +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_PRIMITIVE_RESTART 0x8F9D +#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E +/* Reuse tokens from ARB_copy_buffer */ +/* reuse GL_COPY_READ_BUFFER */ +/* reuse GL_COPY_WRITE_BUFFER */ +/* Reuse tokens from ARB_draw_instanced (none) */ +/* Reuse tokens from ARB_uniform_buffer_object */ +/* reuse GL_UNIFORM_BUFFER */ +/* reuse GL_UNIFORM_BUFFER_BINDING */ +/* reuse GL_UNIFORM_BUFFER_START */ +/* reuse GL_UNIFORM_BUFFER_SIZE */ +/* reuse GL_MAX_VERTEX_UNIFORM_BLOCKS */ +/* reuse GL_MAX_FRAGMENT_UNIFORM_BLOCKS */ +/* reuse GL_MAX_COMBINED_UNIFORM_BLOCKS */ +/* reuse GL_MAX_UNIFORM_BUFFER_BINDINGS */ +/* reuse GL_MAX_UNIFORM_BLOCK_SIZE */ +/* reuse GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS */ +/* reuse GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS */ +/* reuse GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT */ +/* reuse GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH */ +/* reuse GL_ACTIVE_UNIFORM_BLOCKS */ +/* reuse GL_UNIFORM_TYPE */ +/* reuse GL_UNIFORM_SIZE */ +/* reuse GL_UNIFORM_NAME_LENGTH */ +/* reuse GL_UNIFORM_BLOCK_INDEX */ +/* reuse GL_UNIFORM_OFFSET */ +/* reuse GL_UNIFORM_ARRAY_STRIDE */ +/* reuse GL_UNIFORM_MATRIX_STRIDE */ +/* reuse GL_UNIFORM_IS_ROW_MAJOR */ +/* reuse GL_UNIFORM_BLOCK_BINDING */ +/* reuse GL_UNIFORM_BLOCK_DATA_SIZE */ +/* reuse GL_UNIFORM_BLOCK_NAME_LENGTH */ +/* reuse GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS */ +/* reuse GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES */ +/* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER */ +/* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER */ +/* reuse GL_INVALID_INDEX */ +#endif + +#ifndef GL_VERSION_3_2 +#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 +#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 +#define GL_LINES_ADJACENCY 0x000A +#define GL_LINE_STRIP_ADJACENCY 0x000B +#define GL_TRIANGLES_ADJACENCY 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D +#define GL_PROGRAM_POINT_SIZE 0x8642 +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +#define GL_GEOMETRY_SHADER 0x8DD9 +#define GL_GEOMETRY_VERTICES_OUT 0x8916 +#define GL_GEOMETRY_INPUT_TYPE 0x8917 +#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_CONTEXT_PROFILE_MASK 0x9126 +/* reuse GL_MAX_VARYING_COMPONENTS */ +/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */ +/* Reuse tokens from ARB_depth_clamp */ +/* reuse GL_DEPTH_CLAMP */ +/* Reuse tokens from ARB_draw_elements_base_vertex (none) */ +/* Reuse tokens from ARB_fragment_coord_conventions (none) */ +/* Reuse tokens from ARB_provoking_vertex */ +/* reuse GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */ +/* reuse GL_FIRST_VERTEX_CONVENTION */ +/* reuse GL_LAST_VERTEX_CONVENTION */ +/* reuse GL_PROVOKING_VERTEX */ +/* Reuse tokens from ARB_seamless_cube_map */ +/* reuse GL_TEXTURE_CUBE_MAP_SEAMLESS */ +/* Reuse tokens from ARB_sync */ +/* reuse GL_MAX_SERVER_WAIT_TIMEOUT */ +/* reuse GL_OBJECT_TYPE */ +/* reuse GL_SYNC_CONDITION */ +/* reuse GL_SYNC_STATUS */ +/* reuse GL_SYNC_FLAGS */ +/* reuse GL_SYNC_FENCE */ +/* reuse GL_SYNC_GPU_COMMANDS_COMPLETE */ +/* reuse GL_UNSIGNALED */ +/* reuse GL_SIGNALED */ +/* reuse GL_ALREADY_SIGNALED */ +/* reuse GL_TIMEOUT_EXPIRED */ +/* reuse GL_CONDITION_SATISFIED */ +/* reuse GL_WAIT_FAILED */ +/* reuse GL_TIMEOUT_IGNORED */ +/* reuse GL_SYNC_FLUSH_COMMANDS_BIT */ +/* reuse GL_TIMEOUT_IGNORED */ +/* Reuse tokens from ARB_texture_multisample */ +/* reuse GL_SAMPLE_POSITION */ +/* reuse GL_SAMPLE_MASK */ +/* reuse GL_SAMPLE_MASK_VALUE */ +/* reuse GL_MAX_SAMPLE_MASK_WORDS */ +/* reuse GL_TEXTURE_2D_MULTISAMPLE */ +/* reuse GL_PROXY_TEXTURE_2D_MULTISAMPLE */ +/* reuse GL_TEXTURE_2D_MULTISAMPLE_ARRAY */ +/* reuse GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY */ +/* reuse GL_TEXTURE_BINDING_2D_MULTISAMPLE */ +/* reuse GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY */ +/* reuse GL_TEXTURE_SAMPLES */ +/* reuse GL_TEXTURE_FIXED_SAMPLE_LOCATIONS */ +/* reuse GL_SAMPLER_2D_MULTISAMPLE */ +/* reuse GL_INT_SAMPLER_2D_MULTISAMPLE */ +/* reuse GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE */ +/* reuse GL_SAMPLER_2D_MULTISAMPLE_ARRAY */ +/* reuse GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY */ +/* reuse GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY */ +/* reuse GL_MAX_COLOR_TEXTURE_SAMPLES */ +/* reuse GL_MAX_DEPTH_TEXTURE_SAMPLES */ +/* reuse GL_MAX_INTEGER_SAMPLES */ +/* Don't need to reuse tokens from ARB_vertex_array_bgra since they're already in 1.2 core */ +#endif + +#ifndef GL_VERSION_3_3 +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +/* Reuse tokens from ARB_blend_func_extended */ +/* reuse GL_SRC1_COLOR */ +/* reuse GL_ONE_MINUS_SRC1_COLOR */ +/* reuse GL_ONE_MINUS_SRC1_ALPHA */ +/* reuse GL_MAX_DUAL_SOURCE_DRAW_BUFFERS */ +/* Reuse tokens from ARB_explicit_attrib_location (none) */ +/* Reuse tokens from ARB_occlusion_query2 */ +/* reuse GL_ANY_SAMPLES_PASSED */ +/* Reuse tokens from ARB_sampler_objects */ +/* reuse GL_SAMPLER_BINDING */ +/* Reuse tokens from ARB_shader_bit_encoding (none) */ +/* Reuse tokens from ARB_texture_rgb10_a2ui */ +/* reuse GL_RGB10_A2UI */ +/* Reuse tokens from ARB_texture_swizzle */ +/* reuse GL_TEXTURE_SWIZZLE_R */ +/* reuse GL_TEXTURE_SWIZZLE_G */ +/* reuse GL_TEXTURE_SWIZZLE_B */ +/* reuse GL_TEXTURE_SWIZZLE_A */ +/* reuse GL_TEXTURE_SWIZZLE_RGBA */ +/* Reuse tokens from ARB_timer_query */ +/* reuse GL_TIME_ELAPSED */ +/* reuse GL_TIMESTAMP */ +/* Reuse tokens from ARB_vertex_type_2_10_10_10_rev */ +/* reuse GL_INT_2_10_10_10_REV */ +#endif + +#ifndef GL_VERSION_4_0 +#define GL_SAMPLE_SHADING 0x8C36 +#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F +#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B +#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F +/* Reuse tokens from ARB_texture_query_lod (none) */ +/* Reuse tokens from ARB_draw_buffers_blend (none) */ +/* Reuse tokens from ARB_draw_indirect */ +/* reuse GL_DRAW_INDIRECT_BUFFER */ +/* reuse GL_DRAW_INDIRECT_BUFFER_BINDING */ +/* Reuse tokens from ARB_gpu_shader5 */ +/* reuse GL_GEOMETRY_SHADER_INVOCATIONS */ +/* reuse GL_MAX_GEOMETRY_SHADER_INVOCATIONS */ +/* reuse GL_MIN_FRAGMENT_INTERPOLATION_OFFSET */ +/* reuse GL_MAX_FRAGMENT_INTERPOLATION_OFFSET */ +/* reuse GL_FRAGMENT_INTERPOLATION_OFFSET_BITS */ +/* reuse GL_MAX_VERTEX_STREAMS */ +/* Reuse tokens from ARB_gpu_shader_fp64 */ +/* reuse GL_DOUBLE_VEC2 */ +/* reuse GL_DOUBLE_VEC3 */ +/* reuse GL_DOUBLE_VEC4 */ +/* reuse GL_DOUBLE_MAT2 */ +/* reuse GL_DOUBLE_MAT3 */ +/* reuse GL_DOUBLE_MAT4 */ +/* reuse GL_DOUBLE_MAT2x3 */ +/* reuse GL_DOUBLE_MAT2x4 */ +/* reuse GL_DOUBLE_MAT3x2 */ +/* reuse GL_DOUBLE_MAT3x4 */ +/* reuse GL_DOUBLE_MAT4x2 */ +/* reuse GL_DOUBLE_MAT4x3 */ +/* Reuse tokens from ARB_shader_subroutine */ +/* reuse GL_ACTIVE_SUBROUTINES */ +/* reuse GL_ACTIVE_SUBROUTINE_UNIFORMS */ +/* reuse GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS */ +/* reuse GL_ACTIVE_SUBROUTINE_MAX_LENGTH */ +/* reuse GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH */ +/* reuse GL_MAX_SUBROUTINES */ +/* reuse GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS */ +/* reuse GL_NUM_COMPATIBLE_SUBROUTINES */ +/* reuse GL_COMPATIBLE_SUBROUTINES */ +/* Reuse tokens from ARB_tessellation_shader */ +/* reuse GL_PATCHES */ +/* reuse GL_PATCH_VERTICES */ +/* reuse GL_PATCH_DEFAULT_INNER_LEVEL */ +/* reuse GL_PATCH_DEFAULT_OUTER_LEVEL */ +/* reuse GL_TESS_CONTROL_OUTPUT_VERTICES */ +/* reuse GL_TESS_GEN_MODE */ +/* reuse GL_TESS_GEN_SPACING */ +/* reuse GL_TESS_GEN_VERTEX_ORDER */ +/* reuse GL_TESS_GEN_POINT_MODE */ +/* reuse GL_ISOLINES */ +/* reuse GL_FRACTIONAL_ODD */ +/* reuse GL_FRACTIONAL_EVEN */ +/* reuse GL_MAX_PATCH_VERTICES */ +/* reuse GL_MAX_TESS_GEN_LEVEL */ +/* reuse GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS */ +/* reuse GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS */ +/* reuse GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS */ +/* reuse GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS */ +/* reuse GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS */ +/* reuse GL_MAX_TESS_PATCH_COMPONENTS */ +/* reuse GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS */ +/* reuse GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS */ +/* reuse GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS */ +/* reuse GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS */ +/* reuse GL_MAX_TESS_CONTROL_INPUT_COMPONENTS */ +/* reuse GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS */ +/* reuse GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS */ +/* reuse GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS */ +/* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER */ +/* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER */ +/* reuse GL_TESS_EVALUATION_SHADER */ +/* reuse GL_TESS_CONTROL_SHADER */ +/* Reuse tokens from ARB_texture_buffer_object_rgb32 (none) */ +/* Reuse tokens from ARB_transform_feedback2 */ +/* reuse GL_TRANSFORM_FEEDBACK */ +/* reuse GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED */ +/* reuse GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE */ +/* reuse GL_TRANSFORM_FEEDBACK_BINDING */ +/* Reuse tokens from ARB_transform_feedback3 */ +/* reuse GL_MAX_TRANSFORM_FEEDBACK_BUFFERS */ +/* reuse GL_MAX_VERTEX_STREAMS */ +#endif + +#ifndef GL_VERSION_4_1 +/* Reuse tokens from ARB_ES2_compatibility */ +/* reuse GL_FIXED */ +/* reuse GL_IMPLEMENTATION_COLOR_READ_TYPE */ +/* reuse GL_IMPLEMENTATION_COLOR_READ_FORMAT */ +/* reuse GL_LOW_FLOAT */ +/* reuse GL_MEDIUM_FLOAT */ +/* reuse GL_HIGH_FLOAT */ +/* reuse GL_LOW_INT */ +/* reuse GL_MEDIUM_INT */ +/* reuse GL_HIGH_INT */ +/* reuse GL_SHADER_COMPILER */ +/* reuse GL_NUM_SHADER_BINARY_FORMATS */ +/* reuse GL_MAX_VERTEX_UNIFORM_VECTORS */ +/* reuse GL_MAX_VARYING_VECTORS */ +/* reuse GL_MAX_FRAGMENT_UNIFORM_VECTORS */ +/* reuse GL_RGB565 */ +/* Reuse tokens from ARB_get_program_binary */ +/* reuse GL_PROGRAM_BINARY_RETRIEVABLE_HINT */ +/* reuse GL_PROGRAM_BINARY_LENGTH */ +/* reuse GL_NUM_PROGRAM_BINARY_FORMATS */ +/* reuse GL_PROGRAM_BINARY_FORMATS */ +/* Reuse tokens from ARB_separate_shader_objects */ +/* reuse GL_VERTEX_SHADER_BIT */ +/* reuse GL_FRAGMENT_SHADER_BIT */ +/* reuse GL_GEOMETRY_SHADER_BIT */ +/* reuse GL_TESS_CONTROL_SHADER_BIT */ +/* reuse GL_TESS_EVALUATION_SHADER_BIT */ +/* reuse GL_ALL_SHADER_BITS */ +/* reuse GL_PROGRAM_SEPARABLE */ +/* reuse GL_ACTIVE_PROGRAM */ +/* reuse GL_PROGRAM_PIPELINE_BINDING */ +/* Reuse tokens from ARB_shader_precision (none) */ +/* Reuse tokens from ARB_vertex_attrib_64bit - all are in GL 3.0 and 4.0 already */ +/* Reuse tokens from ARB_viewport_array - some are in GL 1.1 and ARB_provoking_vertex already */ +/* reuse GL_MAX_VIEWPORTS */ +/* reuse GL_VIEWPORT_SUBPIXEL_BITS */ +/* reuse GL_VIEWPORT_BOUNDS_RANGE */ +/* reuse GL_LAYER_PROVOKING_VERTEX */ +/* reuse GL_VIEWPORT_INDEX_PROVOKING_VERTEX */ +/* reuse GL_UNDEFINED_VERTEX */ +#endif + +#ifndef GL_VERSION_4_2 +/* Reuse tokens from ARB_base_instance (none) */ +/* Reuse tokens from ARB_shading_language_420pack (none) */ +/* Reuse tokens from ARB_transform_feedback_instanced (none) */ +/* Reuse tokens from ARB_compressed_texture_pixel_storage */ +/* reuse GL_UNPACK_COMPRESSED_BLOCK_WIDTH */ +/* reuse GL_UNPACK_COMPRESSED_BLOCK_HEIGHT */ +/* reuse GL_UNPACK_COMPRESSED_BLOCK_DEPTH */ +/* reuse GL_UNPACK_COMPRESSED_BLOCK_SIZE */ +/* reuse GL_PACK_COMPRESSED_BLOCK_WIDTH */ +/* reuse GL_PACK_COMPRESSED_BLOCK_HEIGHT */ +/* reuse GL_PACK_COMPRESSED_BLOCK_DEPTH */ +/* reuse GL_PACK_COMPRESSED_BLOCK_SIZE */ +/* Reuse tokens from ARB_conservative_depth (none) */ +/* Reuse tokens from ARB_internalformat_query */ +/* reuse GL_NUM_SAMPLE_COUNTS */ +/* Reuse tokens from ARB_map_buffer_alignment */ +/* reuse GL_MIN_MAP_BUFFER_ALIGNMENT */ +/* Reuse tokens from ARB_shader_atomic_counters */ +/* reuse GL_ATOMIC_COUNTER_BUFFER */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_BINDING */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_START */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_SIZE */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER */ +/* reuse GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS */ +/* reuse GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS */ +/* reuse GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS */ +/* reuse GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS */ +/* reuse GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS */ +/* reuse GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS */ +/* reuse GL_MAX_VERTEX_ATOMIC_COUNTERS */ +/* reuse GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS */ +/* reuse GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS */ +/* reuse GL_MAX_GEOMETRY_ATOMIC_COUNTERS */ +/* reuse GL_MAX_FRAGMENT_ATOMIC_COUNTERS */ +/* reuse GL_MAX_COMBINED_ATOMIC_COUNTERS */ +/* reuse GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE */ +/* reuse GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS */ +/* reuse GL_ACTIVE_ATOMIC_COUNTER_BUFFERS */ +/* reuse GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX */ +/* reuse GL_UNSIGNED_INT_ATOMIC_COUNTER */ +/* Reuse tokens from ARB_shader_image_load_store */ +/* reuse GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT */ +/* reuse GL_ELEMENT_ARRAY_BARRIER_BIT */ +/* reuse GL_UNIFORM_BARRIER_BIT */ +/* reuse GL_TEXTURE_FETCH_BARRIER_BIT */ +/* reuse GL_SHADER_IMAGE_ACCESS_BARRIER_BIT */ +/* reuse GL_COMMAND_BARRIER_BIT */ +/* reuse GL_PIXEL_BUFFER_BARRIER_BIT */ +/* reuse GL_TEXTURE_UPDATE_BARRIER_BIT */ +/* reuse GL_BUFFER_UPDATE_BARRIER_BIT */ +/* reuse GL_FRAMEBUFFER_BARRIER_BIT */ +/* reuse GL_TRANSFORM_FEEDBACK_BARRIER_BIT */ +/* reuse GL_ATOMIC_COUNTER_BARRIER_BIT */ +/* reuse GL_ALL_BARRIER_BITS */ +/* reuse GL_MAX_IMAGE_UNITS */ +/* reuse GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS */ +/* reuse GL_IMAGE_BINDING_NAME */ +/* reuse GL_IMAGE_BINDING_LEVEL */ +/* reuse GL_IMAGE_BINDING_LAYERED */ +/* reuse GL_IMAGE_BINDING_LAYER */ +/* reuse GL_IMAGE_BINDING_ACCESS */ +/* reuse GL_IMAGE_1D */ +/* reuse GL_IMAGE_2D */ +/* reuse GL_IMAGE_3D */ +/* reuse GL_IMAGE_2D_RECT */ +/* reuse GL_IMAGE_CUBE */ +/* reuse GL_IMAGE_BUFFER */ +/* reuse GL_IMAGE_1D_ARRAY */ +/* reuse GL_IMAGE_2D_ARRAY */ +/* reuse GL_IMAGE_CUBE_MAP_ARRAY */ +/* reuse GL_IMAGE_2D_MULTISAMPLE */ +/* reuse GL_IMAGE_2D_MULTISAMPLE_ARRAY */ +/* reuse GL_INT_IMAGE_1D */ +/* reuse GL_INT_IMAGE_2D */ +/* reuse GL_INT_IMAGE_3D */ +/* reuse GL_INT_IMAGE_2D_RECT */ +/* reuse GL_INT_IMAGE_CUBE */ +/* reuse GL_INT_IMAGE_BUFFER */ +/* reuse GL_INT_IMAGE_1D_ARRAY */ +/* reuse GL_INT_IMAGE_2D_ARRAY */ +/* reuse GL_INT_IMAGE_CUBE_MAP_ARRAY */ +/* reuse GL_INT_IMAGE_2D_MULTISAMPLE */ +/* reuse GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY */ +/* reuse GL_UNSIGNED_INT_IMAGE_1D */ +/* reuse GL_UNSIGNED_INT_IMAGE_2D */ +/* reuse GL_UNSIGNED_INT_IMAGE_3D */ +/* reuse GL_UNSIGNED_INT_IMAGE_2D_RECT */ +/* reuse GL_UNSIGNED_INT_IMAGE_CUBE */ +/* reuse GL_UNSIGNED_INT_IMAGE_BUFFER */ +/* reuse GL_UNSIGNED_INT_IMAGE_1D_ARRAY */ +/* reuse GL_UNSIGNED_INT_IMAGE_2D_ARRAY */ +/* reuse GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY */ +/* reuse GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE */ +/* reuse GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY */ +/* reuse GL_MAX_IMAGE_SAMPLES */ +/* reuse GL_IMAGE_BINDING_FORMAT */ +/* reuse GL_IMAGE_FORMAT_COMPATIBILITY_TYPE */ +/* reuse GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE */ +/* reuse GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS */ +/* reuse GL_MAX_VERTEX_IMAGE_UNIFORMS */ +/* reuse GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS */ +/* reuse GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS */ +/* reuse GL_MAX_GEOMETRY_IMAGE_UNIFORMS */ +/* reuse GL_MAX_FRAGMENT_IMAGE_UNIFORMS */ +/* reuse GL_MAX_COMBINED_IMAGE_UNIFORMS */ +/* Reuse tokens from ARB_shading_language_packing (none) */ +/* Reuse tokens from ARB_texture_storage */ +/* reuse GL_TEXTURE_IMMUTABLE_FORMAT */ +#endif + +#ifndef GL_VERSION_4_3 +#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 +#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E +/* Reuse tokens from ARB_arrays_of_arrays (none, GLSL only) */ +/* Reuse tokens from ARB_fragment_layer_viewport (none, GLSL only) */ +/* Reuse tokens from ARB_shader_image_size (none, GLSL only) */ +/* Reuse tokens from ARB_ES3_compatibility */ +/* reuse GL_COMPRESSED_RGB8_ETC2 */ +/* reuse GL_COMPRESSED_SRGB8_ETC2 */ +/* reuse GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 */ +/* reuse GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 */ +/* reuse GL_COMPRESSED_RGBA8_ETC2_EAC */ +/* reuse GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC */ +/* reuse GL_COMPRESSED_R11_EAC */ +/* reuse GL_COMPRESSED_SIGNED_R11_EAC */ +/* reuse GL_COMPRESSED_RG11_EAC */ +/* reuse GL_COMPRESSED_SIGNED_RG11_EAC */ +/* reuse GL_PRIMITIVE_RESTART_FIXED_INDEX */ +/* reuse GL_ANY_SAMPLES_PASSED_CONSERVATIVE */ +/* reuse GL_MAX_ELEMENT_INDEX */ +/* Reuse tokens from ARB_clear_buffer_object (none) */ +/* Reuse tokens from ARB_compute_shader */ +/* reuse GL_COMPUTE_SHADER */ +/* reuse GL_MAX_COMPUTE_UNIFORM_BLOCKS */ +/* reuse GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS */ +/* reuse GL_MAX_COMPUTE_IMAGE_UNIFORMS */ +/* reuse GL_MAX_COMPUTE_SHARED_MEMORY_SIZE */ +/* reuse GL_MAX_COMPUTE_UNIFORM_COMPONENTS */ +/* reuse GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS */ +/* reuse GL_MAX_COMPUTE_ATOMIC_COUNTERS */ +/* reuse GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS */ +/* reuse GL_MAX_COMPUTE_LOCAL_INVOCATIONS */ +/* reuse GL_MAX_COMPUTE_WORK_GROUP_COUNT */ +/* reuse GL_MAX_COMPUTE_WORK_GROUP_SIZE */ +/* reuse GL_COMPUTE_LOCAL_WORK_SIZE */ +/* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER */ +/* reuse GL_DISPATCH_INDIRECT_BUFFER */ +/* reuse GL_DISPATCH_INDIRECT_BUFFER_BINDING */ +/* Reuse tokens from ARB_copy_image (none) */ +/* Reuse tokens from KHR_debug */ +/* reuse GL_DEBUG_OUTPUT_SYNCHRONOUS */ +/* reuse GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH */ +/* reuse GL_DEBUG_CALLBACK_FUNCTION */ +/* reuse GL_DEBUG_CALLBACK_USER_PARAM */ +/* reuse GL_DEBUG_SOURCE_API */ +/* reuse GL_DEBUG_SOURCE_WINDOW_SYSTEM */ +/* reuse GL_DEBUG_SOURCE_SHADER_COMPILER */ +/* reuse GL_DEBUG_SOURCE_THIRD_PARTY */ +/* reuse GL_DEBUG_SOURCE_APPLICATION */ +/* reuse GL_DEBUG_SOURCE_OTHER */ +/* reuse GL_DEBUG_TYPE_ERROR */ +/* reuse GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR */ +/* reuse GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR */ +/* reuse GL_DEBUG_TYPE_PORTABILITY */ +/* reuse GL_DEBUG_TYPE_PERFORMANCE */ +/* reuse GL_DEBUG_TYPE_OTHER */ +/* reuse GL_MAX_DEBUG_MESSAGE_LENGTH */ +/* reuse GL_MAX_DEBUG_LOGGED_MESSAGES */ +/* reuse GL_DEBUG_LOGGED_MESSAGES */ +/* reuse GL_DEBUG_SEVERITY_HIGH */ +/* reuse GL_DEBUG_SEVERITY_MEDIUM */ +/* reuse GL_DEBUG_SEVERITY_LOW */ +/* reuse GL_DEBUG_TYPE_MARKER */ +/* reuse GL_DEBUG_TYPE_PUSH_GROUP */ +/* reuse GL_DEBUG_TYPE_POP_GROUP */ +/* reuse GL_DEBUG_SEVERITY_NOTIFICATION */ +/* reuse GL_MAX_DEBUG_GROUP_STACK_DEPTH */ +/* reuse GL_DEBUG_GROUP_STACK_DEPTH */ +/* reuse GL_BUFFER */ +/* reuse GL_SHADER */ +/* reuse GL_PROGRAM */ +/* reuse GL_QUERY */ +/* reuse GL_PROGRAM_PIPELINE */ +/* reuse GL_SAMPLER */ +/* reuse GL_DISPLAY_LIST */ +/* reuse GL_MAX_LABEL_LENGTH */ +/* reuse GL_DEBUG_OUTPUT */ +/* reuse GL_CONTEXT_FLAG_DEBUG_BIT */ +/* reuse GL_STACK_UNDERFLOW */ +/* reuse GL_STACK_OVERFLOW */ +/* Reuse tokens from ARB_explicit_uniform_location */ +/* reuse GL_MAX_UNIFORM_LOCATIONS */ +/* Reuse tokens from ARB_framebuffer_no_attachments */ +/* reuse GL_FRAMEBUFFER_DEFAULT_WIDTH */ +/* reuse GL_FRAMEBUFFER_DEFAULT_HEIGHT */ +/* reuse GL_FRAMEBUFFER_DEFAULT_LAYERS */ +/* reuse GL_FRAMEBUFFER_DEFAULT_SAMPLES */ +/* reuse GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS */ +/* reuse GL_MAX_FRAMEBUFFER_WIDTH */ +/* reuse GL_MAX_FRAMEBUFFER_HEIGHT */ +/* reuse GL_MAX_FRAMEBUFFER_LAYERS */ +/* reuse GL_MAX_FRAMEBUFFER_SAMPLES */ +/* Reuse tokens from ARB_internalformat_query2 */ +/* reuse GL_INTERNALFORMAT_SUPPORTED */ +/* reuse GL_INTERNALFORMAT_PREFERRED */ +/* reuse GL_INTERNALFORMAT_RED_SIZE */ +/* reuse GL_INTERNALFORMAT_GREEN_SIZE */ +/* reuse GL_INTERNALFORMAT_BLUE_SIZE */ +/* reuse GL_INTERNALFORMAT_ALPHA_SIZE */ +/* reuse GL_INTERNALFORMAT_DEPTH_SIZE */ +/* reuse GL_INTERNALFORMAT_STENCIL_SIZE */ +/* reuse GL_INTERNALFORMAT_SHARED_SIZE */ +/* reuse GL_INTERNALFORMAT_RED_TYPE */ +/* reuse GL_INTERNALFORMAT_GREEN_TYPE */ +/* reuse GL_INTERNALFORMAT_BLUE_TYPE */ +/* reuse GL_INTERNALFORMAT_ALPHA_TYPE */ +/* reuse GL_INTERNALFORMAT_DEPTH_TYPE */ +/* reuse GL_INTERNALFORMAT_STENCIL_TYPE */ +/* reuse GL_MAX_WIDTH */ +/* reuse GL_MAX_HEIGHT */ +/* reuse GL_MAX_DEPTH */ +/* reuse GL_MAX_LAYERS */ +/* reuse GL_MAX_COMBINED_DIMENSIONS */ +/* reuse GL_COLOR_COMPONENTS */ +/* reuse GL_DEPTH_COMPONENTS */ +/* reuse GL_STENCIL_COMPONENTS */ +/* reuse GL_COLOR_RENDERABLE */ +/* reuse GL_DEPTH_RENDERABLE */ +/* reuse GL_STENCIL_RENDERABLE */ +/* reuse GL_FRAMEBUFFER_RENDERABLE */ +/* reuse GL_FRAMEBUFFER_RENDERABLE_LAYERED */ +/* reuse GL_FRAMEBUFFER_BLEND */ +/* reuse GL_READ_PIXELS */ +/* reuse GL_READ_PIXELS_FORMAT */ +/* reuse GL_READ_PIXELS_TYPE */ +/* reuse GL_TEXTURE_IMAGE_FORMAT */ +/* reuse GL_TEXTURE_IMAGE_TYPE */ +/* reuse GL_GET_TEXTURE_IMAGE_FORMAT */ +/* reuse GL_GET_TEXTURE_IMAGE_TYPE */ +/* reuse GL_MIPMAP */ +/* reuse GL_MANUAL_GENERATE_MIPMAP */ +/* reuse GL_AUTO_GENERATE_MIPMAP */ +/* reuse GL_COLOR_ENCODING */ +/* reuse GL_SRGB_READ */ +/* reuse GL_SRGB_WRITE */ +/* reuse GL_FILTER */ +/* reuse GL_VERTEX_TEXTURE */ +/* reuse GL_TESS_CONTROL_TEXTURE */ +/* reuse GL_TESS_EVALUATION_TEXTURE */ +/* reuse GL_GEOMETRY_TEXTURE */ +/* reuse GL_FRAGMENT_TEXTURE */ +/* reuse GL_COMPUTE_TEXTURE */ +/* reuse GL_TEXTURE_SHADOW */ +/* reuse GL_TEXTURE_GATHER */ +/* reuse GL_TEXTURE_GATHER_SHADOW */ +/* reuse GL_SHADER_IMAGE_LOAD */ +/* reuse GL_SHADER_IMAGE_STORE */ +/* reuse GL_SHADER_IMAGE_ATOMIC */ +/* reuse GL_IMAGE_TEXEL_SIZE */ +/* reuse GL_IMAGE_COMPATIBILITY_CLASS */ +/* reuse GL_IMAGE_PIXEL_FORMAT */ +/* reuse GL_IMAGE_PIXEL_TYPE */ +/* reuse GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST */ +/* reuse GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST */ +/* reuse GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE */ +/* reuse GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE */ +/* reuse GL_TEXTURE_COMPRESSED_BLOCK_WIDTH */ +/* reuse GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT */ +/* reuse GL_TEXTURE_COMPRESSED_BLOCK_SIZE */ +/* reuse GL_CLEAR_BUFFER */ +/* reuse GL_TEXTURE_VIEW */ +/* reuse GL_VIEW_COMPATIBILITY_CLASS */ +/* reuse GL_FULL_SUPPORT */ +/* reuse GL_CAVEAT_SUPPORT */ +/* reuse GL_IMAGE_CLASS_4_X_32 */ +/* reuse GL_IMAGE_CLASS_2_X_32 */ +/* reuse GL_IMAGE_CLASS_1_X_32 */ +/* reuse GL_IMAGE_CLASS_4_X_16 */ +/* reuse GL_IMAGE_CLASS_2_X_16 */ +/* reuse GL_IMAGE_CLASS_1_X_16 */ +/* reuse GL_IMAGE_CLASS_4_X_8 */ +/* reuse GL_IMAGE_CLASS_2_X_8 */ +/* reuse GL_IMAGE_CLASS_1_X_8 */ +/* reuse GL_IMAGE_CLASS_11_11_10 */ +/* reuse GL_IMAGE_CLASS_10_10_10_2 */ +/* reuse GL_VIEW_CLASS_128_BITS */ +/* reuse GL_VIEW_CLASS_96_BITS */ +/* reuse GL_VIEW_CLASS_64_BITS */ +/* reuse GL_VIEW_CLASS_48_BITS */ +/* reuse GL_VIEW_CLASS_32_BITS */ +/* reuse GL_VIEW_CLASS_24_BITS */ +/* reuse GL_VIEW_CLASS_16_BITS */ +/* reuse GL_VIEW_CLASS_8_BITS */ +/* reuse GL_VIEW_CLASS_S3TC_DXT1_RGB */ +/* reuse GL_VIEW_CLASS_S3TC_DXT1_RGBA */ +/* reuse GL_VIEW_CLASS_S3TC_DXT3_RGBA */ +/* reuse GL_VIEW_CLASS_S3TC_DXT5_RGBA */ +/* reuse GL_VIEW_CLASS_RGTC1_RED */ +/* reuse GL_VIEW_CLASS_RGTC2_RG */ +/* reuse GL_VIEW_CLASS_BPTC_UNORM */ +/* reuse GL_VIEW_CLASS_BPTC_FLOAT */ +/* Reuse tokens from ARB_invalidate_subdata (none) */ +/* Reuse tokens from ARB_multi_draw_indirect (none) */ +/* Reuse tokens from ARB_program_interface_query */ +/* reuse GL_UNIFORM */ +/* reuse GL_UNIFORM_BLOCK */ +/* reuse GL_PROGRAM_INPUT */ +/* reuse GL_PROGRAM_OUTPUT */ +/* reuse GL_BUFFER_VARIABLE */ +/* reuse GL_SHADER_STORAGE_BLOCK */ +/* reuse GL_VERTEX_SUBROUTINE */ +/* reuse GL_TESS_CONTROL_SUBROUTINE */ +/* reuse GL_TESS_EVALUATION_SUBROUTINE */ +/* reuse GL_GEOMETRY_SUBROUTINE */ +/* reuse GL_FRAGMENT_SUBROUTINE */ +/* reuse GL_COMPUTE_SUBROUTINE */ +/* reuse GL_VERTEX_SUBROUTINE_UNIFORM */ +/* reuse GL_TESS_CONTROL_SUBROUTINE_UNIFORM */ +/* reuse GL_TESS_EVALUATION_SUBROUTINE_UNIFORM */ +/* reuse GL_GEOMETRY_SUBROUTINE_UNIFORM */ +/* reuse GL_FRAGMENT_SUBROUTINE_UNIFORM */ +/* reuse GL_COMPUTE_SUBROUTINE_UNIFORM */ +/* reuse GL_TRANSFORM_FEEDBACK_VARYING */ +/* reuse GL_ACTIVE_RESOURCES */ +/* reuse GL_MAX_NAME_LENGTH */ +/* reuse GL_MAX_NUM_ACTIVE_VARIABLES */ +/* reuse GL_MAX_NUM_COMPATIBLE_SUBROUTINES */ +/* reuse GL_NAME_LENGTH */ +/* reuse GL_TYPE */ +/* reuse GL_ARRAY_SIZE */ +/* reuse GL_OFFSET */ +/* reuse GL_BLOCK_INDEX */ +/* reuse GL_ARRAY_STRIDE */ +/* reuse GL_MATRIX_STRIDE */ +/* reuse GL_IS_ROW_MAJOR */ +/* reuse GL_ATOMIC_COUNTER_BUFFER_INDEX */ +/* reuse GL_BUFFER_BINDING */ +/* reuse GL_BUFFER_DATA_SIZE */ +/* reuse GL_NUM_ACTIVE_VARIABLES */ +/* reuse GL_ACTIVE_VARIABLES */ +/* reuse GL_REFERENCED_BY_VERTEX_SHADER */ +/* reuse GL_REFERENCED_BY_TESS_CONTROL_SHADER */ +/* reuse GL_REFERENCED_BY_TESS_EVALUATION_SHADER */ +/* reuse GL_REFERENCED_BY_GEOMETRY_SHADER */ +/* reuse GL_REFERENCED_BY_FRAGMENT_SHADER */ +/* reuse GL_REFERENCED_BY_COMPUTE_SHADER */ +/* reuse GL_TOP_LEVEL_ARRAY_SIZE */ +/* reuse GL_TOP_LEVEL_ARRAY_STRIDE */ +/* reuse GL_LOCATION */ +/* reuse GL_LOCATION_INDEX */ +/* reuse GL_IS_PER_PATCH */ +/* Reuse tokens from ARB_robust_buffer_access_behavior (none) */ +/* Reuse tokens from ARB_shader_storage_buffer_object */ +/* reuse GL_SHADER_STORAGE_BUFFER */ +/* reuse GL_SHADER_STORAGE_BUFFER_BINDING */ +/* reuse GL_SHADER_STORAGE_BUFFER_START */ +/* reuse GL_SHADER_STORAGE_BUFFER_SIZE */ +/* reuse GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS */ +/* reuse GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS */ +/* reuse GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS */ +/* reuse GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS */ +/* reuse GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS */ +/* reuse GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS */ +/* reuse GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS */ +/* reuse GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS */ +/* reuse GL_MAX_SHADER_STORAGE_BLOCK_SIZE */ +/* reuse GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT */ +/* reuse GL_SHADER_STORAGE_BARRIER_BIT */ +/* reuse GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES */ +/* Reuse tokens from ARB_stencil_texturing */ +/* reuse GL_DEPTH_STENCIL_TEXTURE_MODE */ +/* Reuse tokens from ARB_texture_buffer_range */ +/* reuse GL_TEXTURE_BUFFER_OFFSET */ +/* reuse GL_TEXTURE_BUFFER_SIZE */ +/* reuse GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT */ +/* Reuse tokens from ARB_texture_query_levels (none) */ +/* Reuse tokens from ARB_texture_storage_multisample (none) */ +/* Reuse tokens from ARB_texture_view */ +/* reuse GL_TEXTURE_VIEW_MIN_LEVEL */ +/* reuse GL_TEXTURE_VIEW_NUM_LEVELS */ +/* reuse GL_TEXTURE_VIEW_MIN_LAYER */ +/* reuse GL_TEXTURE_VIEW_NUM_LAYERS */ +/* reuse GL_TEXTURE_IMMUTABLE_LEVELS */ +/* Reuse tokens from ARB_vertex_attrib_binding */ +/* reuse GL_VERTEX_ATTRIB_BINDING */ +/* reuse GL_VERTEX_ATTRIB_RELATIVE_OFFSET */ +/* reuse GL_VERTEX_BINDING_DIVISOR */ +/* reuse GL_VERTEX_BINDING_OFFSET */ +/* reuse GL_VERTEX_BINDING_STRIDE */ +/* reuse GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET */ +/* reuse GL_MAX_VERTEX_ATTRIB_BINDINGS */ +#endif + +#ifndef GL_ARB_depth_buffer_float +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#endif + +#ifndef GL_ARB_framebuffer_object +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_STENCIL_INDEX1 0x8D46 +#define GL_STENCIL_INDEX4 0x8D47 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_STENCIL_INDEX16 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 +#endif + +#ifndef GL_ARB_framebuffer_sRGB +#define GL_FRAMEBUFFER_SRGB 0x8DB9 +#endif + +#ifndef GL_ARB_half_float_vertex +#define GL_HALF_FLOAT 0x140B +#endif + +#ifndef GL_ARB_map_buffer_range +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#endif + +#ifndef GL_ARB_texture_compression_rgtc +#define GL_COMPRESSED_RED_RGTC1 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC +#define GL_COMPRESSED_RG_RGTC2 0x8DBD +#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE +#endif + +#ifndef GL_ARB_texture_rg +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_R16 0x822A +#define GL_RG8 0x822B +#define GL_RG16 0x822C +#define GL_R16F 0x822D +#define GL_R32F 0x822E +#define GL_RG16F 0x822F +#define GL_RG32F 0x8230 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#endif + +#ifndef GL_ARB_vertex_array_object +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#endif + +#ifndef GL_ARB_uniform_buffer_object +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_INVALID_INDEX 0xFFFFFFFFu +#endif + +#ifndef GL_ARB_copy_buffer +#define GL_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_READ_BUFFER GL_COPY_READ_BUFFER_BINDING +#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 +#define GL_COPY_WRITE_BUFFER GL_COPY_WRITE_BUFFER_BINDING +#endif + +#ifndef GL_ARB_depth_clamp +#define GL_DEPTH_CLAMP 0x864F +#endif + +#ifndef GL_ARB_draw_elements_base_vertex +#endif + +#ifndef GL_ARB_fragment_coord_conventions +#endif + +#ifndef GL_ARB_provoking_vertex +#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_PROVOKING_VERTEX 0x8E4F +#endif + +#ifndef GL_ARB_seamless_cube_map +#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F +#endif + +#ifndef GL_ARB_sync +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_OBJECT_TYPE 0x9112 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_UNSIGNALED 0x9118 +#define GL_SIGNALED 0x9119 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_CONDITION_SATISFIED 0x911C +#define GL_WAIT_FAILED 0x911D +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull +#endif + +#ifndef GL_ARB_texture_multisample +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_INTEGER_SAMPLES 0x9110 +#endif + +#ifndef GL_ARB_vertex_array_bgra +/* reuse GL_BGRA */ +#endif + +#ifndef GL_ARB_draw_buffers_blend +#endif + +#ifndef GL_ARB_sample_shading +#define GL_SAMPLE_SHADING_ARB 0x8C36 +#define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37 +#endif + +#ifndef GL_ARB_texture_cube_map_array +#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B +#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F +#endif + +#ifndef GL_ARB_texture_gather +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F +#endif + +#ifndef GL_ARB_texture_query_lod +#endif + +#ifndef GL_ARB_shading_language_include +#define GL_SHADER_INCLUDE_ARB 0x8DAE +#define GL_NAMED_STRING_LENGTH_ARB 0x8DE9 +#define GL_NAMED_STRING_TYPE_ARB 0x8DEA +#endif + +#ifndef GL_ARB_texture_compression_bptc +#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F +#endif + +#ifndef GL_ARB_blend_func_extended +#define GL_SRC1_COLOR 0x88F9 +/* reuse GL_SRC1_ALPHA */ +#define GL_ONE_MINUS_SRC1_COLOR 0x88FA +#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC +#endif + +#ifndef GL_ARB_explicit_attrib_location +#endif + +#ifndef GL_ARB_occlusion_query2 +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#endif + +#ifndef GL_ARB_sampler_objects +#define GL_SAMPLER_BINDING 0x8919 +#endif + +#ifndef GL_ARB_shader_bit_encoding +#endif + +#ifndef GL_ARB_texture_rgb10_a2ui +#define GL_RGB10_A2UI 0x906F +#endif + +#ifndef GL_ARB_texture_swizzle +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 +#endif + +#ifndef GL_ARB_timer_query +#define GL_TIME_ELAPSED 0x88BF +#define GL_TIMESTAMP 0x8E28 +#endif + +#ifndef GL_ARB_vertex_type_2_10_10_10_rev +/* reuse GL_UNSIGNED_INT_2_10_10_10_REV */ +#define GL_INT_2_10_10_10_REV 0x8D9F +#endif + +#ifndef GL_ARB_draw_indirect +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 +#endif + +#ifndef GL_ARB_gpu_shader5 +#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C +#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D +/* reuse GL_MAX_VERTEX_STREAMS */ +#endif + +#ifndef GL_ARB_gpu_shader_fp64 +/* reuse GL_DOUBLE */ +#define GL_DOUBLE_VEC2 0x8FFC +#define GL_DOUBLE_VEC3 0x8FFD +#define GL_DOUBLE_VEC4 0x8FFE +#define GL_DOUBLE_MAT2 0x8F46 +#define GL_DOUBLE_MAT3 0x8F47 +#define GL_DOUBLE_MAT4 0x8F48 +#define GL_DOUBLE_MAT2x3 0x8F49 +#define GL_DOUBLE_MAT2x4 0x8F4A +#define GL_DOUBLE_MAT3x2 0x8F4B +#define GL_DOUBLE_MAT3x4 0x8F4C +#define GL_DOUBLE_MAT4x2 0x8F4D +#define GL_DOUBLE_MAT4x3 0x8F4E +#endif + +#ifndef GL_ARB_shader_subroutine +#define GL_ACTIVE_SUBROUTINES 0x8DE5 +#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 +#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 +#define GL_MAX_SUBROUTINES 0x8DE7 +#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 +#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A +#define GL_COMPATIBLE_SUBROUTINES 0x8E4B +/* reuse GL_UNIFORM_SIZE */ +/* reuse GL_UNIFORM_NAME_LENGTH */ +#endif + +#ifndef GL_ARB_tessellation_shader +#define GL_PATCHES 0x000E +#define GL_PATCH_VERTICES 0x8E72 +#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 +#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 +#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 +#define GL_TESS_GEN_MODE 0x8E76 +#define GL_TESS_GEN_SPACING 0x8E77 +#define GL_TESS_GEN_VERTEX_ORDER 0x8E78 +#define GL_TESS_GEN_POINT_MODE 0x8E79 +/* reuse GL_TRIANGLES */ +/* reuse GL_QUADS */ +#define GL_ISOLINES 0x8E7A +/* reuse GL_EQUAL */ +#define GL_FRACTIONAL_ODD 0x8E7B +#define GL_FRACTIONAL_EVEN 0x8E7C +/* reuse GL_CCW */ +/* reuse GL_CW */ +#define GL_MAX_PATCH_VERTICES 0x8E7D +#define GL_MAX_TESS_GEN_LEVEL 0x8E7E +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 +#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 +#define GL_TESS_EVALUATION_SHADER 0x8E87 +#define GL_TESS_CONTROL_SHADER 0x8E88 +#endif + +#ifndef GL_ARB_texture_buffer_object_rgb32 +/* reuse GL_RGB32F */ +/* reuse GL_RGB32UI */ +/* reuse GL_RGB32I */ +#endif + +#ifndef GL_ARB_transform_feedback2 +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED GL_TRANSFORM_FEEDBACK_PAUSED +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE GL_TRANSFORM_FEEDBACK_ACTIVE +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 +#endif + +#ifndef GL_ARB_transform_feedback3 +#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 +#define GL_MAX_VERTEX_STREAMS 0x8E71 +#endif + +#ifndef GL_ARB_ES2_compatibility +#define GL_FIXED 0x140C +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_RGB565 0x8D62 +#endif + +#ifndef GL_ARB_get_program_binary +#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_PROGRAM_BINARY_LENGTH 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#define GL_PROGRAM_BINARY_FORMATS 0x87FF +#endif + +#ifndef GL_ARB_separate_shader_objects +#define GL_VERTEX_SHADER_BIT 0x00000001 +#define GL_FRAGMENT_SHADER_BIT 0x00000002 +#define GL_GEOMETRY_SHADER_BIT 0x00000004 +#define GL_TESS_CONTROL_SHADER_BIT 0x00000008 +#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 +#define GL_ALL_SHADER_BITS 0xFFFFFFFF +#define GL_PROGRAM_SEPARABLE 0x8258 +#define GL_ACTIVE_PROGRAM 0x8259 +#define GL_PROGRAM_PIPELINE_BINDING 0x825A +#endif + +#ifndef GL_ARB_shader_precision +#endif + +#ifndef GL_ARB_vertex_attrib_64bit +/* reuse GL_RGB32I */ +/* reuse GL_DOUBLE_VEC2 */ +/* reuse GL_DOUBLE_VEC3 */ +/* reuse GL_DOUBLE_VEC4 */ +/* reuse GL_DOUBLE_MAT2 */ +/* reuse GL_DOUBLE_MAT3 */ +/* reuse GL_DOUBLE_MAT4 */ +/* reuse GL_DOUBLE_MAT2x3 */ +/* reuse GL_DOUBLE_MAT2x4 */ +/* reuse GL_DOUBLE_MAT3x2 */ +/* reuse GL_DOUBLE_MAT3x4 */ +/* reuse GL_DOUBLE_MAT4x2 */ +/* reuse GL_DOUBLE_MAT4x3 */ +#endif + +#ifndef GL_ARB_viewport_array +/* reuse GL_SCISSOR_BOX */ +/* reuse GL_VIEWPORT */ +/* reuse GL_DEPTH_RANGE */ +/* reuse GL_SCISSOR_TEST */ +#define GL_MAX_VIEWPORTS 0x825B +#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C +#define GL_VIEWPORT_BOUNDS_RANGE 0x825D +#define GL_LAYER_PROVOKING_VERTEX 0x825E +#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F +#define GL_UNDEFINED_VERTEX 0x8260 +/* reuse GL_FIRST_VERTEX_CONVENTION */ +/* reuse GL_LAST_VERTEX_CONVENTION */ +/* reuse GL_PROVOKING_VERTEX */ +#endif + +#ifndef GL_ARB_cl_event +#define GL_SYNC_CL_EVENT_ARB 0x8240 +#define GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241 +#endif + +#ifndef GL_ARB_debug_output +#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 +#define GL_DEBUG_SOURCE_API_ARB 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A +#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B +#define GL_DEBUG_TYPE_ERROR_ARB 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E +#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 +#define GL_DEBUG_TYPE_OTHER_ARB 0x8251 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145 +#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 +#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 +#endif + +#ifndef GL_ARB_robustness +/* reuse GL_NO_ERROR */ +#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 +#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 +#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 +#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define GL_NO_RESET_NOTIFICATION_ARB 0x8261 +#endif + +#ifndef GL_ARB_shader_stencil_export +#endif + +#ifndef GL_ARB_base_instance +#endif + +#ifndef GL_ARB_shading_language_420pack +#endif + +#ifndef GL_ARB_transform_feedback_instanced +#endif + +#ifndef GL_ARB_compressed_texture_pixel_storage +#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 +#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 +#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 +#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A +#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B +#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C +#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D +#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E +#endif + +#ifndef GL_ARB_conservative_depth +#endif + +#ifndef GL_ARB_internalformat_query +#define GL_NUM_SAMPLE_COUNTS 0x9380 +#endif + +#ifndef GL_ARB_map_buffer_alignment +#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC +#endif + +#ifndef GL_ARB_shader_atomic_counters +#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 +#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 +#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 +#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 +#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB +#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF +#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 +#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 +#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3 +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5 +#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 +#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 +#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 +#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC +#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 +#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#endif + +#ifndef GL_ARB_shader_image_load_store +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 +#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 +#define GL_UNIFORM_BARRIER_BIT 0x00000004 +#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 +#define GL_COMMAND_BARRIER_BIT 0x00000040 +#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 +#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 +#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 +#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 +#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 +#define GL_ALL_BARRIER_BITS 0xFFFFFFFF +#define GL_MAX_IMAGE_UNITS 0x8F38 +#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39 +#define GL_IMAGE_BINDING_NAME 0x8F3A +#define GL_IMAGE_BINDING_LEVEL 0x8F3B +#define GL_IMAGE_BINDING_LAYERED 0x8F3C +#define GL_IMAGE_BINDING_LAYER 0x8F3D +#define GL_IMAGE_BINDING_ACCESS 0x8F3E +#define GL_IMAGE_1D 0x904C +#define GL_IMAGE_2D 0x904D +#define GL_IMAGE_3D 0x904E +#define GL_IMAGE_2D_RECT 0x904F +#define GL_IMAGE_CUBE 0x9050 +#define GL_IMAGE_BUFFER 0x9051 +#define GL_IMAGE_1D_ARRAY 0x9052 +#define GL_IMAGE_2D_ARRAY 0x9053 +#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 +#define GL_IMAGE_2D_MULTISAMPLE 0x9055 +#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056 +#define GL_INT_IMAGE_1D 0x9057 +#define GL_INT_IMAGE_2D 0x9058 +#define GL_INT_IMAGE_3D 0x9059 +#define GL_INT_IMAGE_2D_RECT 0x905A +#define GL_INT_IMAGE_CUBE 0x905B +#define GL_INT_IMAGE_BUFFER 0x905C +#define GL_INT_IMAGE_1D_ARRAY 0x905D +#define GL_INT_IMAGE_2D_ARRAY 0x905E +#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F +#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060 +#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061 +#define GL_UNSIGNED_INT_IMAGE_1D 0x9062 +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 +#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065 +#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 +#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 +#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C +#define GL_MAX_IMAGE_SAMPLES 0x906D +#define GL_IMAGE_BINDING_FORMAT 0x906E +#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 +#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA +#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB +#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD +#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE +#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF +#endif + +#ifndef GL_ARB_shading_language_packing +#endif + +#ifndef GL_ARB_texture_storage +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F +#endif + +#ifndef GL_KHR_texture_compression_astc_ldr +#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 +#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 +#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 +#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 +#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 +#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 +#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 +#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 +#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 +#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 +#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA +#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB +#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC +#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD +#endif + +#ifndef GL_KHR_debug +#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 +#define GL_DEBUG_SOURCE_API 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION 0x824A +#define GL_DEBUG_SOURCE_OTHER 0x824B +#define GL_DEBUG_TYPE_ERROR 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E +#define GL_DEBUG_TYPE_PORTABILITY 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE 0x8250 +#define GL_DEBUG_TYPE_OTHER 0x8251 +#define GL_DEBUG_TYPE_MARKER 0x8268 +#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 +#define GL_DEBUG_TYPE_POP_GROUP 0x826A +#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C +#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D +#define GL_BUFFER 0x82E0 +#define GL_SHADER 0x82E1 +#define GL_PROGRAM 0x82E2 +#define GL_QUERY 0x82E3 +#define GL_PROGRAM_PIPELINE 0x82E4 +#define GL_SAMPLER 0x82E6 +#define GL_DISPLAY_LIST 0x82E7 +/* DISPLAY_LIST used in compatibility profile only */ +#define GL_MAX_LABEL_LENGTH 0x82E8 +#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES 0x9145 +#define GL_DEBUG_SEVERITY_HIGH 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 +#define GL_DEBUG_SEVERITY_LOW 0x9148 +#define GL_DEBUG_OUTPUT 0x92E0 +#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 +/* reuse GL_STACK_UNDERFLOW */ +/* reuse GL_STACK_OVERFLOW */ +#endif + +#ifndef GL_ARB_arrays_of_arrays +#endif + +#ifndef GL_ARB_clear_buffer_object +#endif + +#ifndef GL_ARB_compute_shader +#define GL_COMPUTE_SHADER 0x91B9 +#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB +#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC +#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD +#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 +#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 +#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 +#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 +#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 +#define GL_MAX_COMPUTE_LOCAL_INVOCATIONS 0x90EB +#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE +#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF +#define GL_COMPUTE_LOCAL_WORK_SIZE 0x8267 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED +#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE +#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF +#define GL_COMPUTE_SHADER_BIT 0x00000020 +#endif + +#ifndef GL_ARB_copy_image +#endif + +#ifndef GL_ARB_texture_view +#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB +#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC +#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD +#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF +#endif + +#ifndef GL_ARB_vertex_attrib_binding +#define GL_VERTEX_ATTRIB_BINDING 0x82D4 +#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 +#define GL_VERTEX_BINDING_DIVISOR 0x82D6 +#define GL_VERTEX_BINDING_OFFSET 0x82D7 +#define GL_VERTEX_BINDING_STRIDE 0x82D8 +#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 +#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA +#endif + +#ifndef GL_ARB_robustness_isolation +#endif + +#ifndef GL_ARB_ES3_compatibility +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_MAX_ELEMENT_INDEX 0x8D6B +#endif + +#ifndef GL_ARB_explicit_uniform_location +#define GL_MAX_UNIFORM_LOCATIONS 0x826E +#endif + +#ifndef GL_ARB_fragment_layer_viewport +#endif + +#ifndef GL_ARB_framebuffer_no_attachments +#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 +#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312 +#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 +#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 +#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 +#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 +#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 +#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 +#endif + +#ifndef GL_ARB_internalformat_query2 +/* reuse GL_IMAGE_FORMAT_COMPATIBILITY_TYPE */ +/* reuse GL_NUM_SAMPLE_COUNTS */ +/* reuse GL_RENDERBUFFER */ +/* reuse GL_SAMPLES */ +/* reuse GL_TEXTURE_1D */ +/* reuse GL_TEXTURE_1D_ARRAY */ +/* reuse GL_TEXTURE_2D */ +/* reuse GL_TEXTURE_2D_ARRAY */ +/* reuse GL_TEXTURE_3D */ +/* reuse GL_TEXTURE_CUBE_MAP */ +/* reuse GL_TEXTURE_CUBE_MAP_ARRAY */ +/* reuse GL_TEXTURE_RECTANGLE */ +/* reuse GL_TEXTURE_BUFFER */ +/* reuse GL_TEXTURE_2D_MULTISAMPLE */ +/* reuse GL_TEXTURE_2D_MULTISAMPLE_ARRAY */ +/* reuse GL_TEXTURE_COMPRESSED */ +#define GL_INTERNALFORMAT_SUPPORTED 0x826F +#define GL_INTERNALFORMAT_PREFERRED 0x8270 +#define GL_INTERNALFORMAT_RED_SIZE 0x8271 +#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272 +#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273 +#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274 +#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275 +#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276 +#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277 +#define GL_INTERNALFORMAT_RED_TYPE 0x8278 +#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279 +#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A +#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B +#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C +#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D +#define GL_MAX_WIDTH 0x827E +#define GL_MAX_HEIGHT 0x827F +#define GL_MAX_DEPTH 0x8280 +#define GL_MAX_LAYERS 0x8281 +#define GL_MAX_COMBINED_DIMENSIONS 0x8282 +#define GL_COLOR_COMPONENTS 0x8283 +#define GL_DEPTH_COMPONENTS 0x8284 +#define GL_STENCIL_COMPONENTS 0x8285 +#define GL_COLOR_RENDERABLE 0x8286 +#define GL_DEPTH_RENDERABLE 0x8287 +#define GL_STENCIL_RENDERABLE 0x8288 +#define GL_FRAMEBUFFER_RENDERABLE 0x8289 +#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A +#define GL_FRAMEBUFFER_BLEND 0x828B +#define GL_READ_PIXELS 0x828C +#define GL_READ_PIXELS_FORMAT 0x828D +#define GL_READ_PIXELS_TYPE 0x828E +#define GL_TEXTURE_IMAGE_FORMAT 0x828F +#define GL_TEXTURE_IMAGE_TYPE 0x8290 +#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291 +#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292 +#define GL_MIPMAP 0x8293 +#define GL_MANUAL_GENERATE_MIPMAP 0x8294 +#define GL_AUTO_GENERATE_MIPMAP 0x8295 +#define GL_COLOR_ENCODING 0x8296 +#define GL_SRGB_READ 0x8297 +#define GL_SRGB_WRITE 0x8298 +#define GL_SRGB_DECODE_ARB 0x8299 +#define GL_FILTER 0x829A +#define GL_VERTEX_TEXTURE 0x829B +#define GL_TESS_CONTROL_TEXTURE 0x829C +#define GL_TESS_EVALUATION_TEXTURE 0x829D +#define GL_GEOMETRY_TEXTURE 0x829E +#define GL_FRAGMENT_TEXTURE 0x829F +#define GL_COMPUTE_TEXTURE 0x82A0 +#define GL_TEXTURE_SHADOW 0x82A1 +#define GL_TEXTURE_GATHER 0x82A2 +#define GL_TEXTURE_GATHER_SHADOW 0x82A3 +#define GL_SHADER_IMAGE_LOAD 0x82A4 +#define GL_SHADER_IMAGE_STORE 0x82A5 +#define GL_SHADER_IMAGE_ATOMIC 0x82A6 +#define GL_IMAGE_TEXEL_SIZE 0x82A7 +#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8 +#define GL_IMAGE_PIXEL_FORMAT 0x82A9 +#define GL_IMAGE_PIXEL_TYPE 0x82AA +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF +#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1 +#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2 +#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3 +#define GL_CLEAR_BUFFER 0x82B4 +#define GL_TEXTURE_VIEW 0x82B5 +#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6 +#define GL_FULL_SUPPORT 0x82B7 +#define GL_CAVEAT_SUPPORT 0x82B8 +#define GL_IMAGE_CLASS_4_X_32 0x82B9 +#define GL_IMAGE_CLASS_2_X_32 0x82BA +#define GL_IMAGE_CLASS_1_X_32 0x82BB +#define GL_IMAGE_CLASS_4_X_16 0x82BC +#define GL_IMAGE_CLASS_2_X_16 0x82BD +#define GL_IMAGE_CLASS_1_X_16 0x82BE +#define GL_IMAGE_CLASS_4_X_8 0x82BF +#define GL_IMAGE_CLASS_2_X_8 0x82C0 +#define GL_IMAGE_CLASS_1_X_8 0x82C1 +#define GL_IMAGE_CLASS_11_11_10 0x82C2 +#define GL_IMAGE_CLASS_10_10_10_2 0x82C3 +#define GL_VIEW_CLASS_128_BITS 0x82C4 +#define GL_VIEW_CLASS_96_BITS 0x82C5 +#define GL_VIEW_CLASS_64_BITS 0x82C6 +#define GL_VIEW_CLASS_48_BITS 0x82C7 +#define GL_VIEW_CLASS_32_BITS 0x82C8 +#define GL_VIEW_CLASS_24_BITS 0x82C9 +#define GL_VIEW_CLASS_16_BITS 0x82CA +#define GL_VIEW_CLASS_8_BITS 0x82CB +#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC +#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD +#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE +#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF +#define GL_VIEW_CLASS_RGTC1_RED 0x82D0 +#define GL_VIEW_CLASS_RGTC2_RG 0x82D1 +#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2 +#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3 +#endif + +#ifndef GL_ARB_invalidate_subdata +#endif + +#ifndef GL_ARB_multi_draw_indirect +#endif + +#ifndef GL_ARB_program_interface_query +#define GL_UNIFORM 0x92E1 +#define GL_UNIFORM_BLOCK 0x92E2 +#define GL_PROGRAM_INPUT 0x92E3 +#define GL_PROGRAM_OUTPUT 0x92E4 +#define GL_BUFFER_VARIABLE 0x92E5 +#define GL_SHADER_STORAGE_BLOCK 0x92E6 +/* reuse GL_ATOMIC_COUNTER_BUFFER */ +#define GL_VERTEX_SUBROUTINE 0x92E8 +#define GL_TESS_CONTROL_SUBROUTINE 0x92E9 +#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA +#define GL_GEOMETRY_SUBROUTINE 0x92EB +#define GL_FRAGMENT_SUBROUTINE 0x92EC +#define GL_COMPUTE_SUBROUTINE 0x92ED +#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE +#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF +#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0 +#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1 +#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2 +#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3 +#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 +#define GL_ACTIVE_RESOURCES 0x92F5 +#define GL_MAX_NAME_LENGTH 0x92F6 +#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 +#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8 +#define GL_NAME_LENGTH 0x92F9 +#define GL_TYPE 0x92FA +#define GL_ARRAY_SIZE 0x92FB +#define GL_OFFSET 0x92FC +#define GL_BLOCK_INDEX 0x92FD +#define GL_ARRAY_STRIDE 0x92FE +#define GL_MATRIX_STRIDE 0x92FF +#define GL_IS_ROW_MAJOR 0x9300 +#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 +#define GL_BUFFER_BINDING 0x9302 +#define GL_BUFFER_DATA_SIZE 0x9303 +#define GL_NUM_ACTIVE_VARIABLES 0x9304 +#define GL_ACTIVE_VARIABLES 0x9305 +#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 +#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307 +#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308 +#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309 +#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A +#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B +#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C +#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D +#define GL_LOCATION 0x930E +#define GL_LOCATION_INDEX 0x930F +#define GL_IS_PER_PATCH 0x92E7 +/* reuse GL_NUM_COMPATIBLE_SUBROUTINES */ +/* reuse GL_COMPATIBLE_SUBROUTINES */ +#endif + +#ifndef GL_ARB_robust_buffer_access_behavior +#endif + +#ifndef GL_ARB_shader_image_size +#endif + +#ifndef GL_ARB_shader_storage_buffer_object +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 +#define GL_SHADER_STORAGE_BUFFER_START 0x90D4 +#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 +#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7 +#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8 +#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9 +#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA +#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB +#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC +#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD +#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE +#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF +#define GL_SHADER_STORAGE_BARRIER_BIT 0x2000 +#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS +/* reuse GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS */ +#endif + +#ifndef GL_ARB_stencil_texturing +#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA +#endif + +#ifndef GL_ARB_texture_buffer_range +#define GL_TEXTURE_BUFFER_OFFSET 0x919D +#define GL_TEXTURE_BUFFER_SIZE 0x919E +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F +#endif + +#ifndef GL_ARB_texture_query_levels +#endif + +#ifndef GL_ARB_texture_storage_multisample +#endif + + +/*************************************************************/ + +#include +#ifndef GL_VERSION_2_0 +/* GL type for program/shader text */ +typedef char GLchar; +#endif + +#ifndef GL_VERSION_1_5 +/* GL types for handling large vertex buffer objects */ +typedef ptrdiff_t GLintptr; +typedef ptrdiff_t GLsizeiptr; +#endif + +#ifndef GL_ARB_vertex_buffer_object +/* GL types for handling large vertex buffer objects */ +typedef ptrdiff_t GLintptrARB; +typedef ptrdiff_t GLsizeiptrARB; +#endif + +#ifndef GL_ARB_shader_objects +/* GL types for program/shader text and shader object handles */ +typedef char GLcharARB; +typedef unsigned int GLhandleARB; +#endif + +/* GL type for "half" precision (s10e5) float data in host memory */ +#ifndef GL_ARB_half_float_pixel +typedef unsigned short GLhalfARB; +#endif + +#ifndef GL_NV_half_float +typedef unsigned short GLhalfNV; +#endif + +#ifndef GLEXT_64_TYPES_DEFINED +/* This code block is duplicated in glxext.h, so must be protected */ +#define GLEXT_64_TYPES_DEFINED +/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ +/* (as used in the GL_EXT_timer_query extension). */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#include +#elif defined(__sun__) || defined(__digital__) +#include +#if defined(__STDC__) +#if defined(__arch64__) || defined(_LP64) +typedef long int int64_t; +typedef unsigned long int uint64_t; +#else +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#endif /* __arch64__ */ +#endif /* __STDC__ */ +#elif defined( __VMS ) || defined(__sgi) +#include +#elif defined(__SCO__) || defined(__USLC__) +#include +#elif defined(__UNIXOS2__) || defined(__SOL64__) +typedef long int int32_t; +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#elif defined(_WIN32) && defined(__GNUC__) +#include +#elif defined(_WIN32) +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +/* Fallback if nothing above works */ +#include +#endif +#endif + +#ifndef GL_EXT_timer_query +typedef int64_t GLint64EXT; +typedef uint64_t GLuint64EXT; +#endif + +#ifndef GL_ARB_sync +typedef int64_t GLint64; +typedef uint64_t GLuint64; +typedef struct __GLsync *GLsync; +#endif + +#ifndef GL_ARB_cl_event +/* These incomplete types let us declare types compatible with OpenCL's cl_context and cl_event */ +struct _cl_context; +struct _cl_event; +#endif + +#ifndef GL_ARB_debug_output +typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam); +#endif + +#ifndef GL_AMD_debug_output +typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam); +#endif + +#ifndef GL_KHR_debug +typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam); +#endif + +#ifndef GL_NV_vdpau_interop +typedef GLintptr GLvdpauSurfaceNV; +#endif + +#ifndef GL_VERSION_1_0 +#define GL_VERSION_1_0 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glCullFace (GLenum mode); +GLAPI void APIENTRY glFrontFace (GLenum mode); +GLAPI void APIENTRY glHint (GLenum target, GLenum mode); +GLAPI void APIENTRY glLineWidth (GLfloat width); +GLAPI void APIENTRY glPointSize (GLfloat size); +GLAPI void APIENTRY glPolygonMode (GLenum face, GLenum mode); +GLAPI void APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GLAPI void APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glTexImage1D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void APIENTRY glDrawBuffer (GLenum mode); +GLAPI void APIENTRY glClear (GLbitfield mask); +GLAPI void APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI void APIENTRY glClearStencil (GLint s); +GLAPI void APIENTRY glClearDepth (GLdouble depth); +GLAPI void APIENTRY glStencilMask (GLuint mask); +GLAPI void APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GLAPI void APIENTRY glDepthMask (GLboolean flag); +GLAPI void APIENTRY glDisable (GLenum cap); +GLAPI void APIENTRY glEnable (GLenum cap); +GLAPI void APIENTRY glFinish (void); +GLAPI void APIENTRY glFlush (void); +GLAPI void APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GLAPI void APIENTRY glLogicOp (GLenum opcode); +GLAPI void APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GLAPI void APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GLAPI void APIENTRY glDepthFunc (GLenum func); +GLAPI void APIENTRY glPixelStoref (GLenum pname, GLfloat param); +GLAPI void APIENTRY glPixelStorei (GLenum pname, GLint param); +GLAPI void APIENTRY glReadBuffer (GLenum mode); +GLAPI void APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); +GLAPI void APIENTRY glGetBooleanv (GLenum pname, GLboolean *params); +GLAPI void APIENTRY glGetDoublev (GLenum pname, GLdouble *params); +GLAPI GLenum APIENTRY glGetError (void); +GLAPI void APIENTRY glGetFloatv (GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetIntegerv (GLenum pname, GLint *params); +GLAPI const GLubyte * APIENTRY glGetString (GLenum name); +GLAPI void APIENTRY glGetTexImage (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); +GLAPI void APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params); +GLAPI GLboolean APIENTRY glIsEnabled (GLenum cap); +GLAPI void APIENTRY glDepthRange (GLdouble near, GLdouble far); +GLAPI void APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCULLFACEPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLFRONTFACEPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLHINTPROC) (GLenum target, GLenum mode); +typedef void (APIENTRYP PFNGLLINEWIDTHPROC) (GLfloat width); +typedef void (APIENTRYP PFNGLPOINTSIZEPROC) (GLfloat size); +typedef void (APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode); +typedef void (APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLTEXPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLTEXIMAGE1DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLDRAWBUFFERPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLCLEARPROC) (GLbitfield mask); +typedef void (APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (APIENTRYP PFNGLCLEARSTENCILPROC) (GLint s); +typedef void (APIENTRYP PFNGLCLEARDEPTHPROC) (GLdouble depth); +typedef void (APIENTRYP PFNGLSTENCILMASKPROC) (GLuint mask); +typedef void (APIENTRYP PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +typedef void (APIENTRYP PFNGLDEPTHMASKPROC) (GLboolean flag); +typedef void (APIENTRYP PFNGLDISABLEPROC) (GLenum cap); +typedef void (APIENTRYP PFNGLENABLEPROC) (GLenum cap); +typedef void (APIENTRYP PFNGLFINISHPROC) (void); +typedef void (APIENTRYP PFNGLFLUSHPROC) (void); +typedef void (APIENTRYP PFNGLBLENDFUNCPROC) (GLenum sfactor, GLenum dfactor); +typedef void (APIENTRYP PFNGLLOGICOPPROC) (GLenum opcode); +typedef void (APIENTRYP PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask); +typedef void (APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum zpass); +typedef void (APIENTRYP PFNGLDEPTHFUNCPROC) (GLenum func); +typedef void (APIENTRYP PFNGLPIXELSTOREFPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLREADBUFFERPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); +typedef void (APIENTRYP PFNGLGETBOOLEANVPROC) (GLenum pname, GLboolean *params); +typedef void (APIENTRYP PFNGLGETDOUBLEVPROC) (GLenum pname, GLdouble *params); +typedef GLenum (APIENTRYP PFNGLGETERRORPROC) (void); +typedef void (APIENTRYP PFNGLGETFLOATVPROC) (GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *params); +typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGPROC) (GLenum name); +typedef void (APIENTRYP PFNGLGETTEXIMAGEPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERFVPROC) (GLenum target, GLint level, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERIVPROC) (GLenum target, GLint level, GLenum pname, GLint *params); +typedef GLboolean (APIENTRYP PFNGLISENABLEDPROC) (GLenum cap); +typedef void (APIENTRYP PFNGLDEPTHRANGEPROC) (GLdouble near, GLdouble far); +typedef void (APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height); +#endif + +#ifndef GL_VERSION_1_1 +#define GL_VERSION_1_1 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GLAPI void APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); +GLAPI void APIENTRY glGetPointerv (GLenum pname, GLvoid* *params); +GLAPI void APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GLAPI void APIENTRY glCopyTexImage1D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +GLAPI void APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLAPI void APIENTRY glCopyTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void APIENTRY glBindTexture (GLenum target, GLuint texture); +GLAPI void APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures); +GLAPI void APIENTRY glGenTextures (GLsizei n, GLuint *textures); +GLAPI GLboolean APIENTRY glIsTexture (GLuint texture); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); +typedef void (APIENTRYP PFNGLGETPOINTERVPROC) (GLenum pname, GLvoid* *params); +typedef void (APIENTRYP PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat units); +typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture); +typedef void (APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures); +typedef void (APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures); +typedef GLboolean (APIENTRYP PFNGLISTEXTUREPROC) (GLuint texture); +#endif + +#ifndef GL_VERSION_1_2 +#define GL_VERSION_1_2 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GLAPI void APIENTRY glBlendEquation (GLenum mode); +GLAPI void APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +GLAPI void APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); +GLAPI void APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#endif + +#ifndef GL_VERSION_1_3 +#define GL_VERSION_1_3 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glActiveTexture (GLenum texture); +GLAPI void APIENTRY glSampleCoverage (GLfloat value, GLboolean invert); +GLAPI void APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +GLAPI void APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +GLAPI void APIENTRY glCompressedTexImage1D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +GLAPI void APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +GLAPI void APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +GLAPI void APIENTRY glCompressedTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +GLAPI void APIENTRY glGetCompressedTexImage (GLenum target, GLint level, GLvoid *img); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img); +#endif + +#ifndef GL_VERSION_1_4 +#define GL_VERSION_1_4 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +GLAPI void APIENTRY glMultiDrawArrays (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); +GLAPI void APIENTRY glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei drawcount); +GLAPI void APIENTRY glPointParameterf (GLenum pname, GLfloat param); +GLAPI void APIENTRY glPointParameterfv (GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glPointParameteri (GLenum pname, GLint param); +GLAPI void APIENTRY glPointParameteriv (GLenum pname, const GLint *params); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei drawcount); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); +typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); +#endif + +#ifndef GL_VERSION_1_5 +#define GL_VERSION_1_5 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glGenQueries (GLsizei n, GLuint *ids); +GLAPI void APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids); +GLAPI GLboolean APIENTRY glIsQuery (GLuint id); +GLAPI void APIENTRY glBeginQuery (GLenum target, GLuint id); +GLAPI void APIENTRY glEndQuery (GLenum target); +GLAPI void APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetQueryObjectiv (GLuint id, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params); +GLAPI void APIENTRY glBindBuffer (GLenum target, GLuint buffer); +GLAPI void APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers); +GLAPI void APIENTRY glGenBuffers (GLsizei n, GLuint *buffers); +GLAPI GLboolean APIENTRY glIsBuffer (GLuint buffer); +GLAPI void APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); +GLAPI void APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); +GLAPI void APIENTRY glGetBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); +GLAPI GLvoid* APIENTRY glMapBuffer (GLenum target, GLenum access); +GLAPI GLboolean APIENTRY glUnmapBuffer (GLenum target); +GLAPI void APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, GLvoid* *params); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id); +typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); +typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); +typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); +typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); +typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); +typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); +typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); +typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target); +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid* *params); +#endif + +#ifndef GL_VERSION_2_0 +#define GL_VERSION_2_0 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); +GLAPI void APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs); +GLAPI void APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +GLAPI void APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +GLAPI void APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); +GLAPI void APIENTRY glAttachShader (GLuint program, GLuint shader); +GLAPI void APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name); +GLAPI void APIENTRY glCompileShader (GLuint shader); +GLAPI GLuint APIENTRY glCreateProgram (void); +GLAPI GLuint APIENTRY glCreateShader (GLenum type); +GLAPI void APIENTRY glDeleteProgram (GLuint program); +GLAPI void APIENTRY glDeleteShader (GLuint shader); +GLAPI void APIENTRY glDetachShader (GLuint program, GLuint shader); +GLAPI void APIENTRY glDisableVertexAttribArray (GLuint index); +GLAPI void APIENTRY glEnableVertexAttribArray (GLuint index); +GLAPI void APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GLAPI void APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GLAPI void APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj); +GLAPI GLint APIENTRY glGetAttribLocation (GLuint program, const GLchar *name); +GLAPI void APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GLAPI void APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GLAPI void APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +GLAPI GLint APIENTRY glGetUniformLocation (GLuint program, const GLchar *name); +GLAPI void APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params); +GLAPI void APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params); +GLAPI void APIENTRY glGetVertexAttribdv (GLuint index, GLenum pname, GLdouble *params); +GLAPI void APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid* *pointer); +GLAPI GLboolean APIENTRY glIsProgram (GLuint program); +GLAPI GLboolean APIENTRY glIsShader (GLuint shader); +GLAPI void APIENTRY glLinkProgram (GLuint program); +GLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar* const *string, const GLint *length); +GLAPI void APIENTRY glUseProgram (GLuint program); +GLAPI void APIENTRY glUniform1f (GLint location, GLfloat v0); +GLAPI void APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1); +GLAPI void APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GLAPI void APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GLAPI void APIENTRY glUniform1i (GLint location, GLint v0); +GLAPI void APIENTRY glUniform2i (GLint location, GLint v0, GLint v1); +GLAPI void APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2); +GLAPI void APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GLAPI void APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glValidateProgram (GLuint program); +GLAPI void APIENTRY glVertexAttrib1d (GLuint index, GLdouble x); +GLAPI void APIENTRY glVertexAttrib1dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib1f (GLuint index, GLfloat x); +GLAPI void APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib1s (GLuint index, GLshort x); +GLAPI void APIENTRY glVertexAttrib1sv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib2d (GLuint index, GLdouble x, GLdouble y); +GLAPI void APIENTRY glVertexAttrib2dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y); +GLAPI void APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib2s (GLuint index, GLshort x, GLshort y); +GLAPI void APIENTRY glVertexAttrib2sv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib3d (GLuint index, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glVertexAttrib3dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z); +GLAPI void APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib3s (GLuint index, GLshort x, GLshort y, GLshort z); +GLAPI void APIENTRY glVertexAttrib3sv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4Nbv (GLuint index, const GLbyte *v); +GLAPI void APIENTRY glVertexAttrib4Niv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttrib4Nsv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4Nub (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +GLAPI void APIENTRY glVertexAttrib4Nubv (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttrib4Nuiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttrib4Nusv (GLuint index, const GLushort *v); +GLAPI void APIENTRY glVertexAttrib4bv (GLuint index, const GLbyte *v); +GLAPI void APIENTRY glVertexAttrib4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glVertexAttrib4dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GLAPI void APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glVertexAttrib4iv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttrib4s (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +GLAPI void APIENTRY glVertexAttrib4sv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttrib4ubv (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttrib4uiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttrib4usv (GLuint index, const GLushort *v); +GLAPI void APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); +typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs); +typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask); +typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); +typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); +typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); +typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void); +typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type); +typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader); +typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj); +typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); +typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program); +typedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader); +typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* const *string, const GLint *length); +typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); +typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0); +typedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); +typedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); +typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); +typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); +#endif + +#ifndef GL_VERSION_2_1 +#define GL_VERSION_2_1 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#endif + +#ifndef GL_VERSION_3_0 +#define GL_VERSION_3_0 1 +/* OpenGL 3.0 also reuses entry points from these extensions: */ +/* ARB_framebuffer_object */ +/* ARB_map_buffer_range */ +/* ARB_vertex_array_object */ +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glColorMaski (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +GLAPI void APIENTRY glGetBooleani_v (GLenum target, GLuint index, GLboolean *data); +GLAPI void APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data); +GLAPI void APIENTRY glEnablei (GLenum target, GLuint index); +GLAPI void APIENTRY glDisablei (GLenum target, GLuint index); +GLAPI GLboolean APIENTRY glIsEnabledi (GLenum target, GLuint index); +GLAPI void APIENTRY glBeginTransformFeedback (GLenum primitiveMode); +GLAPI void APIENTRY glEndTransformFeedback (void); +GLAPI void APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +GLAPI void APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer); +GLAPI void APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar* const *varyings, GLenum bufferMode); +GLAPI void APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +GLAPI void APIENTRY glClampColor (GLenum target, GLenum clamp); +GLAPI void APIENTRY glBeginConditionalRender (GLuint id, GLenum mode); +GLAPI void APIENTRY glEndConditionalRender (void); +GLAPI void APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params); +GLAPI void APIENTRY glVertexAttribI1i (GLuint index, GLint x); +GLAPI void APIENTRY glVertexAttribI2i (GLuint index, GLint x, GLint y); +GLAPI void APIENTRY glVertexAttribI3i (GLuint index, GLint x, GLint y, GLint z); +GLAPI void APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glVertexAttribI1ui (GLuint index, GLuint x); +GLAPI void APIENTRY glVertexAttribI2ui (GLuint index, GLuint x, GLuint y); +GLAPI void APIENTRY glVertexAttribI3ui (GLuint index, GLuint x, GLuint y, GLuint z); +GLAPI void APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GLAPI void APIENTRY glVertexAttribI1iv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI2iv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI3iv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI1uiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI2uiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI3uiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI4bv (GLuint index, const GLbyte *v); +GLAPI void APIENTRY glVertexAttribI4sv (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttribI4ubv (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttribI4usv (GLuint index, const GLushort *v); +GLAPI void APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params); +GLAPI void APIENTRY glBindFragDataLocation (GLuint program, GLuint color, const GLchar *name); +GLAPI GLint APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name); +GLAPI void APIENTRY glUniform1ui (GLint location, GLuint v0); +GLAPI void APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1); +GLAPI void APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2); +GLAPI void APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GLAPI void APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glTexParameterIiv (GLenum target, GLenum pname, const GLint *params); +GLAPI void APIENTRY glTexParameterIuiv (GLenum target, GLenum pname, const GLuint *params); +GLAPI void APIENTRY glGetTexParameterIiv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetTexParameterIuiv (GLenum target, GLenum pname, GLuint *params); +GLAPI void APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value); +GLAPI void APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value); +GLAPI void APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value); +GLAPI void APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +GLAPI const GLubyte * APIENTRY glGetStringi (GLenum name, GLuint index); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOLORMASKIPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data); +typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data); +typedef void (APIENTRYP PFNGLENABLEIPROC) (GLenum target, GLuint index); +typedef void (APIENTRYP PFNGLDISABLEIPROC) (GLenum target, GLuint index); +typedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC) (GLenum target, GLuint index); +typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode); +typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void); +typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar* const *varyings, GLenum bufferMode); +typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp); +typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode); +typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC) (void); +typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint x, GLint y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint x, GLuint y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params); +typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0); +typedef void (APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1); +typedef void (APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value); +typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value); +typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value); +typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index); +#endif + +#ifndef GL_VERSION_3_1 +#define GL_VERSION_3_1 1 +/* OpenGL 3.1 also reuses entry points from these extensions: */ +/* ARB_copy_buffer */ +/* ARB_uniform_buffer_object */ +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +GLAPI void APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instancecount); +GLAPI void APIENTRY glTexBuffer (GLenum target, GLenum internalformat, GLuint buffer); +GLAPI void APIENTRY glPrimitiveRestartIndex (GLuint index); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instancecount); +typedef void (APIENTRYP PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalformat, GLuint buffer); +typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint index); +#endif + +#ifndef GL_VERSION_3_2 +#define GL_VERSION_3_2 1 +/* OpenGL 3.2 also reuses entry points from these extensions: */ +/* ARB_draw_elements_base_vertex */ +/* ARB_provoking_vertex */ +/* ARB_sync */ +/* ARB_texture_multisample */ +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data); +GLAPI void APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params); +GLAPI void APIENTRY glFramebufferTexture (GLenum target, GLenum attachment, GLuint texture, GLint level); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data); +typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +#endif + +#ifndef GL_VERSION_3_3 +#define GL_VERSION_3_3 1 +/* OpenGL 3.3 also reuses entry points from these extensions: */ +/* ARB_blend_func_extended */ +/* ARB_sampler_objects */ +/* ARB_explicit_attrib_location, but it has none */ +/* ARB_occlusion_query2 (no entry points) */ +/* ARB_shader_bit_encoding (no entry points) */ +/* ARB_texture_rgb10_a2ui (no entry points) */ +/* ARB_texture_swizzle (no entry points) */ +/* ARB_timer_query */ +/* ARB_vertex_type_2_10_10_10_rev */ +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor); +#endif + +#ifndef GL_VERSION_4_0 +#define GL_VERSION_4_0 1 +/* OpenGL 4.0 also reuses entry points from these extensions: */ +/* ARB_texture_query_lod (no entry points) */ +/* ARB_draw_indirect */ +/* ARB_gpu_shader5 (no entry points) */ +/* ARB_gpu_shader_fp64 */ +/* ARB_shader_subroutine */ +/* ARB_tessellation_shader */ +/* ARB_texture_buffer_object_rgb32 (no entry points) */ +/* ARB_texture_cube_map_array (no entry points) */ +/* ARB_texture_gather (no entry points) */ +/* ARB_transform_feedback2 */ +/* ARB_transform_feedback3 */ +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glMinSampleShading (GLfloat value); +GLAPI void APIENTRY glBlendEquationi (GLuint buf, GLenum mode); +GLAPI void APIENTRY glBlendEquationSeparatei (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +GLAPI void APIENTRY glBlendFunci (GLuint buf, GLenum src, GLenum dst); +GLAPI void APIENTRY glBlendFuncSeparatei (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLMINSAMPLESHADINGPROC) (GLfloat value); +typedef void (APIENTRYP PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode); +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (APIENTRYP PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +#endif + +#ifndef GL_VERSION_4_1 +#define GL_VERSION_4_1 1 +/* OpenGL 4.1 reuses entry points from these extensions: */ +/* ARB_ES2_compatibility */ +/* ARB_get_program_binary */ +/* ARB_separate_shader_objects */ +/* ARB_shader_precision (no entry points) */ +/* ARB_vertex_attrib_64bit */ +/* ARB_viewport_array */ +#endif + +#ifndef GL_VERSION_4_2 +#define GL_VERSION_4_2 1 +/* OpenGL 4.2 reuses entry points from these extensions: */ +/* ARB_base_instance */ +/* ARB_shading_language_420pack (no entry points) */ +/* ARB_transform_feedback_instanced */ +/* ARB_compressed_texture_pixel_storage (no entry points) */ +/* ARB_conservative_depth (no entry points) */ +/* ARB_internalformat_query */ +/* ARB_map_buffer_alignment (no entry points) */ +/* ARB_shader_atomic_counters */ +/* ARB_shader_image_load_store */ +/* ARB_shading_language_packing (no entry points) */ +/* ARB_texture_storage */ +#endif + +#ifndef GL_VERSION_4_3 +#define GL_VERSION_4_3 1 +/* OpenGL 4.3 reuses entry points from these extensions: */ +/* ARB_arrays_of_arrays (no entry points, GLSL only) */ +/* ARB_fragment_layer_viewport (no entry points, GLSL only) */ +/* ARB_shader_image_size (no entry points, GLSL only) */ +/* ARB_ES3_compatibility (no entry points) */ +/* ARB_clear_buffer_object */ +/* ARB_compute_shader */ +/* ARB_copy_image */ +/* KHR_debug (includes ARB_debug_output commands promoted to KHR without suffixes) */ +/* ARB_explicit_uniform_location (no entry points) */ +/* ARB_framebuffer_no_attachments */ +/* ARB_internalformat_query2 */ +/* ARB_invalidate_subdata */ +/* ARB_multi_draw_indirect */ +/* ARB_program_interface_query */ +/* ARB_robust_buffer_access_behavior (no entry points) */ +/* ARB_shader_storage_buffer_object */ +/* ARB_stencil_texturing (no entry points) */ +/* ARB_texture_buffer_range */ +/* ARB_texture_query_levels (no entry points) */ +/* ARB_texture_storage_multisample */ +/* ARB_texture_view */ +/* ARB_vertex_attrib_binding */ +#endif + +#ifndef GL_ARB_depth_buffer_float +#define GL_ARB_depth_buffer_float 1 +#endif + +#ifndef GL_ARB_framebuffer_object +#define GL_ARB_framebuffer_object 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI GLboolean APIENTRY glIsRenderbuffer (GLuint renderbuffer); +GLAPI void APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); +GLAPI void APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers); +GLAPI void APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers); +GLAPI void APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI GLboolean APIENTRY glIsFramebuffer (GLuint framebuffer); +GLAPI void APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); +GLAPI void APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers); +GLAPI void APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers); +GLAPI GLenum APIENTRY glCheckFramebufferStatus (GLenum target); +GLAPI void APIENTRY glFramebufferTexture1D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI void APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI void APIENTRY glFramebufferTexture3D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +GLAPI void APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GLAPI void APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params); +GLAPI void APIENTRY glGenerateMipmap (GLenum target); +GLAPI void APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +GLAPI void APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +#endif /* GLCOREARB_PROTOTYPES */ +typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); +typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); +typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); +typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers); +typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); +typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target); +typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +#endif + +#ifndef GL_ARB_framebuffer_sRGB +#define GL_ARB_framebuffer_sRGB 1 +#endif + +#ifndef GL_ARB_half_float_vertex +#define GL_ARB_half_float_vertex 1 +#endif + +#ifndef GL_ARB_map_buffer_range +#define GL_ARB_map_buffer_range 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI GLvoid* APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +GLAPI void APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length); +#endif /* GLCOREARB_PROTOTYPES */ +typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); +#endif + +#ifndef GL_ARB_texture_compression_rgtc +#define GL_ARB_texture_compression_rgtc 1 +#endif + +#ifndef GL_ARB_texture_rg +#define GL_ARB_texture_rg 1 +#endif + +#ifndef GL_ARB_vertex_array_object +#define GL_ARB_vertex_array_object 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glBindVertexArray (GLuint array); +GLAPI void APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays); +GLAPI void APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays); +GLAPI GLboolean APIENTRY glIsVertexArray (GLuint array); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array); +typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays); +typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); +typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array); +#endif + +#ifndef GL_ARB_uniform_buffer_object +#define GL_ARB_uniform_buffer_object 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar* const *uniformNames, GLuint *uniformIndices); +GLAPI void APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetActiveUniformName (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); +GLAPI GLuint APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName); +GLAPI void APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); +GLAPI void APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar* const *uniformNames, GLuint *uniformIndices); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); +typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); +typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +#endif + +#ifndef GL_ARB_copy_buffer +#define GL_ARB_copy_buffer 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +#endif + +#ifndef GL_ARB_depth_clamp +#define GL_ARB_depth_clamp 1 +#endif + +#ifndef GL_ARB_draw_elements_base_vertex +#define GL_ARB_draw_elements_base_vertex 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex); +GLAPI void APIENTRY glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex); +GLAPI void APIENTRY glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instancecount, GLint basevertex); +GLAPI void APIENTRY glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei drawcount, const GLint *basevertex); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex); +typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instancecount, GLint basevertex); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei drawcount, const GLint *basevertex); +#endif + +#ifndef GL_ARB_fragment_coord_conventions +#define GL_ARB_fragment_coord_conventions 1 +#endif + +#ifndef GL_ARB_provoking_vertex +#define GL_ARB_provoking_vertex 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glProvokingVertex (GLenum mode); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC) (GLenum mode); +#endif + +#ifndef GL_ARB_seamless_cube_map +#define GL_ARB_seamless_cube_map 1 +#endif + +#ifndef GL_ARB_sync +#define GL_ARB_sync 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI GLsync APIENTRY glFenceSync (GLenum condition, GLbitfield flags); +GLAPI GLboolean APIENTRY glIsSync (GLsync sync); +GLAPI void APIENTRY glDeleteSync (GLsync sync); +GLAPI GLenum APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); +GLAPI void APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); +GLAPI void APIENTRY glGetInteger64v (GLenum pname, GLint64 *params); +GLAPI void APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +#endif /* GLCOREARB_PROTOTYPES */ +typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags); +typedef GLboolean (APIENTRYP PFNGLISSYNCPROC) (GLsync sync); +typedef void (APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync); +typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *params); +typedef void (APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +#endif + +#ifndef GL_ARB_texture_multisample +#define GL_ARB_texture_multisample 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glTexImage2DMultisample (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glTexImage3DMultisample (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glGetMultisamplefv (GLenum pname, GLuint index, GLfloat *val); +GLAPI void APIENTRY glSampleMaski (GLuint index, GLbitfield mask); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat *val); +typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC) (GLuint index, GLbitfield mask); +#endif + +#ifndef GL_ARB_vertex_array_bgra +#define GL_ARB_vertex_array_bgra 1 +#endif + +#ifndef GL_ARB_draw_buffers_blend +#define GL_ARB_draw_buffers_blend 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glBlendEquationiARB (GLuint buf, GLenum mode); +GLAPI void APIENTRY glBlendEquationSeparateiARB (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +GLAPI void APIENTRY glBlendFunciARB (GLuint buf, GLenum src, GLenum dst); +GLAPI void APIENTRY glBlendFuncSeparateiARB (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode); +typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (APIENTRYP PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +#endif + +#ifndef GL_ARB_sample_shading +#define GL_ARB_sample_shading 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glMinSampleShadingARB (GLfloat value); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLMINSAMPLESHADINGARBPROC) (GLfloat value); +#endif + +#ifndef GL_ARB_texture_cube_map_array +#define GL_ARB_texture_cube_map_array 1 +#endif + +#ifndef GL_ARB_texture_gather +#define GL_ARB_texture_gather 1 +#endif + +#ifndef GL_ARB_texture_query_lod +#define GL_ARB_texture_query_lod 1 +#endif + +#ifndef GL_ARB_shading_language_include +#define GL_ARB_shading_language_include 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glNamedStringARB (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string); +GLAPI void APIENTRY glDeleteNamedStringARB (GLint namelen, const GLchar *name); +GLAPI void APIENTRY glCompileShaderIncludeARB (GLuint shader, GLsizei count, const GLchar* *path, const GLint *length); +GLAPI GLboolean APIENTRY glIsNamedStringARB (GLint namelen, const GLchar *name); +GLAPI void APIENTRY glGetNamedStringARB (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string); +GLAPI void APIENTRY glGetNamedStringivARB (GLint namelen, const GLchar *name, GLenum pname, GLint *params); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string); +typedef void (APIENTRYP PFNGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name); +typedef void (APIENTRYP PFNGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const GLchar* *path, const GLint *length); +typedef GLboolean (APIENTRYP PFNGLISNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name); +typedef void (APIENTRYP PFNGLGETNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string); +typedef void (APIENTRYP PFNGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const GLchar *name, GLenum pname, GLint *params); +#endif + +#ifndef GL_ARB_texture_compression_bptc +#define GL_ARB_texture_compression_bptc 1 +#endif + +#ifndef GL_ARB_blend_func_extended +#define GL_ARB_blend_func_extended 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glBindFragDataLocationIndexed (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); +GLAPI GLint APIENTRY glGetFragDataIndex (GLuint program, const GLchar *name); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETFRAGDATAINDEXPROC) (GLuint program, const GLchar *name); +#endif + +#ifndef GL_ARB_explicit_attrib_location +#define GL_ARB_explicit_attrib_location 1 +#endif + +#ifndef GL_ARB_occlusion_query2 +#define GL_ARB_occlusion_query2 1 +#endif + +#ifndef GL_ARB_sampler_objects +#define GL_ARB_sampler_objects 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glGenSamplers (GLsizei count, GLuint *samplers); +GLAPI void APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers); +GLAPI GLboolean APIENTRY glIsSampler (GLuint sampler); +GLAPI void APIENTRY glBindSampler (GLuint unit, GLuint sampler); +GLAPI void APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param); +GLAPI void APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param); +GLAPI void APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param); +GLAPI void APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param); +GLAPI void APIENTRY glSamplerParameterIiv (GLuint sampler, GLenum pname, const GLint *param); +GLAPI void APIENTRY glSamplerParameterIuiv (GLuint sampler, GLenum pname, const GLuint *param); +GLAPI void APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetSamplerParameterIiv (GLuint sampler, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetSamplerParameterIuiv (GLuint sampler, GLenum pname, GLuint *params); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers); +typedef void (APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers); +typedef GLboolean (APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler); +typedef void (APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint *param); +typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint *param); +typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint *params); +#endif + +#ifndef GL_ARB_shader_bit_encoding +#define GL_ARB_shader_bit_encoding 1 +#endif + +#ifndef GL_ARB_texture_rgb10_a2ui +#define GL_ARB_texture_rgb10_a2ui 1 +#endif + +#ifndef GL_ARB_texture_swizzle +#define GL_ARB_texture_swizzle 1 +#endif + +#ifndef GL_ARB_timer_query +#define GL_ARB_timer_query 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glQueryCounter (GLuint id, GLenum target); +GLAPI void APIENTRY glGetQueryObjecti64v (GLuint id, GLenum pname, GLint64 *params); +GLAPI void APIENTRY glGetQueryObjectui64v (GLuint id, GLenum pname, GLuint64 *params); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64 *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64 *params); +#endif + +#ifndef GL_ARB_vertex_type_2_10_10_10_rev +#define GL_ARB_vertex_type_2_10_10_10_rev 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glVertexP2ui (GLenum type, GLuint value); +GLAPI void APIENTRY glVertexP2uiv (GLenum type, const GLuint *value); +GLAPI void APIENTRY glVertexP3ui (GLenum type, GLuint value); +GLAPI void APIENTRY glVertexP3uiv (GLenum type, const GLuint *value); +GLAPI void APIENTRY glVertexP4ui (GLenum type, GLuint value); +GLAPI void APIENTRY glVertexP4uiv (GLenum type, const GLuint *value); +GLAPI void APIENTRY glTexCoordP1ui (GLenum type, GLuint coords); +GLAPI void APIENTRY glTexCoordP1uiv (GLenum type, const GLuint *coords); +GLAPI void APIENTRY glTexCoordP2ui (GLenum type, GLuint coords); +GLAPI void APIENTRY glTexCoordP2uiv (GLenum type, const GLuint *coords); +GLAPI void APIENTRY glTexCoordP3ui (GLenum type, GLuint coords); +GLAPI void APIENTRY glTexCoordP3uiv (GLenum type, const GLuint *coords); +GLAPI void APIENTRY glTexCoordP4ui (GLenum type, GLuint coords); +GLAPI void APIENTRY glTexCoordP4uiv (GLenum type, const GLuint *coords); +GLAPI void APIENTRY glMultiTexCoordP1ui (GLenum texture, GLenum type, GLuint coords); +GLAPI void APIENTRY glMultiTexCoordP1uiv (GLenum texture, GLenum type, const GLuint *coords); +GLAPI void APIENTRY glMultiTexCoordP2ui (GLenum texture, GLenum type, GLuint coords); +GLAPI void APIENTRY glMultiTexCoordP2uiv (GLenum texture, GLenum type, const GLuint *coords); +GLAPI void APIENTRY glMultiTexCoordP3ui (GLenum texture, GLenum type, GLuint coords); +GLAPI void APIENTRY glMultiTexCoordP3uiv (GLenum texture, GLenum type, const GLuint *coords); +GLAPI void APIENTRY glMultiTexCoordP4ui (GLenum texture, GLenum type, GLuint coords); +GLAPI void APIENTRY glMultiTexCoordP4uiv (GLenum texture, GLenum type, const GLuint *coords); +GLAPI void APIENTRY glNormalP3ui (GLenum type, GLuint coords); +GLAPI void APIENTRY glNormalP3uiv (GLenum type, const GLuint *coords); +GLAPI void APIENTRY glColorP3ui (GLenum type, GLuint color); +GLAPI void APIENTRY glColorP3uiv (GLenum type, const GLuint *color); +GLAPI void APIENTRY glColorP4ui (GLenum type, GLuint color); +GLAPI void APIENTRY glColorP4uiv (GLenum type, const GLuint *color); +GLAPI void APIENTRY glSecondaryColorP3ui (GLenum type, GLuint color); +GLAPI void APIENTRY glSecondaryColorP3uiv (GLenum type, const GLuint *color); +GLAPI void APIENTRY glVertexAttribP1ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); +GLAPI void APIENTRY glVertexAttribP1uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +GLAPI void APIENTRY glVertexAttribP2ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); +GLAPI void APIENTRY glVertexAttribP2uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +GLAPI void APIENTRY glVertexAttribP3ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); +GLAPI void APIENTRY glVertexAttribP3uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +GLAPI void APIENTRY glVertexAttribP4ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); +GLAPI void APIENTRY glVertexAttribP4uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXP2UIPROC) (GLenum type, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXP2UIVPROC) (GLenum type, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXP3UIPROC) (GLenum type, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXP3UIVPROC) (GLenum type, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXP4UIPROC) (GLenum type, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXP4UIVPROC) (GLenum type, const GLuint *value); +typedef void (APIENTRYP PFNGLTEXCOORDP1UIPROC) (GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLTEXCOORDP1UIVPROC) (GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLTEXCOORDP2UIPROC) (GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLTEXCOORDP2UIVPROC) (GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLTEXCOORDP3UIPROC) (GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLTEXCOORDP3UIVPROC) (GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLTEXCOORDP4UIPROC) (GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLTEXCOORDP4UIVPROC) (GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIPROC) (GLenum texture, GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLNORMALP3UIPROC) (GLenum type, GLuint coords); +typedef void (APIENTRYP PFNGLNORMALP3UIVPROC) (GLenum type, const GLuint *coords); +typedef void (APIENTRYP PFNGLCOLORP3UIPROC) (GLenum type, GLuint color); +typedef void (APIENTRYP PFNGLCOLORP3UIVPROC) (GLenum type, const GLuint *color); +typedef void (APIENTRYP PFNGLCOLORP4UIPROC) (GLenum type, GLuint color); +typedef void (APIENTRYP PFNGLCOLORP4UIVPROC) (GLenum type, const GLuint *color); +typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIPROC) (GLenum type, GLuint color); +typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIVPROC) (GLenum type, const GLuint *color); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); +#endif + +#ifndef GL_ARB_draw_indirect +#define GL_ARB_draw_indirect 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glDrawArraysIndirect (GLenum mode, const GLvoid *indirect); +GLAPI void APIENTRY glDrawElementsIndirect (GLenum mode, GLenum type, const GLvoid *indirect); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const GLvoid *indirect); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const GLvoid *indirect); +#endif + +#ifndef GL_ARB_gpu_shader5 +#define GL_ARB_gpu_shader5 1 +#endif + +#ifndef GL_ARB_gpu_shader_fp64 +#define GL_ARB_gpu_shader_fp64 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glUniform1d (GLint location, GLdouble x); +GLAPI void APIENTRY glUniform2d (GLint location, GLdouble x, GLdouble y); +GLAPI void APIENTRY glUniform3d (GLint location, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glUniform4d (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glUniform1dv (GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glUniform2dv (GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glUniform3dv (GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glUniform4dv (GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix2x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix2x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix3x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix3x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix4x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glUniformMatrix4x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glGetUniformdv (GLuint program, GLint location, GLdouble *params); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLUNIFORM1DPROC) (GLint location, GLdouble x); +typedef void (APIENTRYP PFNGLUNIFORM2DPROC) (GLint location, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLUNIFORM3DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLUNIFORM4DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLUNIFORM1DVPROC) (GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORM2DVPROC) (GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORM3DVPROC) (GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORM4DVPROC) (GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location, GLdouble *params); +#endif + +#ifndef GL_ARB_shader_subroutine +#define GL_ARB_shader_subroutine 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI GLint APIENTRY glGetSubroutineUniformLocation (GLuint program, GLenum shadertype, const GLchar *name); +GLAPI GLuint APIENTRY glGetSubroutineIndex (GLuint program, GLenum shadertype, const GLchar *name); +GLAPI void APIENTRY glGetActiveSubroutineUniformiv (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); +GLAPI void APIENTRY glGetActiveSubroutineUniformName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); +GLAPI void APIENTRY glGetActiveSubroutineName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); +GLAPI void APIENTRY glUniformSubroutinesuiv (GLenum shadertype, GLsizei count, const GLuint *indices); +GLAPI void APIENTRY glGetUniformSubroutineuiv (GLenum shadertype, GLint location, GLuint *params); +GLAPI void APIENTRY glGetProgramStageiv (GLuint program, GLenum shadertype, GLenum pname, GLint *values); +#endif /* GLCOREARB_PROTOTYPES */ +typedef GLint (APIENTRYP PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar *name); +typedef GLuint (APIENTRYP PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); +typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); +typedef void (APIENTRYP PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint *indices); +typedef void (APIENTRYP PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint *values); +#endif + +#ifndef GL_ARB_tessellation_shader +#define GL_ARB_tessellation_shader 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glPatchParameteri (GLenum pname, GLint value); +GLAPI void APIENTRY glPatchParameterfv (GLenum pname, const GLfloat *values); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value); +typedef void (APIENTRYP PFNGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat *values); +#endif + +#ifndef GL_ARB_texture_buffer_object_rgb32 +#define GL_ARB_texture_buffer_object_rgb32 1 +#endif + +#ifndef GL_ARB_transform_feedback2 +#define GL_ARB_transform_feedback2 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glBindTransformFeedback (GLenum target, GLuint id); +GLAPI void APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids); +GLAPI void APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids); +GLAPI GLboolean APIENTRY glIsTransformFeedback (GLuint id); +GLAPI void APIENTRY glPauseTransformFeedback (void); +GLAPI void APIENTRY glResumeTransformFeedback (void); +GLAPI void APIENTRY glDrawTransformFeedback (GLenum mode, GLuint id); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id); +typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint *ids); +typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids); +typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id); +typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC) (void); +typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC) (void); +typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id); +#endif + +#ifndef GL_ARB_transform_feedback3 +#define GL_ARB_transform_feedback3 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glDrawTransformFeedbackStream (GLenum mode, GLuint id, GLuint stream); +GLAPI void APIENTRY glBeginQueryIndexed (GLenum target, GLuint index, GLuint id); +GLAPI void APIENTRY glEndQueryIndexed (GLenum target, GLuint index); +GLAPI void APIENTRY glGetQueryIndexediv (GLenum target, GLuint index, GLenum pname, GLint *params); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream); +typedef void (APIENTRYP PFNGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id); +typedef void (APIENTRYP PFNGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index); +typedef void (APIENTRYP PFNGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); +#endif + +#ifndef GL_ARB_ES2_compatibility +#define GL_ARB_ES2_compatibility 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glReleaseShaderCompiler (void); +GLAPI void APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length); +GLAPI void APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); +GLAPI void APIENTRY glDepthRangef (GLfloat n, GLfloat f); +GLAPI void APIENTRY glClearDepthf (GLfloat d); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void); +typedef void (APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length); +typedef void (APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); +typedef void (APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f); +typedef void (APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d); +#endif + +#ifndef GL_ARB_get_program_binary +#define GL_ARB_get_program_binary 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary); +GLAPI void APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLsizei length); +GLAPI void APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary); +typedef void (APIENTRYP PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLsizei length); +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value); +#endif + +#ifndef GL_ARB_separate_shader_objects +#define GL_ARB_separate_shader_objects 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program); +GLAPI void APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program); +GLAPI GLuint APIENTRY glCreateShaderProgramv (GLenum type, GLsizei count, const GLchar* const *strings); +GLAPI void APIENTRY glBindProgramPipeline (GLuint pipeline); +GLAPI void APIENTRY glDeleteProgramPipelines (GLsizei n, const GLuint *pipelines); +GLAPI void APIENTRY glGenProgramPipelines (GLsizei n, GLuint *pipelines); +GLAPI GLboolean APIENTRY glIsProgramPipeline (GLuint pipeline); +GLAPI void APIENTRY glGetProgramPipelineiv (GLuint pipeline, GLenum pname, GLint *params); +GLAPI void APIENTRY glProgramUniform1i (GLuint program, GLint location, GLint v0); +GLAPI void APIENTRY glProgramUniform1iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform1f (GLuint program, GLint location, GLfloat v0); +GLAPI void APIENTRY glProgramUniform1fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform1d (GLuint program, GLint location, GLdouble v0); +GLAPI void APIENTRY glProgramUniform1dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform1ui (GLuint program, GLint location, GLuint v0); +GLAPI void APIENTRY glProgramUniform1uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniform2i (GLuint program, GLint location, GLint v0, GLint v1); +GLAPI void APIENTRY glProgramUniform2iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform2f (GLuint program, GLint location, GLfloat v0, GLfloat v1); +GLAPI void APIENTRY glProgramUniform2fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform2d (GLuint program, GLint location, GLdouble v0, GLdouble v1); +GLAPI void APIENTRY glProgramUniform2dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform2ui (GLuint program, GLint location, GLuint v0, GLuint v1); +GLAPI void APIENTRY glProgramUniform2uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniform3i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +GLAPI void APIENTRY glProgramUniform3iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform3f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GLAPI void APIENTRY glProgramUniform3fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform3d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); +GLAPI void APIENTRY glProgramUniform3dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform3ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +GLAPI void APIENTRY glProgramUniform3uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniform4i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GLAPI void APIENTRY glProgramUniform4iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GLAPI void APIENTRY glProgramUniform4f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GLAPI void APIENTRY glProgramUniform4fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GLAPI void APIENTRY glProgramUniform4d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); +GLAPI void APIENTRY glProgramUniform4dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); +GLAPI void APIENTRY glProgramUniform4ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GLAPI void APIENTRY glProgramUniform4uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glProgramUniformMatrix2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix2x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix3x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix2x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix4x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix3x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix4x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLAPI void APIENTRY glProgramUniformMatrix2x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix3x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix2x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix4x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix3x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glProgramUniformMatrix4x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +GLAPI void APIENTRY glValidateProgramPipeline (GLuint pipeline); +GLAPI void APIENTRY glGetProgramPipelineInfoLog (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program); +typedef void (APIENTRYP PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program); +typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar* const *strings); +typedef void (APIENTRYP PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef void (APIENTRYP PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint *pipelines); +typedef void (APIENTRYP PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines); +typedef GLboolean (APIENTRYP PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DPROC) (GLuint program, GLint location, GLdouble v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint v0); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint v0, GLint v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); +typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +#endif + +#ifndef GL_ARB_vertex_attrib_64bit +#define GL_ARB_vertex_attrib_64bit 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glVertexAttribL1d (GLuint index, GLdouble x); +GLAPI void APIENTRY glVertexAttribL2d (GLuint index, GLdouble x, GLdouble y); +GLAPI void APIENTRY glVertexAttribL3d (GLuint index, GLdouble x, GLdouble y, GLdouble z); +GLAPI void APIENTRY glVertexAttribL4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +GLAPI void APIENTRY glVertexAttribL1dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribL2dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribL3dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribL4dv (GLuint index, const GLdouble *v); +GLAPI void APIENTRY glVertexAttribLPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +GLAPI void APIENTRY glGetVertexAttribLdv (GLuint index, GLenum pname, GLdouble *params); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DPROC) (GLuint index, GLdouble x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVPROC) (GLuint index, const GLdouble *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVPROC) (GLuint index, GLenum pname, GLdouble *params); +#endif + +#ifndef GL_ARB_viewport_array +#define GL_ARB_viewport_array 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glViewportArrayv (GLuint first, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glViewportIndexedf (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +GLAPI void APIENTRY glViewportIndexedfv (GLuint index, const GLfloat *v); +GLAPI void APIENTRY glScissorArrayv (GLuint first, GLsizei count, const GLint *v); +GLAPI void APIENTRY glScissorIndexed (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +GLAPI void APIENTRY glScissorIndexedv (GLuint index, const GLint *v); +GLAPI void APIENTRY glDepthRangeArrayv (GLuint first, GLsizei count, const GLdouble *v); +GLAPI void APIENTRY glDepthRangeIndexed (GLuint index, GLdouble n, GLdouble f); +GLAPI void APIENTRY glGetFloati_v (GLenum target, GLuint index, GLfloat *data); +GLAPI void APIENTRY glGetDoublei_v (GLenum target, GLuint index, GLdouble *data); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVIEWPORTARRAYVPROC) (GLuint first, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFVPROC) (GLuint index, const GLfloat *v); +typedef void (APIENTRYP PFNGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint *v); +typedef void (APIENTRYP PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLSCISSORINDEXEDVPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLdouble n, GLdouble f); +typedef void (APIENTRYP PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat *data); +typedef void (APIENTRYP PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data); +#endif + +#ifndef GL_ARB_cl_event +#define GL_ARB_cl_event 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI GLsync APIENTRY glCreateSyncFromCLeventARB (struct _cl_context * context, struct _cl_event * event, GLbitfield flags); +#endif /* GLCOREARB_PROTOTYPES */ +typedef GLsync (APIENTRYP PFNGLCREATESYNCFROMCLEVENTARBPROC) (struct _cl_context * context, struct _cl_event * event, GLbitfield flags); +#endif + +#ifndef GL_ARB_debug_output +#define GL_ARB_debug_output 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glDebugMessageControlARB (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +GLAPI void APIENTRY glDebugMessageInsertARB (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +GLAPI void APIENTRY glDebugMessageCallbackARB (GLDEBUGPROCARB callback, const GLvoid *userParam); +GLAPI GLuint APIENTRY glGetDebugMessageLogARB (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const GLvoid *userParam); +typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +#endif + +#ifndef GL_ARB_robustness +#define GL_ARB_robustness 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI GLenum APIENTRY glGetGraphicsResetStatusARB (void); +GLAPI void APIENTRY glGetnMapdvARB (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); +GLAPI void APIENTRY glGetnMapfvARB (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); +GLAPI void APIENTRY glGetnMapivARB (GLenum target, GLenum query, GLsizei bufSize, GLint *v); +GLAPI void APIENTRY glGetnPixelMapfvARB (GLenum map, GLsizei bufSize, GLfloat *values); +GLAPI void APIENTRY glGetnPixelMapuivARB (GLenum map, GLsizei bufSize, GLuint *values); +GLAPI void APIENTRY glGetnPixelMapusvARB (GLenum map, GLsizei bufSize, GLushort *values); +GLAPI void APIENTRY glGetnPolygonStippleARB (GLsizei bufSize, GLubyte *pattern); +GLAPI void APIENTRY glGetnColorTableARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *table); +GLAPI void APIENTRY glGetnConvolutionFilterARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *image); +GLAPI void APIENTRY glGetnSeparableFilterARB (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, GLvoid *row, GLsizei columnBufSize, GLvoid *column, GLvoid *span); +GLAPI void APIENTRY glGetnHistogramARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values); +GLAPI void APIENTRY glGetnMinmaxARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values); +GLAPI void APIENTRY glGetnTexImageARB (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid *img); +GLAPI void APIENTRY glReadnPixelsARB (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data); +GLAPI void APIENTRY glGetnCompressedTexImageARB (GLenum target, GLint lod, GLsizei bufSize, GLvoid *img); +GLAPI void APIENTRY glGetnUniformfvARB (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +GLAPI void APIENTRY glGetnUniformivARB (GLuint program, GLint location, GLsizei bufSize, GLint *params); +GLAPI void APIENTRY glGetnUniformuivARB (GLuint program, GLint location, GLsizei bufSize, GLuint *params); +GLAPI void APIENTRY glGetnUniformdvARB (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); +#endif /* GLCOREARB_PROTOTYPES */ +typedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSARBPROC) (void); +typedef void (APIENTRYP PFNGLGETNMAPDVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); +typedef void (APIENTRYP PFNGLGETNMAPFVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); +typedef void (APIENTRYP PFNGLGETNMAPIVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint *v); +typedef void (APIENTRYP PFNGLGETNPIXELMAPFVARBPROC) (GLenum map, GLsizei bufSize, GLfloat *values); +typedef void (APIENTRYP PFNGLGETNPIXELMAPUIVARBPROC) (GLenum map, GLsizei bufSize, GLuint *values); +typedef void (APIENTRYP PFNGLGETNPIXELMAPUSVARBPROC) (GLenum map, GLsizei bufSize, GLushort *values); +typedef void (APIENTRYP PFNGLGETNPOLYGONSTIPPLEARBPROC) (GLsizei bufSize, GLubyte *pattern); +typedef void (APIENTRYP PFNGLGETNCOLORTABLEARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *table); +typedef void (APIENTRYP PFNGLGETNCONVOLUTIONFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *image); +typedef void (APIENTRYP PFNGLGETNSEPARABLEFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, GLvoid *row, GLsizei columnBufSize, GLvoid *column, GLvoid *span); +typedef void (APIENTRYP PFNGLGETNHISTOGRAMARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values); +typedef void (APIENTRYP PFNGLGETNMINMAXARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values); +typedef void (APIENTRYP PFNGLGETNTEXIMAGEARBPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid *img); +typedef void (APIENTRYP PFNGLREADNPIXELSARBPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data); +typedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLsizei bufSize, GLvoid *img); +typedef void (APIENTRYP PFNGLGETNUNIFORMFVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +typedef void (APIENTRYP PFNGLGETNUNIFORMIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); +typedef void (APIENTRYP PFNGLGETNUNIFORMUIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params); +typedef void (APIENTRYP PFNGLGETNUNIFORMDVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); +#endif + +#ifndef GL_ARB_shader_stencil_export +#define GL_ARB_shader_stencil_export 1 +#endif + +#ifndef GL_ARB_base_instance +#define GL_ARB_base_instance 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); +GLAPI void APIENTRY glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); +GLAPI void APIENTRY glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); +#endif + +#ifndef GL_ARB_shading_language_420pack +#define GL_ARB_shading_language_420pack 1 +#endif + +#ifndef GL_ARB_transform_feedback_instanced +#define GL_ARB_transform_feedback_instanced 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glDrawTransformFeedbackInstanced (GLenum mode, GLuint id, GLsizei instancecount); +GLAPI void APIENTRY glDrawTransformFeedbackStreamInstanced (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei instancecount); +typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); +#endif + +#ifndef GL_ARB_compressed_texture_pixel_storage +#define GL_ARB_compressed_texture_pixel_storage 1 +#endif + +#ifndef GL_ARB_conservative_depth +#define GL_ARB_conservative_depth 1 +#endif + +#ifndef GL_ARB_internalformat_query +#define GL_ARB_internalformat_query 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +#endif + +#ifndef GL_ARB_map_buffer_alignment +#define GL_ARB_map_buffer_alignment 1 +#endif + +#ifndef GL_ARB_shader_atomic_counters +#define GL_ARB_shader_atomic_counters 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glGetActiveAtomicCounterBufferiv (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); +#endif + +#ifndef GL_ARB_shader_image_load_store +#define GL_ARB_shader_image_load_store 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glBindImageTexture (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); +GLAPI void APIENTRY glMemoryBarrier (GLbitfield barriers); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); +typedef void (APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers); +#endif + +#ifndef GL_ARB_shading_language_packing +#define GL_ARB_shading_language_packing 1 +#endif + +#ifndef GL_ARB_texture_storage +#define GL_ARB_texture_storage 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glTexStorage1D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GLAPI void APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GLAPI void APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GLAPI void APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXSTORAGE1DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +#endif + +#ifndef GL_KHR_texture_compression_astc_ldr +#define GL_KHR_texture_compression_astc_ldr 1 +#endif + +#ifndef GL_KHR_debug +#define GL_KHR_debug 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glDebugMessageControl (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +GLAPI void APIENTRY glDebugMessageInsert (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +GLAPI void APIENTRY glDebugMessageCallback (GLDEBUGPROC callback, const void *userParam); +GLAPI GLuint APIENTRY glGetDebugMessageLog (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +GLAPI void APIENTRY glPushDebugGroup (GLenum source, GLuint id, GLsizei length, const GLchar *message); +GLAPI void APIENTRY glPopDebugGroup (void); +GLAPI void APIENTRY glObjectLabel (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +GLAPI void APIENTRY glGetObjectLabel (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +GLAPI void APIENTRY glObjectPtrLabel (const void *ptr, GLsizei length, const GLchar *label); +GLAPI void APIENTRY glGetObjectPtrLabel (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam); +typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +typedef void (APIENTRYP PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message); +typedef void (APIENTRYP PFNGLPOPDEBUGGROUPPROC) (void); +typedef void (APIENTRYP PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +typedef void (APIENTRYP PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +typedef void (APIENTRYP PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label); +typedef void (APIENTRYP PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +#endif + +#ifndef GL_ARB_arrays_of_arrays +#define GL_ARB_arrays_of_arrays 1 +#endif + +#ifndef GL_ARB_clear_buffer_object +#define GL_ARB_clear_buffer_object 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glClearBufferData (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glClearBufferSubData (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glClearNamedBufferDataEXT (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glClearNamedBufferSubDataEXT (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, GLsizeiptr offset, GLsizeiptr size, const void *data); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCLEARBUFFERDATAPROC) (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLCLEARBUFFERSUBDATAPROC) (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, GLsizeiptr offset, GLsizeiptr size, const void *data); +#endif + +#ifndef GL_ARB_compute_shader +#define GL_ARB_compute_shader 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glDispatchCompute (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +GLAPI void APIENTRY glDispatchComputeIndirect (GLintptr indirect); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect); +#endif + +#ifndef GL_ARB_copy_image +#define GL_ARB_copy_image 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glCopyImageSubData (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +#endif + +#ifndef GL_ARB_texture_view +#define GL_ARB_texture_view 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glTextureView (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXTUREVIEWPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); +#endif + +#ifndef GL_ARB_vertex_attrib_binding +#define GL_ARB_vertex_attrib_binding 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glBindVertexBuffer (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +GLAPI void APIENTRY glVertexAttribFormat (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +GLAPI void APIENTRY glVertexAttribIFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GLAPI void APIENTRY glVertexAttribLFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GLAPI void APIENTRY glVertexAttribBinding (GLuint attribindex, GLuint bindingindex); +GLAPI void APIENTRY glVertexBindingDivisor (GLuint bindingindex, GLuint divisor); +GLAPI void APIENTRY glVertexArrayBindVertexBufferEXT (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +GLAPI void APIENTRY glVertexArrayVertexAttribFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +GLAPI void APIENTRY glVertexArrayVertexAttribIFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GLAPI void APIENTRY glVertexArrayVertexAttribLFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GLAPI void APIENTRY glVertexArrayVertexAttribBindingEXT (GLuint vaobj, GLuint attribindex, GLuint bindingindex); +GLAPI void APIENTRY glVertexArrayVertexBindingDivisorEXT (GLuint vaobj, GLuint bindingindex, GLuint divisor); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex); +typedef void (APIENTRYP PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor); +typedef void (APIENTRYP PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); +#endif + +#ifndef GL_ARB_robustness_isolation +#define GL_ARB_robustness_isolation 1 +#endif + +#ifndef GL_ARB_ES3_compatibility +#define GL_ARB_ES3_compatibility 1 +#endif + +#ifndef GL_ARB_explicit_uniform_location +#define GL_ARB_explicit_uniform_location 1 +#endif + +#ifndef GL_ARB_fragment_layer_viewport +#define GL_ARB_fragment_layer_viewport 1 +#endif + +#ifndef GL_ARB_framebuffer_no_attachments +#define GL_ARB_framebuffer_no_attachments 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glFramebufferParameteri (GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glGetFramebufferParameteriv (GLenum target, GLenum pname, GLint *params); +GLAPI void APIENTRY glNamedFramebufferParameteriEXT (GLuint framebuffer, GLenum pname, GLint param); +GLAPI void APIENTRY glGetNamedFramebufferParameterivEXT (GLuint framebuffer, GLenum pname, GLint *params); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC) (GLuint framebuffer, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params); +#endif + +#ifndef GL_ARB_internalformat_query2 +#define GL_ARB_internalformat_query2 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glGetInternalformati64v (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params); +#endif + +#ifndef GL_ARB_invalidate_subdata +#define GL_ARB_invalidate_subdata 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glInvalidateTexSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); +GLAPI void APIENTRY glInvalidateTexImage (GLuint texture, GLint level); +GLAPI void APIENTRY glInvalidateBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr length); +GLAPI void APIENTRY glInvalidateBufferData (GLuint buffer); +GLAPI void APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments); +GLAPI void APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLINVALIDATETEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); +typedef void (APIENTRYP PFNGLINVALIDATETEXIMAGEPROC) (GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLINVALIDATEBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); +typedef void (APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); +typedef void (APIENTRYP PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); +#endif + +#ifndef GL_ARB_multi_draw_indirect +#define GL_ARB_multi_draw_indirect 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glMultiDrawArraysIndirect (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); +GLAPI void APIENTRY glMultiDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); +#endif + +#ifndef GL_ARB_program_interface_query +#define GL_ARB_program_interface_query 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glGetProgramInterfaceiv (GLuint program, GLenum programInterface, GLenum pname, GLint *params); +GLAPI GLuint APIENTRY glGetProgramResourceIndex (GLuint program, GLenum programInterface, const GLchar *name); +GLAPI void APIENTRY glGetProgramResourceName (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); +GLAPI void APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); +GLAPI GLint APIENTRY glGetProgramResourceLocation (GLuint program, GLenum programInterface, const GLchar *name); +GLAPI GLint APIENTRY glGetProgramResourceLocationIndex (GLuint program, GLenum programInterface, const GLchar *name); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint *params); +typedef GLuint (APIENTRYP PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); +typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); +typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); +typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); +#endif + +#ifndef GL_ARB_robust_buffer_access_behavior +#define GL_ARB_robust_buffer_access_behavior 1 +#endif + +#ifndef GL_ARB_shader_image_size +#define GL_ARB_shader_image_size 1 +#endif + +#ifndef GL_ARB_shader_storage_buffer_object +#define GL_ARB_shader_storage_buffer_object 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glShaderStorageBlockBinding (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSHADERSTORAGEBLOCKBINDINGPROC) (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); +#endif + +#ifndef GL_ARB_stencil_texturing +#define GL_ARB_stencil_texturing 1 +#endif + +#ifndef GL_ARB_texture_buffer_range +#define GL_ARB_texture_buffer_range 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glTexBufferRange (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +GLAPI void APIENTRY glTextureBufferRangeEXT (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXBUFFERRANGEPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLTEXTUREBUFFERRANGEEXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +#endif + +#ifndef GL_ARB_texture_query_levels +#define GL_ARB_texture_query_levels 1 +#endif + +#ifndef GL_ARB_texture_storage_multisample +#define GL_ARB_texture_storage_multisample 1 +#ifdef GLCOREARB_PROTOTYPES +GLAPI void APIENTRY glTexStorage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glTexStorage3DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glTextureStorage2DMultisampleEXT (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glTextureStorage3DMultisampleEXT (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +#endif /* GLCOREARB_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/GLES3/CMakeLists.txt b/external/GLES3/CMakeLists.txt new file mode 100644 index 000000000..420ee834b --- /dev/null +++ b/external/GLES3/CMakeLists.txt @@ -0,0 +1 @@ +install(FILES gl3.h gl3platform.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/external/GLES3) diff --git a/external/GLES3/gl3.h b/external/GLES3/gl3.h new file mode 100644 index 000000000..738232eaa --- /dev/null +++ b/external/GLES3/gl3.h @@ -0,0 +1,1063 @@ +#ifndef __gl3_h_ +#define __gl3_h_ + +/* + * gl3.h last updated on $Date: 2012-07-23 03:53:52 -0700 (Mon, 23 Jul 2012) $ + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2007-2012 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/*------------------------------------------------------------------------- + * Data type definitions + *-----------------------------------------------------------------------*/ + +/* OpenGL ES 2.0 */ + +typedef void GLvoid; +typedef char GLchar; +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef khronos_int8_t GLbyte; +typedef short GLshort; +typedef int GLint; +typedef int GLsizei; +typedef khronos_uint8_t GLubyte; +typedef unsigned short GLushort; +typedef unsigned int GLuint; +typedef khronos_float_t GLfloat; +typedef khronos_float_t GLclampf; +typedef khronos_int32_t GLfixed; +typedef khronos_intptr_t GLintptr; +typedef khronos_ssize_t GLsizeiptr; + +/* OpenGL ES 3.0 */ + +typedef unsigned short GLhalf; +typedef khronos_int64_t GLint64; +typedef khronos_uint64_t GLuint64; +typedef struct __GLsync *GLsync; + +/*------------------------------------------------------------------------- + * Token definitions + *-----------------------------------------------------------------------*/ + +/* OpenGL ES core versions */ +#define GL_ES_VERSION_3_0 1 +#define GL_ES_VERSION_2_0 1 + +/* OpenGL ES 2.0 */ + +/* ClearBufferMask */ +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_COLOR_BUFFER_BIT 0x00004000 + +/* Boolean */ +#define GL_FALSE 0 +#define GL_TRUE 1 + +/* BeginMode */ +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 + +/* BlendingFactorDest */ +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 + +/* BlendingFactorSrc */ +/* GL_ZERO */ +/* GL_ONE */ +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +/* GL_SRC_ALPHA */ +/* GL_ONE_MINUS_SRC_ALPHA */ +/* GL_DST_ALPHA */ +/* GL_ONE_MINUS_DST_ALPHA */ + +/* BlendEquationSeparate */ +#define GL_FUNC_ADD 0x8006 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_RGB 0x8009 /* same as BLEND_EQUATION */ +#define GL_BLEND_EQUATION_ALPHA 0x883D + +/* BlendSubtract */ +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B + +/* Separate Blend Functions */ +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 + +/* Buffer Objects */ +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 + +#define GL_STREAM_DRAW 0x88E0 +#define GL_STATIC_DRAW 0x88E4 +#define GL_DYNAMIC_DRAW 0x88E8 + +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 + +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 + +/* CullFaceMode */ +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_FRONT_AND_BACK 0x0408 + +/* DepthFunction */ +/* GL_NEVER */ +/* GL_LESS */ +/* GL_EQUAL */ +/* GL_LEQUAL */ +/* GL_GREATER */ +/* GL_NOTEQUAL */ +/* GL_GEQUAL */ +/* GL_ALWAYS */ + +/* EnableCap */ +#define GL_TEXTURE_2D 0x0DE1 +#define GL_CULL_FACE 0x0B44 +#define GL_BLEND 0x0BE2 +#define GL_DITHER 0x0BD0 +#define GL_STENCIL_TEST 0x0B90 +#define GL_DEPTH_TEST 0x0B71 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_COVERAGE 0x80A0 + +/* ErrorCode */ +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_OUT_OF_MEMORY 0x0505 + +/* FrontFaceDirection */ +#define GL_CW 0x0900 +#define GL_CCW 0x0901 + +/* GetPName */ +#define GL_LINE_WIDTH 0x0B21 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_VIEWPORT 0x0BA2 +#define GL_SCISSOR_BOX 0x0C10 +/* GL_SCISSOR_TEST */ +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +/* GL_POLYGON_OFFSET_FILL */ +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB + +/* GetTextureParameter */ +/* GL_TEXTURE_MAG_FILTER */ +/* GL_TEXTURE_MIN_FILTER */ +/* GL_TEXTURE_WRAP_S */ +/* GL_TEXTURE_WRAP_T */ + +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 + +/* HintMode */ +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 + +/* HintTarget */ +#define GL_GENERATE_MIPMAP_HINT 0x8192 + +/* DataType */ +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_FIXED 0x140C + +/* PixelFormat */ +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A + +/* PixelType */ +/* GL_UNSIGNED_BYTE */ +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 + +/* Shaders */ +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_SHADER_TYPE 0x8B4F +#define GL_DELETE_STATUS 0x8B80 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D + +/* StencilFunction */ +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 + +/* StencilOp */ +/* GL_ZERO */ +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_INVERT 0x150A +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 + +/* StringName */ +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 + +/* TextureMagFilter */ +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 + +/* TextureMinFilter */ +/* GL_NEAREST */ +/* GL_LINEAR */ +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 + +/* TextureParameterName */ +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 + +/* TextureTarget */ +/* GL_TEXTURE_2D */ +#define GL_TEXTURE 0x1702 + +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C + +/* TextureUnit */ +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 + +/* TextureWrapMode */ +#define GL_REPEAT 0x2901 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MIRRORED_REPEAT 0x8370 + +/* Uniform Types */ +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_CUBE 0x8B60 + +/* Vertex Arrays */ +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F + +/* Read Format */ +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B + +/* Shader Source */ +#define GL_COMPILE_STATUS 0x8B81 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_COMPILER 0x8DFA + +/* Shader Binary */ +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 + +/* Shader Precision-Specified Types */ +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 + +/* Framebuffer Object. */ +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 + +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGB565 0x8D62 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_STENCIL_INDEX8 0x8D48 + +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 + +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 + +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 + +#define GL_NONE 0 + +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD + +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 + +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 + +/* OpenGL ES 3.0 */ + +#define GL_READ_BUFFER 0x0C02 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_RED 0x1903 +#define GL_RGB8 0x8051 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_RGB9_E5 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_RGBA32UI 0x8D70 +#define GL_RGB32UI 0x8D71 +#define GL_RGBA16UI 0x8D76 +#define GL_RGB16UI 0x8D77 +#define GL_RGBA8UI 0x8D7C +#define GL_RGB8UI 0x8D7D +#define GL_RGBA32I 0x8D82 +#define GL_RGB32I 0x8D83 +#define GL_RGBA16I 0x8D88 +#define GL_RGB16I 0x8D89 +#define GL_RGBA8I 0x8D8E +#define GL_RGB8I 0x8D8F +#define GL_RED_INTEGER 0x8D94 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 +#define GL_HALF_FLOAT 0x140B +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_RG8 0x822B +#define GL_R16F 0x822D +#define GL_R32F 0x822E +#define GL_RG16F 0x822F +#define GL_RG32F 0x8230 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_COPY_READ_BUFFER_BINDING GL_COPY_READ_BUFFER +#define GL_COPY_WRITE_BUFFER_BINDING GL_COPY_WRITE_BUFFER +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_INVALID_INDEX 0xFFFFFFFFu +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_OBJECT_TYPE 0x9112 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_UNSIGNALED 0x9118 +#define GL_SIGNALED 0x9119 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_CONDITION_SATISFIED 0x911C +#define GL_WAIT_FAILED 0x911D +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_SAMPLER_BINDING 0x8919 +#define GL_RGB10_A2UI 0x906F +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_INT_2_10_10_10_REV 0x8D9F +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 +#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_PROGRAM_BINARY_LENGTH 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#define GL_PROGRAM_BINARY_FORMATS 0x87FF +#define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F +#define GL_MAX_ELEMENT_INDEX 0x8D6B +#define GL_NUM_SAMPLE_COUNTS 0x9380 +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x8D63 + +/*------------------------------------------------------------------------- + * Entrypoint definitions + *-----------------------------------------------------------------------*/ + +/* OpenGL ES 2.0 */ + +GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); +GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar* name); +GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer); +GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); +GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture); +GL_APICALL void GL_APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GL_APICALL void GL_APIENTRY glBlendEquation (GLenum mode); +GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage); +GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data); +GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target); +GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); +GL_APICALL void GL_APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GL_APICALL void GL_APIENTRY glClearDepthf (GLfloat depth); +GL_APICALL void GL_APIENTRY glClearStencil (GLint s); +GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader); +GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); +GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type); +GL_APICALL void GL_APIENTRY glCullFace (GLenum mode); +GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers); +GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers); +GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program); +GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint* renderbuffers); +GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader); +GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint* textures); +GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func); +GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); +GL_APICALL void GL_APIENTRY glDepthRangef (GLfloat n, GLfloat f); +GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glDisable (GLenum cap); +GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices); +GL_APICALL void GL_APIENTRY glEnable (GLenum cap); +GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glFinish (void); +GL_APICALL void GL_APIENTRY glFlush (void); +GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode); +GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers); +GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target); +GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers); +GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers); +GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint* textures); +GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name); +GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders); +GL_APICALL int GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name); +GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params); +GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL GLenum GL_APIENTRY glGetError (void); +GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog); +GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog); +GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision); +GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source); +GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenum name); +GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint* params); +GL_APICALL int GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar* name); +GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid** pointer); +GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode); +GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer); +GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap); +GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer); +GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program); +GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer); +GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader); +GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture); +GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); +GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program); +GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels); +GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); +GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert); +GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length); +GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length); +GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat* params); +GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint* params); +GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat x); +GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint x); +GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint x, GLint y); +GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint x, GLint y, GLint z); +GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUseProgram (GLuint program); +GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program); +GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint indx, GLfloat x); +GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint indx, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr); +GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); + +/* OpenGL ES 3.0 */ + +GL_APICALL void GL_APIENTRY glReadBuffer (GLenum mode); +GL_APICALL void GL_APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices); +GL_APICALL void GL_APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glGenQueries (GLsizei n, GLuint* ids); +GL_APICALL void GL_APIENTRY glDeleteQueries (GLsizei n, const GLuint* ids); +GL_APICALL GLboolean GL_APIENTRY glIsQuery (GLuint id); +GL_APICALL void GL_APIENTRY glBeginQuery (GLenum target, GLuint id); +GL_APICALL void GL_APIENTRY glEndQuery (GLenum target); +GL_APICALL void GL_APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint* params); +GL_APICALL GLboolean GL_APIENTRY glUnmapBuffer (GLenum target); +GL_APICALL void GL_APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, GLvoid** params); +GL_APICALL void GL_APIENTRY glDrawBuffers (GLsizei n, const GLenum* bufs); +GL_APICALL void GL_APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +GL_APICALL GLvoid* GL_APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +GL_APICALL void GL_APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length); +GL_APICALL void GL_APIENTRY glBindVertexArray (GLuint array); +GL_APICALL void GL_APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint* arrays); +GL_APICALL void GL_APIENTRY glGenVertexArrays (GLsizei n, GLuint* arrays); +GL_APICALL GLboolean GL_APIENTRY glIsVertexArray (GLuint array); +GL_APICALL void GL_APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint* data); +GL_APICALL void GL_APIENTRY glBeginTransformFeedback (GLenum primitiveMode); +GL_APICALL void GL_APIENTRY glEndTransformFeedback (void); +GL_APICALL void GL_APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +GL_APICALL void GL_APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer); +GL_APICALL void GL_APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode); +GL_APICALL void GL_APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name); +GL_APICALL void GL_APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer); +GL_APICALL void GL_APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint* params); +GL_APICALL void GL_APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void GL_APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GL_APICALL void GL_APIENTRY glVertexAttribI4iv (GLuint index, const GLint* v); +GL_APICALL void GL_APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint* v); +GL_APICALL void GL_APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint* params); +GL_APICALL GLint GL_APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name); +GL_APICALL void GL_APIENTRY glUniform1ui (GLint location, GLuint v0); +GL_APICALL void GL_APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1); +GL_APICALL void GL_APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2); +GL_APICALL void GL_APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GL_APICALL void GL_APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint* value); +GL_APICALL void GL_APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint* value); +GL_APICALL void GL_APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint* value); +GL_APICALL void GL_APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint* value); +GL_APICALL void GL_APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint* value); +GL_APICALL void GL_APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint* value); +GL_APICALL void GL_APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat* value); +GL_APICALL void GL_APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +GL_APICALL const GLubyte* GL_APIENTRY glGetStringi (GLenum name, GLuint index); +GL_APICALL void GL_APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +GL_APICALL void GL_APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices); +GL_APICALL void GL_APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params); +GL_APICALL GLuint GL_APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar* uniformBlockName); +GL_APICALL void GL_APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName); +GL_APICALL void GL_APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +GL_APICALL void GL_APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instanceCount); +GL_APICALL void GL_APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount); +GL_APICALL GLsync GL_APIENTRY glFenceSync (GLenum condition, GLbitfield flags); +GL_APICALL GLboolean GL_APIENTRY glIsSync (GLsync sync); +GL_APICALL void GL_APIENTRY glDeleteSync (GLsync sync); +GL_APICALL GLenum GL_APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glGetInteger64v (GLenum pname, GLint64* params); +GL_APICALL void GL_APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values); +GL_APICALL void GL_APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64* data); +GL_APICALL void GL_APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64* params); +GL_APICALL void GL_APIENTRY glGenSamplers (GLsizei count, GLuint* samplers); +GL_APICALL void GL_APIENTRY glDeleteSamplers (GLsizei count, const GLuint* samplers); +GL_APICALL GLboolean GL_APIENTRY glIsSampler (GLuint sampler); +GL_APICALL void GL_APIENTRY glBindSampler (GLuint unit, GLuint sampler); +GL_APICALL void GL_APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint* param); +GL_APICALL void GL_APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat* param); +GL_APICALL void GL_APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor); +GL_APICALL void GL_APIENTRY glBindTransformFeedback (GLenum target, GLuint id); +GL_APICALL void GL_APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint* ids); +GL_APICALL void GL_APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint* ids); +GL_APICALL GLboolean GL_APIENTRY glIsTransformFeedback (GLuint id); +GL_APICALL void GL_APIENTRY glPauseTransformFeedback (void); +GL_APICALL void GL_APIENTRY glResumeTransformFeedback (void); +GL_APICALL void GL_APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary); +GL_APICALL void GL_APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length); +GL_APICALL void GL_APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value); +GL_APICALL void GL_APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum* attachments); +GL_APICALL void GL_APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GL_APICALL void GL_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/GLES3/gl3platform.h b/external/GLES3/gl3platform.h new file mode 100644 index 000000000..1bd1a850f --- /dev/null +++ b/external/GLES3/gl3platform.h @@ -0,0 +1,30 @@ +#ifndef __gl3platform_h_ +#define __gl3platform_h_ + +/* $Revision: 18437 $ on $Date:: 2012-07-08 23:31:39 -0700 #$ */ + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +/* Platform-specific types and definitions for OpenGL ES 3.X gl3.h + * + * Adopters may modify khrplatform.h and this file to suit their platform. + * You are encouraged to submit all modifications to the Khronos group so that + * they can be included in future versions of this file. Please submit changes + * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla) + * by filing a bug against product "OpenGL-ES" component "Registry". + */ + +#include + +#ifndef GL_APICALL +#define GL_APICALL KHRONOS_APICALL +#endif + +#ifndef GL_APIENTRY +#define GL_APIENTRY KHRONOS_APIENTRY +#endif + +#endif /* __gl3platform_h_ */ diff --git a/external/KHR/CMakeLists.txt b/external/KHR/CMakeLists.txt new file mode 100644 index 000000000..19c9ed8d8 --- /dev/null +++ b/external/KHR/CMakeLists.txt @@ -0,0 +1 @@ +install(FILES khrplatform.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/external/KHR) diff --git a/external/KHR/khrplatform.h b/external/KHR/khrplatform.h new file mode 100644 index 000000000..8ec0d199f --- /dev/null +++ b/external/KHR/khrplatform.h @@ -0,0 +1,269 @@ +#ifndef __khrplatform_h_ +#define __khrplatform_h_ + +/* +** Copyright (c) 2008-2009 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* Khronos platform-specific types and definitions. + * + * $Revision: 9356 $ on $Date: 2009-10-21 02:52:25 -0700 (Wed, 21 Oct 2009) $ + * + * Adopters may modify this file to suit their platform. Adopters are + * encouraged to submit platform specific modifications to the Khronos + * group so that they can be included in future versions of this file. + * Please submit changes by sending them to the public Khronos Bugzilla + * (http://khronos.org/bugzilla) by filing a bug against product + * "Khronos (general)" component "Registry". + * + * A predefined template which fills in some of the bug fields can be + * reached using http://tinyurl.com/khrplatform-h-bugreport, but you + * must create a Bugzilla login first. + * + * + * See the Implementer's Guidelines for information about where this file + * should be located on your system and for more details of its use: + * http://www.khronos.org/registry/implementers_guide.pdf + * + * This file should be included as + * #include + * by Khronos client API header files that use its types and defines. + * + * The types in khrplatform.h should only be used to define API-specific types. + * + * Types defined in khrplatform.h: + * khronos_int8_t signed 8 bit + * khronos_uint8_t unsigned 8 bit + * khronos_int16_t signed 16 bit + * khronos_uint16_t unsigned 16 bit + * khronos_int32_t signed 32 bit + * khronos_uint32_t unsigned 32 bit + * khronos_int64_t signed 64 bit + * khronos_uint64_t unsigned 64 bit + * khronos_intptr_t signed same number of bits as a pointer + * khronos_uintptr_t unsigned same number of bits as a pointer + * khronos_ssize_t signed size + * khronos_usize_t unsigned size + * khronos_float_t signed 32 bit floating point + * khronos_time_ns_t unsigned 64 bit time in nanoseconds + * khronos_utime_nanoseconds_t unsigned time interval or absolute time in + * nanoseconds + * khronos_stime_nanoseconds_t signed time interval in nanoseconds + * khronos_boolean_enum_t enumerated boolean type. This should + * only be used as a base type when a client API's boolean type is + * an enum. Client APIs which use an integer or other type for + * booleans cannot use this as the base type for their boolean. + * + * Tokens defined in khrplatform.h: + * + * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. + * + * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. + * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. + * + * Calling convention macros defined in this file: + * KHRONOS_APICALL + * KHRONOS_APIENTRY + * KHRONOS_APIATTRIBUTES + * + * These may be used in function prototypes as: + * + * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( + * int arg1, + * int arg2) KHRONOS_APIATTRIBUTES; + */ + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APICALL + *------------------------------------------------------------------------- + * This precedes the return type of the function in the function prototype. + */ +#if defined(_WIN32) && !defined(__SCITECH_SNAP__) +# define KHRONOS_APICALL __declspec(dllimport) +#elif defined (__SYMBIAN32__) +# define KHRONOS_APICALL IMPORT_C +#else +# define KHRONOS_APICALL +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIENTRY + *------------------------------------------------------------------------- + * This follows the return type of the function and precedes the function + * name in the function prototype. + */ +#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) + /* Win32 but not WinCE */ +# define KHRONOS_APIENTRY __stdcall +#else +# define KHRONOS_APIENTRY +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIATTRIBUTES + *------------------------------------------------------------------------- + * This follows the closing parenthesis of the function prototype arguments. + */ +#if defined (__ARMCC_2__) +#define KHRONOS_APIATTRIBUTES __softfp +#else +#define KHRONOS_APIATTRIBUTES +#endif + +/*------------------------------------------------------------------------- + * basic type definitions + *-----------------------------------------------------------------------*/ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) + + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__VMS ) || defined(__sgi) + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) + +/* + * Win32 + */ +typedef __int32 khronos_int32_t; +typedef unsigned __int32 khronos_uint32_t; +typedef __int64 khronos_int64_t; +typedef unsigned __int64 khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__sun__) || defined(__digital__) + +/* + * Sun or Digital + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#if defined(__arch64__) || defined(_LP64) +typedef long int khronos_int64_t; +typedef unsigned long int khronos_uint64_t; +#else +typedef long long int khronos_int64_t; +typedef unsigned long long int khronos_uint64_t; +#endif /* __arch64__ */ +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif 0 + +/* + * Hypothetical platform with no float or int64 support + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#define KHRONOS_SUPPORT_INT64 0 +#define KHRONOS_SUPPORT_FLOAT 0 + +#else + +/* + * Generic fallback + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#endif + + +/* + * Types that are (so far) the same on all platforms + */ +typedef signed char khronos_int8_t; +typedef unsigned char khronos_uint8_t; +typedef signed short int khronos_int16_t; +typedef unsigned short int khronos_uint16_t; +typedef signed long int khronos_intptr_t; +typedef unsigned long int khronos_uintptr_t; +typedef signed long int khronos_ssize_t; +typedef unsigned long int khronos_usize_t; + +#if KHRONOS_SUPPORT_FLOAT +/* + * Float type + */ +typedef float khronos_float_t; +#endif + +#if KHRONOS_SUPPORT_INT64 +/* Time types + * + * These types can be used to represent a time interval in nanoseconds or + * an absolute Unadjusted System Time. Unadjusted System Time is the number + * of nanoseconds since some arbitrary system event (e.g. since the last + * time the system booted). The Unadjusted System Time is an unsigned + * 64 bit value that wraps back to 0 every 584 years. Time intervals + * may be either signed or unsigned. + */ +typedef khronos_uint64_t khronos_utime_nanoseconds_t; +typedef khronos_int64_t khronos_stime_nanoseconds_t; +#endif + +/* + * Dummy value used to pad enum types to 32 bits. + */ +#ifndef KHRONOS_MAX_ENUM +#define KHRONOS_MAX_ENUM 0x7FFFFFFF +#endif + +/* + * Enumerated boolean type + * + * Values other than zero should be considered to be true. Therefore + * comparisons should not be made against KHRONOS_TRUE. + */ +typedef enum { + KHRONOS_FALSE = 0, + KHRONOS_TRUE = 1, + KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM +} khronos_boolean_enum_t; + +#endif /* __khrplatform_h_ */ diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index fada6ad10..76175adcc 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -16,7 +16,8 @@ # libraries. Additional dependencies are specified by the components. The # optional components are: # MeshTools - MeshTools library -# Physics - Physics 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 @@ -77,6 +78,13 @@ else() find_package(OpenGLES2 REQUIRED) endif() +# On Windows, *WindowContext libraries need to have ${MAGNUM_LIBRARY} listed +# in dependencies also after *WindowContext.lib static library name to avoid +# linker errors +if(WIN32) + set(_WINDOWCONTEXT_MAGNUM_LIBRARY_DEPENDENCY ${MAGNUM_LIBRARY}) +endif() + # Additional components foreach(component ${Magnum_FIND_COMPONENTS}) string(TOUPPER ${component} _COMPONENT) @@ -86,48 +94,48 @@ foreach(component ${Magnum_FIND_COMPONENTS}) set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_SUFFIX ${component}) - # Contexts - if(${component} MATCHES .+Context) + # Window contexts + if(${component} MATCHES .+WindowContext) set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_SUFFIX Contexts) set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES ${component}.h) - # GLUT context dependencies - if(${component} STREQUAL GlutContext) + # GLUT window context dependencies + if(${component} STREQUAL GlutWindowContext) find_package(GLUT) if(GLUT_FOUND) - set(_MAGNUM_${_COMPONENT}_LIBRARIES ${GLUT_LIBRARIES}) + set(_MAGNUM_${_COMPONENT}_LIBRARIES ${GLUT_LIBRARIES} ${_WINDOWCONTEXT_MAGNUM_LIBRARY_DEPENDENCY}) else() unset(MAGNUM_${_COMPONENT}_LIBRARY) endif() endif() - # SDL2 context dependencies - if(${component} STREQUAL Sdl2Context) + # SDL2 window context dependencies + if(${component} STREQUAL Sdl2WindowContext) find_package(SDL2) if(SDL2_FOUND) - set(_MAGNUM_${_COMPONENT}_LIBRARIES ${SDL2_LIBRARY}) + set(_MAGNUM_${_COMPONENT}_LIBRARIES ${SDL2_LIBRARY} ${_WINDOWCONTEXT_MAGNUM_LIBRARY_DEPENDENCY}) set(_MAGNUM_${_COMPONENT}_INCLUDE_DIRS ${SDL2_INCLUDE_DIR}) else() unset(MAGNUM_${_COMPONENT}_LIBRARY) endif() endif() - # GLX context dependencies - if(${component} STREQUAL GlxContext) + # GLX window context dependencies + if(${component} STREQUAL GlxWindowContext) find_package(X11) if(X11_FOUND) - set(_MAGNUM_${_COMPONENT}_LIBRARIES ${X11_LIBRARIES}) + set(_MAGNUM_${_COMPONENT}_LIBRARIES ${X11_LIBRARIES} ${_WINDOWCONTEXT_MAGNUM_LIBRARY_DEPENDENCY}) else() unset(MAGNUM_${_COMPONENT}_LIBRARY) endif() endif() - # X/EGL context dependencies - if(${component} STREQUAL XEglContext) + # X/EGL window context dependencies + if(${component} STREQUAL XEglWindowContext) find_package(EGL) find_package(X11) if(EGL_FOUND AND X11_FOUND) - set(_MAGNUM_${_COMPONENT}_LIBRARIES ${EGL_LIBRARY} ${X11_LIBRARIES}) + set(_MAGNUM_${_COMPONENT}_LIBRARIES ${EGL_LIBRARY} ${X11_LIBRARIES} ${_WINDOWCONTEXT_MAGNUM_LIBRARY_DEPENDENCY}) else() unset(MAGNUM_${_COMPONENT}_LIBRARY) endif() @@ -186,6 +194,7 @@ find_package_handle_standard_args(Magnum # Dependent libraries and includes set(MAGNUM_INCLUDE_DIRS ${MAGNUM_INCLUDE_DIR} + ${MAGNUM_INCLUDE_DIR}/external ${CORRADE_INCLUDE_DIR}) set(MAGNUM_LIBRARIES ${MAGNUM_LIBRARY} ${CORRADE_UTILITY_LIBRARY} diff --git a/src/AbstractImage.cpp b/src/AbstractImage.cpp index 4194431c2..04f14f2b6 100644 --- a/src/AbstractImage.cpp +++ b/src/AbstractImage.cpp @@ -14,8 +14,13 @@ */ #include "AbstractImage.h" + +#include + #include "TypeTraits.h" +using namespace std; + namespace Magnum { size_t AbstractImage::pixelSize(Components format, ComponentType type) { @@ -69,6 +74,8 @@ size_t AbstractImage::pixelSize(Components format, ComponentType type) { switch(format) { #ifndef MAGNUM_TARGET_GLES case Components::Red: + case Components::Green: + case Components::Blue: return 1*size; case Components::RedGreen: return 2*size; @@ -83,9 +90,16 @@ size_t AbstractImage::pixelSize(Components format, ComponentType type) { case Components::BGRA: #endif return 4*size; - default: - return 0; + + #ifndef MAGNUM_TARGET_GLES + case Components::Depth: + case Components::StencilIndex: + case Components::DepthStencil: + CORRADE_INTERNAL_ASSERT(false); + #endif } + + return 0; } } diff --git a/src/AbstractImage.h b/src/AbstractImage.h index 1a86e4313..e310ff00a 100644 --- a/src/AbstractImage.h +++ b/src/AbstractImage.h @@ -19,8 +19,12 @@ * @brief Class Magnum::AbstractImage */ +#include + #include "Magnum.h" +#include "magnumVisibility.h" + namespace Magnum { /** @@ -264,7 +268,7 @@ class MAGNUM_EXPORT AbstractImage { * @param components Color components * @param type Data type */ - static size_t pixelSize(Components components, ComponentType type); + static std::size_t pixelSize(Components components, ComponentType type); /** * @brief Constructor diff --git a/src/AbstractShaderProgram.cpp b/src/AbstractShaderProgram.cpp index 47ea3eeb4..e02831f1a 100644 --- a/src/AbstractShaderProgram.cpp +++ b/src/AbstractShaderProgram.cpp @@ -17,16 +17,76 @@ #include +#include "Math/Matrix.h" +#include "Shader.h" +#include "Implementation/State.h" +#include "Implementation/ShaderProgramState.h" +#include "Extensions.h" + #define LINKER_MESSAGE_MAX_LENGTH 1024 using namespace std; namespace Magnum { +AbstractShaderProgram::Uniform1fImplementation AbstractShaderProgram::uniform1fImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform2fvImplementation AbstractShaderProgram::uniform2fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform3fvImplementation AbstractShaderProgram::uniform3fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform4fvImplementation AbstractShaderProgram::uniform4fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform1iImplementation AbstractShaderProgram::uniform1iImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform2ivImplementation AbstractShaderProgram::uniform2ivImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform3ivImplementation AbstractShaderProgram::uniform3ivImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform4ivImplementation AbstractShaderProgram::uniform4ivImplementation = &AbstractShaderProgram::uniformImplementationDefault; +#ifndef MAGNUM_TARGET_GLES2 +AbstractShaderProgram::Uniform1uiImplementation AbstractShaderProgram::uniform1uiImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform2uivImplementation AbstractShaderProgram::uniform2uivImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform3uivImplementation AbstractShaderProgram::uniform3uivImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform4uivImplementation AbstractShaderProgram::uniform4uivImplementation = &AbstractShaderProgram::uniformImplementationDefault; +#endif +#ifndef MAGNUM_TARGET_GLES +AbstractShaderProgram::Uniform1dImplementation AbstractShaderProgram::uniform1dImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform2dvImplementation AbstractShaderProgram::uniform2dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform3dvImplementation AbstractShaderProgram::uniform3dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::Uniform4dvImplementation AbstractShaderProgram::uniform4dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +#endif + +AbstractShaderProgram::UniformMatrix2fvImplementation AbstractShaderProgram::uniformMatrix2fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix3fvImplementation AbstractShaderProgram::uniformMatrix3fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix4fvImplementation AbstractShaderProgram::uniformMatrix4fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +#ifndef MAGNUM_TARGET_GLES2 +AbstractShaderProgram::UniformMatrix2x3fvImplementation AbstractShaderProgram::uniformMatrix2x3fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix3x2fvImplementation AbstractShaderProgram::uniformMatrix3x2fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix2x4fvImplementation AbstractShaderProgram::uniformMatrix2x4fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix4x2fvImplementation AbstractShaderProgram::uniformMatrix4x2fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix3x4fvImplementation AbstractShaderProgram::uniformMatrix3x4fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix4x3fvImplementation AbstractShaderProgram::uniformMatrix4x3fvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +#endif +#ifndef MAGNUM_TARGET_GLES +AbstractShaderProgram::UniformMatrix2dvImplementation AbstractShaderProgram::uniformMatrix2dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix3dvImplementation AbstractShaderProgram::uniformMatrix3dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix4dvImplementation AbstractShaderProgram::uniformMatrix4dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix2x3dvImplementation AbstractShaderProgram::uniformMatrix2x3dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix3x2dvImplementation AbstractShaderProgram::uniformMatrix3x2dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix2x4dvImplementation AbstractShaderProgram::uniformMatrix2x4dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix4x2dvImplementation AbstractShaderProgram::uniformMatrix4x2dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix3x4dvImplementation AbstractShaderProgram::uniformMatrix3x4dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +AbstractShaderProgram::UniformMatrix4x3dvImplementation AbstractShaderProgram::uniformMatrix4x3dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; +#endif + +AbstractShaderProgram::~AbstractShaderProgram() { + /* Remove current usage from the state */ + GLuint& current = Context::current()->state()->shaderProgram->current; + if(current == _id) current = 0; + + glDeleteProgram(_id); +} + bool AbstractShaderProgram::use() { if(state != Linked) return false; - glUseProgram(program); + /* Use only if the program isn't already in use */ + GLuint& current = Context::current()->state()->shaderProgram->current; + if(current != _id) glUseProgram(current = _id); return true; } @@ -34,26 +94,26 @@ bool AbstractShaderProgram::attachShader(Shader& shader) { GLuint _shader = shader.compile(); if(!_shader) return false; - glAttachShader(program, _shader); + glAttachShader(_id, _shader); return true; } void AbstractShaderProgram::bindAttributeLocation(GLuint location, const string& name) { CORRADE_ASSERT(state == Initialized, "AbstractShaderProgram: attribute cannot be bound after linking.", ); - glBindAttribLocation(program, location, name.c_str()); + glBindAttribLocation(_id, location, name.c_str()); } #ifndef MAGNUM_TARGET_GLES void AbstractShaderProgram::bindFragmentDataLocation(GLuint location, const std::string& name) { CORRADE_ASSERT(state == Initialized, "AbstractShaderProgram: fragment data location cannot be bound after linking.", ); - glBindFragDataLocation(program, location, name.c_str()); + glBindFragDataLocation(_id, location, name.c_str()); } void AbstractShaderProgram::bindFragmentDataLocationIndexed(GLuint location, GLuint index, const std::string& name) { CORRADE_ASSERT(state == Initialized, "AbstractShaderProgram: fragment data location cannot be bound after linking.", ); - glBindFragDataLocationIndexed(program, location, index, name.c_str()); + glBindFragDataLocationIndexed(_id, location, index, name.c_str()); } #endif @@ -62,15 +122,15 @@ void AbstractShaderProgram::link() { if(state != Initialized) return; /* Link shader program */ - glLinkProgram(program); + glLinkProgram(_id); /* Check link status */ GLint status; - glGetProgramiv(program, GL_LINK_STATUS, &status); + glGetProgramiv(_id, GL_LINK_STATUS, &status); /* Display errors or warnings */ char message[LINKER_MESSAGE_MAX_LENGTH]; - glGetProgramInfoLog(program, LINKER_MESSAGE_MAX_LENGTH, nullptr, message); + glGetProgramInfoLog(_id, LINKER_MESSAGE_MAX_LENGTH, nullptr, message); /* Show error log and delete shader */ if(status == GL_FALSE) { @@ -90,10 +150,414 @@ GLint AbstractShaderProgram::uniformLocation(const std::string& name) { /** @todo What if linking just failed (not programmer error?) */ CORRADE_ASSERT(state == Linked, "AbstractShaderProgram: uniform location cannot be retrieved before linking.", -1); - GLint location = glGetUniformLocation(program, name.c_str()); + GLint location = glGetUniformLocation(_id, name.c_str()); if(location == -1) Warning() << "AbstractShaderProgram: location of uniform \'" + name + "\' cannot be retrieved!"; return location; } +void AbstractShaderProgram::initializeContextBasedFunctionality(Context* context) { + /** @todo OpenGL ES 2 has extension @es_extension{EXT,separate_shader_objects} for this */ + #ifndef MAGNUM_TARGET_GLES + if(context->isExtensionSupported() || + context->isExtensionSupported()) { + Debug() << "AbstractShaderProgram: using" << (context->isExtensionSupported() ? + Extensions::GL::ARB::separate_shader_objects::string() : Extensions::GL::EXT::direct_state_access::string()) << "features"; + uniform1fImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform2fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform3fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform4fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform1iImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform2ivImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform3ivImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform4ivImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform1uiImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform2uivImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform3uivImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform4uivImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform1dImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform2dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform3dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniform4dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + + uniformMatrix2fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix3fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix4fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix2x3fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix3x2fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix2x4fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix4x2fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix3x4fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix4x3fvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix2dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix3dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix4dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix2x3dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix3x2dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix2x4dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix4x2dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix3x4dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + uniformMatrix4x3dvImplementation = &AbstractShaderProgram::uniformImplementationDSA; + } + #else + static_cast(context); + #endif +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, GLfloat value) { + use(); + glUniform1f(location, value); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDSA(GLint location, GLfloat value) { + glProgramUniform1f(_id, location, value); +} +#endif + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<2, GLfloat>& value) { + use(); + glUniform2fv(location, 1, value.data()); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<2, GLfloat>& value) { + glProgramUniform2fv(_id, location, 1, value.data()); +} +#endif + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<3, GLfloat>& value) { + use(); + glUniform3fv(location, 1, value.data()); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<3, GLfloat>& value) { + glProgramUniform3fv(_id, location, 1, value.data()); +} +#endif + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<4, GLfloat>& value) { + use(); + glUniform4fv(location, 1, value.data()); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<4, GLfloat>& value) { + glProgramUniform4fv(_id, location, 1, value.data()); +} +#endif + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, GLint value) { + use(); + glUniform1i(location, value); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDSA(GLint location, GLint value) { + glProgramUniform1i(_id, location, value); +} +#endif + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<2, GLint>& value) { + use(); + glUniform2iv(location, 1, value.data()); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<2, GLint>& value) { + glProgramUniform2iv(_id, location, 1, value.data()); +} +#endif + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<3, GLint>& value) { + use(); + glUniform3iv(location, 1, value.data()); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<3, GLint>& value) { + glProgramUniform3iv(_id, location, 1, value.data()); +} +#endif + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<4, GLint>& value) { + use(); + glUniform4iv(location, 1, value.data()); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<4, GLint>& value) { + glProgramUniform4iv(_id, location, 1, value.data()); +} +#endif + +#ifndef MAGNUM_TARGET_GLES2 +void AbstractShaderProgram::uniformImplementationDefault(GLint location, GLuint value) { + use(); + glUniform1ui(location, value); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDSA(GLint location, GLuint value) { + glProgramUniform1ui(_id, location, value); +} +#endif + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<2, GLuint>& value) { + use(); + glUniform2uiv(location, 1, value.data()); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<2, GLuint>& value) { + glProgramUniform2uiv(_id, location, 1, value.data()); +} +#endif + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<3, GLuint>& value) { + use(); + glUniform3uiv(location, 1, value.data()); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<3, GLuint>& value) { + glProgramUniform3uiv(_id, location, 1, value.data()); +} +#endif + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<4, GLuint>& value) { + use(); + glUniform4uiv(location, 1, value.data()); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<4, GLuint>& value) { + glProgramUniform4uiv(_id, location, 1, value.data()); +} +#endif +#endif + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDefault(GLint location, GLdouble value) { + use(); + glUniform1d(location, value); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, GLdouble value) { + glProgramUniform1d(_id, location, value); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<2, GLdouble>& value) { + use(); + glUniform2dv(location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<2, GLdouble>& value) { + glProgramUniform2dv(_id, location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<3, GLdouble>& value) { + use(); + glUniform3dv(location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<3, GLdouble>& value) { + glProgramUniform3dv(_id, location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Vector<4, GLdouble>& value) { + use(); + glUniform4dv(location, 1, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Vector<4, GLdouble>& value) { + glProgramUniform4dv(_id, location, 1, value.data()); +} +#endif + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<2, GLfloat>& value) { + use(); + glUniformMatrix2fv(location, 1, GL_FALSE, value.data()); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<2, GLfloat>& value) { + glProgramUniformMatrix2fv(_id, location, 1, GL_FALSE, value.data()); +} +#endif + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<3, GLfloat>& value) { + use(); + glUniformMatrix3fv(location, 1, GL_FALSE, value.data()); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<3, GLfloat>& value) { + glProgramUniformMatrix3fv(_id, location, 1, GL_FALSE, value.data()); +} +#endif + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<4, GLfloat>& value) { + use(); + glUniformMatrix4fv(location, 1, GL_FALSE, value.data()); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<4, GLfloat>& value) { + glProgramUniformMatrix4fv(_id, location, 1, GL_FALSE, value.data()); +} +#endif + +#ifndef MAGNUM_TARGET_GLES2 +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 3, GLfloat>& value) { + use(); + glUniformMatrix2x3fv(location, 1, GL_FALSE, value.data()); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 3, GLfloat>& value) { + glProgramUniformMatrix2x3fv(_id, location, 1, GL_FALSE, value.data()); +} +#endif + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 2, GLfloat>& value) { + use(); + glUniformMatrix3x2fv(location, 1, GL_FALSE, value.data()); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 2, GLfloat>& value) { + glProgramUniformMatrix3x2fv(_id, location, 1, GL_FALSE, value.data()); +} +#endif + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 4, GLfloat>& value) { + use(); + glUniformMatrix2x4fv(location, 1, GL_FALSE, value.data()); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 4, GLfloat>& value) { + glProgramUniformMatrix2x4fv(_id, location, 1, GL_FALSE, value.data()); +} +#endif + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 2, GLfloat>& value) { + use(); + glUniformMatrix4x2fv(location, 1, GL_FALSE, value.data()); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 2, GLfloat>& value) { + glProgramUniformMatrix4x2fv(_id, location, 1, GL_FALSE, value.data()); +} +#endif + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 4, GLfloat>& value) { + use(); + glUniformMatrix3x4fv(location, 1, GL_FALSE, value.data()); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 4, GLfloat>& value) { + glProgramUniformMatrix3x4fv(_id, location, 1, GL_FALSE, value.data()); +} +#endif + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 3, GLfloat>& value) { + use(); + glUniformMatrix4x3fv(location, 1, GL_FALSE, value.data()); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 3, GLfloat>& value) { + glProgramUniformMatrix4x3fv(_id, location, 1, GL_FALSE, value.data()); +} +#endif +#endif + +#ifndef MAGNUM_TARGET_GLES +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<2, GLdouble>& value) { + use(); + glUniformMatrix2dv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<2, GLdouble>& value) { + glProgramUniformMatrix2dv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<3, GLdouble>& value) { + use(); + glUniformMatrix3dv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<3, GLdouble>& value) { + glProgramUniformMatrix3dv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::Matrix<4, GLdouble>& value) { + use(); + glUniformMatrix4dv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::Matrix<4, GLdouble>& value) { + glProgramUniformMatrix4dv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 3, GLdouble>& value) { + use(); + glUniformMatrix2x3dv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 3, GLdouble>& value) { + glProgramUniformMatrix2x3dv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 2, GLdouble>& value) { + use(); + glUniformMatrix3x2dv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 2, GLdouble>& value) { + glProgramUniformMatrix3x2dv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 4, GLdouble>& value) { + use(); + glUniformMatrix2x4dv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 4, GLdouble>& value) { + glProgramUniformMatrix2x4dv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 2, GLdouble>& value) { + use(); + glUniformMatrix4x2dv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 2, GLdouble>& value) { + glProgramUniformMatrix4x2dv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 4, GLdouble>& value) { + use(); + glUniformMatrix3x4dv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 4, GLdouble>& value) { + glProgramUniformMatrix3x4dv(_id, location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 3, GLdouble>& value) { + use(); + glUniformMatrix4x3dv(location, 1, GL_FALSE, value.data()); +} + +void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 3, GLdouble>& value) { + glProgramUniformMatrix4x3dv(_id, location, 1, GL_FALSE, value.data()); +} +#endif + } diff --git a/src/AbstractShaderProgram.h b/src/AbstractShaderProgram.h index f50d20040..1ed8222bc 100644 --- a/src/AbstractShaderProgram.h +++ b/src/AbstractShaderProgram.h @@ -19,72 +19,100 @@ * @brief Class Magnum::AbstractShaderProgram */ -#include +#include +#include +#include -#include "Shader.h" +#include "Magnum.h" +#include "TypeTraits.h" + +#include "magnumVisibility.h" namespace Magnum { +namespace Math { + template class RectangularMatrix; + template class Matrix; + template class Vector; +} + +class Context; +class Shader; + +#ifndef DOXYGEN_GENERATING_OUTPUT +namespace Implementation { + template struct Attribute; +} +#endif + /** -@brief Base class for shaders +@brief Base for shader program implementations @section AbstractShaderProgram-subclassing Subclassing workflow This class is designed to be used via subclassing. Subclasses define these functions and properties: - - %Attribute location typedefs defining locations and types - for attribute binding with Mesh::bindAttribute(), for example: + - %Attribute definitions with location and type for + configuring meshes, for example: @code -typedef Attribute<0, Vector4> Vertex; -typedef Attribute<1, Vector3> Normal; -typedef Attribute<2, Vector2> TextureCoords; +static const Attribute<0, Point3D> Position; +static const Attribute<1, Vector3> Normal; +static const Attribute<2, Vector2> TextureCoordinates; @endcode @todoc Output attribute location (for bindFragmentDataLocationIndexed(), referenced also from Framebuffer::mapDefaultForDraw() / Framebuffer::mapForDraw()) + - **Layers for texture uniforms** to which the textures will be bound before rendering, for example: @code static const GLint DiffuseTextureLayer = 0; static const GLint SpecularTextureLayer = 1; +@endcode + - **Uniform locations** for setting uniform data (see below) (private + constants), for example: +@code +static const GLint TransformationUniform = 0; +static const GLint ProjectionUniform = 1; +static const GLint DiffuseTextureUniform = 2; +static const GLint SpecularTextureUniform = 3; @endcode - **Constructor**, which attaches particular shaders, links the program and gets uniform locations, for example: @code MyShader() { // Load shaders from file and attach them to the program - attachShader(Shader::fromFile(Shader::Vertex, "PhongShader.vert")); - attachShader(Shader::fromFile(Shader::Fragment, "PhongShader.frag")); + attachShader(Shader::fromFile(Version::430, Shader::Type::Vertex, "PhongShader.vert")); + attachShader(Shader::fromFile(Version::430, Shader::Type::Fragment, "PhongShader.frag")); // Link link(); - - // Get locations of uniforms - transformationMatrixUniform = uniformLocation("transformationMatrix"); - projectionMatrixUniform = uniformLocation("projectionMatrix"); - // more uniforms like light location, colors etc. } @endcode - **Uniform setting functions**, which will provide public interface for - protected setUniform() functions. Example: + protected setUniform() functions. For usability purposes you can implement + also method chaining. Example: @code -void setTransformationMatrixUniform(const Matrix4& matrix) { - setUniform(transformationMatrixUniform, matrix); +MyShader* setTransformation(const Matrix4& matrix) { + setUniform(TransformationUniform, matrix); + return this; } -void setProjectionMatrixUniform(const Matrix4& matrix) { - setUniform(projectionMatrixUniform, matrix); +MyShader* setProjection(const Matrix4& matrix) { + setUniform(ProjectionUniform, matrix); + return this; } @endcode @subsection AbstractShaderProgram-attribute-location Binding attribute location + The preferred workflow is to specify attribute location for vertex shader input attributes and fragment shader output attributes explicitly in the shader code, e.g.: @code -#version 330 -// or #extension GL_ARB_explicit_attrib_location: enable -layout(location = 0) in vec4 vertex; +// GLSL 3.30, or +#extension GL_ARB_explicit_attrib_location: enable +layout(location = 0) in vec4 position; layout(location = 1) in vec3 normal; -layout(location = 2) in vec2 textureCoords; +layout(location = 2) in vec2 textureCoordinates; @endcode Similarly for ouput attributes, you can also specify blend equation color index for them (see Framebuffer::BlendFunction for more information about @@ -93,26 +121,17 @@ using color input index): layout(location = 0, index = 0) out vec4 color; layout(location = 1, index = 1) out vec4 ambient; @endcode -@requires_gl (for explicit input attribute location instead of using - bindAttributeLocation()) -@requires_gl (for explicit output attribute location or using - bindFragmentDataLocation() / bindFragmentDataLocationIndexed()) -@requires_gl30 Extension @extension{EXT,gpu_shader4} (for using - bindFragmentDataLocation()) -@requires_gl33 Extension @extension{ARB,blend_func_extended} (for using - bindFragmentDataLocationIndexed()) -@requires_gl33 Extension @extension{ARB,explicit_attrib_location} (for - explicit attribute location instead of using bindAttributeLocation()) - -If you don't have the required extension, you can use functions bindAttributeLocation() -and bindFragmentDataLocation() / bindFragmentDataLocationIndexed() between -attaching the shaders and linking the program: + +If you don't have the required extension, you can use functions +bindAttributeLocation() and bindFragmentDataLocation() / +bindFragmentDataLocationIndexed() between attaching the shaders and linking +the program: @code // Shaders attached... -bindAttributeLocation(Vertex::Location, "vertex"); -bindAttributeLocation(Normal::Location, "normal"); -bindAttributeLocation(TextureCoords::Location, "textureCoords"); +bindAttributeLocation(Position.Location, "position"); +bindAttributeLocation(Normal.Location, "normal"); +bindAttributeLocation(TextureCoords.Location, "textureCoordinates"); bindFragmentDataLocationIndexed(0, 0, "color"); bindFragmentDataLocationIndexed(1, 1, "ambient"); @@ -120,49 +139,151 @@ bindFragmentDataLocationIndexed(1, 1, "ambient"); // Link... @endcode +@requires_gl30 %Extension @extension{EXT,gpu_shader4} for using + bindFragmentDataLocation(). +@requires_gl33 %Extension @extension{ARB,blend_func_extended} for using + bindFragmentDataLocationIndexed(). +@requires_gl33 %Extension @extension{ARB,explicit_attrib_location} for + explicit attribute location instead of using bindAttributeLocation(), + bindFragmentDataLocation() or bindFragmentDataLocationIndexed(). +@requires_gles30 Explicit location specification of input attributes is not + supported in OpenGL ES 2.0, use bindAttributeLocation() instead. +@requires_gles30 Multiple fragment shader outputs are not available in OpenGL + ES 2.0, similar functionality is available in extension + @extension{NV,draw_buffers}. + +@subsection AbstractShaderProgram-uniform-location Uniform locations + +The preferred workflow is to specify uniform locations directly in the shader +code, e.g.: +@code +// GLSL 4.30, or +#extension GL_ARB_explicit_uniform_location: enable +layout(location = 0) uniform mat4 transformation; +layout(location = 1) uniform mat4 projection; +@endcode + +If you don't have the required extension, you can get uniform location using +uniformLocation() after linking stage: +@code +GLint transformationUniform = uniformLocation("transformation"); +GLint projectionUniform = uniformLocation("projection"); +@endcode + +@requires_gl43 Extension @extension{ARB,explicit_uniform_location} for + explicit uniform location instead of using uniformLocation(). +@requires_gl Explicit uniform location is not supported in OpenGL ES. Use + uniformLocation() instead. + @subsection AbstractShaderProgram-texture-layer Binding texture layer uniforms + The preferred workflow is to specify texture layers directly in the shader code, e.g.: @code -#version 420 -// or #extension GL_ARB_shading_language_420pack: enable +// GLSL 4.20, or +#extension GL_ARB_shading_language_420pack: enable layout(binding = 0) uniform sampler2D diffuseTexture; layout(binding = 1) uniform sampler2D specularTexture; @endcode -@requires_gl (for explicit texture layer binding instead of using - setUniform(GLint, GLint)) -@requires_gl42 Extension @extension{ARB,shading_language_420pack} (for explicit - texture layer binding instead of using setUniform(GLint, GLint)) If you don't have the required extension (or if you want to change the layer later), you can set the texture layer uniform using setUniform(GLint, GLint): @code -use(); -setUniform(uniformLocation("diffuseTexture"), DiffuseTextureLayer); -setUniform(uniformLocation("specularTexture"), SpecularTextureLayer); +setUniform(DiffuseTextureUniform, DiffuseTextureLayer); +setUniform(SpecularTextureUniform, SpecularTextureLayer); @endcode +@requires_gl42 Extension @extension{ARB,shading_language_420pack} for explicit + texture layer binding instead of using setUniform(GLint, GLint). +@requires_gl Explicit texture layer binding is not supported in OpenGL ES. Use + setUniform(GLint, GLint) instead. + @section AbstractShaderProgram-rendering-workflow Rendering workflow -Basic workflow with %AbstractShaderProgram subclasses is: instancing the class -(once at the beginning), then in Object::draw() reimplementation calling -use(), setting uniforms, binding required textures to their respective layers -using AbstractTexture::bind(GLint) and calling Mesh::draw(). For example: +Basic workflow with %AbstractShaderProgram subclasses is to instance the class +and configuring attribute binding in meshes (see @ref Mesh-configuration "Mesh documentation" +for more information) at the beginning, then in draw event setting uniforms +and marking the shader for use, binding required textures to their respective +layers using AbstractTexture::bind(GLint) and calling Mesh::draw(). Example: @code -void draw(const Magnum::Matrix4& transformationMatrix, Magnum::Camera* camera) { - shader.use(); - shader.setTransformationMatrixUniform(transformationMatrix); - shader.setProjectionMatrixUniform(camera->projectionMatrix()); - diffuseTexture.bind(MyShader::DiffuseTextureLayer); - specularTexture.bind(MyShader::SpecularTextureLayer); - mesh.draw(); -} +shader->setTransformation(transformation) + ->setProjection(projection) + ->use(); + +diffuseTexture->bind(MyShader::DiffuseTextureLayer); +specularTexture->bind(MyShader::SpecularTextureLayer); + +mesh.draw(); @endcode +@section AbstractShaderProgram-types Mapping between GLSL and Magnum types + +- `vec2`, `vec3` and `vec4` is @ref Math::Vector "Math::Vector<2, GLfloat>", + @ref Math::Vector "Math::Vector<3, GLfloat>" and + @ref Math::Vector "Math::Vector<4, GLfloat>". + +- `mat2`, `mat3` and `mat4` is @ref Math::Matrix "Math::Matrix<2, GLfloat>", + @ref Math::Matrix "Math::Matrix<3, GLfloat>" and + @ref Math::Matrix "Math::Matrix<4, GLfloat>". + +- `mat2x3`, `mat3x2`, `mat2x4`, `mat4x2`, `mat3x4`, `mat4x3` is + @ref Math::RectangularMatrix "Math::RectangularMatrix<2, 3, GLfloat>", + @ref Math::RectangularMatrix "Math::RectangularMatrix<3, 2, GLfloat>", + @ref Math::RectangularMatrix "Math::RectangularMatrix<2, 4, GLfloat>", + @ref Math::RectangularMatrix "Math::RectangularMatrix<4, 2, GLfloat>", + @ref Math::RectangularMatrix "Math::RectangularMatrix<3, 4, GLfloat>" and + @ref Math::RectangularMatrix "Math::RectangularMatrix<4, 3, GLfloat>". + +- `ivec2`, `ivec3` and `ivec4` is @ref Math::Vector "Math::Vector<2, GLint>", + @ref Math::Vector "Math::Vector<3, GLint>" and + @ref Math::Vector "Math::Vector<4, GLint>", `uvec2`, `uvec3` and `uvec4` is + @ref Math::Vector "Math::Vector<2, GLuint>", + @ref Math::Vector "Math::Vector<3, GLuint>" and + @ref Math::Vector "Math::Vector<4, GLuint>". + @requires_gl30 %Extension @extension{EXT,gpu_shader4} (for integer attributes + and unsigned integer uniforms) + @requires_gles30 Integer attributes and unsigned integer uniforms are not + available in OpenGL ES 2.0. + +- `dvec2`, `dvec3` and `dvec4` is @ref Math::Vector "Math::Vector<2, GLdouble>", + @ref Math::Vector "Math::Vector<3, GLdouble>" and + @ref Math::Vector "Math::Vector<4, GLdouble>", `dmat2`, `dmat3` and `dmat4` + is @ref Math::Matrix "Math::Matrix<2, GLdouble>", + @ref Math::Matrix "Math::Matrix<3, GLdouble>" and + @ref Math::Matrix "Math::Matrix<4, GLdouble>", `dmat2x3`, `dmat3x2`, + `dmat2x4`, `dmat4x2`, `dmat3x4`, `dmat4x3` is + @ref Math::RectangularMatrix "Math::RectangularMatrix<2, 3, GLdouble>", + @ref Math::RectangularMatrix "Math::RectangularMatrix<3, 2, GLdouble>", + @ref Math::RectangularMatrix "Math::RectangularMatrix<2, 4, GLdouble>", + @ref Math::RectangularMatrix "Math::RectangularMatrix<4, 2, GLdouble>", + @ref Math::RectangularMatrix "Math::RectangularMatrix<3, 4, GLdouble>" and + @ref Math::RectangularMatrix "Math::RectangularMatrix<4, 3, GLdouble>". + @requires_gl41 %Extension @extension{ARB,vertex_attrib_64bit} (for double + attributes) + @requires_gl Double attributes are not available in OpenGL ES. + +Only types listed here (and their subclasses and specializations, such as +@ref Matrix3 or Color4) can be used for setting uniforms and specifying +vertex attributes. See also TypeTraits::AttributeType. + +@section AbstractShaderProgram-performance-optimization Performance optimizations + +The engine tracks currently used shader program to avoid unnecessary calls to +@fn_gl{UseProgram}. + +If extension @extension{ARB,separate_shader_objects} or +@extension{EXT,direct_state_access} is available, uniform setting functions +use DSA functions to avoid unnecessary calls to @fn_gl{UseProgram}. See +setUniform(GLint, GLfloat) documentation for more information. + +To achieve least state changes, set all uniforms in one run -- method chaining +comes in handy. + @todo Uniform arrays support -@todo DSA for uniforms - glProgramUniform*() (OpenGL 4.1, @extension{ARB,separate_shader_objects}) */ class MAGNUM_EXPORT AbstractShaderProgram { + friend class Context; + AbstractShaderProgram(const AbstractShaderProgram& other) = delete; AbstractShaderProgram(AbstractShaderProgram&& other) = delete; AbstractShaderProgram& operator=(const AbstractShaderProgram& other) = delete; @@ -172,67 +293,208 @@ class MAGNUM_EXPORT AbstractShaderProgram { /** * @brief Base struct for attribute location and type * - * See AbstractShaderProgram documentation or Mesh::bindAttribute() - * for an example. + * Template parameter @p T is the type which is used for shader + * attribute, e.g. @ref Math::Vector4 "Vector4" for `ivec4`. + * DataType is type of passed data when adding vertex buffers to mesh. + * By default it is the same as type used in shader (e.g. + * @ref DataType "DataType::Int" for @ref Math::Vector4 "Vector4"). + * It's also possible to pass integer data to floating-point shader + * inputs. In this case you may want to normalize the values (e.g. + * color components from 0-255 to 0.0f-1.0f) - see + * @ref DataOption "DataOption::Normalize". + * + * Only some types are allowed as attribute types, see + * @ref AbstractShaderProgram-types or TypeTraits::AttributeType for + * more information. * - * @todo Support for BGRA attribute type (OpenGL 3.2, @extension{ARB,vertex_array_bgra}) + * See @ref AbstractShaderProgram-subclassing for example usage in + * shaders and @ref Mesh-configuration for example usage when adding + * vertex buffers to mesh. */ - template struct Attribute { - static const size_t Location = i; /**< Location to which the attribute is bound */ - typedef T Type; /**< %Attribute type */ + template class Attribute { + public: + /** @brief Location to which the attribute is bound */ + static const GLuint Location = i; + + /** + * @brief Type + * + * Type used in shader code. + * @see DataType + */ + typedef typename TypeTraits::AttributeType Type; + + /** + * @brief Data type + * + * Type of data passed to shader. + * @see Type, DataOptions, Attribute() + */ + #ifdef DOXYGEN_GENERATING_OUTPUT + enum class DataType: GLenum { + UnsignedByte = GL_UNSIGNED_BYTE, /**< Unsigned byte */ + Byte = GL_BYTE, /**< Byte */ + UnsignedShort = GL_UNSIGNED_SHORT, /**< Unsigned short */ + Short = GL_SHORT, /**< Short */ + UnsignedInt = GL_UNSIGNED_INT, /**< Unsigned int */ + Int = GL_INT, /**< Int */ + + /** + * Half float. Only for float attribute types. + * @requires_gl30 %Extension @extension{NV,half_float} + * @requires_gles30 %Extension @es_extension{OES,vertex_half_float} + */ + Half = GL_HALF_FLOAT, + + /** Float. Only for float attribute types. */ + Float = GL_FLOAT, + + #ifndef MAGNUM_TARGET_GLES + /** + * Double. Only for float and double attribute types. + * @requires_gl Only floats are available in OpenGL ES. + */ + Double = GL_DOUBLE, + #endif + + /* GL_FIXED not supported */ + + /** + * Unsigned 2.10.10.10 packed integer. Only for + * four-component float vector attribute type. + * @todo How about (incompatible) @es_extension{OES,vertex_type_10_10_10_2}? + * @requires_gl33 %Extension @extension{ARB,vertex_type_2_10_10_10_rev} + * @requires_gles30 (no extension providing this functionality) + */ + UnsignedInt2101010REV = GL_UNSIGNED_INT_2_10_10_10_REV, + + /** + * Signed 2.10.10.10 packed integer. Only for + * four-component float vector attribute type. + * @requires_gl33 %Extension @extension{ARB,vertex_type_2_10_10_10_rev} + * @requires_gles30 (no extension providing this functionality) + */ + Int2101010REV = GL_INT_2_10_10_10_REV + }; + #else + typedef typename Implementation::Attribute::DataType DataType; + #endif + + /** + * @brief Data option + * @see DataOptions, Attribute() + */ + #ifdef DOXYGEN_GENERATING_OUTPUT + enum class DataOption: std::uint8_t { + /** + * Normalize integer components. Only for float attribute + * types. Default is to not normalize. + */ + Normalize = 1 << 0, + + /** + * BGRA component ordering. Default is RGBA. Only for + * four-component float vector attribute type. + * @requires_gl32 %Extension @extension{ARB,vertex_array_bgra} + * @requires_gl Only RGBA component ordering is supported + * in OpenGL ES. + */ + BGRA = 1 << 1 + }; + #else + typedef typename Implementation::Attribute::DataOption DataOption; + #endif + + /** + * @brief Data options + * @see Attribute() + */ + #ifdef DOXYGEN_GENERATING_OUTPUT + typedef typename Corrade::Containers::EnumSet DataOptions; + #else + typedef typename Implementation::Attribute::DataOptions DataOptions; + #endif + + /** + * @brief Constructor + * @param dataType Type of passed data. Default is the + * same as type used in shader (e.g. DataType::Integer + * for Vector4). + * @param dataOptions Data options. Default is no options. + */ + inline constexpr Attribute(DataType dataType = Implementation::Attribute::DefaultDataType, DataOptions dataOptions = DataOptions()): _dataType(dataType), _dataOptions(dataOptions) {} + + /** @brief Type of passed data */ + inline constexpr DataType dataType() const { return _dataType; } + + /** @brief Data options */ + inline constexpr DataOptions dataOptions() const { return _dataOptions; } + + private: + const DataType _dataType; + const DataOptions _dataOptions; }; /** * @brief Constructor * * Creates one OpenGL shader program. + * @see @fn_gl{CreateProgram} */ inline AbstractShaderProgram(): state(Initialized) { - program = glCreateProgram(); + _id = glCreateProgram(); } /** * @brief Destructor * * Deletes associated OpenGL shader program. + * @see @fn_gl{DeleteProgram} */ virtual ~AbstractShaderProgram() = 0; /** - * @brief Use shader + * @brief Use shader for rendering * @return False if the program wasn't successfully linked, true * otherwise. + * + * @see @fn_gl{UseProgram} */ bool use(); protected: - #ifndef MAGNUM_TARGET_GLES /** * @brief Allow retrieving program binary * - * Disabled by default. - * @requires_gl - * @requires_gl41 Extension @extension{ARB,get_program_binary} + * Initially disabled. * @note This function should be called after attachShader() calls and * before link(). + * @see @fn_gl{ProgramParameter} with @def_gl{PROGRAM_BINARY_RETRIEVABLE_HINT} + * @requires_gl41 Extension @extension{ARB,get_program_binary} + * @requires_gles30 Always allowed in OpenGL ES 2.0. */ inline void setRetrievableBinary(bool enabled) { - glProgramParameteri(program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, enabled ? GL_TRUE : GL_FALSE); + glProgramParameteri(_id, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, enabled ? GL_TRUE : GL_FALSE); } /** * @brief Allow the program to be bound to individual pipeline stages * - * Disabled by default. - * @requires_gl - * @requires_gl41 Extension @extension{ARB,separate_shader_objects} + * Initially disabled. * @note This function should be called after attachShader() calls and * before link(). + * @see @fn_gl{ProgramParameter} with @def_gl{PROGRAM_SEPARABLE} + * @requires_gl41 Extension @extension{ARB,separate_shader_objects} + * @requires_es_extension %Extension @es_extension{EXT,separate_shader_objects} */ inline void setSeparable(bool enabled) { - glProgramParameteri(program, GL_PROGRAM_SEPARABLE, enabled ? GL_TRUE : GL_FALSE); + /** @todo Remove when extension wrangler is available for ES */ + #ifndef MAGNUM_TARGET_GLES + glProgramParameteri(_id, GL_PROGRAM_SEPARABLE, enabled ? GL_TRUE : GL_FALSE); + #else + static_cast(enabled); + #endif } - #endif /** * @brief Load shader @@ -241,10 +503,11 @@ class MAGNUM_EXPORT AbstractShaderProgram { * * Compiles the shader, if it is not already, and prepares it for * linking. + * @see Shader::compile(), @fn_gl{AttachShader} */ bool attachShader(Shader& shader); - /** @copydoc attachShader(Shader&) */ + /** @overload */ inline bool attachShader(Shader&& shader) { return attachShader(shader); } @@ -262,6 +525,7 @@ class MAGNUM_EXPORT AbstractShaderProgram { * explicitly in the shader instead of using this function. See * @ref AbstractShaderProgram-attribute-location "class documentation" * for more information. + * @see @fn_gl{BindAttribLocation} */ void bindAttributeLocation(GLuint location, const std::string& name); @@ -275,14 +539,16 @@ class MAGNUM_EXPORT AbstractShaderProgram { * Binds fragment data to location which is used later for framebuffer * operations. See also Framebuffer::BlendFunction for more * information about using color input index. - * @requires_gl - * @requires_gl33 Extension @extension{ARB,blend_func_extended} * @note This function should be called after attachShader() calls and * before link(). * @deprecated Preferred usage is to specify attribute location * explicitly in the shader instead of using this function. See * @ref AbstractShaderProgram-attribute-location "class documentation" * for more information. + * @see @fn_gl{BindFragDataLocationIndexed} + * @requires_gl33 Extension @extension{ARB,blend_func_extended} + * @requires_gl Multiple blend function inputs are not available in + * OpenGL ES. */ void bindFragmentDataLocationIndexed(GLuint location, GLuint index, const std::string& name); @@ -293,8 +559,10 @@ class MAGNUM_EXPORT AbstractShaderProgram { * * The same as bindFragmentDataLocationIndexed(), but with `index` set * to `0`. - * @requires_gl + * @see @fn_gl{BindFragDataLocation} * @requires_gl30 Extension @extension{EXT,gpu_shader4} + * @requires_gl Use explicit location specification in OpenGL ES 3.0 + * instead. */ void bindFragmentDataLocation(GLuint location, const std::string& name); #endif @@ -304,6 +572,8 @@ class MAGNUM_EXPORT AbstractShaderProgram { * * Binds previously specified attributes to given indexes and links the * shader program together. + * @see @fn_gl{LinkProgram}, @fn_gl{GetProgram} with + * @def_gl{LINK_STATUS}, @fn_gl{GetProgramInfoLog} */ void link(); @@ -312,6 +582,11 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @param name Uniform name * * @note This function should be called after link(). + * @deprecated Preferred usage is to specify uniform location + * explicitly in the shader instead of using this function. See + * @ref AbstractShaderProgram-uniform-location "class documentation" + * for more information. + * @see @fn_gl{GetUniformLocation} */ GLint uniformLocation(const std::string& name); @@ -320,95 +595,275 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @param location Uniform location (see uniformLocation()) * @param value Value * - * @attention This function doesn't check whether this shader is in use! + * If neither @extension{ARB,separate_shader_objects} nor + * @extension{EXT,direct_state_access} is available, the shader is + * marked for use before the operation. + * @see @fn_gl{UseProgram}, @fn_gl{Uniform} or `glProgramUniform()` + * from @extension{ARB,separate_shader_objects}/@extension{EXT,direct_state_access}. */ inline void setUniform(GLint location, GLfloat value) { - glUniform1f(location, value); + (this->*uniform1fImplementation)(location, value); } /** @copydoc setUniform(GLint, GLfloat) */ - inline void setUniform(GLint location, const Vector2& value) { - glUniform2fv(location, 1, value.data()); + inline void setUniform(GLint location, const Math::Vector<2, GLfloat>& value) { + (this->*uniform2fvImplementation)(location, value); } /** @copydoc setUniform(GLint, GLfloat) */ - inline void setUniform(GLint location, const Vector3& value) { - glUniform3fv(location, 1, value.data()); + inline void setUniform(GLint location, const Math::Vector<3, GLfloat>& value) { + (this->*uniform3fvImplementation)(location, value); } /** @copydoc setUniform(GLint, GLfloat) */ - inline void setUniform(GLint location, const Vector4& value) { - glUniform4fv(location, 1, value.data()); + inline void setUniform(GLint location, const Math::Vector<4, GLfloat>& value) { + (this->*uniform4fvImplementation)(location, value); } /** @copydoc setUniform(GLint, GLfloat) */ inline void setUniform(GLint location, GLint value) { - glUniform1i(location, value); + (this->*uniform1iImplementation)(location, value); } - /** @copydoc setUniform(GLint, GLint) */ - inline void setUniform(GLint location, const Math::Vector2& value) { - glUniform2iv(location, 1, value.data()); + /** @copydoc setUniform(GLint, GLfloat) */ + inline void setUniform(GLint location, const Math::Vector<2, GLint>& value) { + (this->*uniform2ivImplementation)(location, value); } - /** @copydoc setUniform(GLint, GLint) */ - inline void setUniform(GLint location, const Math::Vector3& value) { - glUniform3iv(location, 1, value.data()); + /** @copydoc setUniform(GLint, GLfloat) */ + inline void setUniform(GLint location, const Math::Vector<3, GLint>& value) { + (this->*uniform3ivImplementation)(location, value); } - /** @copydoc setUniform(GLint, GLint) */ - inline void setUniform(GLint location, const Math::Vector4& value) { - glUniform4iv(location, 1, value.data()); + /** @copydoc setUniform(GLint, GLfloat) */ + inline void setUniform(GLint location, const Math::Vector<4, GLint>& value) { + (this->*uniform4ivImplementation)(location, value); } - #ifndef MAGNUM_TARGET_GLES + #ifndef MAGNUM_TARGET_GLES2 /** - * @copydoc setUniform(GLint, GLint) - * @requires_gl + * @copydoc setUniform(GLint, GLfloat) * @requires_gl30 Extension @extension{EXT,gpu_shader4} + * @requires_gles30 Only signed integers are available in OpenGL ES 2.0. */ inline void setUniform(GLint location, GLuint value) { - glUniform1ui(location, value); + (this->*uniform1uiImplementation)(location, value); } /** - * @copydoc setUniform(GLint, GLint) - * @requires_gl + * @copydoc setUniform(GLint, GLfloat) * @requires_gl30 Extension @extension{EXT,gpu_shader4} + * @requires_gles30 Only signed integers are available in OpenGL ES 2.0. */ - inline void setUniform(GLint location, const Math::Vector2& value) { - glUniform2uiv(location, 1, value.data()); + inline void setUniform(GLint location, const Math::Vector<2, GLuint>& value) { + (this->*uniform2uivImplementation)(location, value); } /** - * @copydoc setUniform(GLint, GLint) - * @requires_gl + * @copydoc setUniform(GLint, GLfloat) * @requires_gl30 Extension @extension{EXT,gpu_shader4} + * @requires_gles30 Only signed integers are available in OpenGL ES 2.0. */ - inline void setUniform(GLint location, const Math::Vector3& value) { - glUniform3uiv(location, 1, value.data()); + inline void setUniform(GLint location, const Math::Vector<3, GLuint>& value) { + (this->*uniform3uivImplementation)(location, value); } /** - * @copydoc setUniform(GLint, GLuint) - * @requires_gl + * @copydoc setUniform(GLint, GLfloat) * @requires_gl30 Extension @extension{EXT,gpu_shader4} + * @requires_gles30 Only signed integers are available in OpenGL ES 2.0. */ - inline void setUniform(GLint location, const Math::Vector4& value) { - glUniform4uiv(location, 1, value.data()); + inline void setUniform(GLint location, const Math::Vector<4, GLuint>& value) { + (this->*uniform4uivImplementation)(location, value); } #endif - /** @copydoc setUniform(GLint, GLint) */ - inline void setUniform(GLint location, const Matrix3& value) { - glUniformMatrix3fv(location, 1, GL_FALSE, value.data()); + #ifndef MAGNUM_TARGET_GLES + /** + * @copydoc setUniform(GLint, GLfloat) + * @requires_gl40 Extension @extension{ARB,gpu_shader_fp64} + * @requires_gl Only floats are available in OpenGL ES. + */ + inline void setUniform(GLint location, GLdouble value) { + (this->*uniform1dImplementation)(location, value); } - /** @copydoc setUniform(GLint, GLint) */ - inline void setUniform(GLint location, const Matrix4& value) { - glUniformMatrix4fv(location, 1, GL_FALSE, value.data()); + /** + * @copydoc setUniform(GLint, GLfloat) + * @requires_gl40 Extension @extension{ARB,gpu_shader_fp64} + * @requires_gl Only floats are available in OpenGL ES. + */ + inline void setUniform(GLint location, const Math::Vector<2, GLdouble>& value) { + (this->*uniform2dvImplementation)(location, value); } + /** + * @copydoc setUniform(GLint, GLfloat) + * @requires_gl40 Extension @extension{ARB,gpu_shader_fp64} + * @requires_gl Only floats are available in OpenGL ES. + */ + inline void setUniform(GLint location, const Math::Vector<3, GLdouble>& value) { + (this->*uniform3dvImplementation)(location, value); + } + + /** + * @copydoc setUniform(GLint, GLfloat) + * @requires_gl40 Extension @extension{ARB,gpu_shader_fp64} + * @requires_gl Only floats are available in OpenGL ES. + */ + inline void setUniform(GLint location, const Math::Vector<4, GLdouble>& value) { + (this->*uniform4dvImplementation)(location, value); + } + #endif + + /** @copydoc setUniform(GLint, GLfloat) */ + inline void setUniform(GLint location, const Math::Matrix<2, GLfloat>& value) { + (this->*uniformMatrix2fvImplementation)(location, value); + } + + /** @copydoc setUniform(GLint, GLfloat) */ + inline void setUniform(GLint location, const Math::Matrix<3, GLfloat>& value) { + (this->*uniformMatrix3fvImplementation)(location, value); + } + + /** @copydoc setUniform(GLint, GLfloat) */ + inline void setUniform(GLint location, const Math::Matrix<4, GLfloat>& value) { + (this->*uniformMatrix4fvImplementation)(location, value); + } + + #ifndef MAGNUM_TARGET_GLES2 + /** + * @copydoc setUniform(GLint, GLfloat) + * @requires_gles30 Only square matrices are available in OpenGL ES 2.0. + */ + inline void setUniform(GLint location, const Math::RectangularMatrix<2, 3, GLfloat>& value) { + (this->*uniformMatrix2x3fvImplementation)(location, value); + } + + /** + * @copydoc setUniform(GLint, GLfloat) + * @requires_gles30 Only square matrices are available in OpenGL ES 2.0. + */ + inline void setUniform(GLint location, const Math::RectangularMatrix<3, 2, GLfloat>& value) { + (this->*uniformMatrix3x2fvImplementation)(location, value); + } + + /** + * @copydoc setUniform(GLint, GLfloat) + * @requires_gles30 Only square matrices are available in OpenGL ES 2.0. + */ + inline void setUniform(GLint location, const Math::RectangularMatrix<2, 4, GLfloat>& value) { + (this->*uniformMatrix2x4fvImplementation)(location, value); + } + + /** + * @copydoc setUniform(GLint, GLfloat) + * @requires_gles30 Only square matrices are available in OpenGL ES 2.0. + */ + inline void setUniform(GLint location, const Math::RectangularMatrix<4, 2, GLfloat>& value) { + (this->*uniformMatrix4x2fvImplementation)(location, value); + } + + /** + * @copydoc setUniform(GLint, GLfloat) + * @requires_gles30 Only square matrices are available in OpenGL ES 2.0. + */ + inline void setUniform(GLint location, const Math::RectangularMatrix<3, 4, GLfloat>& value) { + (this->*uniformMatrix3x4fvImplementation)(location, value); + } + + /** + * @copydoc setUniform(GLint, GLfloat) + * @requires_gles30 Only square matrices are available in OpenGL ES 2.0. + */ + inline void setUniform(GLint location, const Math::RectangularMatrix<4, 3, GLfloat>& value) { + (this->*uniformMatrix4x3fvImplementation)(location, value); + } + #endif + + #ifndef MAGNUM_TARGET_GLES + /** + * @copydoc setUniform(GLint, GLfloat) + * @requires_gl40 Extension @extension{ARB,gpu_shader_fp64} + * @requires_gl Only floats are available in OpenGL ES. + */ + inline void setUniform(GLint location, const Math::Matrix<2, GLdouble>& value) { + (this->*uniformMatrix2dvImplementation)(location, value); + } + + /** + * @copydoc setUniform(GLint, GLfloat) + * @requires_gl40 Extension @extension{ARB,gpu_shader_fp64} + * @requires_gl Only floats are available in OpenGL ES. + */ + inline void setUniform(GLint location, const Math::Matrix<3, GLdouble>& value) { + (this->*uniformMatrix3dvImplementation)(location, value); + } + + /** + * @copydoc setUniform(GLint, GLfloat) + * @requires_gl40 Extension @extension{ARB,gpu_shader_fp64} + * @requires_gl Only floats are available in OpenGL ES. + */ + inline void setUniform(GLint location, const Math::Matrix<4, GLdouble>& value) { + (this->*uniformMatrix4dvImplementation)(location, value); + } + + /** + * @copydoc setUniform(GLint, GLfloat) + * @requires_gl40 Extension @extension{ARB,gpu_shader_fp64} + * @requires_gl Only floats are available in OpenGL ES. + */ + inline void setUniform(GLint location, const Math::RectangularMatrix<2, 3, GLdouble>& value) { + (this->*uniformMatrix2x3dvImplementation)(location, value); + } + + /** + * @copydoc setUniform(GLint, GLfloat) + * @requires_gl40 Extension @extension{ARB,gpu_shader_fp64} + * @requires_gl Only floats are available in OpenGL ES. + */ + inline void setUniform(GLint location, const Math::RectangularMatrix<3, 2, GLdouble>& value) { + (this->*uniformMatrix3x2dvImplementation)(location, value); + } + + /** + * @copydoc setUniform(GLint, GLfloat) + * @requires_gl40 Extension @extension{ARB,gpu_shader_fp64} + * @requires_gl Only floats are available in OpenGL ES. + */ + inline void setUniform(GLint location, const Math::RectangularMatrix<2, 4, GLdouble>& value) { + (this->*uniformMatrix2x4dvImplementation)(location, value); + } + + /** + * @copydoc setUniform(GLint, GLfloat) + * @requires_gl40 Extension @extension{ARB,gpu_shader_fp64} + * @requires_gl Only floats are available in OpenGL ES. + */ + inline void setUniform(GLint location, const Math::RectangularMatrix<4, 2, GLdouble>& value) { + (this->*uniformMatrix4x2dvImplementation)(location, value); + } + + /** + * @copydoc setUniform(GLint, GLfloat) + * @requires_gl40 Extension @extension{ARB,gpu_shader_fp64} + * @requires_gl Only floats are available in OpenGL ES. + */ + inline void setUniform(GLint location, const Math::RectangularMatrix<3, 4, GLdouble>& value) { + (this->*uniformMatrix3x4dvImplementation)(location, value); + } + + /** + * @copydoc setUniform(GLint, GLfloat) + * @requires_gl40 Extension @extension{ARB,gpu_shader_fp64} + * @requires_gl Only floats are available in OpenGL ES. + */ + inline void setUniform(GLint location, const Math::RectangularMatrix<4, 3, GLdouble>& value) { + (this->*uniformMatrix4x3dvImplementation)(location, value); + } + #endif + private: enum State { Initialized, @@ -416,11 +871,356 @@ class MAGNUM_EXPORT AbstractShaderProgram { Failed }; - GLuint program; + static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context); + + typedef void(AbstractShaderProgram::*Uniform1fImplementation)(GLint, GLfloat); + typedef void(AbstractShaderProgram::*Uniform2fvImplementation)(GLint, const Math::Vector<2, GLfloat>&); + typedef void(AbstractShaderProgram::*Uniform3fvImplementation)(GLint, const Math::Vector<3, GLfloat>&); + typedef void(AbstractShaderProgram::*Uniform4fvImplementation)(GLint, const Math::Vector<4, GLfloat>&); + typedef void(AbstractShaderProgram::*Uniform1iImplementation)(GLint, GLint); + typedef void(AbstractShaderProgram::*Uniform2ivImplementation)(GLint, const Math::Vector<2, GLint>&); + typedef void(AbstractShaderProgram::*Uniform3ivImplementation)(GLint, const Math::Vector<3, GLint>&); + typedef void(AbstractShaderProgram::*Uniform4ivImplementation)(GLint, const Math::Vector<4, GLint>&); + #ifndef MAGNUM_TARGET_GLES2 + typedef void(AbstractShaderProgram::*Uniform1uiImplementation)(GLint, GLuint); + typedef void(AbstractShaderProgram::*Uniform2uivImplementation)(GLint, const Math::Vector<2, GLuint>&); + typedef void(AbstractShaderProgram::*Uniform3uivImplementation)(GLint, const Math::Vector<3, GLuint>&); + typedef void(AbstractShaderProgram::*Uniform4uivImplementation)(GLint, const Math::Vector<4, GLuint>&); + #endif + #ifndef MAGNUM_TARGET_GLES + typedef void(AbstractShaderProgram::*Uniform1dImplementation)(GLint, GLdouble); + typedef void(AbstractShaderProgram::*Uniform2dvImplementation)(GLint, const Math::Vector<2, GLdouble>&); + typedef void(AbstractShaderProgram::*Uniform3dvImplementation)(GLint, const Math::Vector<3, GLdouble>&); + typedef void(AbstractShaderProgram::*Uniform4dvImplementation)(GLint, const Math::Vector<4, GLdouble>&); + #endif + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLfloat value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<2, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<3, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<4, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLint value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<2, GLint>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<3, GLint>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<4, GLint>& value); + #ifndef MAGNUM_TARGET_GLES2 + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLuint value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<2, GLuint>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<3, GLuint>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<4, GLuint>& value); + #endif + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, GLdouble value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<2, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<3, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Vector<4, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLfloat value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<2, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<3, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<4, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLint value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<2, GLint>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<3, GLint>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<4, GLint>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLuint value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<2, GLuint>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<3, GLuint>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<4, GLuint>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, GLdouble value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<2, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<3, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Vector<4, GLdouble>& value); + #endif + static Uniform1fImplementation uniform1fImplementation; + static Uniform2fvImplementation uniform2fvImplementation; + static Uniform3fvImplementation uniform3fvImplementation; + static Uniform4fvImplementation uniform4fvImplementation; + static Uniform1iImplementation uniform1iImplementation; + static Uniform2ivImplementation uniform2ivImplementation; + static Uniform3ivImplementation uniform3ivImplementation; + static Uniform4ivImplementation uniform4ivImplementation; + #ifndef MAGNUM_TARGET_GLES2 + static Uniform1uiImplementation uniform1uiImplementation; + static Uniform2uivImplementation uniform2uivImplementation; + static Uniform3uivImplementation uniform3uivImplementation; + static Uniform4uivImplementation uniform4uivImplementation; + #endif + #ifndef MAGNUM_TARGET_GLES + static Uniform1dImplementation uniform1dImplementation; + static Uniform2dvImplementation uniform2dvImplementation; + static Uniform3dvImplementation uniform3dvImplementation; + static Uniform4dvImplementation uniform4dvImplementation; + #endif + + typedef void(AbstractShaderProgram::*UniformMatrix2fvImplementation)(GLint, const Math::Matrix<2, GLfloat>&); + typedef void(AbstractShaderProgram::*UniformMatrix3fvImplementation)(GLint, const Math::Matrix<3, GLfloat>&); + typedef void(AbstractShaderProgram::*UniformMatrix4fvImplementation)(GLint, const Math::Matrix<4, GLfloat>&); + #ifndef MAGNUM_TARGET_GLES2 + typedef void(AbstractShaderProgram::*UniformMatrix2x3fvImplementation)(GLint, const Math::RectangularMatrix<2, 3, GLfloat>&); + typedef void(AbstractShaderProgram::*UniformMatrix3x2fvImplementation)(GLint, const Math::RectangularMatrix<3, 2, GLfloat>&); + typedef void(AbstractShaderProgram::*UniformMatrix2x4fvImplementation)(GLint, const Math::RectangularMatrix<2, 4, GLfloat>&); + typedef void(AbstractShaderProgram::*UniformMatrix4x2fvImplementation)(GLint, const Math::RectangularMatrix<4, 2, GLfloat>&); + typedef void(AbstractShaderProgram::*UniformMatrix3x4fvImplementation)(GLint, const Math::RectangularMatrix<3, 4, GLfloat>&); + typedef void(AbstractShaderProgram::*UniformMatrix4x3fvImplementation)(GLint, const Math::RectangularMatrix<4, 3, GLfloat>&); + #endif + #ifndef MAGNUM_TARGET_GLES + typedef void(AbstractShaderProgram::*UniformMatrix2dvImplementation)(GLint, const Math::Matrix<2, GLdouble>&); + typedef void(AbstractShaderProgram::*UniformMatrix3dvImplementation)(GLint, const Math::Matrix<3, GLdouble>&); + typedef void(AbstractShaderProgram::*UniformMatrix4dvImplementation)(GLint, const Math::Matrix<4, GLdouble>&); + typedef void(AbstractShaderProgram::*UniformMatrix2x3dvImplementation)(GLint, const Math::RectangularMatrix<2, 3, GLdouble>&); + typedef void(AbstractShaderProgram::*UniformMatrix3x2dvImplementation)(GLint, const Math::RectangularMatrix<3, 2, GLdouble>&); + typedef void(AbstractShaderProgram::*UniformMatrix2x4dvImplementation)(GLint, const Math::RectangularMatrix<2, 4, GLdouble>&); + typedef void(AbstractShaderProgram::*UniformMatrix4x2dvImplementation)(GLint, const Math::RectangularMatrix<4, 2, GLdouble>&); + typedef void(AbstractShaderProgram::*UniformMatrix3x4dvImplementation)(GLint, const Math::RectangularMatrix<3, 4, GLdouble>&); + typedef void(AbstractShaderProgram::*UniformMatrix4x3dvImplementation)(GLint, const Math::RectangularMatrix<4, 3, GLdouble>&); + #endif + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<2, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<3, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<4, GLfloat>& value); + #ifndef MAGNUM_TARGET_GLES2 + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 3, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 2, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 4, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 2, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 4, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 3, GLfloat>& value); + #endif + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<2, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<3, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::Matrix<4, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 3, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 2, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<2, 4, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 2, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<3, 4, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDefault(GLint location, const Math::RectangularMatrix<4, 3, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<2, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<3, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<4, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 3, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 2, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 4, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 2, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 4, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 3, GLfloat>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<2, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<3, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::Matrix<4, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 3, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 2, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<2, 4, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 2, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<3, 4, GLdouble>& value); + void MAGNUM_LOCAL uniformImplementationDSA(GLint location, const Math::RectangularMatrix<4, 3, GLdouble>& value); + #endif + static UniformMatrix2fvImplementation uniformMatrix2fvImplementation; + static UniformMatrix3fvImplementation uniformMatrix3fvImplementation; + static UniformMatrix4fvImplementation uniformMatrix4fvImplementation; + #ifndef MAGNUM_TARGET_GLES2 + static UniformMatrix2x3fvImplementation uniformMatrix2x3fvImplementation; + static UniformMatrix3x2fvImplementation uniformMatrix3x2fvImplementation; + static UniformMatrix2x4fvImplementation uniformMatrix2x4fvImplementation; + static UniformMatrix4x2fvImplementation uniformMatrix4x2fvImplementation; + static UniformMatrix3x4fvImplementation uniformMatrix3x4fvImplementation; + static UniformMatrix4x3fvImplementation uniformMatrix4x3fvImplementation; + #endif + #ifndef MAGNUM_TARGET_GLES + static UniformMatrix2dvImplementation uniformMatrix2dvImplementation; + static UniformMatrix3dvImplementation uniformMatrix3dvImplementation; + static UniformMatrix4dvImplementation uniformMatrix4dvImplementation; + static UniformMatrix2x3dvImplementation uniformMatrix2x3dvImplementation; + static UniformMatrix3x2dvImplementation uniformMatrix3x2dvImplementation; + static UniformMatrix2x4dvImplementation uniformMatrix2x4dvImplementation; + static UniformMatrix4x2dvImplementation uniformMatrix4x2dvImplementation; + static UniformMatrix3x4dvImplementation uniformMatrix3x4dvImplementation; + static UniformMatrix4x3dvImplementation uniformMatrix4x3dvImplementation; + #endif + + GLuint _id; State state; }; -inline AbstractShaderProgram::~AbstractShaderProgram() { glDeleteProgram(program); } +#ifndef DOXYGEN_GENERATING_OUTPUT +namespace Implementation { + +template struct Attribute {}; + +template<> struct Attribute { + enum class DataType: GLenum { + UnsignedByte = GL_UNSIGNED_BYTE, + Byte = GL_BYTE, + UnsignedShort = GL_UNSIGNED_SHORT, + Short = GL_SHORT, + UnsignedInt = GL_UNSIGNED_INT, + Int = GL_INT, + HalfFloat = GL_HALF_FLOAT, + Float = GL_FLOAT + + #ifndef MAGNUM_TARGET_GLES + , + Double = GL_DOUBLE + #endif + }; + + enum class DataOption: std::uint8_t { + Normalized = 1 << 0 + }; + + typedef Corrade::Containers::EnumSet DataOptions; + + static const DataType DefaultDataType = DataType::Float; + + inline constexpr static GLint size(DataOptions) { return 1; } + inline constexpr static std::size_t vectorCount() { return 1; } +}; + +CORRADE_ENUMSET_OPERATORS(Attribute::DataOptions) + +template struct Attribute>: public Attribute { + inline constexpr static GLint size(DataOptions) { return vectorSize; } + inline constexpr static std::size_t vectorCount() { return 1; } +}; + +template struct Attribute>: public Attribute { + inline constexpr static GLint size(DataOptions) { return rows; } + inline constexpr static std::size_t vectorCount() { return cols; } +}; + +template struct Attribute>: public Attribute { + inline constexpr static GLint size(DataOptions) { return matrixSize; } + inline constexpr static std::size_t vectorCount() { return matrixSize; } +}; + +template<> struct Attribute> { + enum class DataType: GLenum { + UnsignedByte = GL_UNSIGNED_BYTE, + Byte = GL_BYTE, + UnsignedShort = GL_UNSIGNED_SHORT, + Short = GL_SHORT, + UnsignedInt = GL_UNSIGNED_INT, + Int = GL_INT, + Half = GL_HALF_FLOAT, + Float = GL_FLOAT, + #ifndef MAGNUM_TARGET_GLES + Double = GL_DOUBLE, + #endif + UnsignedAlpha2RGB10 = GL_UNSIGNED_INT_2_10_10_10_REV, + Alpha2RGB10 = GL_INT_2_10_10_10_REV + }; + + enum class DataOption: std::uint8_t { + Normalized = 1 << 0 + + #ifndef MAGNUM_TARGET_GLES + , + BGRA = 2 << 0 + #endif + }; + + typedef Corrade::Containers::EnumSet DataOptions; + + static const DataType DefaultDataType = DataType::Float; + + #ifndef MAGNUM_TARGET_GLES + inline constexpr static GLint size(DataOptions options) { + return options & DataOption::BGRA ? GL_BGRA : 4; + } + #else + inline constexpr static GLint size(DataOptions) { return 4; } + #endif + + inline constexpr static std::size_t vectorCount() { return 1; } +}; + +typedef Math::Vector<4, GLfloat> _Vector4; +CORRADE_ENUMSET_OPERATORS(Attribute<_Vector4>::DataOptions) + +template<> struct Attribute { + enum class DataType: GLenum { + UnsignedByte = GL_UNSIGNED_BYTE, + Byte = GL_BYTE, + UnsignedShort = GL_UNSIGNED_SHORT, + Short = GL_SHORT, + UnsignedInt = GL_UNSIGNED_INT, + Int = GL_INT + }; + + enum class DataOption: std::uint8_t {}; + + typedef Corrade::Containers::EnumSet DataOptions; + + static const DataType DefaultDataType = DataType::Int; + + inline constexpr static GLint size() { return 1; } +}; + +template<> struct Attribute { + typedef Attribute::DataType DataType; + typedef Attribute::DataOption DataOption; + + typedef Corrade::Containers::EnumSet DataOptions; + + static const DataType DefaultDataType = DataType::UnsignedInt; + + inline constexpr static GLint size() { return 1; } +}; + +template struct Attribute>: public Attribute { + inline constexpr static GLint size() { return size; } +}; + +template struct Attribute>: public Attribute { + inline constexpr static GLint size() { return size; } +}; + +#ifndef MAGNUM_TARGET_GLES +template<> struct Attribute { + enum class DataType: GLenum { + Double = GL_DOUBLE + }; + + enum class DataOption: std::uint8_t {}; + + typedef Corrade::Containers::EnumSet DataOptions; + + static const DataType DefaultDataType = DataType::Double; + + inline constexpr static GLint size() { return 1; } + inline constexpr static std::size_t vectorCount() { return 1; } +}; + +template struct Attribute>: public Attribute { + inline constexpr static GLint size() { return rows; } + inline constexpr static std::size_t vectorCount() { return cols; } +}; + +template struct Attribute>: public Attribute { + inline constexpr static GLint size() { return size; } + inline constexpr static std::size_t vectorCount() { return size; } +}; + +template struct Attribute>: public Attribute { + inline constexpr static GLint size() { return size; } + inline constexpr static std::size_t vectorCount() { return size; } +}; +#endif + +template struct Attribute>: public Attribute> {}; +template struct Attribute>: public Attribute> {}; +template struct Attribute>: public Attribute> {}; + +template struct Attribute>: public Attribute> {}; +template struct Attribute>: public Attribute> {}; + +template class Color3; +template class Color4; +template struct Attribute>: public Attribute> {}; +template struct Attribute>: public Attribute> {}; + +template struct Attribute>: public Attribute> {}; +template struct Attribute>: public Attribute> {}; + +} +#endif } diff --git a/src/AbstractTexture.cpp b/src/AbstractTexture.cpp index fdce8c9ea..8012626b7 100644 --- a/src/AbstractTexture.cpp +++ b/src/AbstractTexture.cpp @@ -15,8 +15,40 @@ #include "AbstractTexture.h" +#include "Context.h" +#include "Extensions.h" +#include "Implementation/State.h" +#include "Implementation/TextureState.h" + namespace Magnum { +AbstractTexture::BindImplementation AbstractTexture::bindImplementation = + &AbstractTexture::bindImplementationDefault; +AbstractTexture::ParameteriImplementation AbstractTexture::parameteriImplementation = + &AbstractTexture::parameterImplementationDefault; +AbstractTexture::ParameterfImplementation AbstractTexture::parameterfImplementation = + &AbstractTexture::parameterImplementationDefault; +AbstractTexture::ParameterfvImplementation AbstractTexture::parameterfvImplementation = + &AbstractTexture::parameterImplementationDefault; +AbstractTexture::MipmapImplementation AbstractTexture::mipmapImplementation = + &AbstractTexture::mipmapImplementationDefault; +#ifndef MAGNUM_TARGET_GLES +AbstractTexture::Image1DImplementation AbstractTexture::image1DImplementation = + &AbstractTexture::imageImplementationDefault; +#endif +AbstractTexture::Image2DImplementation AbstractTexture::image2DImplementation = + &AbstractTexture::imageImplementationDefault; +AbstractTexture::Image3DImplementation AbstractTexture::image3DImplementation = + &AbstractTexture::imageImplementationDefault; +#ifndef MAGNUM_TARGET_GLES +AbstractTexture::SubImage1DImplementation AbstractTexture::subImage1DImplementation = + &AbstractTexture::subImageImplementationDefault; +#endif +AbstractTexture::SubImage2DImplementation AbstractTexture::subImage2DImplementation = + &AbstractTexture::subImageImplementationDefault; +AbstractTexture::SubImage3DImplementation AbstractTexture::subImage3DImplementation = + &AbstractTexture::subImageImplementationDefault; + #ifndef DOXYGEN_GENERATING_OUTPUT /* Check correctness of binary OR in setMinificationFilter(). If nobody fucks @@ -35,40 +67,253 @@ static_assert((filter_or(NearestNeighbor, BaseLevel) == GL_NEAREST) && #endif GLint AbstractTexture::maxSupportedLayerCount() { - GLint value; - glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &value); - return value; + return Context::current()->state()->texture->maxSupportedLayerCount; } -#ifndef MAGNUM_TARGET_GLES GLfloat AbstractTexture::maxSupportedAnisotropy() { - GLfloat value; - glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &value); + GLfloat& value = Context::current()->state()->texture->maxSupportedAnisotropy; + + /** @todo Re-enable when extension header is available */ + #ifndef MAGNUM_TARGET_GLES + /* Get the value, if not already cached */ + if(value == 0.0f) + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &value); + #endif + return value; } + +AbstractTexture::~AbstractTexture() { + /* Remove all bindings */ + for(GLuint& binding: Context::current()->state()->texture->bindings) + if(binding == _id) binding = 0; + + glDeleteTextures(1, &_id); +} + +void AbstractTexture::bind(GLint layer) { + Implementation::TextureState* const textureState = Context::current()->state()->texture; + + /* If already bound in given layer, nothing to do */ + if(textureState->bindings[layer] == _id) return; + + (this->*bindImplementation)(layer); +} + +void AbstractTexture::bindImplementationDefault(GLint layer) { + Implementation::TextureState* const textureState = Context::current()->state()->texture; + + /* Change to given layer, if not already there */ + if(textureState->currentLayer != layer) + glActiveTexture(GL_TEXTURE0 + (textureState->currentLayer = layer)); + + /* Bind the texture to the layer */ + glBindTexture(_target, (textureState->bindings[layer] = _id)); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractTexture::bindImplementationDSA(GLint layer) { + glBindMultiTextureEXT(GL_TEXTURE0 + layer, _target, (Context::current()->state()->texture->bindings[layer] = _id)); +} #endif -void AbstractTexture::setMinificationFilter(Filter filter, Mipmap mipmap) { +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", ); + CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE || mipmap == Mipmap::BaseLevel, "AbstractTexture: rectangle textures cannot have mipmaps", this); #endif - bind(); - glTexParameteri(_target, GL_TEXTURE_MIN_FILTER, + (this->*parameteriImplementation)(GL_TEXTURE_MIN_FILTER, static_cast(filter)|static_cast(mipmap)); + return this; } -void AbstractTexture::generateMipmap() { +AbstractTexture* AbstractTexture::generateMipmap() { #ifndef MAGNUM_TARGET_GLES - CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE, "AbstractTexture: rectangle textures cannot have mipmaps", ); + CORRADE_ASSERT(_target != GL_TEXTURE_RECTANGLE, "AbstractTexture: rectangle textures cannot have mipmaps", this); #endif - bind(); + (this->*mipmapImplementation)(); + return this; +} + +void AbstractTexture::mipmapImplementationDefault() { + bindInternal(); glGenerateMipmap(_target); } #ifndef MAGNUM_TARGET_GLES +void AbstractTexture::mipmapImplementationDSA() { + glGenerateTextureMipmapEXT(_id, _target); +} +#endif + +#ifndef DOXYGEN_GENERATING_OUTPUT +void AbstractTexture::bindInternal() { + Implementation::TextureState* const textureState = Context::current()->state()->texture; + + /* If the texture is already bound in current layer, nothing to do */ + if(textureState->bindings[textureState->currentLayer] == _id) + return; + + /* Set internal layer as active if not already */ + const GLint internalLayer = textureState->maxSupportedLayerCount-1; + if(textureState->currentLayer != internalLayer) + glActiveTexture(GL_TEXTURE0 + (textureState->currentLayer = internalLayer)); + + /* Bind the texture to internal layer, if not already */ + if(textureState->bindings[internalLayer] != _id) + glBindTexture(_target, (textureState->bindings[internalLayer] = _id)); +} +#endif + +void AbstractTexture::initializeContextBasedFunctionality(Context* context) { + Implementation::TextureState* const textureState = context->state()->texture; + GLint& value = textureState->maxSupportedLayerCount; + + /* Get the value and resize bindings array */ + glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &value); + textureState->bindings.resize(value); + + #ifndef MAGNUM_TARGET_GLES + if(context->isExtensionSupported()) { + Debug() << "AbstractTexture: using" << Extensions::GL::EXT::direct_state_access::string() << "features"; + + bindImplementation = &AbstractTexture::bindImplementationDSA; + parameteriImplementation = &AbstractTexture::parameterImplementationDSA; + parameterfImplementation = &AbstractTexture::parameterImplementationDSA; + parameterfvImplementation = &AbstractTexture::parameterImplementationDSA; + mipmapImplementation = &AbstractTexture::mipmapImplementationDSA; + image1DImplementation = &AbstractTexture::imageImplementationDSA; + image2DImplementation = &AbstractTexture::imageImplementationDSA; + image3DImplementation = &AbstractTexture::imageImplementationDSA; + subImage1DImplementation = &AbstractTexture::subImageImplementationDSA; + subImage2DImplementation = &AbstractTexture::subImageImplementationDSA; + subImage3DImplementation = &AbstractTexture::subImageImplementationDSA; + } + #endif +} + +void AbstractTexture::parameterImplementationDefault(GLenum parameter, GLint value) { + bindInternal(); + glTexParameteri(_target, parameter, value); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractTexture::parameterImplementationDSA(GLenum parameter, GLint value) { + glTextureParameteriEXT(_id, _target, parameter, value); +} +#endif + +void AbstractTexture::parameterImplementationDefault(GLenum parameter, GLfloat value) { + bindInternal(); + glTexParameterf(_target, parameter, value); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractTexture::parameterImplementationDSA(GLenum parameter, GLfloat value) { + glTextureParameterfEXT(_id, _target, parameter, value); +} +#endif + +void AbstractTexture::parameterImplementationDefault(GLenum parameter, const GLfloat* values) { + bindInternal(); + glTexParameterfv(_target, parameter, values); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractTexture::parameterImplementationDSA(GLenum parameter, const GLfloat* values) { + glTextureParameterfvEXT(_id, _target, parameter, values); +} + +void AbstractTexture::imageImplementationDefault(GLenum target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector<1, GLsizei>& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) { + bindInternal(); + glTexImage1D(target, mipLevel, internalFormat, size[0], 0, static_cast(components), static_cast(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(components), static_cast(type), data); +} +#endif + +void AbstractTexture::imageImplementationDefault(GLenum target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector2& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) { + bindInternal(); + glTexImage2D(target, mipLevel, internalFormat, size.x(), size.y(), 0, static_cast(components), static_cast(type), data); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractTexture::imageImplementationDSA(GLenum target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector2& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) { + glTextureImage2DEXT(_id, target, mipLevel, internalFormat, size.x(), size.y(), 0, static_cast(components), static_cast(type), data); +} +#endif + +void AbstractTexture::imageImplementationDefault(GLenum target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector3& size, AbstractImage::Components components, AbstractImage::ComponentType 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(components), static_cast(type), data); + #else + static_cast(target); + static_cast(mipLevel); + static_cast(internalFormat); + static_cast(size); + static_cast(components); + static_cast(type); + static_cast(data); + #endif +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractTexture::imageImplementationDSA(GLenum target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector3& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) { + glTextureImage3DEXT(_id, target, mipLevel, internalFormat, size.x(), size.y(), size.z(), 0, static_cast(components), static_cast(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) { + bindInternal(); + glTexSubImage1D(target, mipLevel, offset[0], size[0], static_cast(components), static_cast(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(components), static_cast(type), data); +} +#endif + +void AbstractTexture::subImageImplementationDefault(GLenum target, GLint mipLevel, const Math::Vector2& offset, const Math::Vector2& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) { + bindInternal(); + glTexSubImage2D(target, mipLevel, offset.x(), offset.y(), size.x(), size.y(), static_cast(components), static_cast(type), data); +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractTexture::subImageImplementationDSA(GLenum target, GLint mipLevel, const Math::Vector2& offset, const Math::Vector2& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data) { + glTextureSubImage2DEXT(_id, target, mipLevel, offset.x(), offset.y(), size.x(), size.y(), static_cast(components), static_cast(type), data); +} +#endif + +void AbstractTexture::subImageImplementationDefault(GLenum target, GLint mipLevel, const Math::Vector3& offset, const Math::Vector3& size, AbstractImage::Components components, AbstractImage::ComponentType 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(components), static_cast(type), data); + #else + static_cast(target); + static_cast(mipLevel); + static_cast(offset); + static_cast(size); + static_cast(components); + static_cast(type); + static_cast(data); + #endif +} + +#ifndef MAGNUM_TARGET_GLES +void AbstractTexture::subImageImplementationDSA(GLenum target, GLint mipLevel, const Math::Vector3& offset, const Math::Vector3& 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(components), static_cast(type), data); +} +#endif + 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; \ @@ -95,6 +340,30 @@ AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Components comp 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; \ + } + #endif if(components == Components::Red) internalFormatSwitch(R) else if(components == Components::RedGreen) @@ -105,23 +374,22 @@ AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Components comp internalFormatSwitch(RGBA) #undef internalFormatSwitch } -#endif #ifndef DOXYGEN_GENERATING_OUTPUT -void AbstractTexture::DataHelper<2>::setWrapping(GLenum target, const Math::Vector<2, Wrapping>& wrapping) { +void AbstractTexture::DataHelper<2>::setWrapping(AbstractTexture* texture, const Math::Vector2& wrapping) { #ifndef MAGNUM_TARGET_GLES - CORRADE_ASSERT(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[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", ); #endif - glTexParameteri(target, GL_TEXTURE_WRAP_S, static_cast(wrapping[0])); - glTexParameteri(target, GL_TEXTURE_WRAP_T, static_cast(wrapping[1])); + (texture->*parameteriImplementation)(GL_TEXTURE_WRAP_S, static_cast(wrapping.x())); + (texture->*parameteriImplementation)(GL_TEXTURE_WRAP_T, static_cast(wrapping.y())); } -void AbstractTexture::DataHelper<3>::setWrapping(GLenum target, const Math::Vector<3, Wrapping>& wrapping) { - glTexParameteri(target, GL_TEXTURE_WRAP_S, static_cast(wrapping[0])); - glTexParameteri(target, GL_TEXTURE_WRAP_T, static_cast(wrapping[1])); +void AbstractTexture::DataHelper<3>::setWrapping(AbstractTexture* texture, const Math::Vector3& wrapping) { + (texture->*parameteriImplementation)(GL_TEXTURE_WRAP_S, static_cast(wrapping.x())); + (texture->*parameteriImplementation)(GL_TEXTURE_WRAP_T, static_cast(wrapping.y())); #ifndef MAGNUM_TARGET_GLES - glTexParameteri(target, GL_TEXTURE_WRAP_R, static_cast(wrapping[2])); + (texture->*parameteriImplementation)(GL_TEXTURE_WRAP_R, static_cast(wrapping.z())); #endif } #endif diff --git a/src/AbstractTexture.h b/src/AbstractTexture.h index 5dd213d17..27b1895eb 100644 --- a/src/AbstractTexture.h +++ b/src/AbstractTexture.h @@ -19,11 +19,16 @@ * @brief Class Magnum::AbstractTexture */ +#include + #include "Magnum.h" #include "Color.h" +#include "AbstractImage.h" namespace Magnum { +class Context; + /** @brief Base for textures @@ -40,10 +45,33 @@ AbstractShaderProgram::setUniform(GLint, GLint). See Texture, CubeMapTexture and CubeMapTextureArray documentation for more information. +@section AbstractTexture-performance-optimization Performance optimizations +The engine tracks currently bound textures in all available layers to avoid +unnecessary calls to @fn_gl{ActiveTexture} and @fn_gl{BindTexture}. %Texture +configuration functions use dedicated highest available texture layer to not +affect active bindings in user layers. %Texture limits (such as +maxSupportedLayerCount()) are cached, so repeated queries don't result in +repeated @fn_gl{Get} calls. + +If extension @extension{EXT,direct_state_access} is available, bind() uses DSA +function to avoid unnecessary calls to @fn_gl{ActiveTexture}. Also all texture +configuration functions use DSA functions to avoid unnecessary calls to +@fn_gl{ActiveTexture} and @fn_gl{BindTexture}. See respective function +documentation for more information. + +To achieve least state changes, fully configure each texture in one run -- +method chaining comes in handy -- and try to have often used textures in +dedicated layers, not occupied by other textures. + +Always fully configure the texture before setting the texture data, so OpenGL +can optimize the data to match your settings. + @todo Add glPixelStore encapsulation @todo Texture copying */ class MAGNUM_EXPORT AbstractTexture { + friend class Context; + AbstractTexture(const AbstractTexture& other) = delete; AbstractTexture(AbstractTexture&& other) = delete; AbstractTexture& operator=(const AbstractTexture& other) = delete; @@ -105,7 +133,7 @@ class MAGNUM_EXPORT AbstractTexture { /** * Clamp to border color. Coordinates out of range will be clamped * to border color (set with setBorderColor()). - * @requires_gl + * @requires_gl Texture border is not available in OpenGL ES. */ ClampToBorder = GL_CLAMP_TO_BORDER #endif @@ -113,10 +141,10 @@ class MAGNUM_EXPORT AbstractTexture { /** @{ @name Internal texture formats */ - #ifndef MAGNUM_TARGET_GLES /** * @brief Color components - * @requires_gl + * + * @requires_gles30 (no extension providing this functionality) */ enum class Components { /** @@ -142,7 +170,7 @@ class MAGNUM_EXPORT AbstractTexture { * * `NormalizedUnsignedByte` and `NormalizedUnsignedShort` are the * main ones for general usage. - * @requires_gl + * @requires_gles30 (no extension providing this functionality) */ enum class ComponentType { /** @@ -206,20 +234,23 @@ class MAGNUM_EXPORT AbstractTexture { */ NormalizedByte, + #ifndef MAGNUM_TARGET_GLES /** * Normalized unsigned short, i.e. values from range @f$ [0; 65536] @f$ * are converted to range @f$ [0.0; 1.0] @f$. + * @requires_gl */ NormalizedUnsignedShort, /** * Normalized signed short, i.e. values from range @f$ [-32768; 32767] @f$ * are converted to range @f$ [-1.0; 1.0] @f$. + * @requires_gl * @requires_gl31 Extension @extension{EXT,texture_snorm} */ NormalizedShort + #endif }; - #endif /** * @brief Internal format @@ -228,23 +259,21 @@ class MAGNUM_EXPORT AbstractTexture { * normalization see enums Components and ComponentType. */ enum class Format: GLenum { - #ifndef MAGNUM_TARGET_GLES /** * One-component (red channel), unsigned normalized, probably * 8bit. - * @requires_gl * @requires_gl30 Extension @extension{ARB,texture_rg} + * @requires_gles30 (no extension providing this functionality) */ Red = GL_RED, /** * Two-component (red and green channel), unsigned normalized, * each component probably 8bit, 16bit total. - * @requires_gl * @requires_gl30 Extension @extension{ARB,texture_rg} + * @requires_gles30 (no extension providing this functionality) */ RedGreen = GL_RG, - #endif /** * Three-component RGB, unsigned normalized, each component @@ -278,36 +307,36 @@ class MAGNUM_EXPORT AbstractTexture { * @requires_gl */ BGRA = GL_BGRA, + #endif /** * Four-component sRGBA, unsigned normalized, each component * 8bit, 32bit total. - * @requires_gl + * @requires_gles30 (no extension providing this functionality) */ SRGBA8 = GL_SRGB8_ALPHA8, /** * Three-component sRGB, unsigned normalized, each component * 8bit, 24bit total. - * @requires_gl + * @requires_gles30 (no extension providing this functionality) */ SRGB8 = GL_SRGB8, /** * Four-component RGBA, unsigned normalized, each RGB component * 10bit, alpha 2bit, 32bit total. - * @requires_gl + * @requires_gles30 (no extension providing this functionality) */ RGB10Alpha2 = GL_RGB10_A2, /** * Four-component RGBA, unsigned non-normalized, each RGB * component 10bit, alpha channel 2bit, 32bit total. - * @requires_gl * @requires_gl33 Extension @extension{ARB,texture_rgb10_a2ui} + * @requires_gles30 (no extension providing this functionality) */ RGB10Alpha2Unsigned = GL_RGB10_A2UI, - #endif /** * Four-component RGBA, unsigned normalized, each RGB component @@ -319,41 +348,35 @@ class MAGNUM_EXPORT AbstractTexture { * Four-component RGBA, unsigned normalized, each component 4bit, * 16bit total. */ - RGBA4 = GL_RGBA4 - - #ifndef MAGNUM_TARGET_GLES - , + RGBA4 = GL_RGBA4, /** * Three-component RGB, float, red and green 11bit, blue 10bit, * 32bit total. - * @requires_gl * @requires_gl30 Extension @extension{EXT,packed_float} + * @requires_gles30 (no extension providing this functionality) */ - RG11B10Float = GL_R11F_G11F_B10F - #endif + RG11B10Float = GL_R11F_G11F_B10F, + /* 1.5.6 <= GLEW < 1.8.0 doesn't have this, even if there is + GL_ARB_ES2_compatibility */ #if defined(GL_RGB565) || defined(DOXYGEN_GENERATING_OUTPUT) - , - /** * Three-component RGB, unsigned normalized, red and blue 5bit, * green 6bit, 16bit total. */ - RGB565 = GL_RGB565 + RGB565 = GL_RGB565, #endif - #ifndef MAGNUM_TARGET_GLES - , - /** * Three-component RGB, unsigned with exponent, each component * 9bit, exponent 5bit, 32bit total. - * @requires_gl * @requires_gl30 Extension @extension{EXT,texture_shared_exponent} + * @requires_gles30 (no extension providing this functionality) */ RGB9Exponent5 = GL_RGB9_E5, + #ifndef MAGNUM_TARGET_GLES /** * Compressed red channel, unsigned normalized. * @requires_gl @@ -408,35 +431,39 @@ class MAGNUM_EXPORT AbstractTexture { */ CompressedRtgcSignedRedGreen = GL_COMPRESSED_SIGNED_RG_RGTC2, - #if defined(GL_COMPRESSED_RGBA_BPTC_UNORM) || defined(DOXYGEN_GENERATING_OUTPUT) + /* These are named with _ARB suffix, because glcorearb.h doesn't + have suffixless version (?!) and GLEW has it without suffix as + late as of 1.8.0 { */ + /** * BPTC compressed RGBA, unsigned normalized. * @requires_gl * @requires_gl42 Extension @extension{ARB,texture_compression_bptc} */ - CompressedBptcRGBA = GL_COMPRESSED_RGBA_BPTC_UNORM, + CompressedBptcRGBA = GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, /** * BPTC compressed sRGBA, unsigned normalized. * @requires_gl * @requires_gl42 Extension @extension{ARB,texture_compression_bptc} */ - CompressedBptcSRGBA = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, + CompressedBptcSRGBA = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB, /** * BPTC compressed RGB, signed float. * @requires_gl * @requires_gl42 Extension @extension{ARB,texture_compression_bptc} */ - CompressedBptcRGBSignedFloat = GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, + CompressedBptcRGBSignedFloat = GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, /** * BPTC compressed RGB, unsigned float. * @requires_gl * @requires_gl42 Extension @extension{ARB,texture_compression_bptc} */ - CompressedBptcRGBUnsignedFloat = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, - #endif + CompressedBptcRGBUnsignedFloat = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB, + + /*}*/ /** * Depth component, at least 16bit. @@ -456,40 +483,40 @@ class MAGNUM_EXPORT AbstractTexture { * @requires_gl */ DepthStencil = GL_DEPTH_STENCIL, + #endif /** * 16bit depth component. - * @requires_gl + * @requires_gles30 (no extension providing this functionality) */ Depth16 = GL_DEPTH_COMPONENT16, /** * 24bit depth component. - * @requires_gl + * @requires_gles30 (no extension providing this functionality) */ Depth24 = GL_DEPTH_COMPONENT24, /** * 32bit float depth component. - * @requires_gl * @requires_gl30 Extension @extension{ARB,depth_buffer_float} + * @requires_gles30 (no extension providing this functionality) */ Depth32Float = GL_DEPTH_COMPONENT32F, /** * 24bit depth and 8bit stencil component. - * @requires_gl * @requires_gl30 Extension @extension{EXT,packed_depth_stencil} + * @requires_gles30 (no extension providing this functionality) */ Depth24Stencil8 = GL_DEPTH24_STENCIL8, /** * 32bit float depth component and 8bit stencil component. - * @requires_gl * @requires_gl30 Extension @extension{ARB,depth_buffer_float} + * @requires_gles30 (no extension providing this functionality) */ Depth32FloatStencil8 = GL_DEPTH32F_STENCIL8 - #endif }; /** @@ -510,14 +537,12 @@ class MAGNUM_EXPORT AbstractTexture { */ class MAGNUM_EXPORT InternalFormat { public: - #ifndef MAGNUM_TARGET_GLES /** * @brief Constructor from component count and data type per component * - * @requires_gl + * @requires_gles30 (no extension providing this functionality) */ InternalFormat(Components components, ComponentType type); - #endif /** @brief Constructor from named internal format */ inline constexpr InternalFormat(Format format): internalFormat(static_cast(format)) {} @@ -534,52 +559,54 @@ class MAGNUM_EXPORT AbstractTexture { /** * @brief Max supported layer count * - * At least 48. - * @see bind(GLint) + * @see bind(GLint), @fn_gl{Get} with @def_gl{MAX_COMBINED_TEXTURE_IMAGE_UNITS}, + * @fn_gl{ActiveTexture} */ static GLint maxSupportedLayerCount(); - #ifndef MAGNUM_TARGET_GLES /** * @brief Max supported anisotropy * - * @see setMaxAnisotropy() - * @requires_extension @extension{EXT,texture_filter_anisotropic} + * @see setMaxAnisotropy(), @fn_gl{Get} with @def_gl{MAX_TEXTURE_MAX_ANISOTROPY_EXT} + * @requires_extension %Extension @extension{EXT,texture_filter_anisotropic} + * @requires_es_extension %Extension @es_extension2{EXT,texture_filter_anisotropic,texture_filter_anisotropic} */ static GLfloat maxSupportedAnisotropy(); - #endif /** * @brief Constructor * @param target Target, e.g. `GL_TEXTURE_2D`. * * Creates one OpenGL texture. + * @see @fn_gl{GenTextures} */ inline AbstractTexture(GLenum target): _target(target) { - glGenTextures(1, &texture); + glGenTextures(1, &_id); } /** * @brief Destructor * * Deletes assigned OpenGL texture. + * @see @fn_gl{DeleteTextures} */ virtual ~AbstractTexture() = 0; - /** @brief OpenGL internal texture ID */ - inline GLuint id() const { return texture; } + /** @brief OpenGL texture ID */ + inline GLuint id() const { return _id; } /** * @brief Bind texture for rendering * * Sets current texture as active in given layer. The layer must be * between 0 and maxSupportedLayerCount(). Note that only one texture - * can be bound to given layer. + * can be bound to given layer. If @extension{EXT,direct_state_access} + * is not available, the layer is made active before binding the + * texture. + * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} or + * @fn_gl_extension{BindMultiTexture,EXT,direct_state_access} */ - inline void bind(GLint layer) { - glActiveTexture(GL_TEXTURE0 + layer); - bind(); - } + void bind(GLint layer); /** * @brief Set minification filter @@ -587,92 +614,185 @@ class MAGNUM_EXPORT AbstractTexture { * @param mipmap Mipmap filtering. If set to anything else than * BaseMipLevel, make sure textures for all mip levels are set or * call generateMipmap(). + * @return Pointer to self (for method chaining) * * Sets filter used when the object pixel size is smaller than the - * texture size. + * texture size. If @extension{EXT,direct_state_access} is not + * available, the texture is bound to some layer before the operation. * @attention For rectangle textures only some modes are supported, - * see @ref AbstractTexture::Filter "Filter" and - * @ref AbstractTexture::Mipmap "Mipmap" documentation for more - * information. + * see @ref AbstractTexture::Filter "Filter" and + * @ref AbstractTexture::Mipmap "Mipmap" documentation for more + * information. + * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} + * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} + * with @def_gl{TEXTURE_MIN_FILTER} */ - void setMinificationFilter(Filter filter, Mipmap mipmap = Mipmap::BaseLevel); + AbstractTexture* setMinificationFilter(Filter filter, Mipmap mipmap = Mipmap::BaseLevel); /** * @brief Set magnification filter * @param filter Filter + * @return Pointer to self (for method chaining) * * Sets filter used when the object pixel size is larger than largest - * texture size. + * texture size. If @extension{EXT,direct_state_access} is not + * available, the texture is bound to some layer before the operation. + * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} + * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} + * with @def_gl{TEXTURE_MAG_FILTER} */ - inline void setMagnificationFilter(Filter filter) { - bind(); - glTexParameteri(_target, GL_TEXTURE_MAG_FILTER, static_cast(filter)); + inline AbstractTexture* setMagnificationFilter(Filter filter) { + (this->*parameteriImplementation)(GL_TEXTURE_MAG_FILTER, static_cast(filter)); + return this; } #ifndef MAGNUM_TARGET_GLES /** * @brief Set border color + * @return Pointer to self (for method chaining) * * Border color when @ref AbstractTexture::Wrapping "wrapping" is set - * to `ClampToBorder`. - * @requires_gl + * to `ClampToBorder`. If @extension{EXT,direct_state_access} is not + * available, the texture is bound to some layer before the operation. + * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} + * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} + * with @def_gl{TEXTURE_BORDER_COLOR} + * @requires_gl Texture border is not available in OpenGL ES. */ - inline void setBorderColor(const Color4& color) { - bind(); - glTexParameterfv(_target, GL_TEXTURE_BORDER_COLOR, color.data()); + inline AbstractTexture* setBorderColor(const Color4& color) { + (this->*parameterfvImplementation)(GL_TEXTURE_BORDER_COLOR, color.data()); + return this; } + #endif /** * @brief Set max anisotropy + * @return Pointer to self (for method chaining) * - * Default value is `1.0`, which means no anisotropy. Set to value - * greater than `1.0` for anisotropic filtering. - * @see maxSupportedAnisotropy() - * @requires_extension @extension{EXT,texture_filter_anisotropic} + * Default value is `1.0f`, which means no anisotropy. Set to value + * greater than `1.0f` for anisotropic filtering. If + * @extension{EXT,direct_state_access} is not available, the texture + * is bound to some layer before the operation. + * @see maxSupportedAnisotropy(), @fn_gl{ActiveTexture}, + * @fn_gl{BindTexture} and @fn_gl{TexParameter} or + * @fn_gl_extension{TextureParameter,EXT,direct_state_access} with + * @def_gl{TEXTURE_MAX_ANISOTROPY_EXT} + * @requires_extension %Extension @extension{EXT,texture_filter_anisotropic} + * @requires_es_extension %Extension @es_extension2{EXT,texture_filter_anisotropic,texture_filter_anisotropic} */ - inline void setMaxAnisotropy(GLfloat anisotropy) { - bind(); - glTexParameterf(_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy); + inline AbstractTexture* setMaxAnisotropy(GLfloat anisotropy) { + /** @todo Remove `ifndef` when extension header is available */ + #ifndef MAGNUM_TARGET_GLES + (this->*parameterfImplementation)(GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy); + #else + static_cast(anisotropy); + #endif + return this; } - #endif /** * @brief Generate mipmap + * @return Pointer to self (for method chaining) * - * Can not be used for rectangle textures. - * @see setMinificationFilter() + * Can not be used for rectangle textures. If + * @extension{EXT,direct_state_access} is not available, the texture + * is bound to some layer before the operation. + * @see setMinificationFilter(), @fn_gl{ActiveTexture}, + * @fn_gl{BindTexture} and @fn_gl{GenerateMipmap} or + * @fn_gl_extension{GenerateTextureMipmap,EXT,direct_state_access} * @requires_gl30 Extension @extension{EXT,framebuffer_object} */ - void generateMipmap(); + AbstractTexture* generateMipmap(); protected: #ifndef DOXYGEN_GENERATING_OUTPUT - template struct DataHelper {}; - #endif + template struct DataHelper {}; - const GLenum _target; /**< @brief Target */ + /* Unlike bind() this also sets the binding layer as active */ + void MAGNUM_LOCAL bindInternal(); - /** - * @brief Bind texture for parameter modification - * - * Unlike bind(GLint) doesn't bind the texture to any particular - * layer, thus unusable for binding for rendering. - */ - inline void bind() { - glBindTexture(_target, texture); - } + const GLenum _target; + #endif private: - GLuint texture; -}; + static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context); -inline AbstractTexture::~AbstractTexture() { glDeleteTextures(1, &texture); } + typedef void(AbstractTexture::*BindImplementation)(GLint); + void MAGNUM_LOCAL bindImplementationDefault(GLint layer); + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL bindImplementationDSA(GLint layer); + #endif + static MAGNUM_LOCAL BindImplementation bindImplementation; + + typedef void(AbstractTexture::*ParameteriImplementation)(GLenum, GLint); + void MAGNUM_LOCAL parameterImplementationDefault(GLenum parameter, GLint value); + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, GLint value); + #endif + static ParameteriImplementation parameteriImplementation; + + typedef void(AbstractTexture::*ParameterfImplementation)(GLenum, GLfloat); + void MAGNUM_LOCAL parameterImplementationDefault(GLenum parameter, GLfloat value); + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, GLfloat value); + #endif + static ParameterfImplementation parameterfImplementation; + + typedef void(AbstractTexture::*ParameterfvImplementation)(GLenum, const GLfloat*); + void MAGNUM_LOCAL parameterImplementationDefault(GLenum parameter, const GLfloat* values); + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL parameterImplementationDSA(GLenum parameter, const GLfloat* values); + #endif + static ParameterfvImplementation parameterfvImplementation; + + typedef void(AbstractTexture::*MipmapImplementation)(); + void MAGNUM_LOCAL mipmapImplementationDefault(); + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL mipmapImplementationDSA(); + #endif + static MAGNUM_LOCAL MipmapImplementation mipmapImplementation; + + #ifndef MAGNUM_TARGET_GLES + typedef void(AbstractTexture::*Image1DImplementation)(GLenum, GLint, InternalFormat, const Math::Vector<1, GLsizei>&, AbstractImage::Components, AbstractImage::ComponentType, const GLvoid*); + void MAGNUM_LOCAL imageImplementationDefault(GLenum target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector<1, GLsizei>& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data); + void MAGNUM_LOCAL imageImplementationDSA(GLenum target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector<1, GLsizei>& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data); + static Image1DImplementation image1DImplementation; + #endif + + typedef void(AbstractTexture::*Image2DImplementation)(GLenum, GLint, InternalFormat, const Math::Vector2&, AbstractImage::Components, AbstractImage::ComponentType, const GLvoid*); + void MAGNUM_LOCAL imageImplementationDefault(GLenum target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector2& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data); + void MAGNUM_LOCAL imageImplementationDSA(GLenum target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector2& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data); + static Image2DImplementation image2DImplementation; + + typedef void(AbstractTexture::*Image3DImplementation)(GLenum, GLint, InternalFormat, const Math::Vector3&, AbstractImage::Components, AbstractImage::ComponentType, const GLvoid*); + void MAGNUM_LOCAL imageImplementationDefault(GLenum target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector3& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data); + void MAGNUM_LOCAL imageImplementationDSA(GLenum target, GLint mipLevel, InternalFormat internalFormat, const Math::Vector3& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data); + static Image3DImplementation image3DImplementation; + + #ifndef MAGNUM_TARGET_GLES + typedef void(AbstractTexture::*SubImage1DImplementation)(GLenum, GLint, const Math::Vector<1, GLint>&, const Math::Vector<1, GLsizei>&, AbstractImage::Components, AbstractImage::ComponentType, const GLvoid*); + void MAGNUM_LOCAL 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 MAGNUM_LOCAL 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); + static SubImage1DImplementation subImage1DImplementation; + #endif + + typedef void(AbstractTexture::*SubImage2DImplementation)(GLenum, GLint, const Math::Vector2&, const Math::Vector2&, AbstractImage::Components, AbstractImage::ComponentType, const GLvoid*); + void MAGNUM_LOCAL subImageImplementationDefault(GLenum target, GLint mipLevel, const Math::Vector2& offset, const Math::Vector2& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data); + void MAGNUM_LOCAL subImageImplementationDSA(GLenum target, GLint mipLevel, const Math::Vector2& offset, const Math::Vector2& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data); + static SubImage2DImplementation subImage2DImplementation; + + typedef void(AbstractTexture::*SubImage3DImplementation)(GLenum, GLint, const Math::Vector3&, const Math::Vector3&, AbstractImage::Components, AbstractImage::ComponentType, const GLvoid*); + void MAGNUM_LOCAL subImageImplementationDefault(GLenum target, GLint mipLevel, const Math::Vector3& offset, const Math::Vector3& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data); + void MAGNUM_LOCAL subImageImplementationDSA(GLenum target, GLint mipLevel, const Math::Vector3& offset, const Math::Vector3& size, AbstractImage::Components components, AbstractImage::ComponentType type, const GLvoid* data); + static SubImage3DImplementation subImage3DImplementation; + + GLuint _id; +}; -#ifndef MAGNUM_TARGET_GLES /** @relates AbstractTexture @brief Convertor of component count and data type to InternalFormat -@requires_gl +@requires_gles30 (no extension providing this functionality) */ inline AbstractTexture::InternalFormat operator|(AbstractTexture::Components components, AbstractTexture::ComponentType type) { return AbstractTexture::InternalFormat(components, type); @@ -684,7 +804,6 @@ inline AbstractTexture::InternalFormat operator|(AbstractTexture::Components com inline AbstractTexture::InternalFormat operator|(AbstractTexture::ComponentType type, AbstractTexture::Components components) { return AbstractTexture::InternalFormat(components, type); } -#endif #ifndef DOXYGEN_GENERATING_OUTPUT #ifndef MAGNUM_TARGET_GLES @@ -695,16 +814,16 @@ template<> struct AbstractTexture::DataHelper<1> { inline constexpr static Target target() { return Target::Texture1D; } - inline static void setWrapping(GLenum target, const Math::Vector<1, Wrapping>& wrapping) { - glTexParameteri(target, GL_TEXTURE_WRAP_S, static_cast(wrapping[0])); + inline static void setWrapping(AbstractTexture* texture, const Math::Vector<1, Wrapping>& wrapping) { + (texture->*parameteriImplementation)(GL_TEXTURE_WRAP_S, static_cast(wrapping[0])); } - template inline static typename std::enable_if::type set(GLenum target, GLint mipLevel, InternalFormat internalFormat, Image* image) { - glTexImage1D(target, mipLevel, internalFormat, image->dimensions()[0], 0, static_cast(image->components()), static_cast(image->type()), image->data()); + template inline static typename std::enable_if::type set(AbstractTexture* texture, GLenum target, GLint mipLevel, InternalFormat internalFormat, Image* image) { + (texture->*image1DImplementation)(target, mipLevel, internalFormat, image->size(), image->components(), image->type(), image->data()); } - template inline static typename std::enable_if::type setSub(GLenum target, GLint mipLevel, const Math::Vector<1, GLint>& offset, Image* image) { - glTexSubImage1D(target, mipLevel, offset[0], image->dimensions()[0], static_cast(image->components()), static_cast(image->type()), image->data()); + template inline static typename std::enable_if::type setSub(AbstractTexture* texture, GLenum target, GLint mipLevel, const Math::Vector<1, GLint>& offset, Image* image) { + (texture->*subImage1DImplementation)(target, mipLevel, offset, image->size(), image->components(), image->type(), image->data()); } }; #endif @@ -720,47 +839,41 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> { inline constexpr static Target target() { return Target::Texture2D; } - static void setWrapping(GLenum target, const Math::Vector<2, Wrapping>& wrapping); + static void setWrapping(AbstractTexture* texture, const Math::Vector2& wrapping); - template inline static typename std::enable_if::type set(GLenum target, GLint mipLevel, InternalFormat internalFormat, Image* image) { - glTexImage2D(target, mipLevel, internalFormat, image->dimensions()[0], image->dimensions()[1], 0, static_cast(image->components()), static_cast(image->type()), image->data()); + template inline static typename std::enable_if::type set(AbstractTexture* texture, GLenum target, GLint mipLevel, InternalFormat internalFormat, Image* image) { + (texture->*image2DImplementation)(target, mipLevel, internalFormat, image->size(), image->components(), image->type(), image->data()); } - template inline static typename std::enable_if::type setSub(GLenum target, GLint mipLevel, const Math::Vector<2, GLint>& offset, Image* image) { - glTexSubImage2D(target, mipLevel, offset[0], offset[1], image->dimensions()[0], image->dimensions()[1], static_cast(image->components()), static_cast(image->type()), image->data()); + template inline static typename std::enable_if::type setSub(AbstractTexture* texture, GLenum target, GLint mipLevel, const Math::Vector2& offset, Image* image) { + (texture->*subImage2DImplementation)(target, mipLevel, offset, image->size(), image->components(), image->type(), image->data()); } - template inline static typename std::enable_if::type setSub(GLenum target, GLint mipLevel, const Math::Vector<2, GLint>& offset, Image* image) { - glTexSubImage2D(target, mipLevel, offset[0], offset[1], image->dimensions()[0], 1, static_cast(image->components()), static_cast(image->type()), image->data()); + template inline static typename std::enable_if::type setSub(AbstractTexture* texture, GLenum target, GLint mipLevel, const Math::Vector2& offset, Image* image) { + (texture->*subImage2DImplementation)(target, mipLevel, offset, Math::Vector2(image->size(), 1), image->components(), image->type(), image->data()); } }; template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> { enum class Target: GLenum { - #ifndef MAGNUM_TARGET_GLES Texture3D = GL_TEXTURE_3D, Texture2DArray = GL_TEXTURE_2D_ARRAY - #endif }; - #ifndef MAGNUM_TARGET_GLES inline constexpr static Target target() { return Target::Texture3D; } - #endif - static void setWrapping(GLenum target, const Math::Vector<3, Wrapping>& wrapping); + static void setWrapping(AbstractTexture* texture, const Math::Vector3& wrapping); - #ifndef MAGNUM_TARGET_GLES - template inline static typename std::enable_if::type set(GLenum target, GLint mipLevel, InternalFormat internalFormat, Image* image) { - glTexImage3D(target, mipLevel, internalFormat, image->dimensions()[0], image->dimensions()[1], image->dimensions()[2], 0, static_cast(image->components()), static_cast(image->type()), image->data()); + template inline static typename std::enable_if::type set(AbstractTexture* texture, GLenum target, GLint mipLevel, InternalFormat internalFormat, Image* image) { + (texture->*image3DImplementation)(target, mipLevel, internalFormat, image->size(), image->components(), image->type(), image->data()); } - template inline static typename std::enable_if::type setSub(GLenum target, GLint mipLevel, const Math::Vector<3, GLint>& offset, Image* image) { - glTexSubImage3D(target, mipLevel, offset[0], offset[1], offset[2], image->dimensions()[0], image->dimensions()[1], image->dimensions()[2], static_cast(image->components()), static_cast(image->type()), image->data()); + template inline static typename std::enable_if::type setSub(AbstractTexture* texture, GLenum target, GLint mipLevel, const Math::Vector3& offset, Image* image) { + (texture->*subImage3DImplementation)(target, mipLevel, offset, image->size(), image->components(), image->type(), image->data()); } - template inline static typename std::enable_if::type setSub(GLenum target, GLint mipLevel, const Math::Vector<3, GLint>& offset, Image* image) { - glTexSubImage3D(target, mipLevel, offset[0], offset[1], offset[2], image->dimensions()[0], image->dimensions()[1], 1, static_cast(image->components()), static_cast(image->type()), image->data()); + template inline static typename std::enable_if::type setSub(AbstractTexture* texture, GLenum target, GLint mipLevel, const Math::Vector3& offset, Image* image) { + (texture->*subImage3DImplementation)(target, mipLevel, offset, Math::Vector3(image->size(), 1), image->components(), image->type(), image->data()); } - #endif }; #endif diff --git a/src/Buffer.cpp b/src/Buffer.cpp new file mode 100644 index 000000000..777d0b06b --- /dev/null +++ b/src/Buffer.cpp @@ -0,0 +1,117 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "Buffer.h" + +#include + +#include "Context.h" +#include "Extensions.h" +#include "Implementation/State.h" +#include "Implementation/BufferState.h" + +namespace Magnum { + +#ifndef MAGNUM_TARGET_GLES2 +Buffer::CopyImplementation Buffer::copyImplementation = &Buffer::copyImplementationDefault; +#endif +Buffer::SetDataImplementation Buffer::setDataImplementation = &Buffer::setDataImplementationDefault; +Buffer::SetSubDataImplementation Buffer::setSubDataImplementation = &Buffer::setSubDataImplementationDefault; + +void Buffer::initializeContextBasedFunctionality(Context* context) { + #ifndef MAGNUM_TARGET_GLES + if(context->isExtensionSupported()) { + Debug() << "Buffer: using" << Extensions::GL::EXT::direct_state_access::string() << "features"; + + copyImplementation = &Buffer::copyImplementationDSA; + setDataImplementation = &Buffer::setDataImplementationDSA; + setSubDataImplementation = &Buffer::setSubDataImplementationDSA; + } + #else + static_cast(context); + #endif +} + +Buffer::~Buffer() { + GLuint* bindings = Context::current()->state()->buffer->bindings; + + /* Remove all current bindings from the state */ + for(std::size_t i = 1; i != Implementation::BufferState::TargetCount; ++i) + if(bindings[i] == _id) bindings[i] = 0; + + glDeleteBuffers(1, &_id); +} + +void Buffer::bind(Target target, GLuint id) { + GLuint& bound = Context::current()->state()->buffer->bindings[Implementation::BufferState::indexForTarget(target)]; + + /* Already bound, nothing to do */ + if(bound == id) return; + + /* Bind the buffer otherwise */ + bound = id; + glBindBuffer(static_cast(target), id); +} + +Buffer::Target Buffer::bindInternal(Target hint) { + GLuint* bindings = Context::current()->state()->buffer->bindings; + GLuint& hintBinding = bindings[Implementation::BufferState::indexForTarget(hint)]; + + /* Shortcut - if already bound to hint, return */ + if(hintBinding == _id) return hint; + + /* Return first target in which the buffer is bound */ + for(std::size_t i = 1; i != Implementation::BufferState::TargetCount; ++i) + if(bindings[i] == _id) return Implementation::BufferState::targetForIndex[i]; + + /* Bind the buffer to hint target otherwise */ + hintBinding = _id; + glBindBuffer(static_cast(hint), _id); + return hint; +} + +#ifndef MAGNUM_TARGET_GLES2 +void Buffer::copyImplementationDefault(Buffer* read, Buffer* write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) { + glCopyBufferSubData(static_cast(read->bindInternal(Target::CopyRead)), static_cast(write->bindInternal(Target::CopyWrite)), readOffset, writeOffset, size); +} + +#ifndef MAGNUM_TARGET_GLES +void Buffer::copyImplementationDSA(Buffer* read, Buffer* write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) { + glNamedCopyBufferSubDataEXT(read->_id, write->_id, readOffset, writeOffset, size); +} +#endif +#endif + +void Buffer::setDataImplementationDefault(GLsizeiptr size, const GLvoid* data, Buffer::Usage usage) { + glBufferData(static_cast(bindInternal(_targetHint)), size, data, static_cast(usage)); +} + +#ifndef MAGNUM_TARGET_GLES +void Buffer::setDataImplementationDSA(GLsizeiptr size, const GLvoid* data, Buffer::Usage usage) { + glNamedBufferDataEXT(_id, size, data, static_cast(usage)); +} +#endif + +void Buffer::setSubDataImplementationDefault(GLintptr offset, GLsizeiptr size, const GLvoid* data) { + glBufferSubData(static_cast(bindInternal(_targetHint)), offset, size, data); +} + +#ifndef MAGNUM_TARGET_GLES +void Buffer::setSubDataImplementationDSA(GLintptr offset, GLsizeiptr size, const GLvoid* data) { + glNamedBufferSubDataEXT(_id, offset, size, data); +} +#endif + +} diff --git a/src/Buffer.h b/src/Buffer.h index 54af31cf4..5efa508a2 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -19,211 +19,327 @@ * @brief Class Magnum::Buffer */ +#include +#include +#include + #include "Magnum.h" +#include "magnumVisibility.h" + namespace Magnum { +class Context; + /** -@brief Class for managing buffers +@brief %Buffer + +Encapsulates one OpenGL buffer object and provides functions for convenient +data updates. + +@section Buffer-data Data updating + +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 +Vector3* data = new Vector3[200]; +buffer.setData(200*sizeof(Vector3), data, Buffer::Usage::StaticDraw); +@endcode +Howewer, in some cases, you have the data in fixed-size array with size known +at compile time. There is an convenient overload which detects the size of +passed array, so you don't have to repeat it: +@code +Vector3 data[] = { + // ... +}; +buffer.setData(data, Buffer::Usage::StaticDraw); +@endcode +There is also overload for array-like containers from STL, such as `std::vector` or +`std::array`: +@code +std::vector data; +buffer.setData(data, Buffer::Usage::StaticDraw); +@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. + +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. -@todo Support for buffer copying (OpenGL 3.1, @extension{ARB,copy_buffer}) @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}) */ -class Buffer { +class MAGNUM_EXPORT Buffer { + friend class Context; + Buffer(const Buffer& other) = delete; Buffer(Buffer&& other) = delete; Buffer& operator=(const Buffer& other) = delete; Buffer& operator=(Buffer&& other) = delete; public: - /** @brief %Buffer target */ + /** + * @brief %Buffer target + * + * @see bind(Target), unbind(Target) + */ enum class Target: GLenum { /** Used for storing vertex attributes. */ Array = GL_ARRAY_BUFFER, #ifndef MAGNUM_TARGET_GLES /** - * Source for copies. - * @requires_gl + * Used for storing 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, + #endif + + /** + * Source for copies. See copy(). * @requires_gl31 Extension @extension{ARB,copy_buffer} + * @requires_gles30 Buffer copying is not available in OpenGL ES + * 2.0. */ CopyRead = GL_COPY_READ_BUFFER, /** - * Target for copies. - * @requires_gl + * Target for copies. See copy(). * @requires_gl31 Extension @extension{ARB,copy_buffer} + * @requires_gles30 Buffer copying is not available in OpenGL ES + * 2.0. */ CopyWrite = GL_COPY_WRITE_BUFFER, + + #ifndef MAGNUM_TARGET_GLES + /** + * Indirect compute dispatch commands. + * @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_gl Indirect drawing not available in OpenGL ES. + */ + DrawIndirect = GL_DRAW_INDIRECT_BUFFER, #endif /** Used for storing vertex indices. */ - ElementArray = GL_ELEMENT_ARRAY_BUFFER + ElementArray = GL_ELEMENT_ARRAY_BUFFER, - #ifndef MAGNUM_TARGET_GLES - , + /** + * Target for pixel pack operations. + * @requires_gles30 Pixel buffer objects are not available in + * OpenGL ES 2.0. + */ + PixelPack = GL_PIXEL_PACK_BUFFER, /** * Source for texture update operations. - * @requires_gl + * @requires_gles30 Pixel buffer objects are not available in + * OpenGL ES 2.0. */ PixelUnpack = GL_PIXEL_UNPACK_BUFFER, + #ifndef MAGNUM_TARGET_GLES /** - * Target for pixel pack operations. - * @requires_gl + * Used for shader storage. + * @requires_gl43 Extension @extension{ARB,shader_storage_buffer_object} + * @requires_gl Shader storage is not available in OpenGL ES. */ - PixelPack = GL_PIXEL_PACK_BUFFER, + ShaderStorage = GL_SHADER_STORAGE_BUFFER, /** - * Source for texel fetches. - * - * @see BufferedTexture - * @requires_gl + * Source for texel fetches. See BufferedTexture. * @requires_gl31 Extension @extension{ARB,texture_buffer_object} + * @requires_gl Texture buffers are not available in OpenGL ES. */ Texture = GL_TEXTURE_BUFFER, + #endif /** * Target for transform feedback. - * @requires_gl * @requires_gl30 Extension @extension{EXT,transform_feedback} + * @requires_gles30 Transform feedback is not available in OpenGL + * ES 2.0. */ TransformFeedback = GL_TRANSFORM_FEEDBACK_BUFFER, /** * Used for storing uniforms. - * @requires_gl * @requires_gl31 Extension @extension{ARB,uniform_buffer_object} + * @requires_gles30 Uniform buffers are not available in OpenGL ES + * 2.0. */ - Uniform = GL_UNIFORM_BUFFER, - - /** - * Used for supplying arguments for instanced drawing. - * @requires_gl - * @requires_gl40 Extension @extension{ARB,draw_indirect} - */ - DrawIndirect = GL_DRAW_INDIRECT_BUFFER - #endif + Uniform = GL_UNIFORM_BUFFER }; - /** @brief Buffer usage */ + /** + * @brief %Buffer usage + * + * @see setData(GLsizeiptr, const GLvoid*, Usage) + */ enum class Usage: GLenum { /** * Set once by the application and used infrequently for drawing. */ StreamDraw = GL_STREAM_DRAW, - #ifndef MAGNUM_TARGET_GLES /** * Set once as output from an OpenGL command and used infequently * for drawing. - * @requires_gl + * @requires_gles30 Only @ref Magnum::Buffer::Usage "Usage::StreamDraw" + * is available in OpenGL ES 2.0. */ StreamRead = GL_STREAM_READ, /** * Set once as output from an OpenGL command and used infrequently * for drawing or copying to other buffers. - * @requires_gl + * @requires_gles30 Only @ref Magnum::Buffer::Usage "Usage::StreamDraw" + * is available in OpenGL ES 2.0. */ StreamCopy = GL_STREAM_COPY, - #endif /** * Set once by the application and used frequently for drawing. */ StaticDraw = GL_STATIC_DRAW, - #ifndef MAGNUM_TARGET_GLES /** * Set once as output from an OpenGL command and queried many * times by the application. - * @requires_gl + * @requires_gles30 Only @ref Magnum::Buffer::Usage "Usage::StaticDraw" + * is available in OpenGL ES 2.0. */ StaticRead = GL_STATIC_READ, /** * Set once as output from an OpenGL command and used frequently * for drawing or copying to other buffers. - * @requires_gl + * @requires_gles30 Only @ref Magnum::Buffer::Usage "Usage::StaticDraw" + * is available in OpenGL ES 2.0. */ StaticCopy = GL_STATIC_COPY, - #endif /** * Updated frequently by the application and used frequently * for drawing or copying to other images. */ - DynamicDraw = GL_DYNAMIC_DRAW - - #ifndef MAGNUM_TARGET_GLES - , + DynamicDraw = GL_DYNAMIC_DRAW, /** * Updated frequently as output from OpenGL command and queried * many times from the application. - * @requires_gl + * @requires_gles30 Only @ref Magnum::Buffer::Usage "Usage::DynamicDraw" + * is available in OpenGL ES 2.0. */ DynamicRead = GL_DYNAMIC_READ, /** * Updated frequently as output from OpenGL command and used * frequently for drawing or copying to other images. - * @requires_gl + * @requires_gles30 Only @ref Magnum::Buffer::Usage "Usage::DynamicCopy" + * is available in OpenGL ES 2.0. */ DynamicCopy = GL_DYNAMIC_COPY - #endif }; /** * @brief Unbind any buffer from given target - * @param target %Target + * @param target %Target + * + * @see @fn_gl{BindBuffer} + */ + inline static void unbind(Target target) { bind(target, 0); } + + #ifndef MAGNUM_TARGET_GLES2 + /** + * @brief Copy one buffer to another + * @param read %Buffer from which to read + * @param write %Buffer to which to copy + * @param readOffset Offset in the read buffer + * @param writeOffset Offset in the write buffer + * @param size Data size + * + * If @extension{EXT,direct_state_access} is not available and the + * 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} */ - inline static void unbind(Target target) { - glBindBuffer(static_cast(target), 0); + inline static void copy(Buffer* read, Buffer* write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) { + copyImplementation(read, write, readOffset, writeOffset, size); } + #endif /** * @brief Constructor - * @param defaultTarget Default target (used when calling bind() - * without parameter) * * Generates new OpenGL buffer. + * @see @fn_gl{GenBuffers} */ - inline Buffer(Target defaultTarget): _defaultTarget(defaultTarget) { - glGenBuffers(1, &buffer); + inline Buffer(): _targetHint(Target::Array) { + glGenBuffers(1, &_id); } /** * @brief Destructor * * Deletes associated OpenGL buffer. + * @see @fn_gl{DeleteBuffers} */ - inline virtual ~Buffer() { - glDeleteBuffers(1, &buffer); - } + virtual ~Buffer(); - /** @brief Default bind type */ - inline Target defaultTarget() const { return _defaultTarget; } + /** @brief OpenGL buffer ID */ + inline GLuint id() const { return _id; } - /** @brief OpenGL internal buffer ID */ - inline GLuint id() const { return buffer; } + /** @brief Target hint */ + inline Target targetHint() const { return _targetHint; } /** - * @brief Bind buffer + * @brief Set target hint + * + * If @extension{EXT,direct_state_access} is not available, the buffer + * must be internally bound to some target before any operation. You + * can specify target which will always be used when binding the + * buffer internally, possibly saving some calls to @fn_gl{BindBuffer}. * - * Binds buffer with default target. + * Default target hint is `Target::Array`. + * @see setData(), setSubData() + * @todo Target::ElementArray cannot be used when no VAO is bound - + * http://www.opengl.org/wiki/Vertex_Specification#Index_buffers + * ... damned GL state */ - inline void bind() { bind(_defaultTarget); } + inline void setTargetHint(Target hint) { _targetHint = hint; } /** * @brief Bind buffer - * @param target %Target + * @param target %Target + * + * @todo Allow binding to Target::ElementArray only if VAO is bound + * to avoid potential issues? + * @bug Binding to ElementArray if any VAO is active will corrupt the mesh + * @todo Don't allow user to bind buffers? + * @see @fn_gl{BindBuffer} */ - inline void bind(Target target) { - glBindBuffer(static_cast(target), buffer); - } + inline void bind(Target target) { bind(target, _id); } /** * @brief Set buffer data @@ -231,10 +347,14 @@ class Buffer { * @param data Pointer to data * @param usage %Buffer usage * - * Sets buffer data with default target. + * 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{BufferData} or + * @fn_gl_extension{NamedBufferData,EXT,direct_state_access} */ inline void setData(GLsizeiptr size, const GLvoid* data, Usage usage) { - setData(_defaultTarget, size, data, usage); + (this->*setDataImplementation)(size, data, usage); } /** @@ -242,12 +362,10 @@ class Buffer { * @param data Fixed-size array with data * @param usage %Buffer usage * - * Sets buffer data with default target. More convenient for setting - * data from fixed-size arrays than - * setData(GLsizeiptr, const GLvoid*, Usage). + * @see setData(GLsizeiptr, const GLvoid*, Usage). */ - template inline void setData(const T(&data)[size], Usage usage) { - setData(_defaultTarget, data, usage); + template inline void setData(const T(&data)[size], Usage usage) { + setData(size*sizeof(T), data, usage); } /** @@ -255,121 +373,91 @@ class Buffer { * @param data Vector with data * @param usage %Buffer usage * - * Sets buffer data with default target. + * @see setData(GLsizeiptr, const GLvoid*, Usage) */ template inline void setData(const std::vector& data, Usage usage) { - setData(_defaultTarget, data, usage); + setData(data.size()*sizeof(T), data.data(), usage); } - /** - * @brief Set buffer data - * @param target %Target - * @param size Data size - * @param data Pointer to data - * @param usage %Buffer usage - */ - inline void setData(Target target, GLsizeiptr size, const GLvoid* data, Usage usage) { - bind(target); - glBufferData(static_cast(target), size, data, static_cast(usage)); - } - - /** - * @brief Set buffer data - * @param target %Target - * @param data Fixed-size array with data - * @param usage %Buffer usage - * - * More convenient for setting data from fixed-size arrays than - * setData(Target, GLsizeiptr, const GLvoid*, Usage). - */ - template inline void setData(Target target, const T(&data)[size], Usage usage) { - setData(target, size*sizeof(T), data, usage); - } - - /** - * @brief Set buffer data - * @param target %Target - * @param data Vector with data - * @param usage %Buffer usage - */ - template inline void setData(Target target, const std::vector& data, Usage usage) { - setData(target, data.size()*sizeof(T), data.data(), usage); + /** @overload */ + template inline void setData(const std::array& data, Usage usage) { + setData(data.size()*sizeof(T), data.data(), usage); } /** * @brief Set buffer subdata - * @param offset Offset + * @param offset Offset in the buffer * @param size Data size * @param data Pointer to data * - * Sets buffer subdata with default target. + * 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{BufferSubData} + * or @fn_gl_extension{NamedBufferSubData,EXT,direct_state_access} */ inline void setSubData(GLintptr offset, GLsizeiptr size, const GLvoid* data) { - setSubData(_defaultTarget, offset, size, data); + (this->*setSubDataImplementation)(offset, size, data); } /** * @brief Set buffer subdata - * @param offset Offset + * @param offset Offset in the buffer * @param data Fixed-size array with data * - * Sets buffer subdata with default target. More convenient for - * setting data from fixed-size arrays than - * setSubData(GLintptr, GLsizeiptr, const GLvoid*). + * @see setSubData(GLintptr, GLsizeiptr, const GLvoid*) */ - template inline void setSubData(GLintptr offset, const T(&data)[size]) { - setSubData(_defaultTarget, offset, data); + template inline void setSubData(GLintptr offset, const T(&data)[size]) { + setSubData(offset, size*sizeof(T), data); } /** * @brief Set buffer subdata - * @param offset Offset + * @param offset Offset in the buffer * @param data Vector with data * - * Sets buffer subdata with default target. + * @see setSubData(GLintptr, GLsizeiptr, const GLvoid*) */ template inline void setSubData(GLintptr offset, const std::vector& data) { - setSubData(_defaultTarget, offset, data); + setSubData(offset, data.size()*sizeof(T), data.data()); } - /** - * @brief Set buffer subdata - * @param target %Target - * @param offset Offset - * @param size Data size - * @param data Pointer to data - */ - inline void setSubData(Target target, GLintptr offset, GLsizeiptr size, const GLvoid* data) { - bind(target); - glBufferSubData(static_cast(target), offset, size, data); - } - - /** - * @brief Set buffer subdata - * @param target %Target - * @param offset Offset - * @param data Fixed-size array with data - * - * More convenient for setting data from fixed-size arrays than - * setSubData(Target, GLintptr, GLsizeiptr, const GLvoid*). - */ - template inline void setSubData(Target target, GLintptr offset, const T(&data)[size]) { - setSubData(target, offset, size*sizeof(T), data); - } - - /** - * @brief Set buffer subdata - * @param target %Target - * @param offset Offset - * @param data Vector with data - */ - template inline void setSubData(Target target, GLintptr offset, const std::vector& data) { - setSubData(target, offset, data.size()*sizeof(T), data.data()); + /** @overload */ + template inline void setSubData(GLintptr offset, const std::array& data) { + setSubData(offset, data.size()*sizeof(T), data.data()); } private: - GLuint buffer; - Target _defaultTarget; + static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context); + + static void bind(Target hint, GLuint id); + Target MAGNUM_LOCAL bindInternal(Target hint); + + #ifndef MAGNUM_TARGET_GLES2 + typedef void(*CopyImplementation)(Buffer*, Buffer*, GLintptr, GLintptr, GLsizeiptr); + static void MAGNUM_LOCAL copyImplementationDefault(Buffer* read, Buffer* write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); + #ifndef MAGNUM_TARGET_GLES + static void MAGNUM_LOCAL copyImplementationDSA(Buffer* read, Buffer* write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); + #endif + static CopyImplementation copyImplementation; + #endif + + typedef void(Buffer::*SetDataImplementation)(GLsizeiptr, const GLvoid*, Usage); + void MAGNUM_LOCAL setDataImplementationDefault(GLsizeiptr size, const GLvoid* data, Usage usage); + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL setDataImplementationDSA(GLsizeiptr size, const GLvoid* data, Usage usage); + #endif + static SetDataImplementation setDataImplementation; + + typedef void(Buffer::*SetSubDataImplementation)(GLintptr, GLsizeiptr, const GLvoid*); + void MAGNUM_LOCAL setSubDataImplementationDefault(GLintptr offset, GLsizeiptr size, const GLvoid* data); + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL setSubDataImplementationDSA(GLintptr offset, GLsizeiptr size, const GLvoid* data); + #endif + static SetSubDataImplementation setSubDataImplementation; + + GLuint _id; + Target _targetHint; }; } diff --git a/src/BufferedImage.cpp b/src/BufferedImage.cpp new file mode 100644 index 000000000..54fdeb03a --- /dev/null +++ b/src/BufferedImage.cpp @@ -0,0 +1,31 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 { + +template void BufferedImage::setData(const typename DimensionTraits::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>; + +} diff --git a/src/BufferedImage.h b/src/BufferedImage.h index 5489716df..0831f653b 100644 --- a/src/BufferedImage.h +++ b/src/BufferedImage.h @@ -19,24 +19,26 @@ * @brief Class Magnum::BufferedImage, typedef Magnum::BufferedImage1D, Magnum::BufferedImage2D, Magnum::BufferedImage3D */ +#include "Math/Vector3.h" #include "AbstractImage.h" #include "Buffer.h" +#include "DimensionTraits.h" #include "TypeTraits.h" namespace Magnum { -#ifndef MAGNUM_TARGET_GLES /** @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. -@requires_gl +@see BufferedImage1D, BufferedImage2D, BufferedImage3D, Buffer +@requires_gles30 Pixel buffer objects are not available in OpenGL ES 2.0. */ -template class BufferedImage: public AbstractImage { +template class MAGNUM_EXPORT BufferedImage: public AbstractImage { public: - const static size_t Dimensions = imageDimensions; /**< @brief Image dimension count */ + const static std::uint8_t Dimensions = dimensions; /**< @brief %Image dimension count */ /** * @brief Constructor @@ -46,10 +48,12 @@ template class BufferedImage: public AbstractImage { * Dimensions and buffer are empty, call setData() to fill the image * with data. */ - BufferedImage(Components components, ComponentType type): AbstractImage(components, type), _buffer(Buffer::Target::PixelPack) {} + inline BufferedImage(Components components, ComponentType type): AbstractImage(components, type) { + _buffer.setTargetHint(Buffer::Target::PixelPack); + } - /** @brief %Image dimensions */ - inline constexpr Math::Vector dimensions() const { return _dimensions; } + /** @brief %Image size */ + inline typename DimensionTraits::VectorType size() const { return _size; } /** * @brief Data @@ -57,8 +61,10 @@ template class BufferedImage: public AbstractImage { * 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) */ - void* data() { + inline void* data() { _buffer.bind(Buffer::Target::PixelUnpack); return nullptr; } @@ -68,7 +74,7 @@ template class BufferedImage: public AbstractImage { /** * @brief Set image data - * @param dimensions %Image dimensions + * @param size %Image size * @param components Color components. Data type is detected * from passed data array. * @param data %Image data @@ -76,14 +82,16 @@ template class BufferedImage: public AbstractImage { * * Updates the image buffer with given data. The data are not deleted * after filling the buffer. + * + * @see setData(const Math::Vector&, Components, ComponentType, const GLvoid*, Buffer::Usage) */ - template inline void setData(const Math::Vector& dimensions, Components components, const T* data, Buffer::Usage usage) { - setData(dimensions, components, TypeTraits::imageType(), data, usage); + template inline void setData(const typename DimensionTraits::VectorType& size, Components components, const T* data, Buffer::Usage usage) { + setData(size, components, TypeTraits::imageType(), data, usage); } /** * @brief Set image data - * @param dimensions %Image dimensions + * @param size %Image size * @param components Color components * @param type Data type * @param data %Image data @@ -91,17 +99,14 @@ template class BufferedImage: public AbstractImage { * * Updates the image buffer with given data. The data are not deleted * after filling the buffer. + * + * @see Buffer::setData() */ - void setData(const Math::Vector& dimensions, Components components, ComponentType type, const GLvoid* data, Buffer::Usage usage) { - _components = components; - _type = type; - _dimensions = dimensions; - _buffer.setData(Buffer::Target::PixelPack, pixelSize(_components, _type)*dimensions.product(), data, usage); - } + void setData(const typename DimensionTraits::VectorType& size, Components components, ComponentType type, const GLvoid* data, Buffer::Usage usage); protected: - Math::Vector _dimensions; /**< @brief %Image dimensions */ - Buffer _buffer; /**< @brief %Image buffer */ + Math::Vector _size; /**< @brief %Image size */ + Buffer _buffer; /**< @brief %Image buffer */ }; /** @brief One-dimensional buffered image */ @@ -112,7 +117,6 @@ typedef BufferedImage<2> BufferedImage2D; /** @brief Three-dimensional buffered image */ typedef BufferedImage<3> BufferedImage3D; -#endif } diff --git a/src/BufferedTexture.cpp b/src/BufferedTexture.cpp index ffd5a6d20..862f1f97a 100644 --- a/src/BufferedTexture.cpp +++ b/src/BufferedTexture.cpp @@ -15,9 +15,32 @@ #include "BufferedTexture.h" +#ifndef MAGNUM_TARGET_GLES +#include "Buffer.h" +#include "Context.h" +#include "Extensions.h" + namespace Magnum { -#ifndef MAGNUM_TARGET_GLES +BufferedTexture::SetBufferImplementation BufferedTexture::setBufferImplementation = &BufferedTexture::setBufferImplementationDefault; + +void BufferedTexture::initializeContextBasedFunctionality(Context* context) { + if(context->isExtensionSupported()) { + 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: \ @@ -49,6 +72,6 @@ BufferedTexture::InternalFormat::InternalFormat(Components components, Component internalFormatSwitch(RGBA) #undef internalFormatSwitch } -#endif } +#endif diff --git a/src/BufferedTexture.h b/src/BufferedTexture.h index 12f2b05c0..170f606b9 100644 --- a/src/BufferedTexture.h +++ b/src/BufferedTexture.h @@ -15,16 +15,20 @@ GNU Lesser General Public License version 3 for more details. */ +#ifndef MAGNUM_TARGET_GLES /** @file * @brief Class Magnum::BufferedTexture */ +#endif -#include "Renderbuffer.h" -#include "Buffer.h" +#include "AbstractTexture.h" +#ifndef MAGNUM_TARGET_GLES namespace Magnum { -#ifndef MAGNUM_TARGET_GLES +class Buffer; +class Context; + /** @brief Buffered texture @@ -37,10 +41,19 @@ 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()`. -@requires_gl +@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 BufferedTexture { +class MAGNUM_EXPORT BufferedTexture: private AbstractTexture { + friend class Context; + BufferedTexture(const BufferedTexture& other) = delete; BufferedTexture(BufferedTexture&& other) = delete; BufferedTexture& operator=(const BufferedTexture& other) = delete; @@ -117,25 +130,10 @@ class BufferedTexture { /*@}*/ - /** - * @brief Constructor - * - * Creates one OpenGL texture. - */ - inline BufferedTexture() { - glGenTextures(1, &texture); - } - - /** @copydoc AbstractTexture::~AbstractTexture() */ - inline virtual ~BufferedTexture() { - glDeleteTextures(1, &texture); - } + inline BufferedTexture(): AbstractTexture(GL_TEXTURE_BUFFER) {} - /** @copydoc AbstractTexture::bind(GLint) */ - inline void bind(GLint layer) { - glActiveTexture(GL_TEXTURE0 + layer); - bind(); - } + /** @copydoc AbstractTexture::bind() */ + inline void bind(GLint layer) { AbstractTexture::bind(layer); } /** * @brief Set texture buffer @@ -145,19 +143,20 @@ class BufferedTexture { * 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} */ - void setBuffer(InternalFormat internalFormat, Buffer* buffer) { - bind(); - glTexBuffer(GL_TEXTURE_BUFFER, internalFormat, buffer->id()); + inline void setBuffer(InternalFormat internalFormat, Buffer* buffer) { + (this->*setBufferImplementation)(internalFormat, buffer); } private: - GLuint texture; + static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context); - /** @copydoc AbstractTexture::bind() */ - inline void bind() { - glBindTexture(GL_TEXTURE_BUFFER, texture); - } + 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 @@ -172,8 +171,8 @@ inline BufferedTexture::InternalFormat operator|(BufferedTexture::Components com inline BufferedTexture::InternalFormat operator|(BufferedTexture::ComponentType type, BufferedTexture::Components components) { return BufferedTexture::InternalFormat(components, type); } -#endif } +#endif #endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bad14abd8..7ca86f181 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,14 +1,21 @@ -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wold-style-cast -pedantic -std=c++0x -fvisibility=hidden") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wold-style-cast -Winit-self -pedantic -std=c++0x -fvisibility=hidden") + +# -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() # If targeting GLES, save it into configuration header if(TARGET_GLES) set(MAGNUM_TARGET_GLES 1) endif() +if(TARGET_GLES2) + set(MAGNUM_TARGET_GLES2 1) +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") +if(GCC46_COMPATIBILITY) + set(MAGNUM_GCC46_COMPATIBILITY 1) endif() configure_file(${CMAKE_CURRENT_SOURCE_DIR}/magnumConfigure.h.cmake @@ -21,8 +28,11 @@ set(Magnum_SRCS AbstractImage.cpp AbstractTexture.cpp AbstractShaderProgram.cpp - BufferedTexture.cpp + Buffer.cpp + BufferedImage.cpp + Context.cpp Framebuffer.cpp + Image.cpp IndexedMesh.cpp Mesh.cpp Profiler.cpp @@ -30,20 +40,33 @@ set(Magnum_SRCS Renderbuffer.cpp Shader.cpp SizeTraits.cpp + Timeline.cpp TypeTraits.cpp + Implementation/BufferState.cpp + Implementation/State.cpp + Trade/AbstractImporter.cpp - Trade/MeshData.cpp) + Trade/MeshData2D.cpp + Trade/MeshData3D.cpp) + +# Desktop-only code +if(NOT TARGET_GLES) + set(Magnum_SRCS ${Magnum_SRCS} + BufferedTexture.cpp) +endif() + set(Magnum_HEADERS AbstractImage.h AbstractShaderProgram.h AbstractTexture.h BufferedImage.h - BufferedTexture.h Buffer.h Color.h - CubeMapTextureArray.h + Context.h CubeMapTexture.h + DimensionTraits.h + Extensions.h Framebuffer.h Image.h ImageWrapper.h @@ -53,14 +76,24 @@ set(Magnum_HEADERS Profiler.h Query.h Renderbuffer.h + ResourceManager.h Shader.h SizeTraits.h Swizzle.h Texture.h + Timeline.h TypeTraits.h magnumCompatibility.h magnumVisibility.h) + +# Desktop-only headers +if(NOT TARGET_GLES) + set(Magnum_HEADERS ${Magnum_HEADERS} + BufferedTexture.h + CubeMapTextureArray.h) +endif() + if(NOT CMAKE_NO_OBJECT_TARGET) add_library(MagnumObjects OBJECT ${Magnum_SRCS}) endif() @@ -88,12 +121,18 @@ else() ${Magnum_SRCS} ${MagnumMath_SRCS}) endif() -target_link_libraries(Magnum ${CORRADE_UTILITY_LIBRARY} ${CORRADE_PLUGINMANAGER_LIBRARY}) +set(Magnum_LIBS + ${CORRADE_UTILITY_LIBRARY} + ${CORRADE_PLUGINMANAGER_LIBRARY}) if(NOT TARGET_GLES) - target_link_libraries(Magnum ${OPENGL_gl_LIBRARY} ${GLEW_LIBRARY}) + set(Magnum_LIBS ${Magnum_LIBS} + ${OPENGL_gl_LIBRARY} + ${GLEW_LIBRARY}) else() - target_link_libraries(Magnum ${OPENGLES2_LIBRARY}) + set(Magnum_LIBS ${Magnum_LIBS} + ${OPENGLES2_LIBRARY}) endif() +target_link_libraries(Magnum ${Magnum_LIBS}) install(TARGETS Magnum DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) install(FILES ${Magnum_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}) @@ -137,12 +176,7 @@ if(BUILD_TESTS) ${Magnum_SRCS}) endif() set_target_properties(MagnumTestLib PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT) - target_link_libraries(MagnumTestLib ${CORRADE_UTILITY_LIBRARY} ${CORRADE_PLUGINMANAGER_LIBRARY}) - if(NOT TARGET_GLES) - target_link_libraries(MagnumTestLib ${OPENGL_gl_LIBRARY} ${GLEW_LIBRARY}) - else() - target_link_libraries(MagnumTestLib ${OPENGLES2_LIBRARY}) - endif() + target_link_libraries(MagnumTestLib ${Magnum_LIBS}) add_subdirectory(Test) endif() diff --git a/src/Color.h b/src/Color.h index 304c5408e..c24866b9d 100644 --- a/src/Color.h +++ b/src/Color.h @@ -160,7 +160,7 @@ template class Color3: public Math::Vector3 { * @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 `unsigned char`. + * `{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. @@ -175,7 +175,7 @@ template class Color3: public Math::Vector3 { * @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 `unsigned char`. + * `{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. @@ -224,13 +224,12 @@ template class Color3: public Math::Vector3 { */ inline constexpr Color3(T r, T g, T b): Math::Vector3(r, g, b) {} - inline constexpr T r() const { return Math::Vector3::x(); } /**< @brief R component */ - inline constexpr T g() const { return Math::Vector3::y(); } /**< @brief G component */ - inline constexpr T b() const { return Math::Vector3::z(); } /**< @brief B component */ - - inline void setR(T value) { Math::Vector3::setX(value); } /**< @brief Set R component */ - inline void setG(T value) { Math::Vector3::setY(value); } /**< @brief Set G component */ - inline void setB(T value) { Math::Vector3::setZ(value); } /**< @brief Set B component */ + inline T& r() { return Math::Vector3::x(); } /**< @brief R component */ + inline constexpr T r() const { return Math::Vector3::x(); } /**< @overload */ + inline T& g() { return Math::Vector3::y(); } /**< @brief G component */ + inline constexpr T g() const { return Math::Vector3::y(); } /**< @overload */ + inline T& b() { return Math::Vector3::z(); } /**< @brief B component */ + inline constexpr T b() const { return Math::Vector3::z(); } /**< @overload */ /** * @brief Convert to HSV @@ -360,17 +359,16 @@ template class Color4: public Math::Vector4 { */ /* 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::Vector<3, T>& rgb, T a = Implementation::defaultAlpha()): Math::Vector4(rgb[0], rgb[1], rgb[2], a) {} - - inline constexpr T r() const { return Math::Vector4::x(); } /**< @brief R component */ - inline constexpr T g() const { return Math::Vector4::y(); } /**< @brief G component */ - inline constexpr T b() const { return Math::Vector4::z(); } /**< @brief B component */ - inline constexpr T a() const { return Math::Vector4::w(); } /**< @brief A component */ + inline constexpr Color4(const Math::Vector3& rgb, T a = Implementation::defaultAlpha()): Math::Vector4(rgb[0], rgb[1], rgb[2], a) {} - inline void setR(T value) { Math::Vector4::setX(value); } /**< @brief Set R component */ - inline void setG(T value) { Math::Vector4::setY(value); } /**< @brief Set G component */ - inline void setB(T value) { Math::Vector4::setZ(value); } /**< @brief Set B component */ - inline void setA(T value) { Math::Vector4::setW(value); } /**< @brief Set A component */ + inline T& r() { return Math::Vector4::x(); } /**< @brief R component */ + inline constexpr T r() const { return Math::Vector4::x(); } /**< @overload */ + inline T& g() { return Math::Vector4::y(); } /**< @brief G component */ + inline constexpr T g() const { return Math::Vector4::y(); } /**< @overload */ + inline T& b() { return Math::Vector4::z(); } /**< @brief B component */ + inline constexpr T b() const { return Math::Vector4::z(); } /**< @overload */ + inline T& a() { return Math::Vector4::w(); } /**< @brief A component */ + inline constexpr T a() const { return Math::Vector4::w(); } /**< @overload */ /** * @brief RGB part of the vector @@ -378,7 +376,8 @@ template class Color4: public Math::Vector4 { * * @see swizzle() */ - inline constexpr Color3 rgb() const { return Math::Vector4::xyz(); } + inline Color3& rgb() { return Color3::from(Math::Vector4::data()); } + inline constexpr Color3 rgb() const { return Color3::from(Math::Vector4::data()); } /**< @overload */ /** @copydoc Color3::toHSV() */ inline constexpr HSV toHSV() const { @@ -407,13 +406,13 @@ template class Color4: public Math::Vector4 { MAGNUM_VECTOR_SUBCLASS_OPERATOR_IMPLEMENTATION(Color4, 4) /** @debugoperator{Magnum::Color3} */ -template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Magnum::Color3& value) { - return debug << static_cast&>(value); +template inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Color3& value) { + return debug << static_cast&>(value); } /** @debugoperator{Magnum::Color4} */ -template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Magnum::Color4& value) { - return debug << static_cast&>(value); +template inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Color4& value) { + return debug << static_cast&>(value); } } diff --git a/src/Context.cpp b/src/Context.cpp new file mode 100644 index 000000000..3f6f11916 --- /dev/null +++ b/src/Context.cpp @@ -0,0 +1,265 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "Context.h" + +#include +#include +#include + +#include "AbstractShaderProgram.h" +#include "AbstractTexture.h" +#include "Buffer.h" +#include "BufferedTexture.h" +#include "Extensions.h" +#include "IndexedMesh.h" +#include "Mesh.h" +#include "Implementation/State.h" + +using namespace std; + +namespace Magnum { + +const std::vector& Extension::extensions(Version version) { + #define _extension(prefix, vendor, extension) \ + {Extensions::prefix::vendor::extension::Index, Extensions::prefix::vendor::extension::requiredVersion(), Extensions::prefix::vendor::extension::coreVersion(), Extensions::prefix::vendor::extension::string()} + static const std::vector empty; + #ifndef MAGNUM_TARGET_GLES + static const std::vector extensions{ + _extension(GL,EXT,texture_filter_anisotropic)}; + static const std::vector extensions300{ + _extension(GL,APPLE,flush_buffer_range), + _extension(GL,APPLE,vertex_array_object), + _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,EXT,framebuffer_object), + _extension(GL,EXT,packed_depth_stencil), + _extension(GL,EXT,framebuffer_blit), + _extension(GL,EXT,framebuffer_multisample), + _extension(GL,EXT,gpu_shader4), + _extension(GL,EXT,packed_float), + _extension(GL,EXT,texture_array), + _extension(GL,EXT,texture_compression_rgtc), + _extension(GL,EXT,texture_shared_exponent), + _extension(GL,EXT,framebuffer_sRGB), + _extension(GL,EXT,draw_buffers2), + _extension(GL,EXT,texture_integer), + _extension(GL,EXT,transform_feedback), + _extension(GL,NV,half_float), + _extension(GL,NV,depth_buffer_float), + _extension(GL,NV,conditional_render)}; + static const std::vector extensions310{ + _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,NV,primitive_restart)}; + static const std::vector extensions320{ + _extension(GL,ARB,geometry_shader4), + _extension(GL,ARB,depth_clamp), + _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,sync), + _extension(GL,ARB,texture_multisample), + _extension(GL,ARB,vertex_array_bgra)}; + static const std::vector 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,sampler_objects), + _extension(GL,ARB,shader_bit_encoding), + _extension(GL,ARB,texture_rgb10_a2ui), + _extension(GL,ARB,texture_swizzle), + _extension(GL,ARB,timer_query), + _extension(GL,ARB,vertex_type_2_10_10_10_rev)}; + static const std::vector extensions400{ + _extension(GL,ARB,draw_buffers_blend), + _extension(GL,ARB,sample_shading), + _extension(GL,ARB,texture_cube_map_array), + _extension(GL,ARB,texture_gather), + _extension(GL,ARB,texture_query_lod), + _extension(GL,ARB,draw_indirect), + _extension(GL,ARB,gpu_shader5), + _extension(GL,ARB,gpu_shader_fp64), + _extension(GL,ARB,shader_subroutine), + _extension(GL,ARB,tessellation_shader), + _extension(GL,ARB,texture_buffer_object_rgb32), + _extension(GL,ARB,transform_feedback2), + _extension(GL,ARB,transform_feedback3)}; + static const std::vector 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,viewport_array)}; + static const std::vector extensions420{ + _extension(GL,ARB,texture_compression_bptc), + _extension(GL,ARB,base_instance), + _extension(GL,ARB,shading_language_420pack), + _extension(GL,ARB,transform_feedback_instanced), + _extension(GL,ARB,compressed_texture_pixel_storage), + _extension(GL,ARB,conservative_depth), + _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 extensions430; + #undef _extension + #else + static const std::vector extensions; + static const std::vector extensionsES200; + static const std::vector extensionsES300; + #endif + + switch(version) { + case Version::None: return extensions; + #ifndef MAGNUM_TARGET_GLES + case Version::GL210: return empty; + case Version::GL300: return extensions300; + case Version::GL310: return extensions310; + case Version::GL320: return extensions320; + case Version::GL330: return extensions330; + case Version::GL400: return extensions400; + /* case Version::GLES200: */ + case Version::GL410: return extensions410; + case Version::GL420: return extensions420; + /* case Version::GLES300: */ + case Version::GL430: return extensions430; + #else + case Version::GLES200: return extensionsES200; + case Version::GLES300: return extensionsES300; + #endif + } + + return empty; +} + +Context* Context::_current = nullptr; + +Context::Context() { + /* Version */ + glGetIntegerv(GL_MAJOR_VERSION, &_majorVersion); + glGetIntegerv(GL_MINOR_VERSION, &_minorVersion); + _version = static_cast(_majorVersion*100+_minorVersion*10); + + /* Get first future (not supported) version */ + vector versions{ + #ifndef MAGNUM_TARGET_GLES + Version::GL300, + Version::GL310, + Version::GL320, + Version::GL330, + Version::GL400, + Version::GL410, + Version::GL420, + Version::GL430, + #else + Version::GLES200, + Version::GLES300, + #endif + Version::None + }; + size_t future = 0; + while(versions[future] != Version::None && versions[future] < _version) + ++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 futureExtensions; + for(size_t i = future; i != versions.size(); ++i) + for(const Extension& extension: Extension::extensions(versions[i])) + futureExtensions.insert(make_pair(extension._string, extension)); + + /* Check for presence of extensions in future versions */ + #ifndef MAGNUM_TARGET_GLES + if(isVersionSupported(Version::GL300)) { + #else + if(isVersionSupported(Version::GLES300)) { + #endif + #ifndef MAGNUM_TARGET_GLES2 + GLuint index = 0; + const char* extension; + while((extension = reinterpret_cast(glGetStringi(GL_EXTENSIONS, index++)))) { + auto found = futureExtensions.find(extension); + if(found != futureExtensions.end()) { + _supportedExtensions.push_back(found->second); + extensionStatus.set(found->second._index); + } + } + #endif + + /* OpenGL 2.1 / OpenGL ES 2.0 doesn't have glGetStringi() */ + } else { + /* Don't crash when glGetString() returns nullptr */ + const char* e = reinterpret_cast(glGetString(GL_EXTENSIONS)); + if(e) { + vector extensions = Corrade::Utility::split(e, ' '); + for(const string& extension: extensions) { + auto found = futureExtensions.find(extension); + if(found != futureExtensions.end()) { + _supportedExtensions.push_back(found->second); + extensionStatus.set(found->second._index); + } + } + } + } + + /* Set this context as current */ + CORRADE_ASSERT(!_current, "Context: Another context currently active", ); + _current = this; + + /* Initialize state tracker */ + _state = new Implementation::State; + + /* Initialize functionality based on current OpenGL version and extensions */ + AbstractShaderProgram::initializeContextBasedFunctionality(this); + AbstractTexture::initializeContextBasedFunctionality(this); + Buffer::initializeContextBasedFunctionality(this); + #ifndef MAGNUM_TARGET_GLES + BufferedTexture::initializeContextBasedFunctionality(this); + #endif + IndexedMesh::initializeContextBasedFunctionality(this); + Mesh::initializeContextBasedFunctionality(this); +} + +Context::~Context() { + CORRADE_ASSERT(_current == this, "Context: Cannot destroy context which is not currently active", ); + delete _state; + _current = nullptr; +} + +Version Context::supportedVersion(initializer_list versions) const { + for(auto version: versions) + if(isVersionSupported(version)) return version; + + #ifndef MAGNUM_TARGET_GLES + return Version::GL210; + #else + return Version::GLES200; + #endif +} + +} diff --git a/src/Context.h b/src/Context.h new file mode 100644 index 000000000..d9f6decd2 --- /dev/null +++ b/src/Context.h @@ -0,0 +1,273 @@ +#ifndef Magnum_Context_h +#define Magnum_Context_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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. +*/ + +/** @file + * @brief Enum Version, class Magnum::Context, Magnum::Extension + */ + +#include +#include + +#include "Magnum.h" + +#include "magnumVisibility.h" + +namespace Magnum { + +#ifndef DOXYGEN_GENERATING_OUTPUT +namespace Implementation { + class State; +} +#endif + +/** @brief OpenGL version */ +enum class Version: GLint { + None = 0, /**< @brief Unspecified */ + #ifndef MAGNUM_TARGET_GLES + GL210 = 210, /**< @brief OpenGL 2.1 / GLSL 1.20 */ + GL300 = 300, /**< @brief OpenGL 3.0 / GLSL 1.30 */ + GL310 = 310, /**< @brief OpenGL 3.1 / GLSL 1.40 */ + GL320 = 320, /**< @brief OpenGL 3.2 / GLSL 1.50 */ + GL330 = 330, /**< @brief OpenGL 3.3, GLSL 3.30 */ + GL400 = 400, /**< @brief OpenGL 4.0, GLSL 4.00 */ + GL410 = 410, /**< @brief OpenGL 4.1, GLSL 4.10 */ + GL420 = 420, /**< @brief OpenGL 4.2, GLSL 4.20 */ + GL430 = 430, /**< @brief OpenGL 4.3, GLSL 4.30 */ + #endif + + /** + * @brief OpenGL ES 2.0, GLSL ES 1.00 + * + * All the functionality is present in OpenGL 4.2 (extension + * @extension{ARB,ES2_compatibility}), so on desktop OpenGL this is + * equivalent to @ref Version "Version::GL410". + */ + #ifndef MAGNUM_TARGET_GLES + GLES200 = 410, + #else + GLES200 = 200, + #endif + + /** + * @brief OpenGL ES 3.0, GLSL ES 3.00 + * + * All the functionality is present in OpenGL 4.3 (extension + * @extension{ARB,ES3_compatibility}), so on desktop OpenGL this is the + * equivalent to @ref Version "Version::GL430". + */ + #ifndef MAGNUM_TARGET_GLES + GLES300 = 430 + #else + GLES300 = 300 + #endif +}; + +/** +@brief Run-time information about OpenGL extension + +Encapsulates runtime information about OpenGL extension, such as name string, +minimal required OpenGL version and version in which the extension was adopted +to core. + +See also Extensions namespace, which contain compile-time information about +OpenGL extensions. +*/ +class MAGNUM_EXPORT Extension { + friend class Context; + + public: + /** @brief All extensions for given OpenGL version */ + static const std::vector& extensions(Version version); + + /** @brief Minimal version required by this extension */ + inline constexpr Version requiredVersion() const { return _requiredVersion; } + + /** @brief Version in which this extension was adopted to core */ + inline constexpr Version coreVersion() const { return _coreVersion; } + + /** @brief %Extension string */ + inline constexpr const char* string() const { return _string; } + + private: + /* GCC 4.6 doesn't like const members, as std::vector doesn't have + proper move semantic yet */ + std::size_t _index; + Version _requiredVersion; + Version _coreVersion; + const char* _string; + + inline constexpr Extension(std::size_t index, Version requiredVersion, Version coreVersion, const char* string): _index(index), _requiredVersion(requiredVersion), _coreVersion(coreVersion), _string(string) {} +}; + +/** +@brief OpenGL context + +Provides access to version and extension information. +*/ +class MAGNUM_EXPORT Context { + Context(const Context&) = delete; + Context(Context&&) = delete; + Context& operator=(const Context&) = delete; + Context& operator=(Context&&) = delete; + + public: + /** + * @brief Constructor + * + * @see @fn_gl{Get} with @def_gl{MAJOR_VERSION}, @def_gl{MINOR_VERSION}, + * @fn_gl{GetString} with @def_gl{EXTENSIONS} + */ + Context(); + ~Context(); + + /** @brief Current context */ + inline static Context* current() { return _current; } + + /** @brief OpenGL version */ + inline Version version() const { return _version; } + + /** @brief Major OpenGL version (e.g. `4`) */ + inline GLint majorVersion() const { return _majorVersion; } + + /** @brief Minor OpenGL version (e.g. `3`) */ + inline GLint minorVersion() const { return _minorVersion; } + + /** + * @brief Vendor string + * + * @see @fn_gl{GetString} with @def_gl{VENDOR} + */ + inline std::string vendorString() const { + return reinterpret_cast(glGetString(GL_VENDOR)); + } + + /** + * @brief Renderer string + * + * @see @fn_gl{GetString} with @def_gl{RENDERER} + */ + inline std::string rendererString() const { + return reinterpret_cast(glGetString(GL_RENDERER)); + } + + /** + * @brief Version string + * + * @see @fn_gl{GetString} with @def_gl{VERSION} + */ + inline std::string versionString() const { + return reinterpret_cast(glGetString(GL_VERSION)); + } + + /** + * @brief Shading language version string + * + * @see @fn_gl{GetString} with @def_gl{SHADING_LANGUAGE_VERSION} + */ + inline std::string shadingLanguageVersionString() const { + return reinterpret_cast(glGetString(GL_SHADING_LANGUAGE_VERSION)); + } + + /** + * @brief Supported extensions + * + * The list contains only extensions from OpenGL versions newer than + * the current. + * + * @see isExtensionSupported(), Extension::extensions() + */ + inline const std::vector& supportedExtensions() const { + return _supportedExtensions; + } + + /** + * @brief Whether given OpenGL version is supported + * + * @see supportedVersion() + */ + inline bool isVersionSupported(Version version) const { + return _version >= version; + } + + /** + * @brief Get supported OpenGL version + * + * Returns first supported OpenGL version from passed list. Convenient + * equivalent to subsequent isVersionSupported() calls, e.g.: + * @code + * Version v = isVersionSupported(Version::GL330) ? Version::GL330 : Version::GL210; + * Version v = supportedVersion({Version::GL330, Version::GL210}); + * @endcode + * + * If no version from the list is supported, returns lowest available + * OpenGL version (@ref Version "Version::GL210" for desktop OpenGL, + * @ref Version "Version::GLES200" for OpenGL ES). + */ + Version supportedVersion(std::initializer_list versions) const; + + /** + * @brief Whether given extension is supported + * + * %Extensions usable with this function are listed in Extensions + * namespace in header Extensions.h. Example usage: + * @code + * if(Context::current()->isExtensionSupported()) { + * // draw fancy detailed model + * } else { + * // texture fallback + * } + * @endcode + * + * @see isExtensionSupported(const Extension&) const + */ + template inline bool isExtensionSupported() const { + return _version >= T::coreVersion() || (_version >= T::requiredVersion() && extensionStatus[T::Index]); + } + + /** + * @brief Whether given extension is supported + * + * Can be used e.g. for listing extensions available on current + * hardware, but for general usage prefer isExtensionSupported() const, + * as it does most operations in compile time. + * + * @see supportedExtensions(), Extension::extensions() + */ + inline bool isExtensionSupported(const Extension& extension) const { + return _version >= extension._coreVersion || (_version >= extension._requiredVersion && extensionStatus[extension._index]); + } + + #ifndef DOXYGEN_GENERATING_OUTPUT + inline Implementation::State* state() { return _state; } + #endif + + private: + static Context* _current; + + Version _version; + GLint _majorVersion; + GLint _minorVersion; + + std::bitset<128> extensionStatus; + std::vector _supportedExtensions; + + Implementation::State* _state; +}; + +} + +#endif diff --git a/src/Contexts/AbstractGlInterface.h b/src/Contexts/AbstractContextHandler.h similarity index 79% rename from src/Contexts/AbstractGlInterface.h rename to src/Contexts/AbstractContextHandler.h index 3f6d14ef6..ba73aa940 100644 --- a/src/Contexts/AbstractGlInterface.h +++ b/src/Contexts/AbstractContextHandler.h @@ -1,5 +1,5 @@ -#ifndef Magnum_Contexts_AbstractGlInterface_h -#define Magnum_Contexts_AbstractGlInterface_h +#ifndef Magnum_Contexts_AbstractContextHandler_h +#define Magnum_Contexts_AbstractContextHandler_h /* Copyright © 2010, 2011, 2012 Vladimír Vondruš @@ -16,29 +16,29 @@ */ /** @file - * @brief Class Magnum::Contexts::AbstractGlInterface + * @brief Class Magnum::Contexts::AbstractContextHandler */ #include "ExtensionWrangler.h" namespace Magnum { namespace Contexts { -/** @brief Base for OpenGL interfaces */ -template class AbstractGlInterface { +/** @brief Base for OpenGL context handlers */ +template class AbstractContextHandler { public: /** * @brief Get visual ID * - * Initializes the interface on given display and returns visual ID. + * Initializes the handler on given display and returns visual ID. */ virtual VisualId getVisualId(Display nativeDisplay) = 0; /** * @brief Destructor * - * Finalizes and closes the interface. + * Finalizes and closes the handler. */ - virtual ~AbstractGlInterface() {} + virtual ~AbstractContextHandler() {} /** @brief Create context */ virtual void createContext(Window nativeWindow) = 0; diff --git a/src/Contexts/AbstractContext.h b/src/Contexts/AbstractWindowContext.h similarity index 79% rename from src/Contexts/AbstractContext.h rename to src/Contexts/AbstractWindowContext.h index 74d42e530..8d5b0ba78 100644 --- a/src/Contexts/AbstractContext.h +++ b/src/Contexts/AbstractWindowContext.h @@ -1,5 +1,5 @@ -#ifndef Magnum_Contexts_AbstractContext_h -#define Magnum_Contexts_AbstractContext_h +#ifndef Magnum_Contexts_AbstractWindowContext_h +#define Magnum_Contexts_AbstractWindowContext_h /* Copyright © 2010, 2011, 2012 Vladimír Vondruš @@ -16,7 +16,7 @@ */ /** @file - * @brief Class Magnum::Contexts::GlutContext + * @brief Class Magnum::Contexts::AbstractWindowContext */ namespace Magnum { namespace Contexts { @@ -27,7 +27,7 @@ namespace Magnum { namespace Contexts { See subclasses documentation for more information. Context classes subclasses are meant to be used directly in `main()`, for example: @code -class MyContext: public Magnum::Contexts::GlutContext { +class MyContext: public Magnum::Contexts::GlutWindowContext { // implement required methods... }; int main(int argc, char** argv) { @@ -36,9 +36,9 @@ int main(int argc, char** argv) { } @endcode */ -class AbstractContext { +class AbstractWindowContext { public: - virtual inline ~AbstractContext() {} + virtual inline ~AbstractWindowContext() {} /** * @brief Execute main loop diff --git a/src/Contexts/AbstractXContext.cpp b/src/Contexts/AbstractXWindowContext.cpp similarity index 86% rename from src/Contexts/AbstractXContext.cpp rename to src/Contexts/AbstractXWindowContext.cpp index 9c0747aaf..0fbb95a9e 100644 --- a/src/Contexts/AbstractXContext.cpp +++ b/src/Contexts/AbstractXWindowContext.cpp @@ -13,8 +13,9 @@ GNU Lesser General Public License version 3 for more details. */ -#include "AbstractXContext.h" +#include "AbstractXWindowContext.h" +#include "Context.h" #include "ExtensionWrangler.h" #define None 0L // redef Xlib nonsense @@ -26,12 +27,12 @@ using namespace std; namespace Magnum { namespace Contexts { -AbstractXContext::AbstractXContext(AbstractGlInterface* glInterface, int&, char**, const string& title, const Math::Vector2& size): glInterface(glInterface), viewportSize(size), flags(Flag::Redraw) { +AbstractXWindowContext::AbstractXWindowContext(AbstractContextHandler* contextHandler, int&, char**, const string& title, const Math::Vector2& size): contextHandler(contextHandler), viewportSize(size), flags(Flag::Redraw) { /* Get default X display */ display = XOpenDisplay(0); /* Get visual ID */ - VisualID visualId = glInterface->getVisualId(display); + VisualID visualId = contextHandler->getVisualId(display); /* Get visual info */ XVisualInfo *visInfo, visTemplate; @@ -60,28 +61,32 @@ AbstractXContext::AbstractXContext(AbstractGlInterfacecreateContext(window); + contextHandler->createContext(window); /* Capture exposure, keyboard and mouse button events */ XSelectInput(display, window, INPUT_MASK); /* Set OpenGL context as current */ - glInterface->makeCurrent(); + contextHandler->makeCurrent(); /* Initialize extension wrangler */ - ExtensionWrangler::initialize(glInterface->experimentalExtensionWranglerFeatures()); + ExtensionWrangler::initialize(contextHandler->experimentalExtensionWranglerFeatures()); + + c = new Context; } -AbstractXContext::~AbstractXContext() { - /* Shut down the interface */ - delete glInterface; +AbstractXWindowContext::~AbstractXWindowContext() { + delete c; + + /* Shut down context handler */ + delete contextHandler; /* Shut down X */ XDestroyWindow(display, window); XCloseDisplay(display); } -int AbstractXContext::exec() { +int AbstractXWindowContext::exec() { /* Show window */ XMapWindow(display, window); diff --git a/src/Contexts/AbstractXContext.h b/src/Contexts/AbstractXWindowContext.h similarity index 84% rename from src/Contexts/AbstractXContext.h rename to src/Contexts/AbstractXWindowContext.h index 620a777ac..dc84d51f5 100644 --- a/src/Contexts/AbstractXContext.h +++ b/src/Contexts/AbstractXWindowContext.h @@ -1,5 +1,5 @@ -#ifndef Magnum_Contexts_AbstractXContext_h -#define Magnum_Contexts_AbstractXContext_h +#ifndef Magnum_Contexts_AbstractXWindowContext_h +#define Magnum_Contexts_AbstractXWindowContext_h /* Copyright © 2010, 2011, 2012 Vladimír Vondruš @@ -16,9 +16,11 @@ */ /** @file - * @brief Class Magnum::Contexts::AbstractXContext + * @brief Class Magnum::Contexts::AbstractXWindowContext */ +#include + #include "Magnum.h" #include @@ -27,12 +29,17 @@ #undef None #undef Always -#include +#include "Math/Vector2.h" +#include "AbstractWindowContext.h" +#include "AbstractContextHandler.h" -#include "AbstractContext.h" -#include "AbstractGlInterface.h" +#include "magnumCompatibility.h" -namespace Magnum { namespace Contexts { +namespace Magnum { + +class Context; + +namespace Contexts { /** @nosubgrouping @brief Base for X11-based contexts @@ -41,11 +48,11 @@ Supports keyboard and mouse handling. @note Not meant to be used directly, see subclasses. */ -class AbstractXContext: public AbstractContext { +class AbstractXWindowContext: public AbstractWindowContext { public: /** * @brief Constructor - * @param glInterface Interface to OpenGL + * @param contextHandler OpenGL context handler * @param argc Count of arguments of `main()` function * @param argv Arguments of `main()` function * @param title Window title @@ -53,16 +60,16 @@ class AbstractXContext: public AbstractContext { * * Creates window with double-buffered OpenGL ES 2 context. */ - AbstractXContext(AbstractGlInterface* glInterface, int& argc, char** argv, const std::string& title = "Magnum X/EGL context", const Math::Vector2& size = Math::Vector2(800, 600)); + AbstractXWindowContext(AbstractContextHandler* contextHandler, int& argc, char** argv, const std::string& title = "Magnum X window context", const Math::Vector2& size = Math::Vector2(800, 600)); /** * @brief Destructor * * Deletes context and destroys the window. */ - virtual ~AbstractXContext() = 0; + virtual ~AbstractXWindowContext() = 0; - int exec(); + int exec() override; /** @brief Exit application main loop */ inline void exit() { flags |= Flag::Exit; } @@ -70,16 +77,16 @@ class AbstractXContext: public AbstractContext { /** @{ @name Drawing functions */ protected: - /** @copydoc GlutContext::viewportEvent() */ + /** @copydoc GlutWindowContext::viewportEvent() */ virtual void viewportEvent(const Math::Vector2& size) = 0; - /** @copydoc GlutContext::drawEvent() */ + /** @copydoc GlutWindowContext::drawEvent() */ virtual void drawEvent() = 0; - /** @copydoc GlutContext::swapBuffers() */ - inline void swapBuffers() { glInterface->swapBuffers(); } + /** @copydoc GlutWindowContext::swapBuffers() */ + inline void swapBuffers() { contextHandler->swapBuffers(); } - /** @copydoc GlutContext::redraw() */ + /** @copydoc GlutWindowContext::redraw() */ inline void redraw() { flags |= Flag::Redraw; } /*@}*/ @@ -276,7 +283,9 @@ class AbstractXContext: public AbstractContext { Window window; Atom deleteWindow; - AbstractGlInterface* glInterface; + AbstractContextHandler* contextHandler; + + Context* c; /** @todo Get this from the created window */ Math::Vector2 viewportSize; @@ -284,15 +293,15 @@ class AbstractXContext: public AbstractContext { Flags flags; }; -CORRADE_ENUMSET_OPERATORS(AbstractXContext::Modifiers) -CORRADE_ENUMSET_OPERATORS(AbstractXContext::Flags) +CORRADE_ENUMSET_OPERATORS(AbstractXWindowContext::Modifiers) +CORRADE_ENUMSET_OPERATORS(AbstractXWindowContext::Flags) /* Implementations for inline functions with unused parameters */ -inline void AbstractXContext::keyPressEvent(Key, Modifiers, const Math::Vector2&) {} -inline void AbstractXContext::keyReleaseEvent(Key, Modifiers, const Math::Vector2&) {} -inline void AbstractXContext::mousePressEvent(MouseButton, Modifiers, const Math::Vector2&) {} -inline void AbstractXContext::mouseReleaseEvent(MouseButton, Modifiers, const Math::Vector2&) {} -inline void AbstractXContext::mouseMotionEvent(Modifiers, const Math::Vector2&) {} +inline void AbstractXWindowContext::keyPressEvent(Key, Modifiers, const Math::Vector2&) {} +inline void AbstractXWindowContext::keyReleaseEvent(Key, Modifiers, const Math::Vector2&) {} +inline void AbstractXWindowContext::mousePressEvent(MouseButton, Modifiers, const Math::Vector2&) {} +inline void AbstractXWindowContext::mouseReleaseEvent(MouseButton, Modifiers, const Math::Vector2&) {} +inline void AbstractXWindowContext::mouseMotionEvent(Modifiers, const Math::Vector2&) {} }} diff --git a/src/Contexts/CMakeLists.txt b/src/Contexts/CMakeLists.txt index 7d5cd8fe0..f11098375 100644 --- a/src/Contexts/CMakeLists.txt +++ b/src/Contexts/CMakeLists.txt @@ -2,92 +2,92 @@ add_library(MagnumContextsExtensionWrangler OBJECT ExtensionWrangler.cpp) set(MagnumContexts_HEADERS - AbstractContext.h - AbstractGlInterface.h + AbstractContextHandler.h + AbstractWindowContext.h ExtensionWrangler.h) install(FILES ${MagnumContexts_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) -# GLUT context -if(WITH_GLUTCONTEXT) +# GLUT window context +if(WITH_GLUTWINDOWCONTEXT) find_package(GLUT) if(GLUT_FOUND) - add_library(MagnumGlutContext STATIC - GlutContext.cpp + add_library(MagnumGlutWindowContext STATIC + GlutWindowContext.cpp $) - install(FILES GlutContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) - install(TARGETS MagnumGlutContext DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) + install(FILES GlutWindowContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) + install(TARGETS MagnumGlutWindowContext DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) else() - message(FATAL_ERROR "GLUT library, required by GlutContext, was not found. Set WITH_GLUTCONTEXT to OFF to skip building it.") + message(FATAL_ERROR "GLUT library, required by GlutWindowContext, was not found. Set WITH_GLUTWINDOWCONTEXT to OFF to skip building it.") endif() endif() -# SDL2 context -if(WITH_SDL2CONTEXT) +# SDL2 window context +if(WITH_SDL2WINDOWCONTEXT) find_package(SDL2) if(SDL2_FOUND) include_directories(${SDL2_INCLUDE_DIR}) - add_library(MagnumSdl2Context STATIC - Sdl2Context.cpp + add_library(MagnumSdl2WindowContext STATIC + Sdl2WindowContext.cpp $) - install(FILES Sdl2Context.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) - install(TARGETS MagnumSdl2Context DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) + install(FILES Sdl2WindowContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) + install(TARGETS MagnumSdl2WindowContext DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) else() - message(FATAL_ERROR "SDL2 library, required by Sdl2Context, was not found. Set WITH_SDL2CONTEXT to OFF to skip building it.") + message(FATAL_ERROR "SDL2 library, required by Sdl2WindowContext, was not found. Set WITH_SDL2WINDOWCONTEXT to OFF to skip building it.") endif() endif() -# GLX context -if(WITH_GLXCONTEXT) - set(NEED_ABSTRACTXCONTEXT 1) - set(NEED_GLXINTERFACE 1) - add_library(MagnumGlxContext STATIC - $ - $ +# GLX window context +if(WITH_GLXWINDOWCONTEXT) + set(NEED_ABSTRACTXWINDOWCONTEXT 1) + set(NEED_GLXCONTEXT 1) + add_library(MagnumGlxWindowContext STATIC + $ + $ $) - install(FILES GlxContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) - install(TARGETS MagnumGlxContext DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) + install(FILES GlxWindowContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) + install(TARGETS MagnumGlxWindowContext DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) endif() -# X/EGL context -if(WITH_XEGLCONTEXT) - set(NEED_ABSTRACTXCONTEXT 1) - set(NEED_EGLINTERFACE 1) - add_library(MagnumXEglContext STATIC - $ - $ +# X/EGL window context +if(WITH_XEGLWINDOWCONTEXT) + set(NEED_ABSTRACTXWINDOWCONTEXT 1) + set(NEED_EGLCONTEXT 1) + add_library(MagnumXEglWindowContext STATIC + $ + $ $) - install(FILES XEglContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) - install(TARGETS MagnumXEglContext DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) + install(FILES XEglWindowContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) + install(TARGETS MagnumXEglWindowContext DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) endif() -# Abstract X context -if(NEED_ABSTRACTXCONTEXT) +# Abstract X window context +if(NEED_ABSTRACTXWINDOWCONTEXT) find_package(X11) if(NOT X11_FOUND) - message(FATAL_ERROR "X11 library, required by some contexts, was not found. Set WITH_*X*CONTEXT to OFF to skip building them.") + message(FATAL_ERROR "X11 library, required by some contexts, was not found. Set WITH_*X*WINDOWCONTEXT to OFF to skip building them.") endif() - add_library(MagnumAbstractXContext OBJECT AbstractXContext.cpp) + add_library(MagnumAbstractXWindowContext OBJECT AbstractXWindowContext.cpp) # X11 macros are a mess, disable warnings for C-style casts - set_target_properties(MagnumAbstractXContext PROPERTIES COMPILE_FLAGS "-Wno-old-style-cast") - install(FILES AbstractXContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) + set_target_properties(MagnumAbstractXWindowContext PROPERTIES COMPILE_FLAGS "-Wno-old-style-cast") + install(FILES AbstractXWindowContext.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) endif() -# GLX interface -if(NEED_GLXINTERFACE) - add_library(MagnumGlxInterface OBJECT GlxInterface.cpp) +# GLX context +if(NEED_GLXCONTEXT) + add_library(MagnumGlxContextHandler OBJECT GlxContextHandler.cpp) # X11 macros are a mess, disable warnings for C-style casts - set_target_properties(MagnumGlxInterface PROPERTIES COMPILE_FLAGS "-Wno-old-style-cast") - install(FILES GlxInterface.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) + set_target_properties(MagnumGlxContextHandler PROPERTIES COMPILE_FLAGS "-Wno-old-style-cast") + install(FILES GlxContextHandler.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) endif() -# EGL interface -if(NEED_EGLINTERFACE) +# EGL context +if(NEED_EGLCONTEXT) find_package(EGL) if(NOT EGL_FOUND) - message(FATAL_ERROR "EGL library, required by some contexts, was not found. Set WITH_*EGL*CONTEXT to OFF to skip building them.") + message(FATAL_ERROR "EGL library, required by some window contexts, was not found. Set WITH_*EGL*WINDOWCONTEXT to OFF to skip building them.") endif() - add_library(MagnumEglInterface OBJECT EglInterface.cpp) + add_library(MagnumEglContextHandler OBJECT EglContextHandler.cpp) # X11 macros are a mess, disable warnings for C-style casts - set_target_properties(MagnumEglInterface PROPERTIES COMPILE_FLAGS "-Wno-old-style-cast") - install(FILES EglInterface.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) + set_target_properties(MagnumEglContextHandler PROPERTIES COMPILE_FLAGS "-Wno-old-style-cast") + install(FILES EglContextHandler.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) endif() diff --git a/src/Contexts/EglContextHandler.cpp b/src/Contexts/EglContextHandler.cpp new file mode 100644 index 000000000..e237b1714 --- /dev/null +++ b/src/Contexts/EglContextHandler.cpp @@ -0,0 +1,125 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "EglContextHandler.h" + +#include + +#include "Context.h" + +namespace Magnum { namespace Contexts { + +EglContextHandler::~EglContextHandler() { + eglDestroyContext(display, context); + eglDestroySurface(display, surface); + eglTerminate(display); +} + +VisualId EglContextHandler::getVisualId(EGLNativeDisplayType nativeDisplay) { + /* Initialize */ + display = eglGetDisplay(nativeDisplay); + if(!eglInitialize(display, nullptr, nullptr)) { + Error() << "Cannot initialize EGL:" << errorString(eglGetError()); + exit(1); + } + + #ifndef MAGNUM_TARGET_GLES + EGLenum api = EGL_OPENGL_API; + #else + EGLenum api = EGL_OPENGL_ES_API; + #endif + if(!eglBindAPI(api)) { + Error() << "Cannot bind EGL API:" << errorString(eglGetError()); + exit(1); + } + + /* Choose EGL config */ + static const EGLint attribs[] = { + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_DEPTH_SIZE, 1, + #ifndef MAGNUM_TARGET_GLES + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, + #else + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + #endif + EGL_NONE + }; + EGLint configCount; + if(!eglChooseConfig(display, attribs, &config, 1, &configCount)) { + Error() << "Cannot get EGL visual config:" << errorString(eglGetError()); + exit(1); + } + + if(!configCount) { + Error() << "No matching EGL visual config available"; + exit(1); + } + + /* Get visual ID */ + EGLint visualId; + if(!eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &visualId)) { + Error() << "Cannot get native visual ID:" << errorString(eglGetError()); + exit(1); + } + + return visualId; +} + +void EglContextHandler::createContext(EGLNativeWindowType window) { + static const EGLint contextAttributes[] = { + #ifdef MAGNUM_TARGET_GLES + EGL_CONTEXT_CLIENT_VERSION, 2, + #endif + EGL_NONE + }; + if(!eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes)) { + Error() << "Cannot create EGL context:" << errorString(eglGetError()); + exit(1); + } + if(!(surface = eglCreateWindowSurface(display, config, window, NULL))) { + Error() << "Cannot create window surface:" << errorString(eglGetError()); + exit(1); + } + + /** @bug Fixme: On desktop OpenGL and Mesa EGL implementation OpenGL version is 1.0, which is wrong */ +} + +const char* EglContextHandler::errorString(EGLint error) { + switch(error) { + #define _error(name) case name: return #name; + _error(EGL_SUCCESS) + _error(EGL_NOT_INITIALIZED) + _error(EGL_BAD_ACCESS) + _error(EGL_BAD_ALLOC) + _error(EGL_BAD_ATTRIBUTE) + _error(EGL_BAD_CONTEXT) + _error(EGL_BAD_CONFIG) + _error(EGL_BAD_CURRENT_SURFACE) + _error(EGL_BAD_DISPLAY) + _error(EGL_BAD_SURFACE) + _error(EGL_BAD_MATCH) + _error(EGL_BAD_PARAMETER) + _error(EGL_BAD_NATIVE_PIXMAP) + _error(EGL_BAD_NATIVE_WINDOW) + _error(EGL_CONTEXT_LOST) + #undef _error + } + + return ""; +} + +}} diff --git a/src/Contexts/EglInterface.h b/src/Contexts/EglContextHandler.h similarity index 67% rename from src/Contexts/EglInterface.h rename to src/Contexts/EglContextHandler.h index 671d6df18..b05c68f69 100644 --- a/src/Contexts/EglInterface.h +++ b/src/Contexts/EglContextHandler.h @@ -1,5 +1,5 @@ -#ifndef Magnum_Contexts_EglInterface_h -#define Magnum_Contexts_EglInterface_h +#ifndef Magnum_Contexts_EglContextHandler_h +#define Magnum_Contexts_EglContextHandler_h /* Copyright © 2010, 2011, 2012 Vladimír Vondruš @@ -16,7 +16,7 @@ */ /** @file - * @brief Class Magnum::Contexts::EglInterface + * @brief Class Magnum::Contexts::EglContextHandler */ #include "Magnum.h" @@ -26,7 +26,12 @@ #endif #include -#include "AbstractGlInterface.h" +/* undef Xlib nonsense to avoid conflicts */ +#undef None + +#include "AbstractContextHandler.h" + +#include "magnumCompatibility.h" namespace Magnum { namespace Contexts { @@ -42,24 +47,26 @@ typedef EGLInt VisualId; /** @brief EGL interface -Used in XEglContext. +Used in XEglWindowContext. */ -class EglInterface: public AbstractGlInterface { +class EglContextHandler: public AbstractContextHandler { public: - ~EglInterface(); + ~EglContextHandler(); - VisualId getVisualId(EGLNativeDisplayType nativeDisplay); - void createContext(EGLNativeWindowType nativeWindow); + VisualId getVisualId(EGLNativeDisplayType nativeDisplay) override; + void createContext(EGLNativeWindowType nativeWindow) override; - inline void makeCurrent() { + inline void makeCurrent() override { eglMakeCurrent(display, surface, surface, context); } - inline void swapBuffers() { + inline void swapBuffers() override { eglSwapBuffers(display, surface); } private: + const char* errorString(EGLint error); + EGLDisplay display; EGLConfig config; EGLSurface surface; diff --git a/src/Contexts/EglInterface.cpp b/src/Contexts/EglInterface.cpp deleted file mode 100644 index 609f37322..000000000 --- a/src/Contexts/EglInterface.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - Copyright © 2010, 2011, 2012 Vladimír Vondruš - - 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 "EglInterface.h" - -namespace Magnum { namespace Contexts { - -EglInterface::~EglInterface() { - eglDestroyContext(display, context); - eglDestroySurface(display, surface); - eglTerminate(display); -} - -VisualId EglInterface::getVisualId(EGLNativeDisplayType nativeDisplay) { - /* Initialize */ - display = eglGetDisplay(nativeDisplay); - eglInitialize(display, 0, 0); - #ifndef MAGNUM_TARGET_GLES - eglBindAPI(EGL_OPENGL_API); - #else - eglBindAPI(EGL_OPENGL_ES_API); - #endif - - /* Choose EGL config */ - static const EGLint attribs[] = { - EGL_RED_SIZE, 1, - EGL_GREEN_SIZE, 1, - EGL_BLUE_SIZE, 1, - EGL_DEPTH_SIZE, 1, - #ifndef MAGNUM_TARGET_GLES - EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, - #else - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - #endif - EGL_NONE - }; - EGLint configCount; - if(!eglChooseConfig(display, attribs, &config, 1, &configCount)) { - Error() << "Cannot get EGL visual config"; - exit(1); - } - - /* Get visual ID */ - EGLint visualId; - if(!eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &visualId)) { - Error() << "Cannot get native visual ID"; - exit(1); - } - - return visualId; -} - -void EglInterface::createContext(EGLNativeWindowType window) { - static const EGLint contextAttributes[] = { - #ifdef MAGNUM_TARGET_GLES - EGL_CONTEXT_CLIENT_VERSION, 2, - #endif - EGL_NONE - }; - context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes); - if(!context) { - Error() << "Cannot create EGL context"; - exit(1); - } - surface = eglCreateWindowSurface(display, config, window, NULL); - if(!surface) { - Error() << "Cannot create window surface"; - exit(1); - } - - /** @bug Fixme: On desktop OpenGL and Mesa EGL implementation OpenGL version is 1.0, which is wrong */ -} - -}} diff --git a/src/Contexts/ExtensionWrangler.cpp b/src/Contexts/ExtensionWrangler.cpp index f9c6dc47e..927b66628 100644 --- a/src/Contexts/ExtensionWrangler.cpp +++ b/src/Contexts/ExtensionWrangler.cpp @@ -15,6 +15,8 @@ #include "ExtensionWrangler.h" +#include + #include "Magnum.h" namespace Magnum { namespace Contexts { diff --git a/src/Contexts/GlutContext.cpp b/src/Contexts/GlutWindowContext.cpp similarity index 79% rename from src/Contexts/GlutContext.cpp rename to src/Contexts/GlutWindowContext.cpp index 01307482d..f06f4b38f 100644 --- a/src/Contexts/GlutContext.cpp +++ b/src/Contexts/GlutWindowContext.cpp @@ -13,15 +13,16 @@ GNU Lesser General Public License version 3 for more details. */ -#include "GlutContext.h" +#include "GlutWindowContext.h" +#include "Context.h" #include "ExtensionWrangler.h" namespace Magnum { namespace Contexts { -GlutContext* GlutContext::instance = nullptr; +GlutWindowContext* GlutWindowContext::instance = nullptr; -GlutContext::GlutContext(int& argc, char** argv, const std::string& title, const Math::Vector2& size): argc(argc), argv(argv) { +GlutWindowContext::GlutWindowContext(int& argc, char** argv, const std::string& title, const Math::Vector2& size) { /* Save global instance */ instance = this; @@ -38,6 +39,12 @@ GlutContext::GlutContext(int& argc, char** argv, const std::string& title, const glutDisplayFunc(staticDrawEvent); ExtensionWrangler::initialize(); + + c = new Context; +} + +GlutWindowContext::~GlutWindowContext() { + delete c; } }} diff --git a/src/Contexts/GlutContext.h b/src/Contexts/GlutWindowContext.h similarity index 88% rename from src/Contexts/GlutContext.h rename to src/Contexts/GlutWindowContext.h index 73e32569f..8cd016cb7 100644 --- a/src/Contexts/GlutContext.h +++ b/src/Contexts/GlutWindowContext.h @@ -1,5 +1,5 @@ -#ifndef Magnum_Contexts_GlutContext_h -#define Magnum_Contexts_GlutContext_h +#ifndef Magnum_Contexts_GlutWindowContext_h +#define Magnum_Contexts_GlutWindowContext_h /* Copyright © 2010, 2011, 2012 Vladimír Vondruš @@ -16,15 +16,25 @@ */ /** @file - * @brief Class Magnum::Contexts::GlutContext + * @brief Class Magnum::Contexts::GlutWindowContext */ +#include + +#include "Math/Vector2.h" #include "Magnum.h" + #include -#include "AbstractContext.h" +#include "AbstractWindowContext.h" + +#include "magnumCompatibility.h" -namespace Magnum { namespace Contexts { +namespace Magnum { + +class Context; + +namespace Contexts { /** @nosubgrouping @brief GLUT context @@ -35,7 +45,7 @@ support for changing cursor and mouse tracking and warping. You need to implement at least drawEvent() and viewportEvent() to be able to draw on the screen. */ -class GlutContext: public AbstractContext { +class GlutWindowContext: public AbstractWindowContext { public: /** * @brief Constructor @@ -46,9 +56,11 @@ class GlutContext: public AbstractContext { * * Creates double-buffered RGBA window with depth and stencil buffers. */ - GlutContext(int& argc, char** argv, const std::string& title = "Magnum GLUT context", const Math::Vector2& size = Math::Vector2(800, 600)); + GlutWindowContext(int& argc, char** argv, const std::string& title = "Magnum GLUT window context", const Math::Vector2& size = Math::Vector2(800, 600)); + + ~GlutWindowContext(); - inline int exec() { + inline int exec() override { glutMainLoop(); return 0; } @@ -238,17 +250,16 @@ class GlutContext: public AbstractContext { instance->drawEvent(); } - static GlutContext* instance; + static GlutWindowContext* instance; - int& argc; - char** argv; + Context* c; }; /* Implementations for inline functions with unused parameters */ -inline void GlutContext::keyPressEvent(Key, const Math::Vector2&) {} -inline void GlutContext::mousePressEvent(MouseButton, const Math::Vector2&) {} -inline void GlutContext::mouseReleaseEvent(MouseButton, const Math::Vector2&) {} -inline void GlutContext::mouseMotionEvent(const Math::Vector2&) {} +inline void GlutWindowContext::keyPressEvent(Key, const Math::Vector2&) {} +inline void GlutWindowContext::mousePressEvent(MouseButton, const Math::Vector2&) {} +inline void GlutWindowContext::mouseReleaseEvent(MouseButton, const Math::Vector2&) {} +inline void GlutWindowContext::mouseMotionEvent(const Math::Vector2&) {} }} diff --git a/src/Contexts/GlxInterface.cpp b/src/Contexts/GlxContextHandler.cpp similarity index 81% rename from src/Contexts/GlxInterface.cpp rename to src/Contexts/GlxContextHandler.cpp index a8fb92680..ebc478b6c 100644 --- a/src/Contexts/GlxInterface.cpp +++ b/src/Contexts/GlxContextHandler.cpp @@ -13,20 +13,25 @@ GNU Lesser General Public License version 3 for more details. */ -#include "GlxInterface.h" +#include "GlxContextHandler.h" #include +#include + +#include "Context.h" + +#define None 0L // redef Xlib nonsense namespace Magnum { namespace Contexts { -VisualID GlxInterface::getVisualId(Display* nativeDisplay) { +VisualID GlxContextHandler::getVisualId(Display* nativeDisplay) { display = nativeDisplay; /* Check version */ int major, minor; glXQueryVersion(nativeDisplay, &major, &minor); if(major == 1 && minor < 4) { - Error() << "GlxInterface: GLX version 1.4 or greater is required."; + Error() << "GlxContextHandler: GLX version 1.4 or greater is required."; exit(1); } @@ -44,7 +49,7 @@ VisualID GlxInterface::getVisualId(Display* nativeDisplay) { }; configs = glXChooseFBConfig(nativeDisplay, DefaultScreen(nativeDisplay), attributes, &configCount); if(!configCount) { - Error() << "GlxInterface: no supported framebuffer configuration found."; + Error() << "GlxContextHandler: no supported framebuffer configuration found."; exit(1); } @@ -56,13 +61,13 @@ VisualID GlxInterface::getVisualId(Display* nativeDisplay) { return visualId; } -void GlxInterface::createContext(Window nativeWindow) { +void GlxContextHandler::createContext(Window nativeWindow) { window = nativeWindow; GLint attributes[] = { #ifndef MAGNUM_TARGET_GLES GLX_CONTEXT_MAJOR_VERSION_ARB, 3, - GLX_CONTEXT_MINOR_VERSION_ARB, 3, + GLX_CONTEXT_MINOR_VERSION_ARB, 2, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, #else GLX_CONTEXT_MAJOR_VERSION_ARB, 2, @@ -77,12 +82,12 @@ void GlxInterface::createContext(Window nativeWindow) { context = glXCreateContextAttribsARB(display, configs[0], 0, True, attributes); XFree(configs); if(!context) { - Error() << "GlxInterface: cannot create context."; + Error() << "GlxContextHandler: cannot create context."; exit(1); } } -GlxInterface::~GlxInterface() { +GlxContextHandler::~GlxContextHandler() { glXMakeCurrent(display, None, nullptr); glXDestroyContext(display, context); } diff --git a/src/Contexts/GlxInterface.h b/src/Contexts/GlxContextHandler.h similarity index 62% rename from src/Contexts/GlxInterface.h rename to src/Contexts/GlxContextHandler.h index e9f3177d8..32ba4a81f 100644 --- a/src/Contexts/GlxInterface.h +++ b/src/Contexts/GlxContextHandler.h @@ -1,5 +1,5 @@ -#ifndef Magnum_Contexts_EglInterface_h -#define Magnum_Contexts_EglInterface_h +#ifndef Magnum_Contexts_GlxContextHandler_h +#define Magnum_Contexts_GlxContextHandler_h /* Copyright © 2010, 2011, 2012 Vladimír Vondruš @@ -16,41 +16,46 @@ */ /** @file - * @brief Class Magnum::Contexts::GlxInterface + * @brief Class Magnum::Contexts::GlxContextHandler */ #include "Magnum.h" #include +/* undef Xlib nonsense to avoid conflicts */ +#undef None +#undef Always -#include "AbstractGlInterface.h" +#include "AbstractContextHandler.h" + +#include "magnumCompatibility.h" namespace Magnum { namespace Contexts { /** @brief GLX interface -Creates OpenGL 3.3 core context or OpenGL ES 2.0 context, if targetting +Creates OpenGL 3.2 core context or OpenGL ES 2.0 context, if targetting OpenGL ES. -Used in GlxContext. +Used in GlxWindowContext. */ -class GlxInterface: public AbstractGlInterface { +class GlxContextHandler: public AbstractContextHandler { public: - ~GlxInterface(); + ~GlxContextHandler(); - VisualID getVisualId(Display* nativeDisplay); - void createContext(Window nativeWindow); + VisualID getVisualId(Display* nativeDisplay) override; + void createContext(Window nativeWindow) override; /* This must be enabled, otherwise (on my NVidia) it crashes when creating VAO. WTF. */ - inline ExtensionWrangler::ExperimentalFeatures experimentalExtensionWranglerFeatures() const { + inline ExtensionWrangler::ExperimentalFeatures experimentalExtensionWranglerFeatures() const override { return ExtensionWrangler::ExperimentalFeatures::Enable; } - inline void makeCurrent() { + inline void makeCurrent() override { glXMakeCurrent(display, window, context); } - inline void swapBuffers() { + inline void swapBuffers() override { glXSwapBuffers(display, window); } diff --git a/src/Contexts/GlxContext.h b/src/Contexts/GlxWindowContext.h similarity index 62% rename from src/Contexts/GlxContext.h rename to src/Contexts/GlxWindowContext.h index a11b503c7..f69f6f7d7 100644 --- a/src/Contexts/GlxContext.h +++ b/src/Contexts/GlxWindowContext.h @@ -1,5 +1,5 @@ -#ifndef Magnum_Contexts_GlxContext_h -#define Magnum_Contexts_GlxContext_h +#ifndef Magnum_Contexts_GlxWindowContext_h +#define Magnum_Contexts_GlxWindowContext_h /* Copyright © 2010, 2011, 2012 Vladimír Vondruš @@ -16,20 +16,20 @@ */ /** @file - * @brief Class Magnum::Contexts::GlxContext + * @brief Class Magnum::Contexts::GlxWindowContext */ -#include "AbstractXContext.h" -#include "GlxInterface.h" +#include "AbstractXWindowContext.h" +#include "GlxContextHandler.h" namespace Magnum { namespace Contexts { /** @brief GLX context -Uses GlxInterface. +Uses GlxContextHandler. */ -class GlxContext: public AbstractXContext { +class GlxWindowContext: public AbstractXWindowContext { public: /** * @brief Constructor @@ -38,10 +38,10 @@ class GlxContext: public AbstractXContext { * @param title Window title * @param size Window size * - * Creates window with double-buffered OpenGL 3.3 core context or + * Creates window with double-buffered OpenGL 3.2 core context or * OpenGL ES 2.0 context, if targetting OpenGL ES. */ - inline GlxContext(int& argc, char** argv, const std::string& title = "Magnum GLX context", const Math::Vector2& size = Math::Vector2(800, 600)): AbstractXContext(new GlxInterface, argc, argv, title, size) {} + inline GlxWindowContext(int& argc, char** argv, const std::string& title = "Magnum GLX window context", const Math::Vector2& size = Math::Vector2(800, 600)): AbstractXWindowContext(new GlxContextHandler, argc, argv, title, size) {} }; }} diff --git a/src/Contexts/Sdl2Context.cpp b/src/Contexts/Sdl2WindowContext.cpp similarity index 79% rename from src/Contexts/Sdl2Context.cpp rename to src/Contexts/Sdl2WindowContext.cpp index f55fa6125..f87e33b06 100644 --- a/src/Contexts/Sdl2Context.cpp +++ b/src/Contexts/Sdl2WindowContext.cpp @@ -13,20 +13,22 @@ GNU Lesser General Public License version 3 for more details. */ -#include "Sdl2Context.h" +#include "Sdl2WindowContext.h" + +#include "Context.h" #include "ExtensionWrangler.h" namespace Magnum { namespace Contexts { -Sdl2Context::Sdl2Context(int, char**, const std::string& name, const Math::Vector2& size): _redraw(true) { +Sdl2WindowContext::Sdl2WindowContext(int, char**, const std::string& name, const Math::Vector2& size): _redraw(true) { if(SDL_Init(SDL_INIT_VIDEO) < 0) { Error() << "Cannot initialize SDL."; exit(1); } - /* Request OpenGL 3.3 */ + /* Request OpenGL 3.2 */ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); /* Enable double buffering and 24bt depth buffer */ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); @@ -52,15 +54,19 @@ Sdl2Context::Sdl2Context(int, char**, const std::string& name, const Math::Vecto sizeEvent->window.data1 = size.x(); sizeEvent->window.data2 = size.y(); SDL_PushEvent(sizeEvent); + + c = new Context; } -Sdl2Context::~Sdl2Context() { +Sdl2WindowContext::~Sdl2WindowContext() { + delete c; + SDL_GL_DeleteContext(context); SDL_DestroyWindow(window); SDL_Quit(); } -int Sdl2Context::exec() { +int Sdl2WindowContext::exec() { for(;;) { SDL_Event event; @@ -77,23 +83,23 @@ int Sdl2Context::exec() { break; } break; case SDL_KEYDOWN: - keyPressEvent(static_cast(event.key.keysym.sym), event.key.repeat); + keyPressEvent(static_cast(event.key.keysym.sym), Modifiers(), {}); break; case SDL_KEYUP: - keyReleaseEvent(static_cast(event.key.keysym.sym)); + keyReleaseEvent(static_cast(event.key.keysym.sym), Modifiers(), {}); break; case SDL_MOUSEBUTTONDOWN: - mousePressEvent(static_cast(event.button.button), {event.button.x, event.button.y}); + mousePressEvent(static_cast(event.button.button), Modifiers(), {event.button.x, event.button.y}); break; case SDL_MOUSEBUTTONUP: - mouseReleaseEvent(static_cast(event.button.button), {event.button.x, event.button.y}); + mouseReleaseEvent(static_cast(event.button.button), Modifiers(), {event.button.x, event.button.y}); break; case SDL_MOUSEWHEEL: - mouseWheelEvent({event.wheel.x, event.wheel.y}); + if(event.wheel.y != 0) + mousePressEvent(event.wheel.y < 0 ? MouseButton::WheelUp : MouseButton::WheelDown, Modifiers(), {event.wheel.x, event.wheel.y}); break; case SDL_MOUSEMOTION: - mouseMotionEvent({event.motion.x, event.motion.y}, - {event.motion.xrel, event.motion.yrel}); + mouseMotionEvent(Modifiers(), {event.motion.x, event.motion.y}); break; case SDL_QUIT: return 0; diff --git a/src/Contexts/Sdl2Context.h b/src/Contexts/Sdl2WindowContext.h similarity index 57% rename from src/Contexts/Sdl2Context.h rename to src/Contexts/Sdl2WindowContext.h index 112b434b8..1a215a2b7 100644 --- a/src/Contexts/Sdl2Context.h +++ b/src/Contexts/Sdl2WindowContext.h @@ -1,5 +1,5 @@ -#ifndef Magnum_Contexts_Sdl2Context_h -#define Magnum_Contexts_Sdl2Context_h +#ifndef Magnum_Contexts_Sdl2WindowContext_h +#define Magnum_Contexts_Sdl2WindowContext_h /* Copyright © 2010, 2011, 2012 Vladimír Vondruš @@ -16,16 +16,25 @@ */ /** @file - * @brief Class Magnum::Contexts::Sdl2Context + * @brief Class Magnum::Contexts::Sdl2WindowContext */ +#include "Math/Vector2.h" #include "Magnum.h" + #include #include +#include + +#include "AbstractWindowContext.h" + +#include "magnumCompatibility.h" -#include "AbstractContext.h" +namespace Magnum { -namespace Magnum { namespace Contexts { +class Context; + +namespace Contexts { /** @nosubgrouping @brief SDL2 context @@ -35,7 +44,7 @@ Supports keyboard and mouse handling. You need to implement at least drawEvent() and viewportEvent() to be able to draw on the screen. */ -class Sdl2Context: public AbstractContext { +class Sdl2WindowContext: public AbstractWindowContext { public: /** * @brief Constructor @@ -45,38 +54,53 @@ class Sdl2Context: public AbstractContext { * @param size Window size * * Creates centered non-resizable window with double-buffered - * OpenGL 3.3 context with 24bit depth buffer. + * OpenGL 3.2 context with 24bit depth buffer. */ - Sdl2Context(int argc, char** argv, const std::string& title = "Magnum SDL2 context", const Math::Vector2& size = Math::Vector2(800, 600)); + Sdl2WindowContext(int argc, char** argv, const std::string& title = "Magnum SDL2 window context", const Math::Vector2& size = Math::Vector2(800, 600)); /** * @brief Destructor * * Deletes context and destroys the window. */ - ~Sdl2Context(); + ~Sdl2WindowContext(); - int exec(); + int exec() override; /** @{ @name Drawing functions */ protected: - /** @copydoc GlutContext::viewportEvent() */ + /** @copydoc GlutWindowContext::viewportEvent() */ virtual void viewportEvent(const Math::Vector2& size) = 0; - /** @copydoc GlutContext::drawEvent() */ + /** @copydoc GlutWindowContext::drawEvent() */ virtual void drawEvent() = 0; - /** @copydoc GlutContext::swapBuffers() */ + /** @copydoc GlutWindowContext::swapBuffers() */ inline void swapBuffers() { SDL_GL_SwapWindow(window); } - /** @copydoc GlutContext::redraw() */ + /** @copydoc GlutWindowContext::redraw() */ inline void redraw() { _redraw = true; } /*@}*/ /** @{ @name Keyboard handling */ public: + /** + * @brief %Modifier + * + * @see Modifiers, keyPressEvent(), keyReleaseEvent(), + * mousePressEvent(), mouseReleaseEvent(), mouseMotionEvent() + */ + enum class Modifier: unsigned int {}; + + /** + * @brief Set of modifiers + * + * @see keyPressEvent(), keyReleaseEvent() + */ + typedef Corrade::Containers::EnumSet Modifiers; + /** * @brief Key * @@ -95,15 +119,18 @@ class Sdl2Context: public AbstractContext { /** * @brief Key press event * @param key Key pressed - * @param repeat Non-zero if this is a key repeat + * @param modifiers Active modifiers (not yet implemented) + * @param position Cursor position (not yet implemented) */ - virtual void keyPressEvent(Key key, Uint8 repeat); + virtual void keyPressEvent(Key key, Modifiers modifiers, const Math::Vector2& position); /** * @brief Key release event * @param key Key released + * @param modifiers Active modifiers (not yet implemented) + * @param position Cursor position (not yet implemented) */ - virtual void keyReleaseEvent(Key key); + virtual void keyReleaseEvent(Key key, Modifiers modifiers, const Math::Vector2& position); /*@}*/ @@ -118,7 +145,9 @@ class Sdl2Context: public AbstractContext { enum class MouseButton: Uint8 { Left = SDL_BUTTON_LEFT, /**< Left button */ Middle = SDL_BUTTON_MIDDLE, /**< Middle button */ - Right = SDL_BUTTON_RIGHT /**< Right button */ + Right = SDL_BUTTON_RIGHT, /**< Right button */ + WheelUp = 4, /**< Wheel up */ + WheelDown = 5 /**< Wheel down */ }; /** @@ -135,41 +164,33 @@ class Sdl2Context: public AbstractContext { /** * @brief Mouse press event * @param button Button pressed + * @param modifiers Active modifiers (not yet implemented) * @param position Cursor position * * Called when mouse button is pressed. Default implementation does * nothing. */ - virtual void mousePressEvent(MouseButton button, const Math::Vector2& position); + virtual void mousePressEvent(MouseButton button, Modifiers modifiers, const Math::Vector2& position); /** * @brief Mouse release event * @param button Button released + * @param modifiers Active modifiers (not yet implemented) * @param position Cursor position * * Called when mouse button is released. Default implementation does * nothing. */ - virtual void mouseReleaseEvent(MouseButton button, const Math::Vector2& position); - - /** - * @brief Mouse wheel event - * @param direction Wheel rotation direction. Negative Y is up and - * positive X is right. - * - * Called when mouse wheel is rotated. Default implementation does - * nothing. - */ - virtual void mouseWheelEvent(const Math::Vector2& direction); + virtual void mouseReleaseEvent(MouseButton button, Modifiers modifiers, const Math::Vector2& position); /** * @brief Mouse motion event + * @param modifiers Active modifiers (not yet implemented) * @param position Mouse position relative to the window - * @param delta Mouse position relative to last motion event * * Called when mouse is moved. Default implementation does nothing. */ - virtual void mouseMotionEvent(const Math::Vector2& position, const Math::Vector2& delta); + virtual void mouseMotionEvent(Modifiers modifiers, const Math::Vector2& position); /*@}*/ @@ -177,16 +198,19 @@ class Sdl2Context: public AbstractContext { SDL_Window* window; SDL_GLContext context; + Context* c; + bool _redraw; }; +CORRADE_ENUMSET_OPERATORS(Sdl2WindowContext::Modifiers) + /* Implementations for inline functions with unused parameters */ -inline void Sdl2Context::keyPressEvent(Key, Uint8) {} -inline void Sdl2Context::keyReleaseEvent(Key) {} -inline void Sdl2Context::mousePressEvent(MouseButton, const Math::Vector2&) {} -inline void Sdl2Context::mouseReleaseEvent(MouseButton, const Math::Vector2&) {} -inline void Sdl2Context::mouseWheelEvent(const Math::Vector2&) {} -inline void Sdl2Context::mouseMotionEvent(const Math::Vector2&, const Math::Vector2&) {} +inline void Sdl2WindowContext::keyPressEvent(Key, Modifiers, const Math::Vector2&) {} +inline void Sdl2WindowContext::keyReleaseEvent(Key, Modifiers, const Math::Vector2&) {} +inline void Sdl2WindowContext::mousePressEvent(MouseButton, Modifiers, const Math::Vector2&) {} +inline void Sdl2WindowContext::mouseReleaseEvent(MouseButton, Modifiers, const Math::Vector2&) {} +inline void Sdl2WindowContext::mouseMotionEvent(Modifiers, const Math::Vector2&) {} }} diff --git a/src/Contexts/XEglContext.h b/src/Contexts/XEglWindowContext.h similarity index 65% rename from src/Contexts/XEglContext.h rename to src/Contexts/XEglWindowContext.h index fb368c1db..94f0ac034 100644 --- a/src/Contexts/XEglContext.h +++ b/src/Contexts/XEglWindowContext.h @@ -1,5 +1,5 @@ -#ifndef Magnum_Contexts_XEglContext_h -#define Magnum_Contexts_XEglContext_h +#ifndef Magnum_Contexts_XEglWindowContext_h +#define Magnum_Contexts_XEglWindowContext_h /* Copyright © 2010, 2011, 2012 Vladimír Vondruš @@ -16,20 +16,20 @@ */ /** @file - * @brief Class Magnum::Contexts::XEglContext + * @brief Class Magnum::Contexts::XEglWindowContext */ -#include "AbstractXContext.h" -#include "EglInterface.h" +#include "AbstractXWindowContext.h" +#include "EglContextHandler.h" namespace Magnum { namespace Contexts { /** @brief X/EGL context -Uses EglInterface. +Uses EglContextHandler. */ -class XEglContext: public AbstractXContext { +class XEglWindowContext: public AbstractXWindowContext { public: /** * @brief Constructor @@ -40,7 +40,7 @@ class XEglContext: public AbstractXContext { * * Creates window with double-buffered OpenGL ES 2 context. */ - inline XEglContext(int& argc, char** argv, const std::string& title = "Magnum X/EGL context", const Math::Vector2& size = Math::Vector2(800, 600)): AbstractXContext(new EglInterface, argc, argv, title, size) {} + inline XEglWindowContext(int& argc, char** argv, const std::string& title = "Magnum X/EGL window context", const Math::Vector2& size = Math::Vector2(800, 600)): AbstractXWindowContext(new EglContextHandler, argc, argv, title, size) {} }; }} diff --git a/src/CubeMapTexture.h b/src/CubeMapTexture.h index 44ae71fce..df1d3b77f 100644 --- a/src/CubeMapTexture.h +++ b/src/CubeMapTexture.h @@ -27,9 +27,9 @@ namespace Magnum { @brief Cube map texture %Texture used mainly for environemnt maps. See AbstractTexture documentation -for more information about usage. 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): +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): +----+ | -Y | @@ -63,8 +63,11 @@ class CubeMapTexture: public AbstractTexture { /** * @brief Enable/disable seamless cube map textures * - * @requires_gl + * Initially disabled on desktop OpenGL. + * @see @fn_gl{Enable}/@fn_gl{Disable} with @def_gl{TEXTURE_CUBE_MAP_SEAMLESS} * @requires_gl32 Extension @extension{ARB,seamless_cube_map} + * @requires_gl Not available in OpenGL ES 2.0, always enabled in + * OpenGL ES 3.0. */ inline static void setSeamless(bool enabled) { enabled ? glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS) : glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS); @@ -75,34 +78,63 @@ class CubeMapTexture: public AbstractTexture { * @brief Constructor * * Creates one cube map OpenGL texture. + * @see @def_gl{TEXTURE_CUBE_MAP} */ inline CubeMapTexture(): AbstractTexture(GL_TEXTURE_CUBE_MAP) {} /** * @copydoc Texture::setWrapping() */ - inline void setWrapping(const Math::Vector<3, Wrapping>& wrapping) { - bind(); - DataHelper<3>::setWrapping(GL_TEXTURE_CUBE_MAP, wrapping); + inline CubeMapTexture* setWrapping(const Math::Vector<3, Wrapping>& wrapping) { + DataHelper<3>::setWrapping(this, wrapping); + return this; } /** * @copydoc Texture::setData(GLint, InternalFormat, Image*) * @param coordinate Coordinate + * @return Pointer to self (for method chaining) */ - template inline void setData(Coordinate coordinate, GLint mipLevel, InternalFormat internalFormat, Image* image) { - bind(); - DataHelper<2>::set(static_cast(coordinate), mipLevel, internalFormat, image); + template inline CubeMapTexture* setData(Coordinate coordinate, GLint mipLevel, InternalFormat internalFormat, Image* image) { + DataHelper<2>::set(this, static_cast(coordinate), mipLevel, internalFormat, image); + return this; } /** - * @copydoc Texture::setSubData(GLint, const Math::Vector&, Image*) + * @copydoc Texture::setSubData(GLint, const typename DimensionTraits::VectorType&, Image*) * @param coordinate Coordinate + * @return Pointer to self (for method chaining) */ - template inline void setSubData(Coordinate coordinate, GLint mipLevel, const Math::Vector<2, GLint>& offset, const Image* image) { - bind(); - DataHelper<2>::setSub(static_cast(coordinate), mipLevel, offset, image); + template inline CubeMapTexture* setSubData(Coordinate coordinate, GLint mipLevel, const Math::Vector2& offset, const Image* image) { + DataHelper<2>::setSub(this, static_cast(coordinate), mipLevel, offset, image); + return this; } + + /* Overloads to remove WTF-factor from method chaining order */ + #ifndef DOXYGEN_GENERATING_OUTPUT + inline CubeMapTexture* setMinificationFilter(Filter filter, Mipmap mipmap = Mipmap::BaseLevel) { + AbstractTexture::setMinificationFilter(filter, mipmap); + return this; + } + inline CubeMapTexture* setMagnificationFilter(Filter filter) { + AbstractTexture::setMagnificationFilter(filter); + return this; + } + #ifndef MAGNUM_TARGET_GLES + inline CubeMapTexture* setBorderColor(const Color4& color) { + AbstractTexture::setBorderColor(color); + return this; + } + #endif + inline CubeMapTexture* setMaxAnisotropy(GLfloat anisotropy) { + AbstractTexture::setMaxAnisotropy(anisotropy); + return this; + } + inline CubeMapTexture* generateMipmap() { + AbstractTexture::generateMipmap(); + return this; + } + #endif }; } diff --git a/src/CubeMapTextureArray.h b/src/CubeMapTextureArray.h index 0a1f0ebca..0aa441935 100644 --- a/src/CubeMapTextureArray.h +++ b/src/CubeMapTextureArray.h @@ -15,25 +15,30 @@ GNU Lesser General Public License version 3 for more details. */ +#ifndef MAGNUM_TARGET_GLES /** @file * @brief Class Magnum::CubeMapTextureArray */ +#endif #include "Texture.h" +#ifndef MAGNUM_TARGET_GLES namespace Magnum { /** @brief Cube map texture array -For information about usage, see CubeMapTexture documentation. +For information, see CubeMapTexture and AbstractTexture documentation. 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. +@see CubeMapTexture::setSeamless() @requires_gl40 Extension @extension{ARB,texture_cube_map_array} +@requires_gl Cube map texture arrays are not available in OpenGL ES. */ class CubeMapTextureArray: public AbstractTexture { public: @@ -47,28 +52,20 @@ class CubeMapTextureArray: public AbstractTexture { NegativeZ = 5 /**< -Z cube side */ }; - /** - * @brief Enable/disable seamless cube map textures - * - * @requires_gl32 Extension @extension{ARB,seamless_cube_map} - */ - inline static void setSeamless(bool enabled) { - enabled ? glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS) : glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS); - } - /** * @brief Constructor * * Creates one cube map OpenGL texture. + * @see @def_gl{TEXTURE_CUBE_MAP_ARRAY} */ inline CubeMapTextureArray(): AbstractTexture(GL_TEXTURE_CUBE_MAP_ARRAY) {} /** * @copydoc Texture::setWrapping() */ - inline void setWrapping(const Math::Vector<3, Wrapping>& wrapping) { - bind(); - DataHelper<3>::setWrapping(GL_TEXTURE_CUBE_MAP_ARRAY, wrapping); + inline CubeMapTextureArray* setWrapping(const Math::Vector3& wrapping) { + DataHelper<3>::setWrapping(this, wrapping); + return this; } /** @@ -78,9 +75,9 @@ class CubeMapTextureArray: public AbstractTexture { * for all layers. Each group of 6 2D images is one cube map layer. * The images are ordered the same way as Coordinate enum. */ - template inline void setData(GLint mipLevel, InternalFormat internalFormat, T* image) { - bind(); - DataHelper<3>::set(GL_TEXTURE_CUBE_MAP_ARRAY, mipLevel, internalFormat, image); + template inline CubeMapTextureArray* setData(GLint mipLevel, InternalFormat internalFormat, T* image) { + DataHelper<3>::set(this, GL_TEXTURE_CUBE_MAP_ARRAY, mipLevel, internalFormat, image); + return this; } /** @@ -89,6 +86,7 @@ class CubeMapTextureArray: public AbstractTexture { * @param offset Offset where to put data in the texture * @param image Three-dimensional Image, BufferedImage or for * example Trade::ImageData + * @return Pointer to self (for method chaining) * * Sets texture subdata from given image. The image is not deleted * afterwards. @@ -100,9 +98,9 @@ class CubeMapTextureArray: public AbstractTexture { * * @see setSubData(GLsizei, Coordinate, GLint, const Math::Vector<2, GLint>&, const Image*) */ - template inline void setSubData(GLint mipLevel, const Math::Vector<3, GLint>& offset, const Image* image) { - bind(); - DataHelper<3>::setSub(GL_TEXTURE_CUBE_MAP_ARRAY, mipLevel, offset, image, Math::Vector<3, GLsizei>(Math::Vector())); + template inline CubeMapTextureArray* setSubData(GLint mipLevel, const Math::Vector3& offset, const Image* image) { + DataHelper<3>::setSub(this, GL_TEXTURE_CUBE_MAP_ARRAY, mipLevel, offset, image, Math::Vector3(Math::Vector())); + return this; } /** @@ -113,18 +111,44 @@ class CubeMapTextureArray: public AbstractTexture { * @param offset Offset where to put data in the texture * @param image Two-dimensional Image, BufferedImage or for * example Trade::ImageData + * @return Pointer to self (for method chaining) * * Sets texture subdata from given image. The image is not deleted * afterwards. * * @see setSubData(GLint, const Math::Vector<3, GLint>&, const Image*) */ - template inline void setSubData(GLsizei layer, Coordinate coordinate, GLint mipLevel, const Math::Vector<2, GLint>& offset, const Image* image) { - bind(); - DataHelper<3>::setSub(GL_TEXTURE_CUBE_MAP_ARRAY, mipLevel, Math::Vector<3, GLint>(offset, layer*6+static_cast(coordinate)), image, Math::Vector<2, GLsizei>(Math::Vector())); + template inline CubeMapTextureArray* setSubData(GLsizei layer, Coordinate coordinate, GLint mipLevel, const Math::Vector2& offset, const Image* image) { + DataHelper<3>::setSub(this, GL_TEXTURE_CUBE_MAP_ARRAY, mipLevel, Math::Vector3(offset, layer*6+static_cast(coordinate)), image, Math::Vector<2, GLsizei>(Math::Vector())); + return this; } + + /* Overloads to remove WTF-factor from method chaining order */ + #ifndef DOXYGEN_GENERATING_OUTPUT + inline CubeMapTextureArray* setMinificationFilter(Filter filter, Mipmap mipmap = Mipmap::BaseLevel) { + AbstractTexture::setMinificationFilter(filter, mipmap); + return this; + } + inline CubeMapTextureArray* setMagnificationFilter(Filter filter) { + AbstractTexture::setMagnificationFilter(filter); + return this; + } + inline CubeMapTextureArray* setBorderColor(const Color4& color) { + AbstractTexture::setBorderColor(color); + return this; + } + inline CubeMapTextureArray* setMaxAnisotropy(GLfloat anisotropy) { + AbstractTexture::setMaxAnisotropy(anisotropy); + return this; + } + inline CubeMapTextureArray* generateMipmap() { + AbstractTexture::generateMipmap(); + return this; + } + #endif }; } +#endif #endif diff --git a/src/DimensionTraits.h b/src/DimensionTraits.h new file mode 100644 index 000000000..fe188f2b3 --- /dev/null +++ b/src/DimensionTraits.h @@ -0,0 +1,109 @@ +#ifndef Magnum_DimensionTraits_h +#define Magnum_DimensionTraits_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 + +/** @file + * @brief Class Magnum::DimensionTraits + */ + +namespace Magnum { + +namespace Math { + template class Vector; + template class Vector2; + template class Vector3; + + template class Point2D; + template class Point3D; + + template class Matrix3; + template class Matrix4; +} + +/** @brief Matrix, point and vector specializations for given dimension count */ +template struct DimensionTraits { + #ifdef DOXYGEN_GENERATING_OUTPUT + /** + * @brief Vector type + * + * Math::Vector, Math::Vector2 or Math::Vector3 based on dimension count. + */ + typedef U VectorType; + + /** + * @brief Point type + * + * Floating-point Math::Point2D or Math::Point3D for 2D or 3D. No point + * type defined for one dimension and integral types. + */ + typedef U PointType; + + /** + * @brief Matrix type + * + * Floating-point Math::Matrix3 or Math::Matrix4 for 2D or 3D. No matrix + * type defined for one dimension and integral types. + */ + typedef U MatrixType; + #endif +}; + +#ifndef DOXYGEN_GENERATING_OUTPUT +/* One dimension */ +template struct DimensionTraits<1, T> { + typedef Math::Vector<1, T> VectorType; +}; + +/* Two dimensions - integral */ +template struct DimensionTraits<2, T> { + typedef Math::Vector2 VectorType; +}; + +/* Two dimensions - floating-point */ +template<> struct DimensionTraits<2, float> { + typedef Math::Vector2 VectorType; + typedef Math::Point2D PointType; + typedef Math::Matrix3 MatrixType; +}; +template<> struct DimensionTraits<2, double> { + typedef Math::Vector2 VectorType; + typedef Math::Point2D PointType; + typedef Math::Matrix3 MatrixType; +}; + +/* Three dimensions - integral */ +template struct DimensionTraits<3, T> { + typedef Math::Vector3 VectorType; +}; + +/* Three dimensions - floating-point */ +template<> struct DimensionTraits<3, float> { + typedef Math::Vector3 VectorType; + typedef Math::Point3D PointType; + typedef Math::Matrix4 MatrixType; +}; +template<> struct DimensionTraits<3, double> { + typedef Math::Vector3 VectorType; + typedef Math::Point3D PointType; + typedef Math::Matrix4 MatrixType; +}; +#endif + +} + +#endif diff --git a/src/Extensions.h b/src/Extensions.h new file mode 100644 index 000000000..a99f9d569 --- /dev/null +++ b/src/Extensions.h @@ -0,0 +1,153 @@ +#ifndef Magnum_Extensions_h +#define Magnum_Extensions_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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. +*/ + +/** @file + * @brief Namespace Magnum::Extensions + */ + +#include "Context.h" + +namespace Magnum { + +/** +@brief Compile-time information about OpenGL extensions + +Each extension is `struct` named hierarchically by prefix, vendor and +extension name, for example `GL::APPLE::vertex_array_object`. Each struct has +the same public methods as Extension class (requiredVersion(), coreVersion() +and string(), but these structs are better suited for compile-time decisions +rather than Extension instances. See Context::isExtensionSupported() for +example usage. + +@todo Manual indices for extensions, this has gaps +@todo Unhide ES2_compatibility, ES3_compatibility on ES +@todo Add ES and GL 4.3 extensions +*/ +namespace Extensions { + +#ifndef MAGNUM_TARGET_GLES +#ifndef DOXYGEN_GENERATING_OUTPUT +#define _extension(prefix, vendor, extension, _requiredVersion, _coreVersion) \ + struct extension { \ + enum: std::size_t { Index = __LINE__-1 }; \ + constexpr static Version requiredVersion() { return Version::_requiredVersion; } \ + constexpr static Version coreVersion() { return Version::_coreVersion; } \ + constexpr static const char* string() { return #prefix "_" #vendor "_" #extension; } \ + }; +namespace GL { + #line 1 + namespace AMD { + _extension(GL,AMD,shader_trinary_minmax, GL210, None) // #428 + } namespace APPLE { + _extension(GL,APPLE,flush_buffer_range, GL210, GL300) // #321 + _extension(GL,APPLE,vertex_array_object, GL210, GL300) // #273 + } namespace ARB { + _extension(GL,ARB,texture_rectangle, GL210, GL310) // #38 + _extension(GL,ARB,color_buffer_float, GL210, GL300) // #39 + _extension(GL,ARB,half_float_pixel, GL210, GL300) // #40 + _extension(GL,ARB,texture_float, GL210, GL300) // #41 + _extension(GL,ARB,depth_buffer_float, GL210, GL300) // #43 + _extension(GL,ARB,draw_instanced, GL210, GL310) // #44 + _extension(GL,ARB,geometry_shader4, GL210, GL320) // #47 + _extension(GL,ARB,instanced_arrays, GL210, GL330) // #49 + _extension(GL,ARB,texture_buffer_object, GL210, GL310) // #51 + _extension(GL,ARB,texture_rg, GL210, GL300) // #53 + _extension(GL,ARB,uniform_buffer_object, GL210, GL310) // #57 + _extension(GL,ARB,copy_buffer, /*?*/ GL210, GL310) // #59 + _extension(GL,ARB,depth_clamp, /*?*/ GL210, GL320) // #61 + _extension(GL,ARB,draw_elements_base_vertex, /*?*/ GL210, GL320) // #62 + _extension(GL,ARB,fragment_coord_conventions, /*?*/ GL210, GL320) // #63 + _extension(GL,ARB,provoking_vertex, /*?*/ GL210, GL320) // #64 + _extension(GL,ARB,seamless_cube_map, GL210, GL320) // #65 + _extension(GL,ARB,sync, GL310, GL320) // #66 + _extension(GL,ARB,texture_multisample, /*?*/ GL210, GL320) // #67 + _extension(GL,ARB,vertex_array_bgra, GL210, GL320) // #68 + _extension(GL,ARB,draw_buffers_blend, GL210, GL400) // #69 + _extension(GL,ARB,sample_shading, GL210, GL400) // #70 + _extension(GL,ARB,texture_cube_map_array, /*?*/ GL210, GL400) // #71 + _extension(GL,ARB,texture_gather, GL210, GL400) // #72 + _extension(GL,ARB,texture_query_lod, GL210, GL400) // #73 + _extension(GL,ARB,texture_compression_bptc, GL310, GL420) // #77 + _extension(GL,ARB,blend_func_extended, GL210, GL330) // #78 + _extension(GL,ARB,explicit_attrib_location, GL210, GL330) // #79 + _extension(GL,ARB,occlusion_query2, GL210, GL330) // #80 + _extension(GL,ARB,sampler_objects, GL210, GL330) // #81 + _extension(GL,ARB,shader_bit_encoding, /*?*/ GL210, GL330) // #82 + _extension(GL,ARB,texture_rgb10_a2ui, GL210, GL330) // #83 + _extension(GL,ARB,texture_swizzle, /*?*/ GL210, GL330) // #84 + _extension(GL,ARB,timer_query, /*?*/ GL210, GL330) // #85 + _extension(GL,ARB,vertex_type_2_10_10_10_rev, GL210, GL330) // #86 + _extension(GL,ARB,draw_indirect, GL310, GL400) // #87 + _extension(GL,ARB,gpu_shader5, GL320, GL400) // #88 + _extension(GL,ARB,gpu_shader_fp64, GL320, GL400) // #89 + _extension(GL,ARB,shader_subroutine, GL320, GL400) // #90 + _extension(GL,ARB,tessellation_shader, GL320, GL400) // #91 + _extension(GL,ARB,texture_buffer_object_rgb32, /*?*/ GL210, GL400) // #92 + _extension(GL,ARB,transform_feedback2, GL210, GL400) // #93 + _extension(GL,ARB,transform_feedback3, GL210, GL400) // #94 + _extension(GL,ARB,ES2_compatibility, /*?*/ GL210, GL410) // #95 + _extension(GL,ARB,get_program_binary, GL300, GL410) // #96 + _extension(GL,ARB,separate_shader_objects, GL210, GL410) // #97 + _extension(GL,ARB,shader_precision, GL400, GL410) // #98 + _extension(GL,ARB,vertex_attrib_64bit, GL300, GL410) // #99 + _extension(GL,ARB,viewport_array, GL210, GL410) // #100 + _extension(GL,ARB,base_instance, GL210, GL420) // #107 + _extension(GL,ARB,shading_language_420pack, GL300, GL420) // #108 + _extension(GL,ARB,transform_feedback_instanced, GL210, GL420) // #109 + _extension(GL,ARB,compressed_texture_pixel_storage, GL210, GL420) // #110 + _extension(GL,ARB,conservative_depth, GL300, GL420) // #111 + _extension(GL,ARB,internalformat_query, GL210, GL420) // #112 + _extension(GL,ARB,map_buffer_alignment, GL210, GL420) // #113 + _extension(GL,ARB,shader_atomic_counters, GL300, GL420) // #114 + _extension(GL,ARB,shader_image_load_store, GL300, GL420) // #115 + _extension(GL,ARB,texture_storage, GL210, GL420) // #117 + } namespace EXT { + _extension(GL,EXT,texture_filter_anisotropic, GL210, None) // #187 + _extension(GL,EXT,framebuffer_object, GL210, GL300) // #310 + _extension(GL,EXT,packed_depth_stencil, GL210, GL300) // #312 + _extension(GL,EXT,framebuffer_blit, GL210, GL300) // #316 + _extension(GL,EXT,framebuffer_multisample, GL210, GL300) // #317 + _extension(GL,EXT,gpu_shader4, GL210, GL300) // #326 + _extension(GL,EXT,packed_float, GL210, GL300) // #328 + _extension(GL,EXT,texture_array, GL210, GL300) // #329 + _extension(GL,EXT,texture_compression_rgtc, GL210, GL300) // #332 + _extension(GL,EXT,texture_shared_exponent, GL210, GL300) // #333 + _extension(GL,EXT,framebuffer_sRGB, GL210, GL300) // #337 + _extension(GL,EXT,draw_buffers2, GL210, GL300) // #340 + _extension(GL,EXT,texture_integer, GL210, GL300) // #343 + _extension(GL,EXT,transform_feedback, GL210, GL300) // #352 + _extension(GL,EXT,direct_state_access, GL210, None) // #353 + _extension(GL,EXT,texture_snorm, GL300, GL310) // #365 + } namespace INTEL { + /* INTEL_map_texture not supported */ // #429 + } namespace NV { + _extension(GL,NV,half_float, GL210, GL300) // #283 + _extension(GL,NV,primitive_restart, GL210, GL310) // #285 + _extension(GL,NV,depth_buffer_float, GL210, GL300) // #334 + _extension(GL,NV,conditional_render, GL210, GL300) // #346 + /* NV_draw_texture not supported */ // #430 + } +} +#undef _extension +#endif +#endif + +} + +} + +#endif diff --git a/src/Framebuffer.cpp b/src/Framebuffer.cpp index d0f1d4cd2..c545c0dc6 100644 --- a/src/Framebuffer.cpp +++ b/src/Framebuffer.cpp @@ -15,28 +15,12 @@ #include "Framebuffer.h" -namespace Magnum { - -Framebuffer::ClearMask Framebuffer::clearMask = Framebuffer::Clear::Color; - -void Framebuffer::setFeature(Feature feature, bool enabled) { - /* Enable or disable the feature */ - enabled ? glEnable(static_cast(feature)) : glDisable(static_cast(feature)); - - /* Update clear mask, if needed */ - ClearMask clearMaskChange; - if(feature == Feature::DepthTest) clearMaskChange = Clear::Depth; - else if(feature == Feature::StencilTest) clearMaskChange = Clear::Stencil; - else return; - - enabled ? clearMask |= clearMaskChange : clearMask &= ~clearMaskChange; -} +#include "BufferedImage.h" +#include "Image.h" -void Framebuffer::setViewport(const Math::Vector2& position, const Math::Vector2& size) { - glViewport(position.x(), position.y(), size.x(), size.y()); -} +namespace Magnum { -#ifndef MAGNUM_TARGET_GLES +#ifndef MAGNUM_TARGET_GLES2 void Framebuffer::mapDefaultForDraw(std::initializer_list attachments) { GLenum* _attachments = new GLenum[attachments.size()]; for(auto it = attachments.begin(); it != attachments.end(); ++it) @@ -46,34 +30,35 @@ void Framebuffer::mapDefaultForDraw(std::initializer_list glDrawBuffers(attachments.size(), _attachments); delete[] _attachments; } +#endif -void Framebuffer::mapForDraw(std::initializer_list colorAttachments) { +void Framebuffer::mapForDraw(std::initializer_list colorAttachments) { GLenum* attachments = new GLenum[colorAttachments.size()]; for(auto it = colorAttachments.begin(); it != colorAttachments.end(); ++it) attachments[it-colorAttachments.begin()] = *it + GL_COLOR_ATTACHMENT0; bind(Target::Draw); + /** @todo Re-enable when extension wrangler is available for ES2 */ + #ifndef MAGNUM_TARGET_GLES2 glDrawBuffers(colorAttachments.size(), attachments); + #endif delete[] attachments; } -#endif -void Framebuffer::read(const Math::Vector2& offset, const Math::Vector2& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, Image2D* image) { - char* data = new char[AbstractImage::pixelSize(components, type)*dimensions.product()]; - glReadPixels(offset.x(), offset.y(), dimensions.x(), dimensions.y(), static_cast(components), static_cast(type), data); - image->setData(dimensions, components, type, data); +void Framebuffer::read(const Math::Vector2& offset, const Math::Vector2& size, AbstractImage::Components components, AbstractImage::ComponentType type, Image2D* image) { + char* data = new char[AbstractImage::pixelSize(components, type)*size.product()]; + glReadPixels(offset.x(), offset.y(), size.x(), size.y(), static_cast(components), static_cast(type), data); + image->setData(size, components, type, data); } -#ifndef MAGNUM_TARGET_GLES -void Framebuffer::read(const Math::Vector2& offset, const Math::Vector2& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, BufferedImage2D* image, Buffer::Usage usage) { +void Framebuffer::read(const Math::Vector2& offset, const Math::Vector2& size, AbstractImage::Components components, AbstractImage::ComponentType type, BufferedImage2D* image, Buffer::Usage usage) { /* If the buffer doesn't have sufficient size, resize it */ /** @todo Explicitly reset also when buffer usage changes */ - if(image->dimensions() != dimensions || image->components() != components || image->type() != type) - image->setData(dimensions, components, type, nullptr, usage); + if(image->size() != size || image->components() != components || image->type() != type) + image->setData(size, components, type, nullptr, usage); image->buffer()->bind(Buffer::Target::PixelPack); - glReadPixels(offset.x(), offset.y(), dimensions.x(), dimensions.y(), static_cast(components), static_cast(type), nullptr); + glReadPixels(offset.x(), offset.y(), size.x(), size.y(), static_cast(components), static_cast(type), nullptr); } -#endif } diff --git a/src/Framebuffer.h b/src/Framebuffer.h index 4282e09ea..3edfac3fa 100644 --- a/src/Framebuffer.h +++ b/src/Framebuffer.h @@ -21,14 +21,24 @@ #include -#include "BufferedImage.h" +#include "AbstractImage.h" +#include "Buffer.h" #include "CubeMapTexture.h" #include "Color.h" -#include "Image.h" #include "Renderbuffer.h" namespace Magnum { +template class BufferedImage; +template class Image; + +typedef BufferedImage<1> BufferedImage1D; +typedef BufferedImage<2> BufferedImage2D; +typedef BufferedImage<3> BufferedImage3D; +typedef Image<1> Image1D; +typedef Image<2> Image2D; +typedef Image<3> Image3D; + /** @nosubgrouping @brief %Framebuffer @@ -43,6 +53,20 @@ class MAGNUM_EXPORT Framebuffer { Framebuffer& operator=(Framebuffer&& other) = delete; public: + /** + * @brief Affected polygon facing for culling, stencil operations and masks + * + * @see setFaceCullingMode(), + * setStencilFunction(PolygonFacing, StencilFunction, GLint, GLuint), + * setStencilOperation(PolygonFacing, StencilOperation, StencilOperation, StencilOperation), + * setStencilMask(PolygonFacing, GLuint) + */ + enum class PolygonFacing: GLenum { + Front = GL_FRONT, /**< Front-facing polygons */ + Back = GL_BACK, /**< Back-facing polygons */ + FrontAndBack = GL_FRONT_AND_BACK /**< Front- and back-facing polygons */ + }; + /** @{ @name Framebuffer features */ /** @@ -62,14 +86,15 @@ class MAGNUM_EXPORT Framebuffer { /** * Logical operation * @see setLogicOperation() - * @requires_gl Logic operations on framebuffer are in desktop OpenGL only. + * @requires_gl Logical operations on framebuffer are not + * available in OpenGL ES. */ LogicOperation = GL_COLOR_LOGIC_OP, /** * Depth clamping. If enabled, ignores near and far clipping plane. - * @requires_gl * @requires_gl32 Extension @extension{ARB,depth_clamp} + * @requires_gl Depth clamping is not available in OpenGL ES. */ DepthClamp = GL_DEPTH_CLAMP, #endif @@ -85,16 +110,36 @@ class MAGNUM_EXPORT Framebuffer { FaceCulling = GL_CULL_FACE /**< Back face culling */ }; - /** @brief Set feature */ - static void setFeature(Feature feature, bool enabled); + /** + * @brief Set feature + * + * @see @fn_gl{Enable}/@fn_gl{Disable} + */ + inline static void setFeature(Feature feature, bool enabled) { + enabled ? glEnable(static_cast(feature)) : glDisable(static_cast(feature)); + } + + /** + * @brief Which polygon facing to cull + * + * Initial value is `PolygonFacing::Back`. If set to both front and + * back, only points and lines are drawn. + * @attention You have to also enable face culling with setFeature(). + * @see @fn_gl{CullFace} + */ + inline static void setFaceCullingMode(PolygonFacing mode) { + glCullFace(static_cast(mode)); + } /** * @brief Set viewport size * * Call when window size changes. - * @see Camera::setViewport() + * @see @fn_gl{Viewport} */ - static void setViewport(const Math::Vector2& position, const Math::Vector2& size); + inline static void setViewport(const Math::Vector2& position, const Math::Vector2& size) { + glViewport(position.x(), position.y(), size.x(), size.y()); + } /*@}*/ @@ -111,23 +156,15 @@ class MAGNUM_EXPORT Framebuffer { Stencil = GL_STENCIL_BUFFER_BIT /**< Stencil value */ }; - typedef Corrade::Containers::EnumSet ClearMask; /**< @brief Mask for clearing */ - - /** - * @brief Clear framebuffer - * - * Clears color buffer, depth and stencil buffer in currently active - * framebuffer. If depth or stencil test is not enabled, it doesn't - * clear these buffers. - * - * @see setFeature(), clear(ClearMask) - */ - inline static void clear() { glClear(static_cast(clearMask)); } + /** @brief Mask for clearing */ + typedef Corrade::Containers::EnumSet ClearMask; /** * @brief Clear specified buffers in framebuffer * - * @see clear() + * @see clear(), setClearColor(), setClearDepth(), setClearStencil(), + * @fn_gl{Clear} * @todo Clearing only given draw buffer */ inline static void clear(ClearMask mask) { glClear(static_cast(mask)); } @@ -136,6 +173,7 @@ class MAGNUM_EXPORT Framebuffer { * @brief Set clear color * * Initial value is `{0.0f, 0.0f, 0.0f, 1.0f}`. + * @see @fn_gl{ClearColor} */ inline static void setClearColor(const Color4& color) { glClearColor(color.r(), color.g(), color.b(), color.a()); @@ -146,7 +184,8 @@ class MAGNUM_EXPORT Framebuffer { * @brief Set clear depth * * Initial value is `1.0`. - * @requires_gl See setClearDepth(GLfloat), which is supported in OpenGL ES. + * @see @fn_gl{ClearDepth} + * @requires_gl See setClearDepth(GLfloat), which is available in OpenGL ES. */ inline static void setClearDepth(GLdouble depth) { glClearDepth(depth); } #endif @@ -154,7 +193,9 @@ class MAGNUM_EXPORT Framebuffer { /** * @overload * + * @see @fn_gl{ClearDepth} * @requires_gl41 Extension @extension{ARB,ES2_compatibility} + * @todo Call double version if the extension is not available */ inline static void setClearDepth(GLfloat depth) { glClearDepthf(depth); } @@ -162,6 +203,7 @@ class MAGNUM_EXPORT Framebuffer { * @brief Set clear stencil * * Initial value is `0`. + * @see @fn_gl{ClearStencil} */ inline static void setClearStencil(GLint stencil) { glClearStencil(stencil); } @@ -175,7 +217,9 @@ class MAGNUM_EXPORT Framebuffer { * @param size Scissor rectangle size. Initial value is * size of the window when the context is first attached to a * window. + * * @attention You have to enable scissoring with setFeature() first. + * @see @fn_gl{Scissor} */ inline static void setScissor(const Math::Vector2& bottomLeft, const Math::Vector2& size) { glScissor(bottomLeft.x(), bottomLeft.y(), size.x(), size.y()); @@ -185,19 +229,6 @@ class MAGNUM_EXPORT Framebuffer { /** @{ @name Stencil operations */ - /** - * @brief Affected polygon facing for stencil operations and masks - * - * @see setStencilFunction(PolygonFacing, StencilFunction, GLint, GLuint), - * setStencilOperation(PolygonFacing, StencilOperation, StencilOperation, StencilOperation), - * setStencilMask(PolygonFacing, GLuint) - */ - enum class PolygonFacing: GLenum { - Front = GL_FRONT, /**< Front-facing polygons */ - Back = GL_BACK, /**< Back-facing polygons */ - FrontAndBack = GL_FRONT_AND_BACK /**< Front- and back-facing polygons */ - }; - /** * @brief Stencil function * @@ -269,7 +300,8 @@ class MAGNUM_EXPORT Framebuffer { * Initial value is all `1`s. * * @attention You have to enable stencil test with setFeature() first. - * @see setStencilFunction(StencilFunction, GLint, GLuint) + * @see setStencilFunction(StencilFunction, GLint, GLuint), + * @fn_gl{StencilFuncSeparate} */ inline static void setStencilFunction(PolygonFacing facing, StencilFunction function, GLint referenceValue, GLuint mask) { glStencilFuncSeparate(static_cast(facing), static_cast(function), referenceValue, mask); @@ -280,6 +312,7 @@ class MAGNUM_EXPORT Framebuffer { * * The same as setStencilFunction(PolygonFacing, StencilFunction, GLint, GLuint) * with `facing` set to `PolygonFacing::FrontAndBack`. + * @see @fn_gl{StencilFunc} */ inline static void setStencilFunction(StencilFunction function, GLint referenceValue, GLuint mask) { glStencilFunc(static_cast(function), referenceValue, mask); @@ -296,7 +329,8 @@ class MAGNUM_EXPORT Framebuffer { * * Initial value for all fields is `StencilOperation::Keep`. * @attention You have to enable stencil test with setFeature() first. - * @see setStencilOperation(StencilOperation, StencilOperation, StencilOperation) + * @see setStencilOperation(StencilOperation, StencilOperation, StencilOperation), + * @fn_gl{StencilOpSeparate} */ inline static void setStencilOperation(PolygonFacing facing, StencilOperation stencilFail, StencilOperation depthFail, StencilOperation depthPass) { glStencilOpSeparate(static_cast(facing), static_cast(stencilFail), static_cast(depthFail), static_cast(depthPass)); @@ -307,6 +341,7 @@ class MAGNUM_EXPORT Framebuffer { * * The same as setStencilOperation(PolygonFacing, StencilOperation, StencilOperation, StencilOperation) * with `facing` set to `PolygonFacing::FrontAndBack`. + * @see @fn_gl{StencilOp} */ inline static void setStencilOperation(StencilOperation stencilFail, StencilOperation depthFail, StencilOperation depthPass) { glStencilOp(static_cast(stencilFail), static_cast(depthFail), static_cast(depthPass)); @@ -328,6 +363,7 @@ class MAGNUM_EXPORT Framebuffer { * * Initial value is `DepthFunction::Less`. * @attention You have to enable depth test with setFeature() first. + * @see @fn_gl{DepthFunc} */ inline static void setDepthFunction(DepthFunction function) { glDepthFunc(static_cast(function)); @@ -342,6 +378,7 @@ class MAGNUM_EXPORT Framebuffer { * * Set to `false` to disallow writing to given color channel. Initial * values are all `true`. + * @see @fn_gl{ColorMask} * @todo Masking only given draw buffer */ inline static void setColorMask(GLboolean allowRed, GLboolean allowGreen, GLboolean allowBlue, GLboolean allowAlpha) { @@ -353,6 +390,7 @@ class MAGNUM_EXPORT Framebuffer { * * Set to `false` to disallow writing to depth buffer. Initial value * is `true`. + * @see @fn_gl{DepthMask} */ inline static void setDepthMask(GLboolean allow) { glDepthMask(allow); @@ -363,7 +401,7 @@ class MAGNUM_EXPORT Framebuffer { * * Set given bit to `0` to disallow writing stencil value for given * faces to it. Initial value is all `1`s. - * @see setStencilMask(GLuint) + * @see setStencilMask(GLuint), @fn_gl{StencilMaskSeparate} */ inline static void setStencilMask(PolygonFacing facing, GLuint allowBits) { glStencilMaskSeparate(static_cast(facing), allowBits); @@ -374,6 +412,7 @@ class MAGNUM_EXPORT Framebuffer { * * The same as setStencilMask(PolygonFacing, GLuint) with `facing` set * to `PolygonFacing::FrontAndBack`. + * @see @fn_gl{StencilMask} */ inline static void setStencilMask(GLuint allowBits) { glStencilMask(allowBits); @@ -394,24 +433,19 @@ class MAGNUM_EXPORT Framebuffer { enum class BlendEquation: GLenum { Add = GL_FUNC_ADD, /**< `source + destination` */ Subtract = GL_FUNC_SUBTRACT, /**< `source - destination` */ - ReverseSubtract = GL_FUNC_REVERSE_SUBTRACT /**< `destination - source` */ - - #ifndef MAGNUM_TARGET_GLES - /** @todo Enable for ES3 when the headers are available */ - , + ReverseSubtract = GL_FUNC_REVERSE_SUBTRACT, /**< `destination - source` */ /** * `min(source, destination)` - * @requires_gles30 Extension @es_extension{EXT,blend_minmax} + * @requires_gles30 %Extension @es_extension2{EXT,blend_minmax,blend_minmax} */ Min = GL_MIN, /** * `max(source, destination)` - * @requires_gles30 Extension @es_extension{EXT,blend_minmax} + * @requires_gles30 %Extension @es_extension2{EXT,blend_minmax,blend_minmax} */ Max = GL_MAX - #endif }; /** @@ -462,8 +496,9 @@ class MAGNUM_EXPORT Framebuffer { * Second source color (@f$ RGB = (R_{s1}, G_{s1}, B_{s1}); A = A_{s1} @f$) * * @see AbstractShaderProgram::bindFragmentDataLocationIndexed() - * @requires_gl * @requires_gl33 Extension @extension{ARB,blend_func_extended} + * @requires_gl Multiple blending inputs are not available in + * OpenGL ES. */ SecondSourceColor = GL_SRC1_COLOR, #endif @@ -478,8 +513,9 @@ class MAGNUM_EXPORT Framebuffer { * One minus second source color (@f$ RGB = (1.0 - R_{s1}, 1.0 - G_{s1}, 1.0 - B_{s1}); A = 1.0 - A_{s1} @f$) * * @see AbstractShaderProgram::bindFragmentDataLocationIndexed() - * @requires_gl * @requires_gl33 Extension @extension{ARB,blend_func_extended} + * @requires_gl Multiple blending inputs are not available in + * OpenGL ES. */ OneMinusSecondSourceColor = GL_ONE_MINUS_SRC1_COLOR, #endif @@ -499,8 +535,9 @@ class MAGNUM_EXPORT Framebuffer { * Second source alpha (@f$ RGB = (A_{s1}, A_{s1}, A_{s1}); A = A_{s1} @f$) * * @see AbstractShaderProgram::bindFragmentDataLocationIndexed() - * @requires_gl * @requires_gl33 Extension @extension{ARB,blend_func_extended} + * @requires_gl Multiple blending inputs are not available in + * OpenGL ES. */ SecondSourceAlpha = GL_SRC1_ALPHA, #endif @@ -515,8 +552,9 @@ class MAGNUM_EXPORT Framebuffer { * One minus second source alpha (@f$ RGB = (1.0 - A_{s1}, 1.0 - A_{s1}, 1.0 - A_{s1}); A = 1.0 - A_{s1} @f$) * * @see AbstractShaderProgram::bindFragmentDataLocationIndexed() - * @requires_gl * @requires_gl33 Extension @extension{ARB,blend_func_extended} + * @requires_gl Multiple blending inputs are not available in + * OpenGL ES. */ OneMinusSecondSourceAlpha = GL_ONE_MINUS_SRC1_ALPHA, #endif @@ -544,7 +582,8 @@ class MAGNUM_EXPORT Framebuffer { * How to combine source color (pixel value) with destination color * (framebuffer). Initial value is `BlendEquation::Add`. * @attention You have to enable blending with setFeature() first. - * @see setBlendEquation(BlendEquation, BlendEquation) + * @see setBlendEquation(BlendEquation, BlendEquation), + * @fn_gl{BlendEquation} */ inline static void setBlendEquation(BlendEquation equation) { glBlendEquation(static_cast(equation)); @@ -555,6 +594,7 @@ class MAGNUM_EXPORT Framebuffer { * * See setBlendEquation(BlendEquation) for more information. * @attention You have to enable blending with setFeature() first. + * @see @fn_gl{BlendEquationSeparate} */ inline static void setBlendEquation(BlendEquation rgb, BlendEquation alpha) { glBlendEquationSeparate(static_cast(rgb), static_cast(alpha)); @@ -569,7 +609,8 @@ class MAGNUM_EXPORT Framebuffer { * `BlendFunction::Zero`. * * @attention You have to enable blending with setFeature() first. - * @see setBlendFunction(BlendFunction, BlendFunction, BlendFunction, BlendFunction) + * @see setBlendFunction(BlendFunction, BlendFunction, BlendFunction, BlendFunction), + * @fn_gl{BlendFunc} */ inline static void setBlendFunction(BlendFunction source, BlendFunction destination) { glBlendFunc(static_cast(source), static_cast(destination)); @@ -580,6 +621,7 @@ class MAGNUM_EXPORT Framebuffer { * * See setBlendFunction(BlendFunction, BlendFunction) for more information. * @attention You have to enable blending with setFeature() first. + * @see @fn_gl{BlendFuncSeparate} */ inline static void setBlendFunction(BlendFunction sourceRgb, BlendFunction destinationRgb, BlendFunction sourceAlpha, BlendFunction destinationAlpha) { glBlendFuncSeparate(static_cast(sourceRgb), static_cast(destinationRgb), static_cast(sourceAlpha), static_cast(destinationAlpha)); @@ -594,6 +636,7 @@ class MAGNUM_EXPORT Framebuffer { * `BlendFunction::ConstantAlpha` and * `BlendFunction::OneMinusConstantAlpha`. * @attention You have to enable blending with setFeature() first. + * @see @fn_gl{BlendColor} */ inline static void setBlendColor(const Color4& color) { glBlendColor(color.r(), color.g(), color.b(), color.a()); @@ -608,7 +651,8 @@ class MAGNUM_EXPORT Framebuffer { * @brief Logical operation * * @see setLogicOperation() - * @requires_gl + * @requires_gl Logical operations on framebuffer are not available in + * OpenGL ES. */ enum class LogicOperation: GLenum { Clear = GL_CLEAR, /**< `0` */ @@ -633,7 +677,9 @@ class MAGNUM_EXPORT Framebuffer { * @brief Set logical operation * * @attention You have to enable logical operation with setFeature() first. - * @requires_gl Logic operations on framebuffer are in desktop OpenGL only. + * @see @fn_gl{LogicOp} + * @requires_gl Logical operations on framebuffer are not available in + * OpenGL ES. */ inline static void setLogicOperation(LogicOperation operation) { glLogicOp(static_cast(operation)); @@ -651,81 +697,184 @@ class MAGNUM_EXPORT Framebuffer { * @requires_gl30 Extension @extension{EXT,framebuffer_object} */ enum class Target: GLenum { - #ifndef MAGNUM_TARGET_GLES /** * For reading only. - * @requires_gl * @requires_gl30 Extension @extension{EXT,framebuffer_blit} + * @requires_gles30 %Extension @es_extension{APPLE,framebuffer_multisample} + * or @es_extension{ANGLE,framebuffer_blit} */ Read = GL_READ_FRAMEBUFFER, /** * For drawing only. - * @requires_gl * @requires_gl30 Extension @extension{EXT,framebuffer_blit} + * @requires_gles30 %Extension @es_extension{APPLE,framebuffer_multisample} + * or @es_extension{ANGLE,framebuffer_blit} */ Draw = GL_DRAW_FRAMEBUFFER, - #endif ReadDraw = GL_FRAMEBUFFER /**< For both reading and drawing. */ }; - #ifndef MAGNUM_TARGET_GLES + #ifndef MAGNUM_TARGET_GLES2 /** * @brief Draw attachment for default framebuffer * * @see mapDefaultForDraw() - * @requires_gl * @requires_gl30 Extension @extension{EXT,framebuffer_object} + * @requires_gles30 Draw attachments for default framebuffer are + * available only in OpenGL ES 3.0. */ enum class DefaultDrawAttachment: GLenum { - None = GL_NONE, /**< Don't use the output. */ - BackLeft = GL_BACK_LEFT, /**< Write output to back left framebuffer. */ - BackRight = GL_BACK_RIGHT, /**< Write output to back right framebuffer. */ - FrontLeft = GL_FRONT_LEFT, /**< Write output to front left framebuffer. */ - FrontRight = GL_FRONT_RIGHT /**< Write output to front right framebuffer. */ + /** Don't use the output. */ + None = GL_NONE, + + #ifndef MAGNUM_TARGET_GLES + /** + * Write output to back left framebuffer. + * @requires_gl Stereo rendering is not available in OpenGL ES. + */ + BackLeft = GL_BACK_LEFT, + + /** + * Write output to back right framebuffer. + * @requires_gl Stereo rendering is not available in OpenGL ES. + */ + BackRight = GL_BACK_RIGHT, + + /** + * Write output to front left framebuffer. + * @requires_gl Stereo rendering is not available in OpenGL ES. + */ + FrontLeft = GL_FRONT_LEFT, + + /** + * Write output to front right framebuffer. + * @requires_gl Stereo rendering is not available in OpenGL ES. + */ + FrontRight = GL_FRONT_RIGHT, + #endif + + /** + * Write output to back framebuffer. + * + * On desktop OpenGL, this is equal to + * @ref Magnum::Framebuffer::DefaultDrawAttachment "DefaultDrawAttachment::BackLeft". + */ + #ifdef MAGNUM_TARGET_GLES + Back = GL_BACK, + #else + Back = GL_BACK_LEFT, + #endif + + /** + * Write output to front framebuffer. + * + * On desktop OpenGL, this is equal to + * @ref Magnum::Framebuffer::DefaultDrawAttachment "DefaultDrawAttachment::FrontLeft". + */ + #ifdef MAGNUM_TARGET_GLES + Front = GL_FRONT + #else + Front = GL_FRONT_LEFT + #endif }; + #endif /** * @brief Read attachment for default framebuffer * * @see mapDefaultForRead() - * @requires_gl - * @requires_gl30 Extension @extension{EXT,framebuffer_object} + * @requires_gl30 %Extension @extension{EXT,framebuffer_object} + * @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer} */ enum class DefaultReadAttachment: GLenum { - FrontLeft = GL_FRONT_LEFT, /**< Read from front left framebuffer. */ - FrontRight = GL_FRONT_RIGHT, /**< Read from front right framebuffer. */ - BackLeft = GL_BACK_LEFT, /**< Read from back left framebuffer. */ - BackRight = GL_BACK_RIGHT, /**< Read from back right framebuffer. */ - Left = GL_LEFT, /**< Read from left framebuffers. */ - Right = GL_RIGHT, /**< Read from right framebuffers. */ - Front = GL_FRONT, /**< Read from front framebuffers. */ - Back = GL_BACK, /**< Read from back framebuffers. */ - FrontAndBack = GL_FRONT_AND_BACK /**< Read from front and back framebuffers. */ + /** Don't read from any framebuffer */ + None = GL_NONE, + + #ifndef MAGNUM_TARGET_GLES + /** + * Read from back left framebuffer. + * @requires_gl Stereo rendering is not available in OpenGL ES. + */ + BackLeft = GL_BACK_LEFT, + + /** + * Read from back right framebuffer. + * @requires_gl Stereo rendering is not available in OpenGL ES. + */ + BackRight = GL_BACK_RIGHT, + + /** + * Read from front left framebuffer. + * @requires_gl Stereo rendering is not available in OpenGL ES. + */ + FrontLeft = GL_FRONT_LEFT, + + /** + * Read from front right framebuffer. + * @requires_gl Stereo rendering is not available in OpenGL ES. + */ + FrontRight = GL_FRONT_RIGHT, + + /** + * Read from left framebuffer. + * @requires_gl Stereo rendering is not available in OpenGL ES. + */ + Left = GL_LEFT, + + /** + * Read from right framebuffer. + * @requires_gl Stereo rendering is not available in OpenGL ES. + */ + Right = GL_RIGHT, + #endif + + /** Read from back framebuffer. */ + Back = GL_BACK, + + /** + * Read from front framebuffer. + * @requires_es_extension %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer} + */ + Front = GL_FRONT + + #ifndef MAGNUM_TARGET_GLES + , + + /** + * Read from front and back framebuffer. + * @requires_gl In OpenGL ES you must specify either + * @ref Magnum::Framebuffer::DefaultReadAttachment "DefaultReadAttachment::Front" + * or @ref Magnum::Framebuffer::DefaultReadAttachment "DefaultReadAttachment::Back". + */ + FrontAndBack = GL_FRONT_AND_BACK + #endif }; - #endif /** * @brief Constructor * * Generates new OpenGL framebuffer. + * @see @fn_gl{GenFramebuffers} * @requires_gl30 Extension @extension{EXT,framebuffer_object} */ - inline Framebuffer() { glGenFramebuffers(1, &framebuffer); } + inline Framebuffer() { glGenFramebuffers(1, &_id); } /** * @brief Destructor * * Deletes associated OpenGL framebuffer. + * @see @fn_gl{DeleteFramebuffers} * @requires_gl30 Extension @extension{EXT,framebuffer_object} */ - inline ~Framebuffer() { glDeleteFramebuffers(1, &framebuffer); } + inline ~Framebuffer() { glDeleteFramebuffers(1, &_id); } /** * @brief Bind default framebuffer to given target * @param target %Target * + * @see @fn_gl{BindFramebuffer} * @requires_gl30 Extension @extension{EXT,framebuffer_object} */ inline static void bindDefault(Target target) { @@ -735,13 +884,14 @@ class MAGNUM_EXPORT Framebuffer { /** * @brief Bind framebuffer * + * @see @fn_gl{BindFramebuffer} * @requires_gl30 Extension @extension{EXT,framebuffer_object} */ inline void bind(Target target) { - glBindFramebuffer(static_cast(target), framebuffer); + glBindFramebuffer(static_cast(target), _id); } - #ifndef MAGNUM_TARGET_GLES + #ifndef MAGNUM_TARGET_GLES2 /** * @brief Map given attachments of default framebuffer for drawing * @param attachments Default attachments. If any value is @@ -752,11 +902,13 @@ class MAGNUM_EXPORT Framebuffer { * If used for blit(), the order is not important. Each used attachment * should have either renderbuffer or texture attached for writing to * work properly. - * @see mapForDraw(), mapDefaultForRead() - * @requires_gl + * @see mapForDraw(), mapDefaultForRead(), bindDefault(), @fn_gl{DrawBuffers} * @requires_gl30 Extension @extension{EXT,framebuffer_object} + * @requires_gles30 Draw attachments for default framebuffer are + * available only in OpenGL ES 3.0. */ static void mapDefaultForDraw(std::initializer_list attachments); + #endif /** * @brief Map given color attachments of current framebuffer for drawing @@ -768,11 +920,11 @@ class MAGNUM_EXPORT Framebuffer { * If used for blit(), the order is not important. Each used attachment * should have either renderbuffer or texture attached for writing to * work properly. - * @see mapDefaultForDraw(), mapForRead() - * @requires_gl + * @see mapDefaultForDraw(), mapForRead(), bind(), @fn_gl{DrawBuffers} * @requires_gl30 Extension @extension{EXT,framebuffer_object} + * @requires_gles30 %Extension @es_extension2{NV,draw_buffers,GL_NV_draw_buffers} */ - void mapForDraw(std::initializer_list colorAttachments); + void mapForDraw(std::initializer_list colorAttachments); /** * @brief Map given attachment of default framebuffer for reading @@ -780,9 +932,9 @@ class MAGNUM_EXPORT Framebuffer { * * Each used attachment should have either renderbuffer or texture * attached to work properly. - * @see mapForRead(), mapDefaultForDraw() - * @requires_gl + * @see mapForRead(), mapDefaultForDraw(), bindDefault(), @fn_gl{ReadBuffer} * @requires_gl30 Extension @extension{EXT,framebuffer_object} + * @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer} */ inline static void mapDefaultForRead(DefaultReadAttachment attachment) { bindDefault(Target::Read); @@ -795,15 +947,14 @@ class MAGNUM_EXPORT Framebuffer { * * The color attachment should have either renderbuffer or texture * attached for reading to work properly. - * @see mapDefaultForRead(), mapForDraw() - * @requires_gl + * @see mapDefaultForRead(), mapForDraw(), bind(), @fn_gl{ReadBuffer} * @requires_gl30 Extension @extension{EXT,framebuffer_object} + * @requires_gles30 %Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer} */ - inline void mapForRead(unsigned int colorAttachment) { + inline void mapForRead(std::uint8_t colorAttachment) { bind(Target::Read); glReadBuffer(GL_COLOR_ATTACHMENT0 + colorAttachment); } - #endif /*@}*/ @@ -824,10 +975,12 @@ class MAGNUM_EXPORT Framebuffer { Stencil = GL_STENCIL_ATTACHMENT /**< Stencil output only. */ - #ifndef MAGNUM_TARGET_GLES + #ifndef MAGNUM_TARGET_GLES2 , /** * Both depth and stencil output. + * @requires_gles30 Combined depth and stencil attachment is not + * available in OpenGL ES 2.0. */ DepthStencil = GL_DEPTH_STENCIL_ATTACHMENT #endif @@ -837,8 +990,9 @@ class MAGNUM_EXPORT Framebuffer { * @brief Attach renderbuffer to given framebuffer depth/stencil attachment * @param target %Target * @param depthStencilAttachment Depth/stencil attachment - * @param renderbuffer Renderbuffer + * @param renderbuffer %Renderbuffer * + * @see bind(), @fn_gl{FramebufferRenderbuffer} * @requires_gl30 Extension @extension{EXT,framebuffer_object} */ inline void attachRenderbuffer(Target target, DepthStencilAttachment depthStencilAttachment, Renderbuffer* renderbuffer) { @@ -851,11 +1005,12 @@ class MAGNUM_EXPORT Framebuffer { * @brief Attach renderbuffer to given framebuffer color attachment * @param target %Target * @param colorAttachment Color attachment ID (number between 0 and 15) - * @param renderbuffer Renderbuffer + * @param renderbuffer %Renderbuffer * + * @see bind(), @fn_gl{FramebufferRenderbuffer} * @requires_gl30 Extension @extension{EXT,framebuffer_object} */ - inline void attachRenderbuffer(Target target, unsigned int colorAttachment, Renderbuffer* renderbuffer) { + inline void attachRenderbuffer(Target target, std::uint8_t colorAttachment, Renderbuffer* renderbuffer) { /** @todo Check for internal format compatibility */ bind(target); glFramebufferRenderbuffer(static_cast(target), GL_COLOR_ATTACHMENT0 + colorAttachment, GL_RENDERBUFFER, renderbuffer->id()); @@ -869,8 +1024,9 @@ class MAGNUM_EXPORT Framebuffer { * @param texture 1D texture * @param mipLevel Mip level * - * @requires_gl + * @see bind(), @fn_gl{FramebufferTexture} * @requires_gl30 Extension @extension{EXT,framebuffer_object} + * @requires_gl Only 2D and 3D textures are available in OpenGL ES. */ inline void attachTexture1D(Target target, DepthStencilAttachment depthStencilAttachment, Texture1D* texture, GLint mipLevel) { /** @todo Check for internal format compatibility */ @@ -886,10 +1042,11 @@ class MAGNUM_EXPORT Framebuffer { * @param texture 1D texture * @param mipLevel Mip level * - * @requires_gl + * @see bind(), @fn_gl{FramebufferTexture} * @requires_gl30 Extension @extension{EXT,framebuffer_object} + * @requires_gl Only 2D and 3D textures are available in OpenGL ES. */ - inline void attachTexture1D(Target target, unsigned int colorAttachment, Texture1D* texture, GLint mipLevel) { + inline void attachTexture1D(Target target, std::uint8_t colorAttachment, Texture1D* texture, GLint mipLevel) { /** @todo Check for internal format compatibility */ /** @todo Check for texture target compatibility */ bind(target); @@ -905,7 +1062,7 @@ class MAGNUM_EXPORT Framebuffer { * @param mipLevel Mip level. For rectangle textures it * should be always 0. * - * @see attachCubeMapTexture() + * @see attachCubeMapTexture(), bind(), @fn_gl{FramebufferTexture} * @requires_gl30 Extension @extension{EXT,framebuffer_object} */ inline void attachTexture2D(Target target, DepthStencilAttachment depthStencilAttachment, Texture2D* texture, GLint mipLevel) { @@ -923,10 +1080,10 @@ class MAGNUM_EXPORT Framebuffer { * @param mipLevel Mip level. For rectangle textures it * should be always 0. * - * @see attachCubeMapTexture() + * @see attachCubeMapTexture(), bind(), @fn_gl{FramebufferTexture} * @requires_gl30 Extension @extension{EXT,framebuffer_object} */ - inline void attachTexture2D(Target target, unsigned int colorAttachment, Texture2D* texture, GLint mipLevel) { + inline void attachTexture2D(Target target, std::uint8_t colorAttachment, Texture2D* texture, GLint mipLevel) { /** @todo Check for internal format compatibility */ /** @todo Check for texture target compatibility */ bind(target); @@ -941,7 +1098,7 @@ class MAGNUM_EXPORT Framebuffer { * @param coordinate Cube map coordinate * @param mipLevel Mip level * - * @see attachTexture2D() + * @see attachTexture2D(), bind(), @fn_gl{FramebufferTexture} * @requires_gl30 Extension @extension{EXT,framebuffer_object} */ inline void attachCubeMapTexture(Target target, DepthStencilAttachment depthStencilAttachment, CubeMapTexture* texture, CubeMapTexture::Coordinate coordinate, GLint mipLevel) { @@ -958,16 +1115,15 @@ class MAGNUM_EXPORT Framebuffer { * @param coordinate Cube map coordinate * @param mipLevel Mip level * - * @see attachTexture2D() + * @see attachTexture2D(), bind(), @fn_gl{FramebufferTexture} * @requires_gl30 Extension @extension{EXT,framebuffer_object} */ - inline void attachCubeMapTexture(Target target, unsigned int colorAttachment, CubeMapTexture* texture, CubeMapTexture::Coordinate coordinate, GLint mipLevel) { + inline void attachCubeMapTexture(Target target, std::uint8_t colorAttachment, CubeMapTexture* texture, CubeMapTexture::Coordinate coordinate, GLint mipLevel) { /** @todo Check for internal format compatibility */ bind(target); glFramebufferTexture2D(static_cast(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast(coordinate), texture->id(), mipLevel); } - #ifndef MAGNUM_TARGET_GLES /** * @brief Attach 3D texture to given framebuffer depth/stencil attachment * @param target %Target @@ -976,14 +1132,23 @@ class MAGNUM_EXPORT Framebuffer { * @param mipLevel Mip level * @param layer Layer of 2D image within a 3D texture * - * @requires_gl + * @see bind(), @fn_gl{FramebufferTexture} * @requires_gl30 Extension @extension{EXT,framebuffer_object} + * @requires_es_extension %Extension @es_extension{OES,texture_3D} */ inline void attachTexture3D(Target target, DepthStencilAttachment depthStencilAttachment, Texture3D* texture, GLint mipLevel, GLint layer) { /** @todo Check for internal format compatibility */ /** @todo Check for texture target compatibility */ bind(target); + /** @todo Get some extension wrangler for glFramebufferTexture3D() (extension only) */ + #ifndef MAGNUM_TARGET_GLES glFramebufferTexture3D(static_cast(target), static_cast(depthStencilAttachment), static_cast(texture->target()), texture->id(), mipLevel, layer); + #else + static_cast(depthStencilAttachment); + static_cast(texture); + static_cast(mipLevel); + static_cast(layer); + #endif } /** @@ -994,30 +1159,37 @@ class MAGNUM_EXPORT Framebuffer { * @param mipLevel Mip level * @param layer Layer of 2D image within a 3D texture. * - * @requires_gl + * @see bind(), @fn_gl{FramebufferTexture} * @requires_gl30 Extension @extension{EXT,framebuffer_object} + * @requires_es_extension %Extension @es_extension{OES,texture_3D} */ - inline void attachTexture3D(Target target, unsigned int colorAttachment, Texture3D* texture, GLint mipLevel, GLint layer) { + inline void attachTexture3D(Target target, std::uint8_t colorAttachment, Texture3D* texture, GLint mipLevel, GLint layer) { /** @todo Check for internal format compatibility */ /** @todo Check for texture target compatibility */ bind(target); + /** @todo Get some extension wrangler for glFramebufferTexture3D() (extension only) */ + #ifndef MAGNUM_TARGET_GLES glFramebufferTexture3D(static_cast(target), GL_COLOR_ATTACHMENT0 + colorAttachment, static_cast(texture->target()), texture->id(), mipLevel, layer); + #else + static_cast(colorAttachment); + static_cast(texture); + static_cast(mipLevel); + static_cast(layer); + #endif } - #endif /*@}*/ /** @{ @name Framebuffer blitting and reading */ - #ifndef MAGNUM_TARGET_GLES /** * @brief Output mask for blitting * * Specifies which data are copied when performing blit operation * using blit(). * @see BlitMask - * @requires_gl * @requires_gl30 Extension @extension{EXT,framebuffer_object} + * @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} */ enum class Blit: GLbitfield { Color = GL_COLOR_BUFFER_BIT, /**< Color */ @@ -1027,10 +1199,11 @@ class MAGNUM_EXPORT Framebuffer { /** * @brief Output mask for blitting - * @requires_gl * @requires_gl30 Extension @extension{EXT,framebuffer_object} + * @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} */ - typedef Corrade::Containers::EnumSet BlitMask; + typedef Corrade::Containers::EnumSet BlitMask; /** * @brief Copy block of pixels from read to draw framebuffer @@ -1047,8 +1220,9 @@ class MAGNUM_EXPORT Framebuffer { * mapDefaultForDraw() for binding particular framebuffer for reading * and drawing. If multiple attachments are specified in mapForDraw() * / mapDefaultForDraw(), the data are written to each of them. - * @requires_gl + * @see @fn_gl{BlitFramebuffer} * @requires_gl30 Extension @extension{EXT,framebuffer_blit} + * @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} */ inline static void blit(const Math::Vector2& bottomLeft, const Math::Vector2& topRight, const Math::Vector2& destinationBottomLeft, const Math::Vector2& destinationTopRight, BlitMask blitMask, AbstractTexture::Filter filter) { glBlitFramebuffer(bottomLeft.x(), bottomLeft.y(), topRight.x(), topRight.y(), destinationBottomLeft.x(), destinationBottomLeft.y(), destinationTopRight.x(), destinationTopRight.y(), static_cast(blitMask), static_cast(filter)); @@ -1067,48 +1241,46 @@ class MAGNUM_EXPORT Framebuffer { * no interpolation is needed and thus * AbstractTexture::Filter::NearestNeighbor filtering is used by * default. - * @requires_gl + * @see @fn_gl{BlitFramebuffer} * @requires_gl30 Extension @extension{EXT,framebuffer_blit} + * @requires_gles30 %Extension @es_extension{ANGLE,framebuffer_blit} */ inline static void blit(const Math::Vector2& bottomLeft, const Math::Vector2& topRight, BlitMask blitMask) { glBlitFramebuffer(bottomLeft.x(), bottomLeft.y(), topRight.x(), topRight.y(), bottomLeft.x(), bottomLeft.y(), topRight.x(), topRight.y(), static_cast(blitMask), static_cast(AbstractTexture::Filter::NearestNeighbor)); } - #endif /** * @brief Read block of pixels from framebuffer to image * @param offset Offset in the framebuffer - * @param dimensions %Image dimensions + * @param size %Image size * @param components Color components * @param type Data type * @param image %Image where to put the data * + * @see @fn_gl{ReadPixels} * @requires_gl30 Extension @extension{EXT,framebuffer_object} */ - static void read(const Math::Vector2& offset, const Math::Vector2& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, Image2D* image); + static void read(const Math::Vector2& offset, const Math::Vector2& size, AbstractImage::Components components, AbstractImage::ComponentType type, Image2D* image); - #ifndef MAGNUM_TARGET_GLES /** * @brief Read block of pixels from framebuffer to buffered image * @param offset Offset in the framebuffer - * @param dimensions %Image dimensions + * @param size %Image size * @param components Color components * @param type Data type * @param image Buffered image where to put the data * @param usage %Buffer usage * - * @requires_gl + * @see Buffer::bind(Target), @fn_gl{ReadPixels} * @requires_gl30 Extension @extension{EXT,framebuffer_object} + * @requires_gles30 Pixel buffer objects are not available in OpenGL ES 2.0. */ - static void read(const Math::Vector2& offset, const Math::Vector2& dimensions, AbstractImage::Components components, AbstractImage::ComponentType type, BufferedImage2D* image, Buffer::Usage usage); - #endif + static void read(const Math::Vector2& offset, const Math::Vector2& size, AbstractImage::Components components, AbstractImage::ComponentType type, BufferedImage2D* image, Buffer::Usage usage); /*@}*/ private: - static ClearMask clearMask; - - GLuint framebuffer; + GLuint _id; }; CORRADE_ENUMSET_OPERATORS(Framebuffer::ClearMask) diff --git a/src/Image.cpp b/src/Image.cpp new file mode 100644 index 000000000..637001733 --- /dev/null +++ b/src/Image.cpp @@ -0,0 +1,32 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "Image.h" + +namespace Magnum { + +template void Image::setData(const typename DimensionTraits::VectorType& size, Components components, ComponentType type, GLvoid* data) { + delete[] _data; + _components = components; + _type = type; + _size = size; + _data = reinterpret_cast(data); +} + +template class Image<1>; +template class Image<2>; +template class Image<3>; + +} diff --git a/src/Image.h b/src/Image.h index fd83832a7..8613ebc5c 100644 --- a/src/Image.h +++ b/src/Image.h @@ -19,7 +19,9 @@ * @brief Class Magnum::Image, typedef Magnum::Image1D, Magnum::Image2D, Magnum::Image3D */ +#include "Math/Vector3.h" #include "AbstractImage.h" +#include "DimensionTraits.h" #include "TypeTraits.h" namespace Magnum { @@ -30,14 +32,15 @@ namespace Magnum { Class for storing image data on client memory. Can be replaced with ImageWrapper, BufferedImage, which stores image data in GPU memory, or for example with Trade::ImageData. +@see Image1D, Image2D, Image3D */ -template class Image: public AbstractImage { +template class Image: public AbstractImage { public: - const static size_t Dimensions = imageDimensions; /**< @brief Image dimension count */ + const static std::uint8_t Dimensions = dimensions; /**< @brief %Image dimension count */ /** * @brief Constructor - * @param dimensions %Image dimensions + * @param size %Image size * @param components Color components. Data type is detected * from passed data array. * @param data %Image data with proper size @@ -45,11 +48,11 @@ template class Image: public AbstractImage { * Note that the image data are not copied on construction, but they * are deleted on class destruction. */ - template inline Image(const Math::Vector& dimensions, Components components, T* data): AbstractImage(components, TypeTraits::imageType()), _dimensions(dimensions), _data(data) {} + template inline Image(const typename DimensionTraits::VectorType& size, Components components, T* data): AbstractImage(components, TypeTraits::imageType()), _size(size), _data(data) {} /** * @brief Constructor - * @param dimensions %Image dimensions + * @param size %Image size * @param components Color components * @param type Data type * @param data %Image data @@ -57,7 +60,7 @@ template class Image: public AbstractImage { * Note that the image data are not copied on construction, but they * are deleted on class destruction. */ - inline Image(const Math::Vector& dimensions, Components components, ComponentType type, GLvoid* data): AbstractImage(components, type), _dimensions(dimensions), _data(reinterpret_cast(data)) {} + inline Image(const typename DimensionTraits::VectorType& size, Components components, ComponentType type, GLvoid* data): AbstractImage(components, type), _size(size), _data(reinterpret_cast(data)) {} /** * @brief Constructor @@ -72,16 +75,16 @@ template class Image: public AbstractImage { /** @brief Destructor */ inline ~Image() { delete[] _data; } - /** @brief %Image dimensions */ - inline constexpr const Math::Vector& dimensions() const { return _dimensions; } + /** @brief %Image size */ + inline typename DimensionTraits::VectorType size() const { return _size; } /** @brief Pointer to raw data */ inline void* data() { return _data; } - inline constexpr const void* data() const { return _data; } /**< @overload */ + inline const void* data() const { return _data; } /**< @overload */ /** * @brief Set image data - * @param dimensions %Image dimensions + * @param size %Image size * @param components Color components. Data type is detected * from passed data array. * @param data %Image data @@ -89,13 +92,13 @@ template class Image: public AbstractImage { * Deletes previous data and replaces them with new. Note that the * data are not copied, but they are deleted on destruction. */ - template inline void setData(const Math::Vector& dimensions, Components components, T* data) { - setData(dimensions, components, TypeTraits::imageType(), data); + template inline void setData(const typename DimensionTraits::VectorType& size, Components components, T* data) { + setData(size, components, TypeTraits::imageType(), data); } /** * @brief Set image data - * @param dimensions %Image dimensions + * @param size %Image size * @param components Color components * @param type Data type * @param data %Image data @@ -103,19 +106,19 @@ template class Image: public AbstractImage { * Deletes previous data and replaces them with new. Note that the * data are not copied, but they are deleted on destruction. */ - void setData(const Math::Vector& dimensions, Components components, ComponentType type, GLvoid* data) { - delete[] _data; - _components = components; - _type = type; - _dimensions = dimensions; - _data = reinterpret_cast(data); - } + void setData(const typename DimensionTraits::VectorType& size, Components components, ComponentType type, GLvoid* data); protected: - Math::Vector _dimensions; /**< @brief %Image dimensions */ - char* _data; /**< @brief %Image data */ + Math::Vector _size; /**< @brief %Image size */ + char* _data; /**< @brief %Image data */ }; +#ifndef DOXYGEN_GENERATING_OUTPUT +extern template class MAGNUM_EXPORT Image<1>; +extern template class MAGNUM_EXPORT Image<2>; +extern template class MAGNUM_EXPORT Image<3>; +#endif + /** @brief One-dimensional image */ typedef Image<1> Image1D; diff --git a/src/ImageWrapper.h b/src/ImageWrapper.h index 3a4ca8ce3..68aabd58f 100644 --- a/src/ImageWrapper.h +++ b/src/ImageWrapper.h @@ -19,7 +19,9 @@ * @brief Class Magnum::ImageWrapper */ +#include "Math/Vector3.h" #include "AbstractImage.h" +#include "DimensionTraits.h" #include "TypeTraits.h" namespace Magnum { @@ -38,13 +40,13 @@ to change image properties, only data pointer. See also Image, BufferedImage and Trade::ImageData. */ -template class ImageWrapper: public AbstractImage { +template class ImageWrapper: public AbstractImage { public: - const static size_t Dimensions = imageDimensions; /**< @brief Image dimension count */ + const static std::uint8_t Dimensions = dimensions; /**< @brief %Image dimension count */ /** * @brief Constructor - * @param dimensions %Image dimensions + * @param size %Image size * @param components Color components. Data type is detected * from passed data array. * @param data %Image data with proper size @@ -52,11 +54,11 @@ template class ImageWrapper: public AbstractImage { * Note that the image data are not copied on construction, but they * are deleted on class destruction. */ - template inline ImageWrapper(const Math::Vector& dimensions, Components components, T* data): AbstractImage(components, TypeTraits::imageType()), _dimensions(dimensions), _data(data) {} + template inline ImageWrapper(const typename DimensionTraits::VectorType& size, Components components, T* data): AbstractImage(components, TypeTraits::imageType()), _size(size), _data(data) {} /** * @brief Constructor - * @param dimensions %Image dimensions + * @param size %Image size * @param components Color components * @param type Data type * @param data %Image data @@ -64,25 +66,25 @@ template class ImageWrapper: public AbstractImage { * Note that the image data are not copied on construction, but they * are deleted on class destruction. */ - inline ImageWrapper(const Math::Vector& dimensions, Components components, ComponentType type, GLvoid* data): AbstractImage(components, type), _dimensions(dimensions), _data(reinterpret_cast(data)) {} + inline ImageWrapper(const typename DimensionTraits::VectorType& size, Components components, ComponentType type, GLvoid* data): AbstractImage(components, type), _size(size), _data(reinterpret_cast(data)) {} /** * @brief Constructor - * @param dimensions %Image dimensions + * @param size %Image size * @param components Color components * @param type Data type * * Dimensions and data pointer are set to zero, call setData() to fill * the image with data. */ - inline ImageWrapper(const Math::Vector& dimensions, Components components, ComponentType type): AbstractImage(components, type), _dimensions(dimensions), _data(nullptr) {} + inline ImageWrapper(const typename DimensionTraits::VectorType& size, Components components, ComponentType type): AbstractImage(components, type), _size(size), _data(nullptr) {} - /** @brief %Image dimensions */ - inline constexpr const Math::Vector& dimensions() const { return _dimensions; } + /** @brief %Image size */ + inline typename DimensionTraits::VectorType size() const { return _size; } /** @brief Pointer to raw data */ inline void* data() { return _data; } - inline constexpr const void* data() const { return _data; } /**< @overload */ + inline const void* data() const { return _data; } /**< @overload */ /** * @brief Set image data @@ -92,13 +94,13 @@ template class ImageWrapper: public AbstractImage { * passed in constructor. The data are not copied nor deleted on * destruction. */ - void setData(GLvoid* data) { + inline void setData(GLvoid* data) { _data = reinterpret_cast(data); } protected: - Math::Vector _dimensions; /**< @brief %Image dimensions */ - char* _data; /**< @brief %Image data */ + Math::Vector _size; /**< @brief %Image size */ + char* _data; /**< @brief %Image data */ }; /** @brief One-dimensional image wrapper */ diff --git a/src/Implementation/BufferState.cpp b/src/Implementation/BufferState.cpp new file mode 100644 index 000000000..b8ef09cd4 --- /dev/null +++ b/src/Implementation/BufferState.cpp @@ -0,0 +1,63 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "BufferState.h" + +#include + +namespace Magnum { namespace Implementation { + +const Buffer::Target BufferState::targetForIndex[] = { + Buffer::Target::Array, + Buffer::Target::CopyRead, + Buffer::Target::CopyWrite, + Buffer::Target::ElementArray, + Buffer::Target::PixelPack, + Buffer::Target::PixelUnpack, + Buffer::Target::TransformFeedback, + Buffer::Target::Uniform, + #ifndef MAGNUM_TARGET_GLES + Buffer::Target::AtomicCounter, + Buffer::Target::DispatchIndirect, + Buffer::Target::DrawIndirect, + Buffer::Target::ShaderStorage, + Buffer::Target::Texture + #endif +}; + +std::size_t BufferState::indexForTarget(Buffer::Target target) { + switch(target) { + case Buffer::Target::Array: return 1; + case Buffer::Target::CopyRead: return 2; + case Buffer::Target::CopyWrite: return 3; + case Buffer::Target::ElementArray: return 4; + case Buffer::Target::PixelPack: return 5; + case Buffer::Target::PixelUnpack: return 6; + case Buffer::Target::TransformFeedback: return 7; + case Buffer::Target::Uniform: return 8; + #ifndef MAGNUM_TARGET_GLES + case Buffer::Target::AtomicCounter: return 9; + case Buffer::Target::DispatchIndirect: return 10; + case Buffer::Target::DrawIndirect: return 11; + case Buffer::Target::ShaderStorage: return 12; + case Buffer::Target::Texture: return 13; + #endif + } + + CORRADE_ASSERT(false, "Unknown Buffer target", 0); + return 0; +} + +}} diff --git a/src/Implementation/BufferState.h b/src/Implementation/BufferState.h new file mode 100644 index 000000000..3ea1e551b --- /dev/null +++ b/src/Implementation/BufferState.h @@ -0,0 +1,43 @@ +#ifndef Magnum_Implementation_BufferState_h +#define Magnum_Implementation_BufferState_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "Magnum.h" + +#include "Buffer.h" + +namespace Magnum { namespace Implementation { + +struct BufferState { + #ifndef MAGNUM_TARGET_GLES + static const std::size_t TargetCount = 13+1; + #else + static const std::size_t TargetCount = 8+1; + #endif + + /* Target <-> index mapping */ + static std::size_t indexForTarget(Buffer::Target target); + static const Buffer::Target targetForIndex[TargetCount-1]; + + inline constexpr BufferState(): bindings() {} + + /* Currently bound buffer for all targets */ + GLuint bindings[TargetCount]; +}; + +}} + +#endif diff --git a/src/Implementation/MeshState.h b/src/Implementation/MeshState.h new file mode 100644 index 000000000..1e0b24328 --- /dev/null +++ b/src/Implementation/MeshState.h @@ -0,0 +1,30 @@ +#ifndef Magnum_Implementation_MeshState_h +#define Magnum_Implementation_MeshState_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "Magnum.h" + +namespace Magnum { namespace Implementation { + +struct MeshState { + inline MeshState(): currentVAO(0) {} + + GLuint currentVAO; +}; + +}} + +#endif diff --git a/src/Implementation/ShaderProgramState.h b/src/Implementation/ShaderProgramState.h new file mode 100644 index 000000000..d81af0aca --- /dev/null +++ b/src/Implementation/ShaderProgramState.h @@ -0,0 +1,31 @@ +#ifndef Magnum_Implementation_ShaderProgramState_h +#define Magnum_Implementation_ShaderProgramState_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "Magnum.h" + +namespace Magnum { namespace Implementation { + +struct ShaderProgramState { + inline constexpr ShaderProgramState(): current(0) {} + + /* Currently used program */ + GLuint current; +}; + +}} + +#endif diff --git a/src/Implementation/State.cpp b/src/Implementation/State.cpp new file mode 100644 index 000000000..062a98a8c --- /dev/null +++ b/src/Implementation/State.cpp @@ -0,0 +1,34 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "State.h" + +#include "BufferState.h" +#include "MeshState.h" +#include "ShaderProgramState.h" +#include "TextureState.h" + +namespace Magnum { namespace Implementation { + +State::State(): buffer(new BufferState), mesh(new MeshState), shaderProgram(new ShaderProgramState), texture(new TextureState) {} + +State::~State() { + delete texture; + delete shaderProgram; + delete mesh; + delete buffer; +} + +}} diff --git a/src/Implementation/State.h b/src/Implementation/State.h new file mode 100644 index 000000000..a264247d7 --- /dev/null +++ b/src/Implementation/State.h @@ -0,0 +1,39 @@ +#ifndef Magnum_Implementation_State_h +#define Magnum_Implementation_State_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "Magnum.h" + +namespace Magnum { namespace Implementation { + +struct BufferState; +struct MeshState; +struct ShaderProgramState; +struct TextureState; + +struct State { + State(); + ~State(); + + BufferState* const buffer; + MeshState* const mesh; + ShaderProgramState* const shaderProgram; + TextureState* const texture; +}; + +}} + +#endif diff --git a/src/Implementation/TextureState.h b/src/Implementation/TextureState.h new file mode 100644 index 000000000..73eca32af --- /dev/null +++ b/src/Implementation/TextureState.h @@ -0,0 +1,34 @@ +#ifndef Magnum_Implementation_TextureState_h +#define Magnum_Implementation_TextureState_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "Magnum.h" + +namespace Magnum { namespace Implementation { + +struct TextureState { + inline TextureState(): maxSupportedLayerCount(0), maxSupportedAnisotropy(0.0f), currentLayer(0) {} + + GLint maxSupportedLayerCount; + GLfloat maxSupportedAnisotropy; + GLint currentLayer; + + std::vector bindings; +}; + +}} + +#endif diff --git a/src/IndexedMesh.cpp b/src/IndexedMesh.cpp index 05a9b009a..e91453f74 100644 --- a/src/IndexedMesh.cpp +++ b/src/IndexedMesh.cpp @@ -15,21 +15,25 @@ #include "IndexedMesh.h" +#include + +#include "Buffer.h" +#include "Context.h" +#include "Extensions.h" + namespace Magnum { -void IndexedMesh::draw() { - /* Vertex array must be bound before finalization */ - #ifndef MAGNUM_TARGET_GLES - bind(); - #endif +IndexedMesh::BindIndexBufferImplementation IndexedMesh::bindIndexBufferImplementation = &IndexedMesh::bindIndexBufferImplementationDefault; +IndexedMesh::BindIndexedImplementation IndexedMesh::bindIndexedImplementation = &IndexedMesh::bindIndexedImplementationDefault; - finalize(); +IndexedMesh* IndexedMesh::setIndexBuffer(Buffer* buffer) { + _indexBuffer = buffer; + (this->*bindIndexBufferImplementation)(); + return this; +} - /* Buffers must be bound after initialization */ - #ifdef MAGNUM_TARGET_GLES +void IndexedMesh::draw() { bind(); - _indexBuffer.bind(); - #endif /** @todo Start at given index */ glDrawElements(static_cast(primitive()), _indexCount, static_cast(_indexType), nullptr); @@ -37,20 +41,38 @@ void IndexedMesh::draw() { unbind(); } -#ifndef DOXYGEN_GENERATING_OUTPUT -void IndexedMesh::finalize() { - if(isFinalized()) return; - +void IndexedMesh::bind() { CORRADE_ASSERT(_indexCount, "IndexedMesh: the mesh has zero index count!", ); - /* Finalize attribute positions */ - Mesh::finalize(); + Mesh::bind(); + (this->*bindIndexedImplementation)(); +} - /* Bind index buffer to VAO too */ +void IndexedMesh::initializeContextBasedFunctionality(Context* context) { + /** @todo VAOs are in ES 3.0 and as extension in ES 2.0, enable them when some extension wrangler is available */ #ifndef MAGNUM_TARGET_GLES - _indexBuffer.bind(); + if(context->isExtensionSupported()) { + Debug() << "IndexedMesh: using" << Extensions::GL::APPLE::vertex_array_object::string() << "features"; + + bindIndexBufferImplementation = &IndexedMesh::bindIndexBufferImplementationVAO; + bindIndexedImplementation = &IndexedMesh::bindIndexedImplementationVAO; + } + #else + static_cast(context); #endif } -#endif + +void IndexedMesh::bindIndexBufferImplementationDefault() {} + +void IndexedMesh::bindIndexBufferImplementationVAO() { + bindVAO(vao); + _indexBuffer->bind(Buffer::Target::ElementArray); +} + +void IndexedMesh::bindIndexedImplementationDefault() { + _indexBuffer->bind(Buffer::Target::ElementArray); +} + +void IndexedMesh::bindIndexedImplementationVAO() {} } diff --git a/src/IndexedMesh.h b/src/IndexedMesh.h index 7250357b2..1a0b25e9f 100644 --- a/src/IndexedMesh.h +++ b/src/IndexedMesh.h @@ -20,64 +20,117 @@ */ #include "Mesh.h" -#include "Buffer.h" namespace Magnum { /** - * @brief Indexed mesh - */ +@brief Indexed mesh + +@section IndexedMesh-configuration Indexed mesh configuration + +Next to @ref Mesh-configuration "everything needed for non-indexed mesh" you +have to call also setIndexCount() and setIndexType(). Then create index buffer +and assign it to the mesh using setIndexBuffer() or use +MeshTools::compressIndices() to conveniently fill the index buffer and set +index count and type. + +Similarly as in Mesh itself the index buffer is not managed by the mesh, so +you have to manage it on your own. On the other hand it allows you to use +one index buffer for more meshes (with different vertex data in each mesh, for +example) or store more than only index data in one buffer. + +@section IndexedMesh-drawing Rendering meshes + +From user point-of-view the operation is the same as for +@ref Mesh-drawing "non-indexed meshes". + +@section IndexedMesh-performance-optimization Performance optimizations + +If @extension{APPLE,vertex_array_object} is supported, next to +@ref Mesh-performance-optimization "optimizations in Mesh itself" the index +buffer is bound on object construction instead of in every draw() call. +*/ class MAGNUM_EXPORT IndexedMesh: public Mesh { + friend class Context; + public: /** - * @brief Implicit constructor + * @brief Constructor * @param primitive Primitive type * - * Allows creating the object without knowing anything about mesh data. - * Note that you have to call setVertexCount(), setIndexCount() and - * setIndexType() manually for mesh to draw properly. + * Creates indexed mesh with no index buffer, zero vertex count and + * zero index count. + * @see setPrimitive(), setVertexCount(), setIndexBuffer(), + * setIndexCount(), setIndexType() */ - inline IndexedMesh(Primitive primitive = Primitive::Triangles): Mesh(primitive), _indexBuffer(Buffer::Target::ElementArray), _indexCount(0), _indexType(Type::UnsignedShort) {} + inline IndexedMesh(Primitive primitive = Primitive::Triangles): Mesh(primitive), _indexBuffer(nullptr), _indexCount(0), _indexType(Type::UnsignedShort) {} /** - * @brief Constructor - * @param primitive Primitive type - * @param vertexCount Count of unique vertices - * @param indexCount Count of indices - * @param indexType Type of indices (indexable, see TypeTraits) + * @brief Set index buffer + * + * @see MeshTools::compressIndices(), @fn_gl{BindVertexArray}, + * @fn_gl{BindBuffer} (if @extension{APPLE,vertex_array_object} + * is available) */ - inline IndexedMesh(Primitive primitive, GLsizei vertexCount, GLsizei indexCount, Type indexType = Type::UnsignedShort): Mesh(primitive, vertexCount), _indexBuffer(Buffer::Target::ElementArray), _indexCount(indexCount), _indexType(indexType) {} + IndexedMesh* setIndexBuffer(Buffer* buffer); /** @brief Index count */ inline GLsizei indexCount() const { return _indexCount; } - /** @brief Set index count */ - /** @todo definalize after that? */ - inline void setIndexCount(GLsizei count) { _indexCount = count; } + /** + * @brief Set index count + * @return Pointer to self (for method chaining) + * + * @see MeshTools::compressIndices() + */ + inline IndexedMesh* setIndexCount(GLsizei count) { + _indexCount = count; + return this; + } /** @brief Index type */ inline Type indexType() const { return _indexType; } - /** @brief Set index type */ - inline void setIndexType(Type type) { _indexType = type; } - /** - * @brief Index buffer + * @brief Set index type + * @return Pointer to self (for method chaining) * - * Returns pointer to index buffer, which should be then filled with - * indices (of type specified in constructor). + * @see MeshTools::compressIndices() */ - inline Buffer* indexBuffer() { return &_indexBuffer; } + inline IndexedMesh* setIndexType(Type type) { + _indexType = type; + return this; + } + /** + * @brief Draw the mesh + * + * Expects an active shader with all uniforms set. See + * @ref AbstractShaderProgram-rendering-workflow "AbstractShaderProgram documentation" + * for more information. + * @see @fn_gl{EnableVertexAttribArray}, @fn_gl{BindBuffer}, + * @fn_gl{VertexAttribPointer}, @fn_gl{DisableVertexAttribArray} + * or @fn_gl{BindVertexArray} (if @extension{APPLE,vertex_array_object} + * is available), @fn_gl{DrawElements} + */ void draw(); - protected: - #ifndef DOXYGEN_GENERATING_OUTPUT - MAGNUM_LOCAL void finalize(); - #endif - private: - Buffer _indexBuffer; + static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context); + + void MAGNUM_LOCAL bind(); + + typedef void(IndexedMesh::*BindIndexBufferImplementation)(); + void MAGNUM_LOCAL bindIndexBufferImplementationDefault(); + void MAGNUM_LOCAL bindIndexBufferImplementationVAO(); + static MAGNUM_LOCAL BindIndexBufferImplementation bindIndexBufferImplementation; + + typedef void(IndexedMesh::*BindIndexedImplementation)(); + void MAGNUM_LOCAL bindIndexedImplementationDefault(); + void MAGNUM_LOCAL bindIndexedImplementationVAO(); + static MAGNUM_LOCAL BindIndexedImplementation bindIndexedImplementation; + + Buffer* _indexBuffer; GLsizei _indexCount; Type _indexType; }; diff --git a/src/Magnum.h b/src/Magnum.h index 630b962c7..9300082ee 100644 --- a/src/Magnum.h +++ b/src/Magnum.h @@ -23,15 +23,41 @@ #ifndef MAGNUM_TARGET_GLES #include +#include #else -#include +#include #endif -#include "Math/Math.h" -#include "Math/Matrix4.h" -#include "Math/Vector2.h" +/** + * @todo Link to libGL / libGLES based on which windowcontext is used in app + * and whether GLES is enabled or not -- this allows us to use glx with + * ES on nvidia/intel. Using libGL and EGL on nvidia is whole another + * problem, though. How about windows? It won't allow unlinked DLLs, so + * probably always link Magnum itself to GL library there. How about unit + * tests not needing any of GL? -- different testing library? + */ + +namespace Corrade { + namespace Utility { + class Debug; + class Warning; + class Error; + } +} namespace Magnum { + namespace Math { + template class Vector2; + template class Vector3; + template class Vector4; + template class Point2D; + template class Point3D; + template class Matrix3; + template class Matrix4; + + template constexpr T deg(T value); + template constexpr T rad(T value); + } /* Bring debugging facility from Corrade::Utility namespace */ using Corrade::Utility::Debug; @@ -47,6 +73,12 @@ typedef Math::Vector3 Vector3; /** @brief Four-component floating-point vector */ typedef Math::Vector4 Vector4; +/** @brief Two-dimensional floating-point homogeneous coordinates */ +typedef Math::Point2D Point2D; + +/** @brief Three-dimensional floating-point homogeneous coordinates */ +typedef Math::Point3D Point3D; + /** @brief 3x3 floating-point matrix */ typedef Math::Matrix3 Matrix3; diff --git a/src/Math/Algorithms/GaussJordan.h b/src/Math/Algorithms/GaussJordan.h index d98bf89c8..2778fa5c2 100644 --- a/src/Math/Algorithms/GaussJordan.h +++ b/src/Math/Algorithms/GaussJordan.h @@ -16,7 +16,7 @@ */ /** @file - * @brief Class GaussJordan + * @brief Class Magnum::Math::Algorithms::GaussJordan */ #include "Math/RectangularMatrix.h" @@ -48,7 +48,7 @@ class GaussJordan { * and the final backsubstitution is done only on @p t, as @p a would * always end with identity matrix anyway. */ - template static bool inPlaceTransposed(RectangularMatrix& a, RectangularMatrix& t); + template static bool inPlaceTransposed(RectangularMatrix& a, RectangularMatrix& t); /** * @brief Eliminate in place @@ -56,7 +56,7 @@ class GaussJordan { * Transposes the matrices, calls inPlaceTransposed() on them and then * transposes them back. */ - template static bool inPlace(RectangularMatrix& a, RectangularMatrix& t) { + template static bool inPlace(RectangularMatrix& a, RectangularMatrix& t) { a = a.transposed(); RectangularMatrix tTransposed = t.transposed(); @@ -69,11 +69,11 @@ class GaussJordan { } }; -template bool GaussJordan::inPlaceTransposed(RectangularMatrix& a, RectangularMatrix& t) { - for(size_t row = 0; row != size; ++row) { +template bool GaussJordan::inPlaceTransposed(RectangularMatrix& a, RectangularMatrix& t) { + for(std::size_t row = 0; row != size; ++row) { /* Find max pivot */ - size_t rowMax = row; - for(size_t row2 = row+1; row2 != size; ++row2) + std::size_t rowMax = row; + for(std::size_t row2 = row+1; row2 != size; ++row2) if(std::abs(a(row2, row)) > std::abs(a(rowMax, row))) rowMax = row2; @@ -86,7 +86,7 @@ template bool GaussJordan::inPlaceTransposed( return false; /* Eliminate column */ - for(size_t row2 = row+1; row2 != size; ++row2) { + for(std::size_t row2 = row+1; row2 != size; ++row2) { T c = a(row2, row)/a(row, row); a[row2] -= a[row]*c; @@ -95,10 +95,10 @@ template bool GaussJordan::inPlaceTransposed( } /* Backsubstitute */ - for(size_t row = size; row != 0; --row) { + for(std::size_t row = size; row != 0; --row) { T c = T(1)/a(row-1, row-1); - for(size_t row2 = 0; row2 != row-1; ++row2) + for(std::size_t row2 = 0; row2 != row-1; ++row2) t[row2] -= t[row-1]*a(row2, row-1)*c; /* Normalize the row */ diff --git a/src/Math/CMakeLists.txt b/src/Math/CMakeLists.txt index cf24e5d0b..a92da34c4 100644 --- a/src/Math/CMakeLists.txt +++ b/src/Math/CMakeLists.txt @@ -1,11 +1,14 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}) set(MagnumMath_HEADERS + Constants.h Math.h MathTypeTraits.h Matrix.h Matrix3.h Matrix4.h + Point2D.h + Point3D.h RectangularMatrix.h Vector.h Vector2.h diff --git a/src/Math/Constants.h b/src/Math/Constants.h new file mode 100644 index 000000000..a4c8a50e5 --- /dev/null +++ b/src/Math/Constants.h @@ -0,0 +1,79 @@ +#ifndef Magnum_Math_Constants_h +#define Magnum_Math_Constants_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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. +*/ + +/** @file + * @brief Class Magnum::Math::Constants, functions Magnum::Math::deg(), Magnum::Math::rad() + */ + +namespace Magnum { namespace Math { + +/** +@brief Numeric constants + +@internal See MathTypeTraits class for implementation notes. +*/ +template struct Constants { + #ifdef DOXYGEN_GENERATING_OUTPUT + /** + * @brief Pi + * + * @see deg(), rad() + */ + static inline constexpr T pi(); + + static inline constexpr T sqrt2(); /**< @brief Square root of 2 */ + static inline constexpr T sqrt3(); /**< @brief Square root of 3 */ + #endif +}; + +#ifndef DOXYGEN_GENERATING_OUTPUT +template<> struct Constants { + static inline constexpr double pi() { return 3.141592653589793; } + static inline constexpr double sqrt2() { return 1.414213562373095; } + static inline constexpr double sqrt3() { return 1.732050807568877; } +}; +template<> struct Constants { + static inline constexpr float pi() { return 3.141592654f; } + static inline constexpr float sqrt2() { return 1.414213562f; } + static inline constexpr float sqrt3() { return 1.732050808f; } +}; +#endif + +/** +@brief Angle in degrees + +Function to make angle entering less error-prone. Converts the value to +radians at compile time. For example `deg(180.0f)` is converted to `3.14f`. + +Usable for entering e.g. rotation: +@code +Matrix4::rotation(deg(30.0f), Vector3::yAxis()); +@endcode +@see Constants, rad() + */ +template inline constexpr T deg(T value) { return value*Constants::pi()/180; } + +/** + * @brief Angle in radians + * + * See deg() for more information. + */ +template inline constexpr T rad(T value) { return value; } + +}} + +#endif diff --git a/src/Math/Geometry/Distance.h b/src/Math/Geometry/Distance.h index 143ab8784..9073520a8 100644 --- a/src/Math/Geometry/Distance.h +++ b/src/Math/Geometry/Distance.h @@ -19,6 +19,8 @@ * @brief Class Magnum::Math::Geometry::Distance */ +#include "Math/Math.h" +#include "Math/Matrix.h" #include "Math/Vector3.h" namespace Magnum { namespace Math { namespace Geometry { @@ -27,36 +29,68 @@ namespace Magnum { namespace Math { namespace Geometry { class Distance { public: /** - * @brief %Distance of line and point + * @brief %Distance of line and point in 2D * @param a First point of the line * @param b Second point of the line * @param point Point * * The distance *d* is computed from point **p** and line defined by **a** - * and **b** using @ref Vector3::cross() "cross product": - * @f[ + * and **b** using @ref Matrix::determinant() "determinant": @f[ + * d = \frac{|det(b - a a - point)|} {|b - a|} + * @f] + * Source: http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html + * @see linePointSquared(const Vector2&, const Vector2&, const Vector2&) + */ + template inline static T linePoint(const Vector2& a, const Vector2& b, const Vector2& point) { + return std::abs(Matrix<2, T>::from(b - a, a - point).determinant())/(b - a).length(); + } + + /** + * @brief %Distance of line and point in 2D, squared + * @param a First point of the line + * @param b Second point of the line + * @param point Point + * + * More efficient than linePoint(const Vector2&, const Vector2&, const Vector2&) + * for comparing distance with other values, because it doesn't + * compute the square root. + */ + template inline static T linePointSquared(const Vector2& a, const Vector2& b, const Vector2& point) { + Vector2 bMinusA = b - a; + return Math::pow<2>(Matrix<2, T>::from(bMinusA, a - point).determinant())/bMinusA.dot(); + } + + /** + * @brief %Distance of line and point in 3D + * @param a First point of the line + * @param b Second point of the line + * @param point Point + * + * The distance *d* is computed from point **p** and line defined by **a** + * and **b** using @ref Vector3::cross() "cross product": @f[ * d = \frac{|(\boldsymbol p - \boldsymbol a) \times (\boldsymbol p - \boldsymbol b)|} * {|\boldsymbol b - \boldsymbol a|} * @f] - * - * @see linePointSquared() + * Source: http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html + * @see linePointSquared(const Vector3&, const Vector3&, const Vector3&) */ template inline static T linePoint(const Vector3& a, const Vector3& b, const Vector3& point) { - return sqrt(linePointSquared(a, b, point)); + return std::sqrt(linePointSquared(a, b, point)); } /** - * @brief %Distance of line and point, squared + * @brief %Distance of line and point in 3D, squared * - * More efficient than linePoint() for comparing distance with other - * values, because it doesn't compute the square root. + * More efficient than linePoint(const Vector3&, const Vector3&, const Vector3&) + * for comparing distance with other values, because it doesn't + * compute the square root. */ template static T linePointSquared(const Vector3& a, const Vector3& b, const Vector3& point) { return Vector3::cross(point - a, point - b).dot()/(b - a).dot(); } /** - * @brief %Dístance of point from line segment + * @brief %Dístance of point from line segment in 2D * @param a Starting point of the line * @param b Ending point of the line * @param point Point @@ -66,34 +100,88 @@ class Distance { * * Determining whether the point lies next to line segment or outside * is done using Pythagorean theorem. If the following equation - * applies, the point **p** lies outside line segment closer to **a**: - * @f[ + * applies, the point **p** lies outside line segment closer to **a**: @f[ * |\boldsymbol p - \boldsymbol b|^2 > |\boldsymbol b - \boldsymbol a|^2 + |\boldsymbol p - \boldsymbol a|^2 * @f] * On the other hand, if the following equation applies, the point - * lies outside line segment closer to **b**: - * @f[ + * lies outside line segment closer to **b**: @f[ * |\boldsymbol p - \boldsymbol a|^2 > |\boldsymbol b - \boldsymbol a|^2 + |\boldsymbol p - \boldsymbol b|^2 * @f] * The last alternative is when the following equation applies. The * point then lies between **a** and **b** and the distance is - * computed the same way as in linePoint(). - * @f[ + * computed the same way as in linePoint(). @f[ * |\boldsymbol b - \boldsymbol a|^2 > |\boldsymbol p - \boldsymbol a|^2 + |\boldsymbol p - \boldsymbol b|^2 * @f] * * @see lineSegmentPointSquared() */ - template inline static T lineSegmentPoint(const Vector3& a, const Vector3& b, const Vector3& point) { - return sqrt(lineSegmentPointSquared(a, b, point)); + template inline static T lineSegmentPoint(const Vector2& a, const Vector2& b, const Vector2& point) { + Vector2 pointMinusA = point - a; + Vector2 pointMinusB = point - b; + Vector2 bMinusA = b - a; + T pointDistanceA = pointMinusA.dot(); + T pointDistanceB = pointMinusB.dot(); + T bDistanceA = bMinusA.dot(); + + /* Point is before A */ + if(pointDistanceB > bDistanceA + pointDistanceA) + return std::sqrt(pointDistanceA); + + /* Point is after B */ + if(pointDistanceA > bDistanceA + pointDistanceB) + return std::sqrt(pointDistanceB); + + /* Between A and B */ + return std::abs(Matrix<2, T>::from(bMinusA, -pointMinusA).determinant())/std::sqrt(bDistanceA); } /** - * @brief %Distance of point from line segment, squared + * @brief %Distance of point from line segment in 2D, squared * * More efficient than lineSegmentPoint() for comparing distance with * other values, because it doesn't compute the square root. */ + template static T lineSegmentPointSquared(const Vector2& a, const Vector2& b, const Vector2& point) { + Vector2 pointMinusA = point - a; + Vector2 pointMinusB = point - b; + Vector2 bMinusA = b - a; + T pointDistanceA = pointMinusA.dot(); + T pointDistanceB = pointMinusB.dot(); + T bDistanceA = bMinusA.dot(); + + /* Point is before A */ + if(pointDistanceB > bDistanceA + pointDistanceA) + return pointDistanceA; + + /* Point is after B */ + if(pointDistanceA > bDistanceA + pointDistanceB) + return pointDistanceB; + + /* Between A and B */ + return Math::pow<2>(Matrix<2, T>::from(bMinusA, -pointMinusA).determinant())/bDistanceA; + } + + /** + * @brief %Dístance of point from line segment in 3D + * @param a Starting point of the line + * @param b Ending point of the line + * @param point Point + * + * Similar to 2D implementation + * lineSegmentPoint(const Vector2&, const Vector2&, const Vector2&). + * + * @see lineSegmentPointSquared(const Vector3&, const Vector3&, const Vector3&) + */ + template inline static T lineSegmentPoint(const Vector3& a, const Vector3& b, const Vector3& point) { + return std::sqrt(lineSegmentPointSquared(a, b, point)); + } + + /** + * @brief %Distance of point from line segment in 3D, squared + * + * More efficient than lineSegmentPoint(const Vector3&, const Vector3&, const Vector3&) for comparing distance with + * other values, because it doesn't compute the square root. + */ template static T lineSegmentPointSquared(const Vector3& a, const Vector3& b, const Vector3& point) { Vector3 pointMinusA = point - a; Vector3 pointMinusB = point - b; diff --git a/src/Math/Geometry/Intersection.h b/src/Math/Geometry/Intersection.h index b4cee3f72..6eeba75bc 100644 --- a/src/Math/Geometry/Intersection.h +++ b/src/Math/Geometry/Intersection.h @@ -39,14 +39,12 @@ class Intersection { * is inside the line segment defined by `a` and `b`. * * First the parameter *f* of parametric equation of the plane - * is computed from plane normal **n** and plane position: - * @f[ + * is computed from plane normal **n** and plane position: @f[ * \begin{pmatrix} n_0 \\ n_1 \\ n_2 \end{pmatrix} \cdot * \begin{pmatrix} x \\ y \\ z \end{pmatrix} - f = 0 * @f] * Using plane normal **n**, parameter *f* and points **a** and **b**, - * value of *t* is computed and returned. - * @f[ + * value of *t* is computed and returned. @f[ * \begin{array}{rcl} * \Delta \boldsymbol b & = & \boldsymbol b - \boldsymbol a \\ * f & = & \boldsymbol n \cdot (\boldsymbol a + \Delta \boldsymbol b \cdot t) \\ diff --git a/src/Math/Geometry/Test/DistanceTest.cpp b/src/Math/Geometry/Test/DistanceTest.cpp index 5f14c0aa4..ace9c485a 100644 --- a/src/Math/Geometry/Test/DistanceTest.cpp +++ b/src/Math/Geometry/Test/DistanceTest.cpp @@ -17,7 +17,7 @@ #include -#include "Math.h" +#include "Constants.h" #include "Distance.h" CORRADE_TEST_MAIN(Magnum::Math::Geometry::Test::DistanceTest) @@ -26,14 +26,35 @@ using namespace std; namespace Magnum { namespace Math { namespace Geometry { namespace Test { +typedef Magnum::Math::Vector2 Vector2; typedef Magnum::Math::Vector3 Vector3; DistanceTest::DistanceTest() { - addTests(&DistanceTest::linePoint, - &DistanceTest::lineSegmentPoint); + addTests(&DistanceTest::linePoint2D, + &DistanceTest::linePoint3D, + &DistanceTest::lineSegmentPoint2D, + &DistanceTest::lineSegmentPoint3D); } -void DistanceTest::linePoint() { +void DistanceTest::linePoint2D() { + Vector2 a(0.0f); + Vector2 b(1.0f); + + /* Point on the line */ + CORRADE_COMPARE((Distance::linePoint(a, b, Vector2(0.25f))), 0.0f); + + /* The distance should be the same for all equidistant points */ + CORRADE_COMPARE((Distance::linePoint(a, b, Vector2(1.0f, 0.0f))), + 1.0f/Constants::sqrt2()); + CORRADE_COMPARE((Distance::linePoint(a, b, Vector2(1.0f, 0.0f)+Vector2(100.0f))), + 1.0f/Constants::sqrt2()); + + /* Be sure that *Squared() works the same, as it has slightly different implementation */ + CORRADE_COMPARE((Distance::linePointSquared(a, b, Vector2(1.0f, 0.0f))), + 0.5f); +} + +void DistanceTest::linePoint3D() { Vector3 a(0.0f); Vector3 b(1.0f); @@ -47,7 +68,38 @@ void DistanceTest::linePoint() { Constants::sqrt2()/Constants::sqrt3()); } -void DistanceTest::lineSegmentPoint() { +void DistanceTest::lineSegmentPoint2D() { + Vector2 a(0.0f); + Vector2 b(1.0f); + + /* Point on the line segment */ + CORRADE_COMPARE((Distance::lineSegmentPoint(a, b, Vector2(0.25f))), 0.0f); + + /* Point on the line, outside the segment, closer to A */ + CORRADE_COMPARE((Distance::lineSegmentPoint(a, b, Vector2(-1.0f))), Constants::sqrt2()); + /* Be sure that *Squared() works the same, as it has slightly different implementation */ + CORRADE_COMPARE((Distance::lineSegmentPointSquared(a, b, Vector2(-1.0f))), 2.0f); + + /* Point on the line, outside the segment, closer to B */ + CORRADE_COMPARE((Distance::lineSegmentPoint(a, b, Vector2(1.0f+1.0f/Constants::sqrt2()))), 1.0f); + CORRADE_COMPARE((Distance::lineSegmentPointSquared(a, b, Vector2(1.0f+1.0f/Constants::sqrt2()))), 1.0f); + + /* Point next to the line segment */ + CORRADE_COMPARE((Distance::lineSegmentPoint(a, b, Vector2(1.0f, 0.0f))), + 1.0f/Constants::sqrt2()); + CORRADE_COMPARE((Distance::lineSegmentPointSquared(a, b, Vector2(1.0f, 0.0f))), + 0.5f); + + /* Point outside the line segment, closer to A */ + CORRADE_COMPARE((Distance::lineSegmentPoint(a, b, Vector2(1.0f, 0.0f)-Vector2(1.0f, 0.5f))), 0.5f); + CORRADE_COMPARE((Distance::lineSegmentPointSquared(a, b, Vector2(1.0f, 0.0f)-Vector2(1.0f, 0.5f))), 0.25f); + + /* Point outside the line segment, closer to B */ + CORRADE_COMPARE((Distance::lineSegmentPoint(a, b, Vector2(1.0f, 0.0f)+Vector2(0.5f, 1.0f))), 0.5f); + CORRADE_COMPARE((Distance::lineSegmentPointSquared(a, b, Vector2(1.0f, 0.0f)+Vector2(0.5f, 1.0f))), 0.25f); +} + +void DistanceTest::lineSegmentPoint3D() { Vector3 a(0.0f); Vector3 b(1.0f); diff --git a/src/Math/Geometry/Test/DistanceTest.h b/src/Math/Geometry/Test/DistanceTest.h index 0cae07036..dc7c7bc88 100644 --- a/src/Math/Geometry/Test/DistanceTest.h +++ b/src/Math/Geometry/Test/DistanceTest.h @@ -23,8 +23,10 @@ class DistanceTest: public Corrade::TestSuite::Tester { public: DistanceTest(); - void linePoint(); - void lineSegmentPoint(); + void linePoint2D(); + void linePoint3D(); + void lineSegmentPoint2D(); + void lineSegmentPoint3D(); }; }}}} diff --git a/src/Math/Math.cpp b/src/Math/Math.cpp index 5c2560a21..ec39d403d 100644 --- a/src/Math/Math.cpp +++ b/src/Math/Math.cpp @@ -15,10 +15,12 @@ #include "Math.h" +using namespace std; + namespace Magnum { namespace Math { -size_t log(size_t base, size_t number) { - size_t log = 0; +std::uint32_t log(std::uint32_t base, std::uint32_t number) { + uint32_t log = 0; while(number /= base) ++log; return log; diff --git a/src/Math/Math.h b/src/Math/Math.h index f5f718ae4..014f895ff 100644 --- a/src/Math/Math.h +++ b/src/Math/Math.h @@ -15,7 +15,6 @@ GNU Lesser General Public License version 3 for more details. */ -#include #include #include #include @@ -25,7 +24,7 @@ #include "magnumVisibility.h" /** @file - * @brief Math constants and utilities + * @brief Math utilities */ namespace Magnum { namespace Math { @@ -37,33 +36,9 @@ namespace Magnum { namespace Math { matrices) */ -/** -@brief Numeric constants - -@internal See MathTypeTraits class for implementation notes. -*/ -template struct Constants { - #ifdef DOXYGEN_GENERATING_OUTPUT - static inline constexpr T pi(); /**< @brief Pi */ - static inline constexpr T sqrt2(); /**< @brief Square root of 2 */ - static inline constexpr T sqrt3(); /**< @brief Square root of 3 */ - #endif -}; - #ifndef DOXYGEN_GENERATING_OUTPUT -template<> struct Constants { - static inline constexpr double pi() { return 3.141592653589793; } - static inline constexpr double sqrt2() { return 1.414213562373095; } - static inline constexpr double sqrt3() { return 1.732050807568877; } -}; -template<> struct Constants { - static inline constexpr float pi() { return 3.141592654f; } - static inline constexpr float sqrt2() { return 1.414213562f; } - static inline constexpr float sqrt3() { return 1.732050808f; } -}; - namespace Implementation { - template struct Pow { + template struct Pow { template inline constexpr T operator()(T base) const { return base*Pow()(base); } @@ -79,7 +54,7 @@ namespace Implementation { * * Returns integral power of base to the exponent. */ -template inline constexpr T pow(T base) { +template inline constexpr T pow(T base) { return Implementation::Pow()(base); } @@ -88,7 +63,7 @@ template inline constexpr T pow(T base) { * * Returns integral logarithm of given number with given base. */ -size_t MAGNUM_EXPORT log(size_t base, size_t number); +std::uint32_t MAGNUM_EXPORT log(std::uint32_t base, std::uint32_t number); /** @brief Normalize floating-point value @@ -100,11 +75,11 @@ type to value in range @f$ [0, 1] @f$. literals, this function should be called with both template parameters explicit, e.g.: @code -// Even if this is char literal, integral type is `int`, thus a = 0.1f +// Even if this is character literal, integral type is 32bit, thus a != 1.0f float a = normalize('\127'); // b = 1.0f -float b = normalize('\127'); +float b = normalize('\127'); @endcode @todo Signed normalization to [-1.0, 1.0] like in OpenGL? @@ -121,9 +96,12 @@ Converts floating-point value in range @f$ [0, 1] @f$ to full range of given integral type. @note For best precision, `FloatingPoint` type should be always larger that -resulting `Integral` type (e.g. `double` to `int`, `long double` to `long long`). +resulting `Integral` type (e.g. `double` to `std::int32_t`, `long double` to +`std::int64_t`). @todo Signed normalization to [-1.0, 1.0] like in OpenGL? +@todo Stable behavior (working/broken) for long double and long long + (currently fails in Debug builds, but passes in Release on GCC 4.7) */ template inline constexpr typename std::enable_if::value && std::is_integral::value, Integral>::type denormalize(FloatingPoint value) { return std::numeric_limits::min() + @@ -136,27 +114,6 @@ template inline T clamp(T value, T min, T max) { return std::min(std::max(value, min), max); } -/** -@brief Angle in degrees - -Function to make angle entering less error-prone. Converts the value to -radians at compile time. For example `deg(180.0f)` is converted to `3.14f`. - -Usable for entering e.g. rotation: -@code -Matrix4::rotation(deg(30.0f), Vector3::yAxis()); -@endcode -@see rad() - */ -template inline constexpr T deg(T value) { return value*Constants::pi()/180; } - -/** - * @brief Angle in radians - * - * See deg() for more information. - */ -template inline constexpr T rad(T value) { return value; } - }} #endif diff --git a/src/Math/MathTypeTraits.h b/src/Math/MathTypeTraits.h index 1c2385c7d..6799989da 100644 --- a/src/Math/MathTypeTraits.h +++ b/src/Math/MathTypeTraits.h @@ -19,7 +19,7 @@ * @brief Class Magnum::Math::MathTypeTraits */ -#include +#include #include #include "magnumCompatibility.h" @@ -55,7 +55,7 @@ support given feature, thus forcing the compilation stop with an error. template struct MathTypeTraits { #ifdef DOXYGEN_GENERATING_OUTPUT /** - * @brief Corresponding numeric type large at least as `int` + * @brief Corresponding numeric type large at least as 32bit integer * * Usable e.g. to prevent conversion of `char` to characters when printing * numeric types to output. @@ -114,67 +114,63 @@ template struct MathTypeTraitsFloatingPoint { } }; -template struct MathTypeTraitsLong {}; +template struct MathTypeTraitsLong {}; -template<> struct MathTypeTraitsLong { - typedef unsigned int UnsignedType; - typedef int Type; +template<> struct MathTypeTraitsLong<4> { + typedef std::uint32_t UnsignedType; + typedef std::int32_t Type; }; -template<> struct MathTypeTraitsLong { - typedef unsigned long long UnsignedType; - typedef long long Type; +template<> struct MathTypeTraitsLong<8> { + typedef std::uint64_t UnsignedType; + typedef std::int64_t Type; }; } -template<> struct MathTypeTraits: public Implementation::MathTypeTraitsIntegral { - typedef unsigned int NumericType; +template<> struct MathTypeTraits: Implementation::MathTypeTraitsIntegral { + typedef std::uint32_t NumericType; typedef float FloatingPointType; }; -template<> struct MathTypeTraits: public Implementation::MathTypeTraitsIntegral { - typedef int NumericType; +template<> struct MathTypeTraits: Implementation::MathTypeTraitsIntegral { + typedef std::int32_t NumericType; typedef float FloatingPointType; }; -template<> struct MathTypeTraits: public Implementation::MathTypeTraitsIntegral { - typedef unsigned int NumericType; +template<> struct MathTypeTraits: Implementation::MathTypeTraitsIntegral { + typedef std::uint32_t NumericType; typedef float FloatingPointType; }; -template<> struct MathTypeTraits: public Implementation::MathTypeTraitsIntegral { - typedef int NumericType; +template<> struct MathTypeTraits: Implementation::MathTypeTraitsIntegral { + typedef std::int32_t NumericType; typedef float FloatingPointType; }; -template<> struct MathTypeTraits: public Implementation::MathTypeTraitsIntegral { - typedef unsigned int NumericType; +template<> struct MathTypeTraits: Implementation::MathTypeTraitsIntegral { + typedef std::uint32_t NumericType; typedef double FloatingPointType; }; -template<> struct MathTypeTraits: public Implementation::MathTypeTraitsIntegral { - typedef int NumericType; +template<> struct MathTypeTraits: Implementation::MathTypeTraitsIntegral { + typedef std::int32_t NumericType; typedef double FloatingPointType; }; -template<> struct MathTypeTraits: public Implementation::MathTypeTraitsIntegral { - typedef unsigned long long NumericType; +template<> struct MathTypeTraits: Implementation::MathTypeTraitsIntegral { + typedef std::uint64_t NumericType; typedef long double FloatingPointType; }; -template<> struct MathTypeTraits: public Implementation::MathTypeTraitsIntegral { - typedef long long NumericType; +template<> struct MathTypeTraits: Implementation::MathTypeTraitsIntegral { + typedef std::int64_t NumericType; typedef long double FloatingPointType; }; -/* long is 32 bits somewhere and 64 bits elsewhere */ -template<> struct MathTypeTraits: public Implementation::MathTypeTraitsIntegral::Type> {}; -template<> struct MathTypeTraits: public Implementation::MathTypeTraitsIntegral::Type> {}; - -template<> struct MathTypeTraits: public Implementation::MathTypeTraitsFloatingPoint { +template<> struct MathTypeTraits: Implementation::MathTypeTraitsFloatingPoint { typedef float NumericType; typedef float FloatingPointType; inline constexpr static float epsilon() { return FLOAT_EQUALITY_PRECISION; } }; -template<> struct MathTypeTraits: public Implementation::MathTypeTraitsFloatingPoint { +template<> struct MathTypeTraits: Implementation::MathTypeTraitsFloatingPoint { typedef float NumericType; typedef double FloatingPointType; diff --git a/src/Math/Matrix.h b/src/Math/Matrix.h index 2273ce3b1..2f882cc2f 100644 --- a/src/Math/Matrix.h +++ b/src/Math/Matrix.h @@ -25,21 +25,22 @@ namespace Magnum { namespace Math { #ifndef DOXYGEN_GENERATING_OUTPUT namespace Implementation { - template class MatrixDeterminant; + template class MatrixDeterminant; } #endif /** @brief Square matrix -@tparam s %Matrix size +@tparam size %Matrix size +@tparam T Data type + +See @ref matrix-vector for brief introduction. @configurationvalueref{Magnum::Math::Matrix} -@todo @c PERFORMANCE - loop unrolling for Matrix<3, T> and Matrix<4, T> -@todo first col, then row (cache adjacency) */ -template class Matrix: public RectangularMatrix { +template class Matrix: public RectangularMatrix { public: - const static size_t size = s; /**< @brief %Matrix size */ + const static std::size_t Size = size; /**< @brief %Matrix size */ /** @brief Pass to constructor to create zero-filled matrix */ enum ZeroType { Zero }; @@ -61,12 +62,12 @@ template class Matrix: public RectangularMatrix { * `Matrix m(Matrix::Identity);`. Optional parameter @p value allows * you to specify value on diagonal. */ - inline explicit Matrix(IdentityType = Identity, T value = T(1)) { - for(size_t i = 0; i != size; ++i) + inline Matrix(IdentityType = Identity, T value = T(1)) { + for(std::size_t i = 0; i != size; ++i) (*this)(i, i) = value; } - /** @copydoc RectangularMatrix::RectangularMatrix(T, U...) */ + /** @copydoc RectangularMatrix::RectangularMatrix */ #ifndef DOXYGEN_GENERATING_OUTPUT template inline constexpr Matrix(T first, U... next): RectangularMatrix(first, next...) {} #else @@ -91,18 +92,18 @@ template class Matrix: public RectangularMatrix { T trace() const { T out(0); - for(size_t i = 0; i != size; ++i) + for(std::size_t i = 0; i != size; ++i) out += (*this)(i, i); return out; } /** @brief %Matrix without given column and row */ - Matrix ij(size_t skipCol, size_t skipRow) const { + Matrix ij(std::size_t skipCol, std::size_t skipRow) const { Matrix out(Matrix::Zero); - for(size_t row = 0; row != size-1; ++row) - for(size_t col = 0; col != size-1; ++col) + for(std::size_t col = 0; col != size-1; ++col) + for(std::size_t row = 0; row != size-1; ++row) out(col, row) = (*this)(col + (col >= skipCol), row + (row >= skipRow)); @@ -112,15 +113,12 @@ template class Matrix: public RectangularMatrix { /** * @brief Determinant * - * Computed recursively using Laplace's formula: - * @f[ - * \det(A) = \sum_{j=1}^n (-1)^{i+j} a_{i,j} \det(A^{i,j}) - * @f] - * @f$ A^{i, j} @f$ is matrix without i-th row and j-th column, see + * Computed recursively using Laplace's formula: @f[ + * \det(A) = \sum_{j=1}^n (-1)^{i+j} a_{i,j} \det(A^{i,j}) + * @f] @f$ A^{i, j} @f$ is matrix without i-th row and j-th column, see * ij(). The formula is expanded down to 2x2 matrix, where the - * determinant is computed directly: - * @f[ - * \det(A) = a_{0, 0} a_{1, 1} - a_{1, 0} a_{0, 1} + * determinant is computed directly: @f[ + * \det(A) = a_{0, 0} a_{1, 1} - a_{1, 0} a_{0, 1} * @f] */ inline T determinant() const { return Implementation::MatrixDeterminant()(*this); } @@ -128,9 +126,8 @@ template class Matrix: public RectangularMatrix { /** * @brief Inverted matrix * - * Computed using Cramer's rule: - * @f[ - * A^{-1} = \frac{1}{\det(A)} Adj(A) + * Computed using Cramer's rule: @f[ + * A^{-1} = \frac{1}{\det(A)} Adj(A) * @f] */ Matrix inverted() const { @@ -138,8 +135,8 @@ template class Matrix: public RectangularMatrix { T _determinant = determinant(); - for(size_t row = 0; row != size; ++row) - for(size_t col = 0; col != size; ++col) + for(std::size_t col = 0; col != size; ++col) + for(std::size_t row = 0; row != size; ++row) out(col, row) = (((row+col) & 1) ? -1 : 1)*ij(row, col).determinant()/_determinant; return out; @@ -150,7 +147,7 @@ template class Matrix: public RectangularMatrix { inline Matrix operator*(const Matrix& other) const { return RectangularMatrix::operator*(other); } - template inline RectangularMatrix operator*(const RectangularMatrix& other) const { + template inline RectangularMatrix operator*(const RectangularMatrix& other) const { return RectangularMatrix::operator*(other); } inline Vector operator*(const Vector& other) const { @@ -162,17 +159,17 @@ template class Matrix: public RectangularMatrix { }; #ifndef DOXYGEN_GENERATING_OUTPUT -template inline typename std::enable_if::value, Matrix>::type operator*(U number, const Matrix& matrix) { +template inline typename std::enable_if::value, Matrix>::type operator*(U number, const Matrix& matrix) { return number*RectangularMatrix(matrix); } -template inline typename std::enable_if::value, Matrix>::type operator/(U number, const Matrix& matrix) { +template inline typename std::enable_if::value, Matrix>::type operator/(U number, const Matrix& matrix) { return number/RectangularMatrix(matrix); } #endif /** @debugoperator{Magnum::Math::Matrix} */ -template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Magnum::Math::Matrix& value) { - return debug << static_cast&>(value); +template inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Matrix& value) { + return debug << static_cast&>(value); } #ifndef DOXYGEN_GENERATING_OUTPUT @@ -192,10 +189,10 @@ template Corrade::Utility::Debug operator<<(Corrade::Utili return *this; \ } \ \ - inline VectorType& operator[](size_t col) { \ + inline VectorType& operator[](std::size_t col) { \ return VectorType::from(Matrix::data()+col*size); \ } \ - inline constexpr const VectorType& operator[](size_t col) const { \ + inline constexpr const VectorType& operator[](std::size_t col) const { \ return VectorType::from(Matrix::data()+col*size); \ } \ \ @@ -206,7 +203,7 @@ template Corrade::Utility::Debug operator<<(Corrade::Utili Matrix::operator*=(other); \ return *this; \ } \ - template inline RectangularMatrix operator*(const RectangularMatrix& other) const { \ + template inline RectangularMatrix operator*(const RectangularMatrix& other) const { \ return Matrix::operator*(other); \ } \ inline VectorType operator*(const Vector& other) const { \ @@ -226,13 +223,12 @@ template Corrade::Utility::Debug operator<<(Corrade::Utili namespace Implementation { -template class MatrixDeterminant { +template class MatrixDeterminant { public: - /** @brief Functor */ T operator()(const Matrix& m) { T out(0); - for(size_t col = 0; col != size; ++col) + for(std::size_t col = 0; col != size; ++col) out += ((col & 1) ? -1 : 1)*m(col, 0)*m.ij(col, 0).determinant(); return out; @@ -241,7 +237,6 @@ template class MatrixDeterminant { template class MatrixDeterminant<2, T> { public: - /** @brief Functor */ inline constexpr T operator()(const Matrix<2, T>& m) { return m(0, 0)*m(1, 1) - m(1, 0)*m(0, 1); } @@ -249,7 +244,6 @@ template class MatrixDeterminant<2, T> { template class MatrixDeterminant<1, T> { public: - /** @brief Functor */ inline constexpr T operator()(const Matrix<1, T>& m) { return m(0, 0); } @@ -262,7 +256,7 @@ template class MatrixDeterminant<1, T> { namespace Corrade { namespace Utility { /** @configurationvalue{Magnum::Math::Matrix} */ - template struct ConfigurationValue>: public ConfigurationValue> {}; + template struct ConfigurationValue>: public ConfigurationValue> {}; }} #endif diff --git a/src/Math/Matrix3.h b/src/Math/Matrix3.h index e537de58a..9d0ec0223 100644 --- a/src/Math/Matrix3.h +++ b/src/Math/Matrix3.h @@ -20,57 +20,64 @@ */ #include "Matrix.h" -#include "Vector3.h" +#include "Point2D.h" namespace Magnum { namespace Math { /** -@brief 3x3 matrix +@brief 3x3 matrix for affine transformations in 2D +@tparam T Data type -Provides functions for transformations in 2D. See also Matrix4 for 3D -transformations. +Provides functions for transformations in 2D. See Matrix4 for 3D +transformations. See also @ref matrix-vector for brief introduction. @configurationvalueref{Magnum::Math::Matrix3} */ template class Matrix3: public Matrix<3, T> { public: /** * @brief 2D translation matrix - * @param vec Translation vector + * @param vector Translation vector * - * @see Matrix4::translation(), Vector2::xAxis(), Vector2::yAxis() + * @see translation(), Matrix4::translation(const Vector3&), + * Vector2::xAxis(), Vector2::yAxis() */ - inline constexpr static Matrix3 translation(const Vector2& vec) { + inline constexpr static Matrix3 translation(const Vector2& vector) { return Matrix3( /* Column-major! */ T(1), T(0), T(0), T(0), T(1), T(0), - vec.x(), vec.y(), T(1) + vector.x(), vector.y(), T(1) ); } /** * @brief 2D scaling matrix - * @param vec Scaling vector + * @param vector Scaling vector * - * @see Matrix4::scaling(), Vector2::xScale(), Vector2::yScale() + * @see rotationScaling() const, Matrix4::scaling(const Vector3&), + * Vector2::xScale(), Vector2::yScale() */ - inline constexpr static Matrix3 scaling(const Vector2& vec) { + inline constexpr static Matrix3 scaling(const Vector2& vector) { return Matrix3( /* Column-major! */ - vec.x(), T(0), T(0), - T(0), vec.y(), T(0), + vector.x(), T(0), T(0), + T(0), vector.y(), T(0), T(0), T(0), T(1) ); } /** - * @brief 3D rotation matrix - * @param angle Rotation angle (counterclockwise, in radians) + * @brief 2D rotation matrix + * @param angle Rotation angle (counterclockwise, in radians) * - * @see Matrix4::rotation(), deg(), rad() + * @see rotation() const, Matrix4::rotation(T, const Vector3&), deg(), + * rad() */ static Matrix3 rotation(T angle) { + T sine = std::sin(angle); + T cosine = std::cos(angle); + return Matrix3( /* Column-major! */ - T(cos(angle)), T(sin(angle)), T(0), - -T(sin(angle)), T(cos(angle)), T(0), + cosine, sine, T(0), + -sine, cosine, T(0), T(0), T(0), T(1) ); } @@ -79,13 +86,13 @@ template class Matrix3: public Matrix<3, T> { inline constexpr explicit Matrix3(typename Matrix<3, T>::ZeroType): Matrix<3, T>(Matrix<3, T>::Zero) {} /** @copydoc Matrix::Matrix(IdentityType, T) */ - inline constexpr explicit Matrix3(typename Matrix<3, T>::IdentityType = (Matrix<3, T>::Identity), T value = T(1)): Matrix<3, T>( + inline constexpr Matrix3(typename Matrix<3, T>::IdentityType = (Matrix<3, T>::Identity), T value = T(1)): Matrix<3, T>( value, T(0), T(0), T(0), value, T(0), T(0), T(0), value ) {} - /** @copydoc Matrix::Matrix(T, U...) */ + /** @copydoc Matrix::Matrix */ #ifndef DOXYGEN_GENERATING_OUTPUT template inline constexpr Matrix3(T first, U... next): Matrix<3, T>(first, next...) {} #else @@ -95,13 +102,60 @@ template class Matrix3: public Matrix<3, T> { /** @brief Copy constructor */ inline constexpr Matrix3(const RectangularMatrix<3, 3, T>& other): Matrix<3, T>(other) {} + /** + * @brief 2D rotation and scaling part of the matrix + * + * Upper-left 2x2 part of the matrix. + * @see rotation() const, rotation(T), Matrix4::rotationScaling() const + */ + inline Matrix<2, T> rotationScaling() const { + return Matrix<2, T>::from( + (*this)[0].xy(), + (*this)[1].xy()); + } + + /** + * @brief 2D rotation part of the matrix + * + * Normalized upper-left 2x2 part of the matrix. + * @see rotationScaling() const, rotation(T), Matrix4::rotation() const + */ + inline Matrix<2, T> rotation() const { + return Matrix<2, T>::from( + (*this)[0].xy().normalized(), + (*this)[1].xy().normalized()); + } + + /** + * @brief 2D translation part of the matrix + * + * First two elements of last column. + * @see translation(const Vector2&), Matrix4::translation() + */ + inline Vector2& translation() { + return (*this)[2].xy(); + } + + /** @overload */ + inline constexpr Vector2 translation() const { + return (*this)[2].xy(); + } + + /** @todo up(), right() */ + + #ifndef DOXYGEN_GENERATING_OUTPUT + inline Point2D operator*(const Point2D& other) const { + return Matrix<3, T>::operator*(other); + } + #endif + MAGNUM_MATRIX_SUBCLASS_IMPLEMENTATION(Matrix3, Vector3, 3) MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(3, 3, Matrix3) }; /** @debugoperator{Magnum::Math::Matrix3} */ -template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Magnum::Math::Matrix3& value) { - return debug << static_cast&>(value); +template inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Matrix3& value) { + return debug << static_cast&>(value); } }} diff --git a/src/Math/Matrix4.h b/src/Math/Matrix4.h index 58b67c4fa..3b904a5cd 100644 --- a/src/Math/Matrix4.h +++ b/src/Math/Matrix4.h @@ -19,16 +19,17 @@ * @brief Class Magnum::Math::Matrix4 */ -#include "Matrix3.h" -#include "Vector4.h" +#include "Matrix.h" +#include "Point3D.h" namespace Magnum { namespace Math { /** -@brief 4x4 matrix +@brief 4x4 matrix for affine transformations in 3D +@tparam T Data type -Provides functions for transformations in 3D. See also Matrix3 for 2D -transformations. +Provides functions for transformations in 3D. See Matrix3 for 2D +transformations. See also @ref matrix-vector for brief introduction. @configurationvalueref{Magnum::Math::Matrix4} @todo Shearing @todo Reflection @@ -36,86 +37,153 @@ transformations. template class Matrix4: public Matrix<4, T> { public: /** - * @brief 3D translation matrix - * @param vec Translation vector + * @brief 3D translation + * @param vector Translation vector * - * @see Matrix3::translation(), Vector3::xAxis(), Vector3::yAxis(), Vector3::zAxis() + * @see translation(), Matrix3::translation(const Vector2&), + * Vector3::xAxis(), Vector3::yAxis(), Vector3::zAxis() */ - inline constexpr static Matrix4 translation(const Vector3& vec) { + inline constexpr static Matrix4 translation(const Vector3& vector) { return Matrix4( /* Column-major! */ T(1), T(0), T(0), T(0), T(0), T(1), T(0), T(0), T(0), T(0), T(1), T(0), - vec.x(), vec.y(), vec.z(), T(1) + vector.x(), vector.y(), vector.z(), T(1) ); } /** - * @brief 3D scaling matrix - * @param vec Scaling vector + * @brief 3D scaling + * @param vector Scaling vector * - * @see Matrix3::scaling(), Vector3::xScale(), Vector3::yScale(), Vector3::zScale() + * @see rotationScaling() const, Matrix3::scaling(const Vector2&), + * Vector3::xScale(), Vector3::yScale(), Vector3::zScale() */ - inline constexpr static Matrix4 scaling(const Vector3& vec) { + inline constexpr static Matrix4 scaling(const Vector3& vector) { return Matrix4( /* Column-major! */ - vec.x(), T(0), T(0), T(0), - T(0), vec.y(), T(0), T(0), - T(0), T(0), vec.z(), T(0), + vector.x(), T(0), T(0), T(0), + T(0), vector.y(), T(0), T(0), + T(0), T(0), vector.z(), T(0), T(0), T(0), T(0), T(1) ); } /** - * @brief 3D rotation matrix - * @param angle Rotation angle (counterclockwise, in radians) - * @param vec Rotation vector + * @brief 3D rotation around arbitrary axis + * @param angle Rotation angle (counterclockwise, in radians) + * @param normalizedAxis Normalized rotation axis * - * @see Matrix3::rotation(), Vector3::xAxis(), Vector3::yAxis(), Vector3::zAxis(), deg(), rad() - * @todo optimize - Assume the vectors are normalized? + * If possible, use faster alternatives like rotationX(), rotationY() + * and rotationZ(). + * @see rotation() const, Matrix3::rotation(T), Vector3::xAxis(), + * Vector3::yAxis(), Vector3::zAxis(), deg(), rad() + * @attention Assertion fails on non-normalized rotation vector and + * identity matrix is returned. */ - static Matrix4 rotation(T angle, const Vector3& vec) { - Vector3 vn = vec.normalized(); + static Matrix4 rotation(T angle, const Vector3& normalizedAxis) { + CORRADE_ASSERT(MathTypeTraits::equals(normalizedAxis.dot(), T(1)), + "Math::Matrix4::rotation(): axis must be normalized", {}); T sine = std::sin(angle); T cosine = std::cos(angle); T oneMinusCosine = T(1) - cosine; - T xx = vn.x()*vn.x(); - T xy = vn.x()*vn.y(); - T xz = vn.x()*vn.z(); - T yy = vn.y()*vn.y(); - T yz = vn.y()*vn.z(); - T zz = vn.z()*vn.z(); + T xx = normalizedAxis.x()*normalizedAxis.x(); + T xy = normalizedAxis.x()*normalizedAxis.y(); + T xz = normalizedAxis.x()*normalizedAxis.z(); + T yy = normalizedAxis.y()*normalizedAxis.y(); + T yz = normalizedAxis.y()*normalizedAxis.z(); + T zz = normalizedAxis.z()*normalizedAxis.z(); return Matrix4( /* Column-major! */ cosine + xx*oneMinusCosine, - xy*oneMinusCosine + vn.z()*sine, - xz*oneMinusCosine - vn.y()*sine, + xy*oneMinusCosine + normalizedAxis.z()*sine, + xz*oneMinusCosine - normalizedAxis.y()*sine, T(0), - xy*oneMinusCosine - vn.z()*sine, + xy*oneMinusCosine - normalizedAxis.z()*sine, cosine + yy*oneMinusCosine, - yz*oneMinusCosine + vn.x()*sine, + yz*oneMinusCosine + normalizedAxis.x()*sine, T(0), - xz*oneMinusCosine + vn.y()*sine, - yz*oneMinusCosine - vn.x()*sine, + xz*oneMinusCosine + normalizedAxis.y()*sine, + yz*oneMinusCosine - normalizedAxis.x()*sine, cosine + zz*oneMinusCosine, T(0), T(0), T(0), T(0), T(1) ); } + /** + * @brief 3D rotation around X axis + * @param angle Rotation angle (counterclockwise, in radians) + * + * Faster than calling `Matrix4::rotation(angle, Vector3::xAxis())`. + * @see rotation(T, const Vector3&), rotationY(), rotationZ(), + * rotation() const, Matrix3::rotation(T), deg(), rad() + */ + static Matrix4 rotationX(T angle) { + T sine = std::sin(angle); + T cosine = std::cos(angle); + + return Matrix4( /* Column-major! */ + T(1), T(0), T(0), T(0), + T(0), cosine, sine, T(0), + T(0), -sine, cosine, T(0), + T(0), T(0), T(0), T(1) + ); + } + + /** + * @brief 3D rotation around Y axis + * @param angle Rotation angle (counterclockwise, in radians) + * + * Faster than calling `Matrix4::rotation(angle, Vector3::yAxis())`. + * @see rotation(T, const Vector3&), rotationX(), rotationZ(), + * rotation() const, Matrix3::rotation(T), deg(), rad() + */ + static Matrix4 rotationY(T angle) { + T sine = std::sin(angle); + T cosine = std::cos(angle); + + return Matrix4( /* Column-major! */ + cosine, T(0), -sine, T(0), + T(0), T(1), T(0), T(0), + sine, T(0), cosine, T(0), + T(0), T(0), T(0), T(1) + ); + } + + /** + * @brief 3D rotation matrix around Z axis + * @param angle Rotation angle (counterclockwise, in radians) + * + * Faster than calling `Matrix4::rotation(angle, Vector3::zAxis())`. + * @see rotation(T, const Vector3&), rotationX(), rotationY(), + * rotation() const, Matrix3::rotation(T), deg(), rad() + */ + static Matrix4 rotationZ(T angle) { + T sine = std::sin(angle); + T cosine = std::cos(angle); + + return Matrix4( /* Column-major! */ + cosine, sine, T(0), T(0), + -sine, cosine, T(0), T(0), + T(0), T(0), T(1), T(0), + T(0), T(0), T(0), T(1) + ); + } + /** @copydoc Matrix::Matrix(ZeroType) */ inline constexpr explicit Matrix4(typename Matrix<4, T>::ZeroType): Matrix<4, T>(Matrix<4, T>::Zero) {} /** @copydoc Matrix::Matrix(IdentityType, T) */ - inline constexpr explicit Matrix4(typename Matrix<4, T>::IdentityType = (Matrix<4, T>::Identity), T value = T(1)): Matrix<4, T>( + inline constexpr Matrix4(typename Matrix<4, T>::IdentityType = (Matrix<4, T>::Identity), T value = T(1)): Matrix<4, T>( value, T(0), T(0), T(0), T(0), value, T(0), T(0), T(0), T(0), value, T(0), T(0), T(0), T(0), value ) {} - /** @copydoc Matrix::Matrix(T, U...) */ + /** @copydoc Matrix::Matrix */ #ifndef DOXYGEN_GENERATING_OUTPUT template inline constexpr Matrix4(T first, U... next): Matrix<4, T>(first, next...) {} #else @@ -125,27 +193,38 @@ template class Matrix4: public Matrix<4, T> { /** @brief Copy constructor */ inline constexpr Matrix4(const RectangularMatrix<4, 4, T>& other): Matrix<4, T>(other) {} - /** @copydoc Matrix::ij() */ - inline Matrix3 ij(size_t skipRow, size_t skipCol) const { return Matrix<4, T>::ij(skipRow, skipCol); } - - /** @brief Rotation and scaling part of the matrix */ - inline Matrix3 rotationScaling() const { + /** + * @brief 3D rotation and scaling part of the matrix + * + * Upper-left 3x3 part of the matrix. + * @see rotation() const, rotation(T, const Vector3&), + * Matrix3::rotationScaling() const + */ + inline Matrix<3, T> rotationScaling() const { + /* Not Matrix3, because it is for affine 2D transformations */ #ifndef CORRADE_GCC45_COMPATIBILITY /* GCC 4.5 badly optimizes this */ - return Matrix3::from( + return Matrix<3, T>::from( (*this)[0].xyz(), (*this)[1].xyz(), (*this)[2].xyz()); #else - return Matrix3( + return Matrix<3, T>( (*this)(0, 0), (*this)(0, 1), (*this)(0, 2), (*this)(1, 0), (*this)(1, 1), (*this)(1, 2), (*this)(2, 0), (*this)(2, 1), (*this)(2, 2)); #endif } - /** @brief Rotation part of the matrix */ - inline Matrix3 rotation() const { - return Matrix3::from( + /** + * @brief 3D rotation part of the matrix + * + * Normalized upper-left 3x3 part of the matrix. + * @see rotationScaling() const, rotation(T, const Vector3&), + * Matrix3::rotation() const + */ + inline Matrix<3, T> rotation() const { + /* Not Matrix3, because it is for affine 2D transformations */ + return Matrix<3, T>::from( #ifndef CORRADE_GCC45_COMPATIBILITY /* GCC 4.5 badly optimizes this */ (*this)[0].xyz().normalized(), (*this)[1].xyz().normalized(), @@ -157,13 +236,36 @@ template class Matrix4: public Matrix<4, T> { #endif } + /** + * @brief 3D translation part of the matrix + * + * First three elements of last column. + * @see translation(const Vector3&), Matrix3::translation() + */ + inline Vector3& translation() { + return (*this)[3].xyz(); + } + + /** @overload */ + inline constexpr Vector3 translation() const { + return (*this)[3].xyz(); + } + + /** @todo up(), forward(), right() */ + + #ifndef DOXYGEN_GENERATING_OUTPUT + inline Point3D operator*(const Point3D& other) const { + return Matrix<4, T>::operator*(other); + } + #endif + MAGNUM_MATRIX_SUBCLASS_IMPLEMENTATION(Matrix4, Vector4, 4) MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(4, 4, Matrix4) }; /** @debugoperator{Magnum::Math::Matrix4} */ -template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Magnum::Math::Matrix4& value) { - return debug << static_cast&>(value); +template inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Matrix4& value) { + return debug << static_cast&>(value); } }} diff --git a/src/Math/Point2D.h b/src/Math/Point2D.h new file mode 100644 index 000000000..76a775b89 --- /dev/null +++ b/src/Math/Point2D.h @@ -0,0 +1,89 @@ +#ifndef Magnum_Math_Point2D_h +#define Magnum_Math_Point2D_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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. +*/ + +/** @file + * @brief Class Magnum::Math::Point2D + */ + +#include "Vector3.h" + +namespace Magnum { namespace Math { + +/** +@brief Two-dimensional homogeneous coordinates +@tparam T Data type + +Same as Vector3, except that constructors have default value for Z component +set to one. See also @ref matrix-vector for brief introduction. +@see Point3D +@configurationvalueref{Magnum::Math::Point2D} +*/ +template class Point2D: public Vector3 { + public: + /** + * @brief Default constructor + * + * X and Y components are set to zero, Z is set to one. + */ + inline constexpr Point2D(): Vector3(T(0), T(0), T(1)) {} + + /** @brief Copy constructor */ + inline constexpr Point2D(const RectangularMatrix<1, 3, T>& other): Vector3(other) {} + + /** + * @brief Constructor + * @param x X component + * @param y Y component + * @param z Z component + */ + inline constexpr Point2D(T x, T y, T z = T(1)): Vector3(x, y, z) {} + + /** + * @brief Constructor + * @param xy Two-component vector + * @param z Z component + */ + inline constexpr Point2D(const Vector2& xy, T z = T(1)): Vector3(xy, z) {} + + /** + * @brief Vector part of the point + * + * Equivalent to calling xy(). Useful for seamless 2D/3D integration. + * @see Point3D::vector() + */ + inline Vector2& vector() { return Vector3::xy(); } + inline constexpr Vector2 vector() const { return Vector3::xy(); } /**< @overload */ + + MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(Point2D, 3) + MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(1, 3, Point2D) +}; + +MAGNUM_VECTOR_SUBCLASS_OPERATOR_IMPLEMENTATION(Point2D, 3) + +/** @debugoperator{Magnum::Math::Point2D} */ +template inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Point2D& value) { + return debug << static_cast&>(value); +} + +}} + +namespace Corrade { namespace Utility { + /** @configurationvalue{Magnum::Math::Point2D} */ + template struct ConfigurationValue>: public ConfigurationValue> {}; +}} + +#endif diff --git a/src/Math/Point3D.h b/src/Math/Point3D.h new file mode 100644 index 000000000..432ea5c0d --- /dev/null +++ b/src/Math/Point3D.h @@ -0,0 +1,90 @@ +#ifndef Magnum_Math_Point3D_h +#define Magnum_Math_Point3D_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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. +*/ + +/** @file + * @brief Class Magnum::Math::Point3D + */ + +#include "Vector4.h" + +namespace Magnum { namespace Math { + +/** +@brief Three-dimensional homogeneous coordinates +@tparam T Data type + +Same as Vector4, except that constructors have default value for W component +set to one. See also @ref matrix-vector for brief introduction. +@see Point2D +@configurationvalueref{Magnum::Math::Point3D} +*/ +template class Point3D: public Vector4 { + public: + /** + * @brief Default constructor + * + * X, Y and Z components are set to zero, W is set to one. + */ + inline constexpr Point3D(): Vector4(T(0), T(0), T(0), T(1)) {} + + /** @brief Copy constructor */ + inline constexpr Point3D(const RectangularMatrix<1, 4, T>& other): Vector4(other) {} + + /** + * @brief Constructor + * @param x X component + * @param y Y component + * @param z Z component + * @param w W component + */ + inline constexpr Point3D(T x, T y, T z, T w = T(1)): Vector4(x, y, z, w) {} + + /** + * @brief Constructor + * @param xyz Three-component vector + * @param w W component + */ + inline constexpr Point3D(const Vector3& xyz, T w = T(1)): Vector4(xyz, w) {} + + /** + * @brief Vector part of the point + * + * Equivalent to calling xyz(). Useful for seamless 2D/3D integration. + * @see Point2D::vector() + */ + inline Vector3& vector() { return Vector4::xyz(); } + inline constexpr Vector3 vector() const { return Vector4::xyz(); } /**< @overload */ + + MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(Point3D, 4) + MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(1, 4, Point3D) +}; + +MAGNUM_VECTOR_SUBCLASS_OPERATOR_IMPLEMENTATION(Point3D, 4) + +/** @debugoperator{Magnum::Math::Point3D} */ +template inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Point3D& value) { + return debug << static_cast&>(value); +} + +}} + +namespace Corrade { namespace Utility { + /** @configurationvalue{Magnum::Math::Point3D} */ + template struct ConfigurationValue>: public ConfigurationValue> {}; +}} + +#endif diff --git a/src/Math/RectangularMatrix.h b/src/Math/RectangularMatrix.h index 6c52764a8..8d917e19b 100644 --- a/src/Math/RectangularMatrix.h +++ b/src/Math/RectangularMatrix.h @@ -28,38 +28,47 @@ namespace Magnum { namespace Math { +/** @todo Properly test all constexpr */ + +template class RectangularMatrix; + #ifndef DOXYGEN_GENERATING_OUTPUT namespace Implementation { - template struct Sequence {}; + template struct Sequence {}; /* E.g. GenerateSequence<3>::Type is Sequence<0, 1, 2> */ - template struct GenerateSequence: + template struct GenerateSequence: GenerateSequence {}; - template struct GenerateSequence<0, sequence...> { + template struct GenerateSequence<0, sequence...> { typedef Sequence Type; }; + + /* Implementation for RectangularMatrix::from(const RectangularMatrix&) */ + template inline constexpr Math::RectangularMatrix rectangularMatrixFrom(Sequence, const Math::RectangularMatrix& matrix) { + return {T(matrix.data()[sequence])...}; + } } #endif -template class Vector; +template class Vector; /** @brief Rectangular matrix -@tparam c Column count -@tparam r Row count +@tparam cols Column count +@tparam rows Row count +@tparam T Data type -See also Matrix (square) and Vector. +See @ref matrix-vector for brief introduction. See also Matrix (square) and +Vector. */ -template class RectangularMatrix { - static_assert(c != 0 && r != 0, "Matrix cannot have zero elements"); - - friend class Vector; +template class RectangularMatrix { + static_assert(cols != 0 && rows != 0, "Matrix cannot have zero elements"); public: - typedef T Type; /**< @brief Data type */ - const static size_t cols = c; /**< @brief %Matrix column count */ - const static size_t rows = r; /**< @brief %Matrix row count */ + typedef T Type; /**< @brief Data type */ + const static std::size_t Cols = cols; /**< @brief %Matrix column count */ + const static std::size_t Rows = rows; /**< @brief %Matrix row count */ /** * @brief %Matrix from array @@ -81,12 +90,29 @@ template class RectangularMatrix { * @brief %Matrix from column vectors * @param first First column vector * @param next Next column vectors + * + * @todo Creating matrix from arbitrary combination of matrices with n rows */ template inline constexpr static RectangularMatrix from(const Vector& first, const U&... next) { static_assert(sizeof...(next)+1 == cols, "Improper number of arguments passed to Matrix from Vector constructor"); return from(typename Implementation::GenerateSequence::Type(), first, next...); } + /** + * @brief %Matrix from another of different type + * + * Performs only default casting on the values, no rounding or + * anything else. Example usage: + * @code + * RectangularMatrix<4, 1, float> floatingPoint(1.3f, 2.7f, -15.0f, 7.0f); + * RectangularMatrix<4, 1, std::int8_t> integral(RectangularMatrix<4, 1, std::int8_t>::from(floatingPoint)); + * // integral == {1, 2, -15, 7} + * @endcode + */ + template inline constexpr static RectangularMatrix from(const RectangularMatrix& other) { + return Implementation::rectangularMatrixFrom(typename Implementation::GenerateSequence::Type(), other); + } + /** @brief Zero-filled matrix constructor */ inline constexpr RectangularMatrix(): _data() {} @@ -107,10 +133,10 @@ template class RectangularMatrix { #endif /** @brief Copy constructor */ - inline constexpr RectangularMatrix(const RectangularMatrix&) = default; + inline constexpr RectangularMatrix(const RectangularMatrix&) = default; /** @brief Assignment operator */ - inline RectangularMatrix& operator=(const RectangularMatrix&) = default; + inline RectangularMatrix& operator=(const RectangularMatrix&) = default; /** * @brief Raw data @@ -126,11 +152,11 @@ template class RectangularMatrix { * For accessing individual elements prefer to use operator(), as it * is guaranteed to not involve unnecessary conversions. */ - inline Vector& operator[](size_t col) { + inline Vector& operator[](std::size_t col) { return Vector::from(_data+col*rows); } /** @overload */ - inline constexpr const Vector& operator[](size_t col) const { + inline constexpr const Vector& operator[](std::size_t col) const { return Vector::from(_data+col*rows); } @@ -140,17 +166,17 @@ template class RectangularMatrix { * Prefer this instead of using `[][]`. * @see operator[] */ - inline T& operator()(size_t col, size_t row) { + inline T& operator()(std::size_t col, std::size_t row) { return _data[col*rows+row]; } /** @overload */ - inline constexpr const T& operator()(size_t col, size_t row) const { + inline constexpr const T& operator()(std::size_t col, std::size_t row) const { return _data[col*rows+row]; } /** @brief Equality operator */ inline bool operator==(const RectangularMatrix& other) const { - for(size_t i = 0; i != cols*rows; ++i) + for(std::size_t i = 0; i != cols*rows; ++i) if(!MathTypeTraits::equals(_data[i], other._data[i])) return false; return true; @@ -177,7 +203,7 @@ template class RectangularMatrix { * in-place. */ RectangularMatrix& operator+=(const RectangularMatrix& other) { - for(size_t i = 0; i != cols*rows; ++i) + for(std::size_t i = 0; i != cols*rows; ++i) _data[i] += other._data[i]; return *this; @@ -187,7 +213,7 @@ template class RectangularMatrix { RectangularMatrix operator-() const { RectangularMatrix out; - for(size_t i = 0; i != cols*rows; ++i) + for(std::size_t i = 0; i != cols*rows; ++i) out._data[i] = -_data[i]; return out; @@ -209,7 +235,7 @@ template class RectangularMatrix { * in-place. */ RectangularMatrix& operator-=(const RectangularMatrix& other) { - for(size_t i = 0; i != cols*rows; ++i) + for(std::size_t i = 0; i != cols*rows; ++i) _data[i] -= other._data[i]; return *this; @@ -239,7 +265,7 @@ template class RectangularMatrix { #else template RectangularMatrix& operator*=(U number) { #endif - for(size_t i = 0; i != cols*rows; ++i) + for(std::size_t i = 0; i != cols*rows; ++i) _data[i] *= number; return *this; @@ -269,19 +295,19 @@ template class RectangularMatrix { #else template RectangularMatrix& operator/=(U number) { #endif - for(size_t i = 0; i != cols*rows; ++i) + for(std::size_t i = 0; i != cols*rows; ++i) _data[i] /= number; return *this; } /** @brief Multiply matrix */ - template RectangularMatrix operator*(const RectangularMatrix& other) const { + template RectangularMatrix operator*(const RectangularMatrix& other) const { RectangularMatrix out; - for(size_t row = 0; row != rows; ++row) - for(size_t col = 0; col != size; ++col) /** @todo swap */ - for(size_t pos = 0; pos != cols; ++pos) + for(std::size_t col = 0; col != size; ++col) + for(std::size_t row = 0; row != rows; ++row) + for(std::size_t pos = 0; pos != cols; ++pos) out(col, row) += (*this)(pos, row)*other(col, pos); return out; @@ -301,22 +327,25 @@ template class RectangularMatrix { RectangularMatrix transposed() const { RectangularMatrix out; - for(size_t col = 0; col != cols; ++col) - for(size_t row = 0; row != rows; ++row) + for(std::size_t col = 0; col != cols; ++col) + for(std::size_t row = 0; row != rows; ++row) out(row, col) = (*this)(col, row); return out; } + #ifndef DOXYGEN_GENERATING_OUTPUT + protected: + T _data[rows*cols]; + #endif + private: - template inline constexpr static RectangularMatrix from(Implementation::Sequence s, const Vector& first, U... next) { + template inline constexpr static RectangularMatrix from(Implementation::Sequence s, const Vector& first, U... next) { return from(s, next..., first[sequence]...); } - template inline constexpr static RectangularMatrix from(Implementation::Sequence, T first, U... next) { + template inline constexpr static RectangularMatrix from(Implementation::Sequence, T first, U... next) { return RectangularMatrix(first, next...); } - - T _data[rows*cols]; }; /** @relates RectangularMatrix @@ -325,9 +354,9 @@ template class RectangularMatrix { @see RectangularMatrix::operator*(U) const */ #ifndef DOXYGEN_GENERATING_OUTPUT -template inline typename std::enable_if::value, RectangularMatrix>::type operator*(U number, const RectangularMatrix& matrix) { +template inline typename std::enable_if::value, RectangularMatrix>::type operator*(U number, const RectangularMatrix& matrix) { #else -template inline RectangularMatrix operator*(U number, const RectangularMatrix& matrix) { +template inline RectangularMatrix operator*(U number, const RectangularMatrix& matrix) { #endif return matrix*number; } @@ -343,25 +372,25 @@ RectangularMatrix<2, 3, float> another = 1.0f/mat; // {1.0f, 0.5f, -0.25f, 0.128 @see RectangularMatrix::operator/() */ #ifndef DOXYGEN_GENERATING_OUTPUT -template typename std::enable_if::value, RectangularMatrix>::type operator/(U number, const RectangularMatrix& matrix) { +template typename std::enable_if::value, RectangularMatrix>::type operator/(U number, const RectangularMatrix& matrix) { #else -template RectangularMatrix operator/(U number, const RectangularMatrix& matrix) { +template RectangularMatrix operator/(U number, const RectangularMatrix& matrix) { #endif RectangularMatrix out; - for(size_t i = 0; i != cols*rows; ++i) + for(std::size_t i = 0; i != cols*rows; ++i) out.data()[i] = number/matrix.data()[i]; return out; } /** @debugoperator{Magnum::Math::RectangularMatrix} */ -template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Magnum::Math::RectangularMatrix& value) { +template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Magnum::Math::RectangularMatrix& value) { debug << "Matrix("; debug.setFlag(Corrade::Utility::Debug::SpaceAfterEachValue, false); - for(size_t row = 0; row != rows; ++row) { + for(std::size_t row = 0; row != rows; ++row) { if(row != 0) debug << ",\n "; - for(size_t col = 0; col != cols; ++col) { + for(std::size_t col = 0; col != cols; ++col) { if(col != 0) debug << ", "; debug << typename MathTypeTraits::NumericType(value[col][row]); } @@ -381,6 +410,9 @@ template Corrade::Utility::Debug operator<<(C } \ template inline constexpr static __VA_ARGS__ from(const Math::Vector& first, const U&... next) { \ return Math::RectangularMatrix::from(first, next...); \ + } \ + template inline constexpr static RectangularMatrix from(const Math::RectangularMatrix& other) { \ + return Math::RectangularMatrix::from(other); \ } \ \ inline __VA_ARGS__& operator=(const Math::RectangularMatrix& other) { \ @@ -427,13 +459,13 @@ template Corrade::Utility::Debug operator<<(C namespace Corrade { namespace Utility { /** @configurationvalue{Magnum::Math::RectangularMatrix} */ -template struct ConfigurationValue> { +template struct ConfigurationValue> { /** @brief Writes elements separated with spaces */ static std::string toString(const Magnum::Math::RectangularMatrix& value, int flags = 0) { std::string output; - for(size_t row = 0; row != rows; ++row) { - for(size_t col = 0; col != cols; ++col) { + for(std::size_t row = 0; row != rows; ++row) { + for(std::size_t col = 0; col != cols; ++col) { if(!output.empty()) output += ' '; output += ConfigurationValue::toString(value(col, row), flags); } @@ -447,8 +479,8 @@ template struct ConfigurationValue result; std::istringstream in(stringValue); - for(size_t row = 0; row != rows; ++row) { - for(size_t col = 0; col != cols; ++col) { + for(std::size_t row = 0; row != rows; ++row) { + for(std::size_t col = 0; col != cols; ++col) { std::string num; in >> num; result(col, row) = ConfigurationValue::fromString(num, flags); diff --git a/src/Math/Test/CMakeLists.txt b/src/Math/Test/CMakeLists.txt index cd2050f55..a7f583747 100644 --- a/src/Math/Test/CMakeLists.txt +++ b/src/Math/Test/CMakeLists.txt @@ -1,20 +1,24 @@ +corrade_add_test2(MathConstantsTest ConstantsTest.cpp) +if(NOT CMAKE_NO_OBJECT_TARGET) + set(MathTest_SRCS MathTest.cpp $) +else() + set(MathTest_SRCS MathTest.cpp ${MagnumMath_SRCS}) +endif() +corrade_add_test2(MathTest ${MathTest_SRCS}) corrade_add_test2(MathMathTypeTraitsTest MathTypeTraitsTest.cpp) corrade_add_test2(MathRectangularMatrixTest RectangularMatrixTest.cpp) corrade_add_test2(MathVectorTest VectorTest.cpp) -set_target_properties(MathVectorTest PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT) corrade_add_test2(MathVector2Test Vector2Test.cpp) corrade_add_test2(MathVector3Test Vector3Test.cpp) corrade_add_test2(MathVector4Test Vector4Test.cpp) +corrade_add_test2(MathPoint2DTest Point2DTest.cpp) +corrade_add_test2(MathPoint3DTest Point3DTest.cpp) + corrade_add_test2(MathMatrixTest MatrixTest.cpp) corrade_add_test2(MathMatrix3Test Matrix3Test.cpp) corrade_add_test2(MathMatrix4Test Matrix4Test.cpp) -if(NOT CMAKE_NO_OBJECT_TARGET) - set(MathTest_SRCS MathTest.cpp $) -else() - set(MathTest_SRCS MathTest.cpp ${MagnumMath_SRCS}) -endif() -corrade_add_test2(MathTest ${MathTest_SRCS}) +set_target_properties(MathVectorTest MathMatrix4Test PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT) diff --git a/src/Math/Test/ConstantsTest.cpp b/src/Math/Test/ConstantsTest.cpp new file mode 100644 index 000000000..4a780de5c --- /dev/null +++ b/src/Math/Test/ConstantsTest.cpp @@ -0,0 +1,44 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "ConstantsTest.h" + +#include "Constants.h" +#include "Math.h" + +CORRADE_TEST_MAIN(Magnum::Math::Test::ConstantsTest) + +namespace Magnum { namespace Math { namespace Test { + +ConstantsTest::ConstantsTest() { + addTests(&ConstantsTest::constants, + &ConstantsTest::degrad); +} + +void ConstantsTest::constants() { + CORRADE_COMPARE(Math::pow<2>(Constants::sqrt2()), 2.0f); + CORRADE_COMPARE(Math::pow<2>(Constants::sqrt3()), 3.0f); + + CORRADE_COMPARE(Math::pow<2>(Constants::sqrt2()), 2.0); + CORRADE_COMPARE(Math::pow<2>(Constants::sqrt3()), 3.0); +} + +void ConstantsTest::degrad() { + CORRADE_COMPARE(deg(90.0), Constants::pi()/2); + CORRADE_COMPARE(deg(90.0f), Constants::pi()/2); + CORRADE_COMPARE(rad(Constants::pi()/2), Constants::pi()/2); +} + +}}} diff --git a/src/Math/Test/ConstantsTest.h b/src/Math/Test/ConstantsTest.h new file mode 100644 index 000000000..a52c49543 --- /dev/null +++ b/src/Math/Test/ConstantsTest.h @@ -0,0 +1,32 @@ +#ifndef Magnum_Math_Test_ConstantsTest_h +#define Magnum_Math_Test_ConstantsTest_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 + +namespace Magnum { namespace Math { namespace Test { + +class ConstantsTest: public Corrade::TestSuite::Tester { + public: + ConstantsTest(); + + void constants(); + void degrad(); +}; + +}}} + +#endif diff --git a/src/Math/Test/MathTest.cpp b/src/Math/Test/MathTest.cpp index cfdc49243..3aa7348ed 100644 --- a/src/Math/Test/MathTest.cpp +++ b/src/Math/Test/MathTest.cpp @@ -24,77 +24,61 @@ CORRADE_TEST_MAIN(Magnum::Math::Test::MathTest) namespace Magnum { namespace Math { namespace Test { MathTest::MathTest() { - addTests(&MathTest::constants, - &MathTest::degrad, - &MathTest::normalize, + addTests(&MathTest::normalize, &MathTest::denormalize, &MathTest::clamp, &MathTest::pow, &MathTest::log); } -void MathTest::constants() { - CORRADE_COMPARE(Math::pow<2>(Constants::sqrt2()), 2.0f); - CORRADE_COMPARE(Math::pow<2>(Constants::sqrt3()), 3.0f); - - CORRADE_COMPARE(Math::pow<2>(Constants::sqrt2()), 2.0); - CORRADE_COMPARE(Math::pow<2>(Constants::sqrt3()), 3.0); -} - -void MathTest::degrad() { - CORRADE_COMPARE(deg(90.0), Constants::pi()/2); - CORRADE_COMPARE(deg(90.0f), Constants::pi()/2); - CORRADE_COMPARE(rad(Constants::pi()/2), Constants::pi()/2); -} - void MathTest::normalize() { /* Range for signed and unsigned */ - CORRADE_COMPARE((Math::normalize(-128)), 0.0f); - CORRADE_COMPARE((Math::normalize(127)), 1.0f); - CORRADE_COMPARE((Math::normalize(0)), 0.0f); - CORRADE_COMPARE((Math::normalize(255)), 1.0f); + CORRADE_COMPARE((Math::normalize(-128)), 0.0f); + CORRADE_COMPARE((Math::normalize(127)), 1.0f); + CORRADE_COMPARE((Math::normalize(0)), 0.0f); + CORRADE_COMPARE((Math::normalize(255)), 1.0f); /* Between */ - CORRADE_COMPARE((Math::normalize(16384)), 0.750011f); - CORRADE_COMPARE((Math::normalize(-16384)), 0.250004f); + CORRADE_COMPARE((Math::normalize(16384)), 0.750011f); + CORRADE_COMPARE((Math::normalize(-16384)), 0.250004f); /* Test overflow for large types */ - CORRADE_COMPARE((Math::normalize(numeric_limits::min())), 0.0f); - CORRADE_COMPARE((Math::normalize(numeric_limits::max())), 1.0f); - CORRADE_COMPARE((Math::normalize(0)), 0.0f); - CORRADE_COMPARE((Math::normalize(numeric_limits::max())), 1.0f); - - CORRADE_COMPARE((Math::normalize(numeric_limits::min())), 0.0); - CORRADE_COMPARE((Math::normalize(numeric_limits::max())), 1.0); - CORRADE_COMPARE((Math::normalize(0)), 0.0); - CORRADE_COMPARE((Math::normalize(numeric_limits::max())), 1.0); + CORRADE_COMPARE((Math::normalize(numeric_limits::min())), 0.0f); + CORRADE_COMPARE((Math::normalize(numeric_limits::max())), 1.0f); + CORRADE_COMPARE((Math::normalize(0)), 0.0f); + CORRADE_COMPARE((Math::normalize(numeric_limits::max())), 1.0f); + + CORRADE_COMPARE((Math::normalize(numeric_limits::min())), 0.0); + CORRADE_COMPARE((Math::normalize(numeric_limits::max())), 1.0); + CORRADE_COMPARE((Math::normalize(0)), 0.0); + CORRADE_COMPARE((Math::normalize(numeric_limits::max())), 1.0); } void MathTest::denormalize() { /* Range for signed and unsigned */ - CORRADE_COMPARE(Math::denormalize(0.0f), -128); - CORRADE_COMPARE(Math::denormalize(1.0f), 127); - CORRADE_COMPARE(Math::denormalize(0.0f), 0); - CORRADE_COMPARE(Math::denormalize(1.0f), 255); + CORRADE_COMPARE(Math::denormalize(0.0f), -128); + CORRADE_COMPARE(Math::denormalize(1.0f), 127); + CORRADE_COMPARE(Math::denormalize(0.0f), 0); + CORRADE_COMPARE(Math::denormalize(1.0f), 255); /* Between */ - CORRADE_COMPARE(Math::denormalize(0.33f), -11141); - CORRADE_COMPARE(Math::denormalize(0.66f), 10485); + CORRADE_COMPARE(Math::denormalize(0.33f), -11141); + CORRADE_COMPARE(Math::denormalize(0.66f), 10485); /* Test overflow for large types */ - CORRADE_COMPARE(Math::denormalize(0.0f), numeric_limits::min()); - CORRADE_COMPARE(Math::denormalize(0.0f), 0); - CORRADE_COMPARE(Math::denormalize(0.0), numeric_limits::min()); - CORRADE_COMPARE(Math::denormalize(0.0), 0); - - CORRADE_COMPARE(Math::denormalize(1.0), numeric_limits::max()); - CORRADE_COMPARE(Math::denormalize(1.0), numeric_limits::max()); - - { - CORRADE_EXPECT_FAIL("Denormalize doesn't work for large types well"); - CORRADE_COMPARE((Math::denormalize(1.0)), numeric_limits::max()); - CORRADE_COMPARE((Math::denormalize(1.0)), numeric_limits::max()); - } + CORRADE_COMPARE(Math::denormalize(0.0f), numeric_limits::min()); + CORRADE_COMPARE(Math::denormalize(0.0f), 0); + CORRADE_COMPARE(Math::denormalize(0.0), numeric_limits::min()); + CORRADE_COMPARE(Math::denormalize(0.0), 0); + + CORRADE_COMPARE(Math::denormalize(1.0), numeric_limits::max()); + CORRADE_COMPARE(Math::denormalize(1.0), numeric_limits::max()); + +// { +// CORRADE_EXPECT_FAIL("Denormalize doesn't work for large types well"); +// CORRADE_COMPARE((Math::denormalize(1.0)), numeric_limits::max()); +// CORRADE_COMPARE((Math::denormalize(1.0)), numeric_limits::max()); +// } } void MathTest::clamp() { diff --git a/src/Math/Test/MathTest.h b/src/Math/Test/MathTest.h index 568c0b148..658d47690 100644 --- a/src/Math/Test/MathTest.h +++ b/src/Math/Test/MathTest.h @@ -23,8 +23,6 @@ class MathTest: public Corrade::TestSuite::Tester { public: MathTest(); - void constants(); - void degrad(); void normalize(); void denormalize(); void clamp(); diff --git a/src/Math/Test/MathTypeTraitsTest.cpp b/src/Math/Test/MathTypeTraitsTest.cpp index 523b32017..cae312032 100644 --- a/src/Math/Test/MathTypeTraitsTest.cpp +++ b/src/Math/Test/MathTypeTraitsTest.cpp @@ -21,6 +21,8 @@ CORRADE_TEST_MAIN(Magnum::Math::Test::MathTypeTraitsTest) +using namespace std; + namespace Magnum { namespace Math { namespace Test { MathTypeTraitsTest::MathTypeTraitsTest() { @@ -29,16 +31,14 @@ MathTypeTraitsTest::MathTypeTraitsTest() { } void MathTypeTraitsTest::equalsIntegral() { - _equalsIntegral(); - _equalsIntegral(); - _equalsIntegral(); - _equalsIntegral(); - _equalsIntegral(); - _equalsIntegral(); - _equalsIntegral(); - _equalsIntegral(); - _equalsIntegral(); - _equalsIntegral(); + _equalsIntegral(); + _equalsIntegral(); + _equalsIntegral(); + _equalsIntegral(); + _equalsIntegral(); + _equalsIntegral(); + _equalsIntegral(); + _equalsIntegral(); } void MathTypeTraitsTest::equalsFloatingPoint() { diff --git a/src/Math/Test/Matrix3Test.cpp b/src/Math/Test/Matrix3Test.cpp index 840e75c92..e2e8b8975 100644 --- a/src/Math/Test/Matrix3Test.cpp +++ b/src/Math/Test/Matrix3Test.cpp @@ -17,8 +17,8 @@ #include +#include "Constants.h" #include "Matrix3.h" -#include "Math.h" CORRADE_TEST_MAIN(Magnum::Math::Test::Matrix3Test) @@ -28,12 +28,17 @@ using namespace Corrade::Utility; namespace Magnum { namespace Math { namespace Test { typedef Math::Matrix3 Matrix3; +typedef Math::Matrix<2, float> Matrix2; +typedef Math::Vector2 Vector2; Matrix3Test::Matrix3Test() { addTests(&Matrix3Test::constructIdentity, &Matrix3Test::translation, &Matrix3Test::scaling, &Matrix3Test::rotation, + &Matrix3Test::rotationScalingPart, + &Matrix3Test::rotationPart, + &Matrix3Test::translationPart, &Matrix3Test::debug, &Matrix3Test::configuration); } @@ -90,6 +95,42 @@ void Matrix3Test::rotation() { CORRADE_COMPARE(Matrix3::rotation(deg(15.0f)), matrix); } +void Matrix3Test::rotationScalingPart() { + Matrix3 m( + 3.0f, 5.0f, 8.0f, + 4.0f, 4.0f, 7.0f, + 7.0f, -1.0f, 8.0f + ); + + Matrix2 expected( + 3.0f, 5.0f, + 4.0f, 4.0f + ); + + CORRADE_COMPARE(m.rotationScaling(), expected); +} + +void Matrix3Test::rotationPart() { + Matrix2 expectedRotationPart( + 0.965926f, 0.258819f, + -0.258819f, 0.965926f + ); + + Matrix3 rotation = Matrix3::rotation(deg(15.0f)); + CORRADE_COMPARE(rotation.rotation(), expectedRotationPart); + + Matrix3 rotationTransformed = Matrix3::translation({2.0f, 5.0f})*rotation*Matrix3::scaling(Vector2(9.0f)); + CORRADE_COMPARE(rotationTransformed.rotation(), expectedRotationPart); +} + +void Matrix3Test::translationPart() { + Matrix3 m(1.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + -5.0f, 12.0f, 1.0f); + Vector2 expected(-5.0f, 12.0f); + CORRADE_COMPARE(m.translation(), expected); +} + void Matrix3Test::debug() { Matrix3 m( 3.0f, 5.0f, 8.0f, diff --git a/src/Math/Test/Matrix3Test.h b/src/Math/Test/Matrix3Test.h index 2402fbc93..c76040678 100644 --- a/src/Math/Test/Matrix3Test.h +++ b/src/Math/Test/Matrix3Test.h @@ -28,6 +28,9 @@ class Matrix3Test: public Corrade::TestSuite::Tester { void translation(); void scaling(); void rotation(); + void rotationScalingPart(); + void rotationPart(); + void translationPart(); void debug(); void configuration(); diff --git a/src/Math/Test/Matrix4Test.cpp b/src/Math/Test/Matrix4Test.cpp index 9cc253cc6..a124d2b4c 100644 --- a/src/Math/Test/Matrix4Test.cpp +++ b/src/Math/Test/Matrix4Test.cpp @@ -17,8 +17,8 @@ #include +#include "Constants.h" #include "Matrix4.h" -#include "Math.h" CORRADE_TEST_MAIN(Magnum::Math::Test::Matrix4Test) @@ -28,15 +28,20 @@ using namespace Corrade::Utility; namespace Magnum { namespace Math { namespace Test { typedef Math::Matrix4 Matrix4; -typedef Math::Matrix3 Matrix3; +typedef Math::Matrix<3, float> Matrix3; +typedef Math::Vector3 Vector3; Matrix4Test::Matrix4Test() { addTests(&Matrix4Test::constructIdentity, &Matrix4Test::translation, &Matrix4Test::scaling, &Matrix4Test::rotation, + &Matrix4Test::rotationX, + &Matrix4Test::rotationY, + &Matrix4Test::rotationZ, &Matrix4Test::rotationScalingPart, &Matrix4Test::rotationPart, + &Matrix4Test::translationPart, &Matrix4Test::debug, &Matrix4Test::configuration); } @@ -88,14 +93,46 @@ void Matrix4Test::scaling() { } void Matrix4Test::rotation() { + ostringstream o; + Error::setOutput(&o); + + CORRADE_COMPARE(Matrix4::rotation(deg(-74.0f), {-1.0f, 2.0f, 2.0f}), Matrix4()); + CORRADE_COMPARE(o.str(), "Math::Matrix4::rotation(): axis must be normalized\n"); + Matrix4 matrix( - 0.35612214f, -0.80181062f, 0.47987163f, 0.0f, - 0.47987163f, 0.59757638f, 0.6423595f, 0.0f, - -0.80181062f, 0.0015183985f, 0.59757638f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f + 0.35612214f, -0.80181062f, 0.47987163f, 0.0f, + 0.47987163f, 0.59757638f, 0.6423595f, 0.0f, + -0.80181062f, 0.0015183985f, 0.59757638f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f ); + CORRADE_COMPARE(Matrix4::rotation(deg(-74.0f), Vector3(-1.0f, 2.0f, 2.0f).normalized()), matrix); +} + +void Matrix4Test::rotationX() { + Matrix4 matrix(1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.90096887f, 0.43388374f, 0.0f, + 0.0f, -0.43388374f, 0.90096887f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f); + CORRADE_COMPARE(Matrix4::rotation(rad(Math::Constants::pi()/7), Vector3::xAxis()), matrix); + CORRADE_COMPARE(Matrix4::rotationX(rad(Math::Constants::pi()/7)), matrix); +} + +void Matrix4Test::rotationY() { + Matrix4 matrix(0.90096887f, 0.0f, -0.43388374f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.43388374f, 0.0f, 0.90096887f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f); + CORRADE_COMPARE(Matrix4::rotation(rad(Math::Constants::pi()/7), Vector3::yAxis()), matrix); + CORRADE_COMPARE(Matrix4::rotationY(rad(Math::Constants::pi()/7)), matrix); +} - CORRADE_COMPARE(Matrix4::rotation(deg(-74.0f), {-1.0f, 2.0f, 2.0f}), matrix); +void Matrix4Test::rotationZ() { + Matrix4 matrix( 0.90096887f, 0.43388374f, 0.0f, 0.0f, + -0.43388374f, 0.90096887f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f); + CORRADE_COMPARE(Matrix4::rotation(rad(Math::Constants::pi()/7), Vector3::zAxis()), matrix); + CORRADE_COMPARE(Matrix4::rotationZ(rad(Math::Constants::pi()/7)), matrix); } void Matrix4Test::rotationScalingPart() { @@ -122,13 +159,22 @@ void Matrix4Test::rotationPart() { -0.80181062f, 0.0015183985f, 0.59757638f ); - Matrix4 rotation = Matrix4::rotation(deg(-74.0f), {-1.0f, 2.0f, 2.0f}); + Matrix4 rotation = Matrix4::rotation(deg(-74.0f), Vector3(-1.0f, 2.0f, 2.0f).normalized()); CORRADE_COMPARE(rotation.rotation(), expectedRotationPart); - Matrix4 rotationTransformed = Matrix4::translation({2.0f, 5.0f, -3.0f})*rotation*Matrix4::scaling(Vector3(9.0f)); + Matrix4 rotationTransformed = Matrix4::translation({2.0f, 5.0f, -3.0f})*rotation*Matrix4::scaling(Vector3(9.0f)); CORRADE_COMPARE(rotationTransformed.rotation(), expectedRotationPart); } +void Matrix4Test::translationPart() { + Matrix4 m(1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + -5.0f, 12.0f, 0.5f, 1.0f); + Vector3 expected(-5.0f, 12.0f, 0.5f); + CORRADE_COMPARE(m.translation(), expected); +} + void Matrix4Test::debug() { Matrix4 m( 3.0f, 5.0f, 8.0f, 4.0f, diff --git a/src/Math/Test/Matrix4Test.h b/src/Math/Test/Matrix4Test.h index a49cfddb1..783c6adb2 100644 --- a/src/Math/Test/Matrix4Test.h +++ b/src/Math/Test/Matrix4Test.h @@ -28,8 +28,12 @@ class Matrix4Test: public Corrade::TestSuite::Tester { void translation(); void scaling(); void rotation(); + void rotationX(); + void rotationY(); + void rotationZ(); void rotationScalingPart(); void rotationPart(); + void translationPart(); void debug(); void configuration(); diff --git a/src/Math/Test/MatrixTest.cpp b/src/Math/Test/MatrixTest.cpp index 2d803ec16..6a015b328 100644 --- a/src/Math/Test/MatrixTest.cpp +++ b/src/Math/Test/MatrixTest.cpp @@ -98,7 +98,7 @@ void MatrixTest::constructZero() { } void MatrixTest::trace() { - Matrix<5, int> m( + Matrix<5, int32_t> m( 1, 2, 3, 0, 0, 2, 3, 2, 1, -2, 1, 1, -20, 1, 0, @@ -127,7 +127,7 @@ void MatrixTest::ij() { } void MatrixTest::determinant() { - Matrix<5, int> m( + Matrix<5, int32_t> m( 1, 2, 2, 1, 0, 2, 3, 2, 1, -2, 1, 1, 1, 1, 0, diff --git a/src/Math/Test/Point2DTest.cpp b/src/Math/Test/Point2DTest.cpp new file mode 100644 index 000000000..64d5540bc --- /dev/null +++ b/src/Math/Test/Point2DTest.cpp @@ -0,0 +1,56 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "Point2DTest.h" + +#include + +#include "Point2D.h" + +CORRADE_TEST_MAIN(Magnum::Math::Test::Point2DTest) + +using namespace std; +using namespace Corrade::Utility; + +namespace Magnum { namespace Math { namespace Test { + +typedef Math::Point2D Point2D; + +Point2DTest::Point2DTest() { + addTests(&Point2DTest::construct, + &Point2DTest::debug, + &Point2DTest::configuration); +} + +void Point2DTest::construct() { + CORRADE_COMPARE(Point2D(), (Vector<3, float>(0.0f, 0.0f, 1.0f))); + CORRADE_COMPARE(Point2D(1, 2), (Vector<3, float>(1.0f, 2.0f, 1.0f))); + CORRADE_COMPARE(Point2D(Vector<2, float>(1.0f, 2.0f), 3), (Vector<3, float>(1.0f, 2.0f, 3.0f))); +} + +void Point2DTest::debug() { + ostringstream o; + Debug(&o) << Point2D(0.5f, 15.0f, 1.0f); + CORRADE_COMPARE(o.str(), "Vector(0.5, 15, 1)\n"); +} + +void Point2DTest::configuration() { + Point2D vec(3.0f, 3.125f, 9.55f); + string value("3 3.125 9.55"); + CORRADE_COMPARE(ConfigurationValue::toString(vec), value); + CORRADE_COMPARE(ConfigurationValue::fromString(value), vec); +} + +}}} diff --git a/src/Math/Test/Point2DTest.h b/src/Math/Test/Point2DTest.h new file mode 100644 index 000000000..39ec72d3b --- /dev/null +++ b/src/Math/Test/Point2DTest.h @@ -0,0 +1,33 @@ +#ifndef Magnum_Math_Test_Point2DTest_h +#define Magnum_Math_Test_Point2DTest_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 + +namespace Magnum { namespace Math { namespace Test { + +class Point2DTest: public Corrade::TestSuite::Tester { + public: + Point2DTest(); + + void construct(); + void debug(); + void configuration(); +}; + +}}} + +#endif diff --git a/src/Math/Test/Point3DTest.cpp b/src/Math/Test/Point3DTest.cpp new file mode 100644 index 000000000..092f5a0f0 --- /dev/null +++ b/src/Math/Test/Point3DTest.cpp @@ -0,0 +1,56 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "Point3DTest.h" + +#include + +#include "Point3D.h" + +CORRADE_TEST_MAIN(Magnum::Math::Test::Point3DTest) + +using namespace std; +using namespace Corrade::Utility; + +namespace Magnum { namespace Math { namespace Test { + +typedef Math::Point3D Point3D; + +Point3DTest::Point3DTest() { + addTests(&Point3DTest::construct, + &Point3DTest::debug, + &Point3DTest::configuration); +} + +void Point3DTest::construct() { + CORRADE_COMPARE(Point3D(), Point3D(0.0f, 0.0f, 0.0f, 1.0f)); + CORRADE_COMPARE(Point3D(1, 2, 3, 4), (Vector<4, float>(1.0f, 2.0f, 3.0f, 4.0f))); + CORRADE_COMPARE(Point3D(Vector<3, float>(1.0f, 2.0f, 3.0f), 4), (Vector<4, float>(1.0f, 2.0f, 3.0f, 4.0f))); +} + +void Point3DTest::debug() { + ostringstream o; + Debug(&o) << Point3D(0.5f, 15.0f, 1.0f, 1.0f); + CORRADE_COMPARE(o.str(), "Vector(0.5, 15, 1, 1)\n"); +} + +void Point3DTest::configuration() { + Point3D vec(3.0f, 3.125f, 9.0f, 9.55f); + string value("3 3.125 9 9.55"); + CORRADE_COMPARE(ConfigurationValue::toString(vec), value); + CORRADE_COMPARE(ConfigurationValue::fromString(value), vec); +} + +}}} diff --git a/src/Math/Test/Point3DTest.h b/src/Math/Test/Point3DTest.h new file mode 100644 index 000000000..9560e01d5 --- /dev/null +++ b/src/Math/Test/Point3DTest.h @@ -0,0 +1,33 @@ +#ifndef Magnum_Math_Test_Point3DTest_h +#define Magnum_Math_Test_Point3DTest_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 + +namespace Magnum { namespace Math { namespace Test { + +class Point3DTest: public Corrade::TestSuite::Tester { + public: + Point3DTest(); + + void construct(); + void debug(); + void configuration(); +}; + +}}} + +#endif diff --git a/src/Math/Test/RectangularMatrixTest.cpp b/src/Math/Test/RectangularMatrixTest.cpp index da0762179..e43c6e5e2 100644 --- a/src/Math/Test/RectangularMatrixTest.cpp +++ b/src/Math/Test/RectangularMatrixTest.cpp @@ -29,11 +29,13 @@ namespace Magnum { namespace Math { namespace Test { typedef RectangularMatrix<4, 3, float> Matrix4x3; typedef RectangularMatrix<3, 4, float> Matrix3x4; typedef RectangularMatrix<2, 2, float> Matrix2; +typedef RectangularMatrix<2, 2, int32_t> Matrix2i; typedef Vector<4, float> Vector4; RectangularMatrixTest::RectangularMatrixTest() { addTests(&RectangularMatrixTest::construct, &RectangularMatrixTest::constructFromVectors, + &RectangularMatrixTest::constructFrom, &RectangularMatrixTest::constructZero, &RectangularMatrixTest::data, @@ -76,6 +78,16 @@ void RectangularMatrixTest::constructFromVectors() { CORRADE_COMPARE(actual, expected); } + +void RectangularMatrixTest::constructFrom() { + Matrix2 floatingPoint(1.3f, 2.7f, -15.0f, 7.0f); + Matrix2 floatingPointRounded(1.0f, 2.0f, -15.0f, 7.0f); + Matrix2i integral(1, 2, -15, 7); + + CORRADE_COMPARE(Matrix2i::from(floatingPoint), integral); + CORRADE_COMPARE(Matrix2::from(integral), floatingPointRounded); +} + void RectangularMatrixTest::constructZero() { Matrix4x3 zero; @@ -142,8 +154,8 @@ void RectangularMatrixTest::multiplyDivide() { CORRADE_COMPARE(-1.5f*vec, multiplied); CORRADE_COMPARE(multiplied/-1.5f, vec); - Math::RectangularMatrix<1, 1, char> vecChar(32); - Math::RectangularMatrix<1, 1, char> multipliedChar(-48); + Math::RectangularMatrix<1, 1, int8_t> vecChar(32); + Math::RectangularMatrix<1, 1, int8_t> multipliedChar(-48); CORRADE_COMPARE(vecChar*-1.5f, multipliedChar); CORRADE_COMPARE(multipliedChar/-1.5f, vecChar); CORRADE_COMPARE(-1.5f*vecChar, multipliedChar); @@ -156,14 +168,14 @@ void RectangularMatrixTest::multiplyDivide() { } void RectangularMatrixTest::multiply() { - RectangularMatrix<4, 6, int> left( + RectangularMatrix<4, 6, int32_t> left( -5, 27, 10, 33, 0, -15, 7, 56, 66, 1, 0, -24, 4, 41, 4, 0, 1, -4, 9, -100, 19, -49, 1, 9 ); - RectangularMatrix<5, 4, int> right( + RectangularMatrix<5, 4, int32_t> right( 1, -7, 0, 158, 2, 24, -3, 40, 3, -15, -2, -50, @@ -171,7 +183,7 @@ void RectangularMatrixTest::multiply() { 5, 30, 4, 18 ); - RectangularMatrix<5, 6, int> expected( + RectangularMatrix<5, 6, int32_t> expected( 1368, -16165, 2550, -7716, 158, 1575, 506, -2725, 2352, -1870, 37, -234, -578, 4159, -1918, 2534, -52, -127, @@ -214,7 +226,7 @@ void RectangularMatrixTest::debug() { " 4, 3, 0)\n"); o.str(""); - Debug(&o) << "a" << Matrix3x4() << "b" << RectangularMatrix<4, 3, char>(); + Debug(&o) << "a" << Matrix3x4() << "b" << RectangularMatrix<4, 3, int8_t>(); CORRADE_COMPARE(o.str(), "a Matrix(0, 0, 0,\n" " 0, 0, 0,\n" " 0, 0, 0,\n" diff --git a/src/Math/Test/RectangularMatrixTest.h b/src/Math/Test/RectangularMatrixTest.h index 0eae0204a..469762177 100644 --- a/src/Math/Test/RectangularMatrixTest.h +++ b/src/Math/Test/RectangularMatrixTest.h @@ -25,6 +25,7 @@ class RectangularMatrixTest: public Corrade::TestSuite::Tester(1.0f, 2.0f, 3.0f))); CORRADE_COMPARE(Vector3(Vector<2, float>(1.0f, 2.0f), 3), (Vector<3, float>(1.0f, 2.0f, 3.0f))); } diff --git a/src/Math/Test/Vector4Test.cpp b/src/Math/Test/Vector4Test.cpp index b8765b65b..c12838a20 100644 --- a/src/Math/Test/Vector4Test.cpp +++ b/src/Math/Test/Vector4Test.cpp @@ -39,7 +39,7 @@ Vector4Test::Vector4Test() { } void Vector4Test::construct() { - CORRADE_COMPARE(Vector4(), Vector4(0.0f, 0.0f, 0.0f, 1.0f)); + CORRADE_COMPARE(Vector4(), Vector4(0.0f, 0.0f, 0.0f, 0.0f)); CORRADE_COMPARE(Vector4(1, 2, 3, 4), (Vector<4, float>(1.0f, 2.0f, 3.0f, 4.0f))); CORRADE_COMPARE(Vector4(Vector<3, float>(1.0f, 2.0f, 3.0f), 4), (Vector<4, float>(1.0f, 2.0f, 3.0f, 4.0f))); } diff --git a/src/Math/Test/VectorTest.cpp b/src/Math/Test/VectorTest.cpp index 4e18e3b69..5bd824c16 100644 --- a/src/Math/Test/VectorTest.cpp +++ b/src/Math/Test/VectorTest.cpp @@ -17,8 +17,8 @@ #include +#include "Constants.h" #include "Vector.h" -#include "Math.h" CORRADE_TEST_MAIN(Magnum::Math::Test::VectorTest) @@ -28,12 +28,10 @@ using namespace Corrade::Utility; namespace Magnum { namespace Math { namespace Test { typedef Vector<4, float> Vector4; -typedef Vector<4, int> Vector4i; typedef Vector<3, float> Vector3; VectorTest::VectorTest() { addTests(&VectorTest::construct, - &VectorTest::constructFrom, &VectorTest::dot, &VectorTest::multiplyDivideComponentWise, &VectorTest::dotSelf, @@ -55,15 +53,6 @@ void VectorTest::construct() { CORRADE_COMPARE(Vector4::from(data), Vector4(1.0f, 2.0f, 3.0f, 4.0f)); } -void VectorTest::constructFrom() { - Vector4 floatingPoint(1.3f, 2.7f, -15.0f, 7.0f); - Vector4 floatingPointRounded(1.0f, 2.0f, -15.0f, 7.0f); - Vector4i integral(1, 2, -15, 7); - - CORRADE_COMPARE(Vector4i::from(floatingPoint), integral); - CORRADE_COMPARE(Vector4::from(integral), floatingPointRounded); -} - void VectorTest::dot() { CORRADE_COMPARE(Vector4::dot({1.0f, 0.5f, 0.75f, 1.5f}, {2.0f, 4.0f, 1.0f, 7.0f}), 15.25f); } @@ -110,7 +99,7 @@ void VectorTest::angle() { Error::setOutput(&o); /* Both vectors must be normalized, otherwise NaN is returned */ CORRADE_COMPARE(Vector3::angle(Vector3(2.0f, 3.0f, 4.0f).normalized(), {1.0f, -2.0f, 3.0f}), numeric_limits::quiet_NaN()); - CORRADE_COMPARE(o.str(), "Math::Vector::angle(): vectors must be normalized!\n"); + CORRADE_COMPARE(o.str(), "Math::Vector::angle(): vectors must be normalized\n"); CORRADE_COMPARE(Vector3::angle({2.0f, 3.0f, 4.0f}, Vector3(1.0f, -2.0f, 3.0f).normalized()), numeric_limits::quiet_NaN()); CORRADE_COMPARE(Vector3::angle(Vector3(2.0f, 3.0f, 4.0f).normalized(), Vector3(1.0f, -2.0f, 3.0f).normalized()), rad(1.162514f)); diff --git a/src/Math/Test/VectorTest.h b/src/Math/Test/VectorTest.h index e31af0aa0..1af4b7122 100644 --- a/src/Math/Test/VectorTest.h +++ b/src/Math/Test/VectorTest.h @@ -24,7 +24,6 @@ class VectorTest: public Corrade::TestSuite::Tester { VectorTest(); void construct(); - void constructFrom(); void dot(); void multiplyDivideComponentWise(); void dotSelf(); diff --git a/src/Math/Vector.h b/src/Math/Vector.h index da1372ee2..b698f88df 100644 --- a/src/Math/Vector.h +++ b/src/Math/Vector.h @@ -23,41 +23,17 @@ namespace Magnum { namespace Math { -template class Vector; - -#ifndef DOXYGEN_GENERATING_OUTPUT -namespace Implementation { - /* Implementation for Vector::from(const Vector&) */ - template inline constexpr Math::Vector vectorFrom(Sequence, const Math::Vector& vector) { - return {T(vector[sequence])...}; - } -} -#endif - /** @brief %Vector +@tparam size %Vector size +@tparam T Data type +See @ref matrix-vector for brief introduction. @configurationvalueref{Magnum::Math::Vector} -@todo Constexprize all for loops */ -template class Vector: public RectangularMatrix<1, s, T> { +template class Vector: public RectangularMatrix<1, size, T> { public: - const static size_t size = s; /**< @brief %Vector size */ - - /** - * @brief %Vector from another of different type - * - * Performs only default casting on the values, no rounding or - * anything else. Example usage: - * @code - * Vector<4, float> floatingPoint(1.3f, 2.7f, -15.0f, 7.0f); - * Vector<4, int> integral(Vector<4, int>::from(floatingPoint)); - * // integral == {1, 2, -15, 7} - * @endcode - */ - template inline constexpr static Vector from(const Vector& other) { - return Implementation::vectorFrom(typename Implementation::GenerateSequence::Type(), other); - } + const static std::size_t Size = size; /**< @brief %Vector size */ /** * @brief Dot product @@ -70,7 +46,7 @@ template class Vector: public RectangularMatrix<1, s, T> { static T dot(const Vector& a, const Vector& b) { T out(0); - for(size_t i = 0; i != size; ++i) + for(std::size_t i = 0; i != size; ++i) out += a[i]*b[i]; return out; @@ -82,18 +58,20 @@ template class Vector: public RectangularMatrix<1, s, T> { * @f[ * \phi = \frac{a \cdot b}{|a| \cdot |b|} * @f] - * @attention If any of the parameters is not normalized (and - * assertions are enabled), returns NaN. + * @attention Assertion fails on non-normalized vectors and NaN is + * returned. */ inline static T angle(const Vector& a, const Vector& b) { CORRADE_ASSERT(MathTypeTraits::equals(a.dot(), T(1)) && MathTypeTraits::equals(b.dot(), T(1)), - "Math::Vector::angle(): vectors must be normalized!", std::numeric_limits::quiet_NaN()); + "Math::Vector::angle(): vectors must be normalized", std::numeric_limits::quiet_NaN()); return std::acos(dot(a, b)); } /** @brief Default constructor */ inline constexpr Vector() {} + /** @todo Creating Vector from combination of vector and scalar types */ + /** * @brief Initializer-list constructor * @param first First value @@ -114,7 +92,7 @@ template class Vector: public RectangularMatrix<1, s, T> { #else inline explicit Vector(T value) { #endif - for(size_t i = 0; i != size; ++i) + for(std::size_t i = 0; i != size; ++i) (*this)[i] = value; } @@ -122,15 +100,15 @@ template class Vector: public RectangularMatrix<1, s, T> { inline constexpr Vector(const RectangularMatrix<1, size, T>& other): RectangularMatrix<1, size, T>(other) {} /** @brief Value at given position */ - inline T& operator[](size_t pos) { return RectangularMatrix<1, size, T>::_data[pos]; } - inline constexpr T operator[](size_t pos) const { return RectangularMatrix<1, size, T>::_data[pos]; } /**< @overload */ + inline T& operator[](std::size_t pos) { return RectangularMatrix<1, size, T>::_data[pos]; } + inline constexpr T operator[](std::size_t pos) const { return RectangularMatrix<1, size, T>::_data[pos]; } /**< @overload */ /** * @brief Multiply vector component-wise * * @see operator*=(const Vector&) */ - Vector operator*(const Vector& other) const { + inline Vector operator*(const Vector& other) const { return Vector(*this)*=other; } @@ -141,7 +119,7 @@ template class Vector: public RectangularMatrix<1, s, T> { * because it does the computation in-place. */ Vector& operator*=(const Vector& other) { - for(size_t i = 0; i != size; ++i) + for(std::size_t i = 0; i != size; ++i) (*this)[i] *= other[i]; return *this; @@ -152,7 +130,7 @@ template class Vector: public RectangularMatrix<1, s, T> { * * @see operator/=(const Vector&) */ - Vector operator/(const Vector& other) const { + inline Vector operator/(const Vector& other) const { return Vector(*this)/=other; } @@ -163,7 +141,7 @@ template class Vector: public RectangularMatrix<1, s, T> { * because it does the computation in-place. */ Vector& operator/=(const Vector& other) { - for(size_t i = 0; i != size; ++i) + for(std::size_t i = 0; i != size; ++i) (*this)[i] /= other[i]; return *this; @@ -201,7 +179,7 @@ template class Vector: public RectangularMatrix<1, s, T> { T sum() const { T out(0); - for(size_t i = 0; i != size; ++i) + for(std::size_t i = 0; i != size; ++i) out += (*this)[i]; return out; @@ -211,7 +189,7 @@ template class Vector: public RectangularMatrix<1, s, T> { T product() const { T out(1); - for(size_t i = 0; i != size; ++i) + for(std::size_t i = 0; i != size; ++i) out *= (*this)[i]; return out; @@ -221,7 +199,7 @@ template class Vector: public RectangularMatrix<1, s, T> { T min() const { T out((*this)[0]); - for(size_t i = 1; i != size; ++i) + for(std::size_t i = 1; i != size; ++i) out = std::min(out, (*this)[i]); return out; @@ -231,7 +209,7 @@ template class Vector: public RectangularMatrix<1, s, T> { T max() const { T out((*this)[0]); - for(size_t i = 1; i != size; ++i) + for(std::size_t i = 1; i != size; ++i) out = std::max(out, (*this)[i]); return out; @@ -239,7 +217,7 @@ template class Vector: public RectangularMatrix<1, s, T> { #ifndef DOXYGEN_GENERATING_OUTPUT /* Reimplementation of functions to return correct type */ - template inline RectangularMatrix operator*(const RectangularMatrix& other) const { + template inline RectangularMatrix operator*(const RectangularMatrix& other) const { return RectangularMatrix<1, size, T>::operator*(other); } MAGNUM_RECTANGULARMATRIX_SUBCLASS_IMPLEMENTATION(1, size, Vector) @@ -248,26 +226,26 @@ template class Vector: public RectangularMatrix<1, s, T> { private: /* Hiding unused things from RectangularMatrix */ - using RectangularMatrix<1, size, T>::cols; - using RectangularMatrix<1, size, T>::rows; + using RectangularMatrix<1, size, T>::Cols; + using RectangularMatrix<1, size, T>::Rows; using RectangularMatrix<1, size, T>::operator[]; using RectangularMatrix<1, size, T>::operator(); }; #ifndef DOXYGEN_GENERATING_OUTPUT -template inline typename std::enable_if::value, Vector>::type operator*(U number, const Vector& vector) { +template inline typename std::enable_if::value, Vector>::type operator*(U number, const Vector& vector) { return number*RectangularMatrix<1, size, T>(vector); } -template inline typename std::enable_if::value, Vector>::type operator/(U number, const Vector& vector) { +template inline typename std::enable_if::value, Vector>::type operator/(U number, const Vector& vector) { return number/RectangularMatrix<1, size, T>(vector); } #endif /** @debugoperator{Magnum::Math::Vector} */ -template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Magnum::Math::Vector& value) { +template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Vector& value) { debug << "Vector("; debug.setFlag(Corrade::Utility::Debug::SpaceAfterEachValue, false); - for(size_t i = 0; i != size; ++i) { + for(std::size_t i = 0; i != size; ++i) { if(i != 0) debug << ", "; debug << typename MathTypeTraits::NumericType(value[i]); } @@ -293,7 +271,7 @@ template Corrade::Utility::Debug operator<<(Corrade::Utili return *this; \ } \ \ - template inline Math::RectangularMatrix operator*(const Math::RectangularMatrix& other) const { \ + template inline Math::RectangularMatrix operator*(const Math::RectangularMatrix& other) const { \ return Math::Vector::operator*(other); \ } \ inline Type operator*(const Math::Vector& other) const { \ @@ -327,33 +305,7 @@ template Corrade::Utility::Debug operator<<(Corrade::Utili namespace Corrade { namespace Utility { /** @configurationvalue{Magnum::Math::Vector} */ -template struct ConfigurationValue> { - /** @brief Writes elements separated with spaces */ - static std::string toString(const Magnum::Math::Vector& value, int flags = 0) { - std::string output; - - for(size_t pos = 0; pos != size; ++pos) { - if(!output.empty()) output += ' '; - output += ConfigurationValue::toString(value[pos], flags); - } - - return output; - } - - /** @brief Reads elements separated with whitespace */ - static Magnum::Math::Vector fromString(const std::string& stringValue, int flags = 0) { - Magnum::Math::Vector result; - std::istringstream in(stringValue); - - std::string num; - for(size_t pos = 0; pos != size; ++pos) { - in >> num; - result[pos] = ConfigurationValue::fromString(num, flags); - } - - return result; - } -}; +template struct ConfigurationValue>: public ConfigurationValue> {}; }} diff --git a/src/Math/Vector2.h b/src/Math/Vector2.h index d67e8b0c7..c4d26eb11 100644 --- a/src/Math/Vector2.h +++ b/src/Math/Vector2.h @@ -25,7 +25,9 @@ namespace Magnum { namespace Math { /** @brief Two-component vector +@tparam T Data type +See @ref matrix-vector for brief introduction. @configurationvalueref{Magnum::Math::Vector2} */ template class Vector2: public Vector<2, T> { @@ -68,8 +70,11 @@ template class Vector2: public Vector<2, T> { */ inline constexpr static Vector2 yScale(T scale) { return Vector2(T(1), scale); } + /** @copydoc Vector::Vector() */ + inline constexpr Vector2() {} + /** @copydoc Vector::Vector(T) */ - inline constexpr explicit Vector2(T value = T()): Vector<2, T>(value, value) {} + inline constexpr explicit Vector2(T value): Vector<2, T>(value, value) {} /** @brief Copy constructor */ inline constexpr Vector2(const RectangularMatrix<1, 2, T>& other): Vector<2, T>(other) {} @@ -81,11 +86,10 @@ template class Vector2: public Vector<2, T> { */ inline constexpr Vector2(T x, T y): Vector<2, T>(x, y) {} - inline constexpr T x() const { return (*this)[0]; } /**< @brief X component */ - inline constexpr T y() const { return (*this)[1]; } /**< @brief Y component */ - - inline void setX(T value) { (*this)[0] = value; } /**< @brief Set X component */ - inline void setY(T value) { (*this)[1] = value; } /**< @brief Set Y component */ + 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 */ MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(Vector2, 2) MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(1, 2, Vector2) @@ -94,8 +98,8 @@ template class Vector2: public Vector<2, T> { MAGNUM_VECTOR_SUBCLASS_OPERATOR_IMPLEMENTATION(Vector2, 2) /** @debugoperator{Magnum::Math::Vector2} */ -template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Magnum::Math::Vector2& value) { - return debug << static_cast&>(value); +template inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Vector2& value) { + return debug << static_cast&>(value); } }} diff --git a/src/Math/Vector3.h b/src/Math/Vector3.h index 623bb2c33..51ce88517 100644 --- a/src/Math/Vector3.h +++ b/src/Math/Vector3.h @@ -25,7 +25,10 @@ namespace Magnum { namespace Math { /** @brief Three-component vector +@tparam T Data type +See @ref matrix-vector for brief introduction. See also Point2D for +homogeneous two-dimensional coordinates. @configurationvalueref{Magnum::Math::Vector3} */ template class Vector3: public Vector<3, T> { @@ -110,26 +113,25 @@ template class Vector3: public Vector<3, T> { /** * @brief Constructor - * @param x X value - * @param y Y value - * @param z Z value + * @param x X component + * @param y Y component + * @param z Z component */ inline constexpr Vector3(T x, T y, T z): Vector<3, T>(x, y, z) {} /** * @brief Constructor - * @param xy Two component vector - * @param z Z value + * @param xy Two-component vector + * @param z Z component */ - inline constexpr Vector3(const Vector<2, T>& xy, T z): Vector<3, T>(xy[0], xy[1], z) {} + inline constexpr Vector3(const Vector2& xy, T z): Vector<3, T>(xy[0], xy[1], z) {} - inline constexpr T x() const { return (*this)[0]; } /**< @brief X component */ - inline constexpr T y() const { return (*this)[1]; } /**< @brief Y component */ - inline constexpr T z() const { return (*this)[2]; } /**< @brief Z component */ - - inline void setX(T value) { (*this)[0] = value; } /**< @brief Set X component */ - inline void setY(T value) { (*this)[1] = value; } /**< @brief Set Y component */ - inline void setZ(T value) { (*this)[2] = value; } /**< @brief Set Z component */ + 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 */ /** * @brief XY part of the vector @@ -137,7 +139,8 @@ template class Vector3: public Vector<3, T> { * * @see swizzle() */ - inline constexpr Vector2 xy() const { return Vector2::from(Vector<3, T>::data()); } + inline Vector2& xy() { return Vector2::from(Vector<3, T>::data()); } + inline constexpr Vector2 xy() const { return Vector2::from(Vector<3, T>::data()); } /**< @overload */ MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(Vector3, 3) MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(1, 3, Vector3) @@ -146,8 +149,8 @@ template class Vector3: public Vector<3, T> { MAGNUM_VECTOR_SUBCLASS_OPERATOR_IMPLEMENTATION(Vector3, 3) /** @debugoperator{Magnum::Math::Vector3} */ -template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Magnum::Math::Vector3& value) { - return debug << static_cast&>(value); +template inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Vector3& value) { + return debug << static_cast&>(value); } }} diff --git a/src/Math/Vector4.h b/src/Math/Vector4.h index 5adfe60ee..be28aa83f 100644 --- a/src/Math/Vector4.h +++ b/src/Math/Vector4.h @@ -25,17 +25,16 @@ namespace Magnum { namespace Math { /** @brief Four-component vector +@tparam T Data type +See @ref matrix-vector for brief introduction. See also Point3D for +homogeneous three-dimensional coordinates. @configurationvalueref{Magnum::Math::Vector4} */ template class Vector4: public Vector<4, T> { public: - /** - * @copydoc Vector::Vector - * - * W component is set to one. - */ - inline constexpr Vector4(): Vector<4, T>(T(0), T(0), T(0), T(1)) {} + /** @copydoc Vector::Vector() */ + inline constexpr Vector4() {} /** @copydoc Vector::Vector(T) */ inline constexpr explicit Vector4(T value): Vector<4, T>(value, value, value, value) {} @@ -45,31 +44,28 @@ template class Vector4: public Vector<4, T> { /** * @brief Constructor - * @param x X value - * @param y Y value - * @param z Z value - * @param w W value + * @param x X component + * @param y Y component + * @param z Z component + * @param w W component */ - inline constexpr Vector4(T x, T y, T z, T w = T(1)): Vector<4, T>(x, y, z, w) {} + inline constexpr Vector4(T x, T y, T z, T w): Vector<4, T>(x, y, z, w) {} /** * @brief Constructor - * @param xyz Three component vector - * @param w W value + * @param xyz Three-component vector + * @param w W component */ - /* Not marked as explicit, because conversion from Vector3 to Vector4 - is fairly common, nearly always with W set to 1 */ - inline constexpr Vector4(const Vector<3, T>& xyz, T w = T(1)): Vector<4, T>(xyz[0], xyz[1], xyz[2], w) {} - - inline constexpr T x() const { return (*this)[0]; } /**< @brief X component */ - inline constexpr T y() const { return (*this)[1]; } /**< @brief Y component */ - inline constexpr T z() const { return (*this)[2]; } /**< @brief Z component */ - inline constexpr T w() const { return (*this)[3]; } /**< @brief W component */ + inline constexpr Vector4(const Vector3& xyz, T w): Vector<4, T>(xyz[0], xyz[1], xyz[2], w) {} - inline void setX(T value) { (*this)[0] = value; } /**< @brief Set X component */ - inline void setY(T value) { (*this)[1] = value; } /**< @brief Set Y component */ - inline void setZ(T value) { (*this)[2] = value; } /**< @brief Set Z component */ - inline void setW(T value) { (*this)[3] = value; } /**< @brief Set W component */ + 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 */ + inline T& w() { return (*this)[3]; } /**< @brief W component */ + inline constexpr T w() const { return (*this)[3]; } /**< @overload */ /** * @brief XYZ part of the vector @@ -77,7 +73,8 @@ template class Vector4: public Vector<4, T> { * * @see swizzle() */ - inline constexpr Vector3 xyz() const { return Vector3::from(Vector<4, T>::data()); } + inline Vector3& xyz() { return Vector3::from(Vector<4, T>::data()); } + inline constexpr Vector3 xyz() const { return Vector3::from(Vector<4, T>::data()); } /**< @overload */ /** * @brief XY part of the vector @@ -85,17 +82,18 @@ template class Vector4: public Vector<4, T> { * * @see swizzle() */ - inline constexpr Vector2 xy() const { return Vector2::from(Vector<4, T>::data()); } + inline Vector2& xy() { return Vector2::from(Vector<4, T>::data()); } + inline constexpr Vector2 xy() const { return Vector2::from(Vector<4, T>::data()); } /**< @overload */ MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(Vector4, 4) - MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(1, 3, Vector4) + MAGNUM_RECTANGULARMATRIX_SUBCLASS_OPERATOR_IMPLEMENTATION(1, 4, Vector4) }; MAGNUM_VECTOR_SUBCLASS_OPERATOR_IMPLEMENTATION(Vector4, 4) /** @debugoperator{Magnum::Math::Vector4} */ -template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Magnum::Math::Vector4& value) { - return debug << static_cast&>(value); +template inline Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Vector4& value) { + return debug << static_cast&>(value); } }} diff --git a/src/Mesh.cpp b/src/Mesh.cpp index 85dd74b8e..4cb19a549 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -14,71 +14,83 @@ */ #include "Mesh.h" + +#include + #include "Buffer.h" +#include "Context.h" +#include "Extensions.h" +#include "Implementation/MeshState.h" +#include "Implementation/State.h" using namespace std; namespace Magnum { -Mesh::Mesh(Mesh&& other): - #ifndef MAGNUM_TARGET_GLES - vao(other.vao), - #endif - _primitive(other._primitive), _vertexCount(other._vertexCount), finalized(other.finalized), _buffers(other._buffers), _attributes(other._attributes) -{ - #ifndef MAGNUM_TARGET_GLES - other.vao = 0; - #endif -} +Mesh::CreateImplementation Mesh::createImplementation = &Mesh::createImplementationDefault; +Mesh::DestroyImplementation Mesh::destroyImplementation = &Mesh::destroyImplementationDefault; +Mesh::AttributePointerImplementation Mesh::attributePointerImplementation = &Mesh::attributePointerImplementationDefault; +#ifndef MAGNUM_TARGET_GLES2 +Mesh::AttributeIPointerImplementation Mesh::attributeIPointerImplementation = &Mesh::attributePointerImplementationDefault; +#ifndef MAGNUM_TARGET_GLES +Mesh::AttributeLPointerImplementation Mesh::attributeLPointerImplementation = &Mesh::attributePointerImplementationDefault; +#endif +#endif +Mesh::BindImplementation Mesh::bindImplementation = &Mesh::bindImplementationDefault; +Mesh::UnbindImplementation Mesh::unbindImplementation = &Mesh::unbindImplementationDefault; -void Mesh::destroy() { - for(auto it = _buffers.begin(); it != _buffers.end(); ++it) - delete it->first; +Mesh::~Mesh() { + /* Remove current vao from the state */ + GLuint& current = Context::current()->state()->mesh->currentVAO; + if(current == vao) current = 0; + (this->*destroyImplementation)(); +} + +Mesh::Mesh(Mesh&& other): vao(other.vao), _primitive(other._primitive), _vertexCount(other._vertexCount), attributes(std::move(other.attributes)) + #ifndef MAGNUM_TARGET_GLES2 + , integerAttributes(std::move(other.integerAttributes)) #ifndef MAGNUM_TARGET_GLES - glDeleteVertexArrays(1, &vao); + , longAttributes(std::move(other.longAttributes)) #endif + #endif +{ + other.vao = 0; } Mesh& Mesh::operator=(Mesh&& other) { - destroy(); + (this->*destroyImplementation)(); - #ifndef MAGNUM_TARGET_GLES vao = other.vao; - #endif _primitive = other._primitive; _vertexCount = other._vertexCount; - finalized = other.finalized; - _buffers = other._buffers; - _attributes = other._attributes; - + attributes = std::move(other.attributes); + #ifndef MAGNUM_TARGET_GLES2 + integerAttributes = std::move(other.integerAttributes); #ifndef MAGNUM_TARGET_GLES - other.vao = 0; + longAttributes = std::move(other.longAttributes); + #endif #endif - return *this; -} - -Buffer* Mesh::addBuffer(BufferType interleaved) { - Buffer* buffer = new Buffer(Buffer::Target::Array); - _buffers.insert(make_pair(buffer, make_pair(interleaved, vector()))); + other.vao = 0; - return buffer; + return *this; } -void Mesh::draw() { - /* Vertex array must be bound before finalization */ +Mesh* Mesh::setVertexCount(GLsizei vertexCount) { + _vertexCount = vertexCount; + attributes.clear(); + #ifndef MAGNUM_TARGET_GLES2 + integerAttributes.clear(); #ifndef MAGNUM_TARGET_GLES - bind(); + longAttributes.clear(); #endif + #endif + return this; +} - /* Finalize, if not already */ - finalize(); - - /* Buffers must be bound after initialization */ - #ifdef MAGNUM_TARGET_GLES +void Mesh::draw() { bind(); - #endif /** @todo Start at given index */ glDrawArrays(static_cast(_primitive), 0, _vertexCount); @@ -86,115 +98,169 @@ void Mesh::draw() { unbind(); } -#ifndef DOXYGEN_GENERATING_OUTPUT -void Mesh::bind() { - #ifndef MAGNUM_TARGET_GLES - glBindVertexArray(vao); +void Mesh::bindVAO(GLuint vao) { + /** @todo Get some extension wrangler instead to avoid linker errors to glBindVertexArray() on ES2 */ + #ifndef MAGNUM_TARGET_GLES2 + GLuint& current = Context::current()->state()->mesh->currentVAO; + if(current != vao) glBindVertexArray(current = vao); #else - bindBuffers(); + static_cast(vao); #endif } -void Mesh::unbind() { - #ifndef MAGNUM_TARGET_GLES - glBindVertexArray(0); - #else - for(set::const_iterator it = _attributes.begin(); it != _attributes.end(); ++it) - glDisableVertexAttribArray(*it); - #endif +void Mesh::bind() { + CORRADE_ASSERT((_vertexCount == 0) == attributes.empty(), "Mesh: vertex count is non-zero, but no attributes are bound", ); + + (this->*bindImplementation)(); } -void Mesh::finalize() { - /* Already finalized */ - if(finalized) return; +void Mesh::vertexAttribPointer(const Attribute& attribute) { + glEnableVertexAttribArray(attribute.location); + attribute.buffer->bind(Buffer::Target::Array); + glVertexAttribPointer(attribute.location, attribute.size, attribute.type, attribute.normalized, attribute.stride, reinterpret_cast(attribute.offset)); +} - CORRADE_ASSERT(_vertexCount, "Mesh: the mesh has zero vertex count!", ); +#ifndef MAGNUM_TARGET_GLES2 +void Mesh::vertexAttribPointer(const IntegerAttribute& attribute) { + glEnableVertexAttribArray(attribute.location); + attribute.buffer->bind(Buffer::Target::Array); + glVertexAttribIPointer(attribute.location, attribute.size, attribute.type, attribute.stride, reinterpret_cast(attribute.offset)); +} - /* Finalize attribute positions for every buffer */ - for(auto it = _buffers.begin(); it != _buffers.end(); ++it) { - /* Avoid confustion */ - bool interleaved = it->second.first == BufferType::Interleaved; - vector& attributes = it->second.second; +#ifndef MAGNUM_TARGET_GLES +void Mesh::vertexAttribPointer(const LongAttribute& attribute) { + glEnableVertexAttribArray(attribute.location); + attribute.buffer->bind(Buffer::Target::Array); + glVertexAttribLPointer(attribute.location, attribute.size, attribute.type, attribute.stride, reinterpret_cast(attribute.offset)); +} +#endif +#endif - /* Interleaved buffer, set stride and position of first attribute */ - if(interleaved) { - /* Set attribute position and compute stride */ - GLsizei stride = 0; - for(vector::iterator ait = attributes.begin(); ait != attributes.end(); ++ait) { - /* The attribute is positioned at the end of previous */ - ait->pointer = reinterpret_cast(stride); +void Mesh::initializeContextBasedFunctionality(Context* context) { + /** @todo VAOs are in ES 3.0 and as extension in ES 2.0, enable them when some extension wrangler is available */ + #ifndef MAGNUM_TARGET_GLES + if(context->isExtensionSupported()) { + Debug() << "Mesh: using" << Extensions::GL::APPLE::vertex_array_object::string() << "features"; - /* Add attribute size (per vertex) to stride */ - stride += ait->size*TypeInfo::sizeOf(ait->type); - } + createImplementation = &Mesh::createImplementationVAO; + destroyImplementation = &Mesh::destroyImplementationVAO; - /* Set computed stride for all attributes */ - for(vector::iterator ait = attributes.begin(); ait != attributes.end(); ++ait) - ait->stride = stride; + if(context->isExtensionSupported()) { + Debug() << "Mesh: using" << Extensions::GL::EXT::direct_state_access::string() << "features"; - /* Non-interleaved buffer, set position of every attribute */ + attributePointerImplementation = &Mesh::attributePointerImplementationDSA; + attributeIPointerImplementation = &Mesh::attributePointerImplementationDSA; + attributeLPointerImplementation = &Mesh::attributePointerImplementationDSA; } else { - /* Set attribute position */ - GLsizei position = 0; - for(vector::iterator ait = attributes.begin(); ait != attributes.end(); ++ait) { - /* The attribute is positioned at the end of previous attribute array */ - ait->pointer = reinterpret_cast(position); - - /* Add attribute size (for all vertices) to position */ - position += ait->size*TypeInfo::sizeOf(ait->type)*_vertexCount; - } + attributePointerImplementation = &Mesh::attributePointerImplementationVAO; + attributeIPointerImplementation = &Mesh::attributePointerImplementationVAO; + attributeLPointerImplementation = &Mesh::attributePointerImplementationVAO; } + + bindImplementation = &Mesh::bindImplementationVAO; + unbindImplementation = &Mesh::unbindImplementationVAO; } + #else + static_cast(context); + #endif +} - /* Mesh is now finalized, attribute binding is not allowed */ - finalized = true; +void Mesh::createImplementationDefault() {} - #ifndef MAGNUM_TARGET_GLES - bindBuffers(); +void Mesh::createImplementationVAO() { + /** @todo Get some extension wrangler instead to avoid linker errors to glGenVertexArrays() on ES2 */ + #ifndef MAGNUM_TARGET_GLES2 + glGenVertexArrays(1, &vao); #endif } -void Mesh::bindBuffers() { - /* Enable vertex arrays for all attributes */ - for(set::const_iterator it = _attributes.begin(); it != _attributes.end(); ++it) - glEnableVertexAttribArray(*it); +void Mesh::destroyImplementationDefault() {} - for(auto it = _buffers.begin(); it != _buffers.end(); ++it) { - /* Avoid confusion */ - vector& attributes = it->second.second; +void Mesh::destroyImplementationVAO() { + /** @todo Get some extension wrangler instead to avoid linker errors to glDeleteVertexArrays() on ES2 */ + #ifndef MAGNUM_TARGET_GLES2 + glDeleteVertexArrays(1, &vao); + #endif +} - /* Bind buffer */ - it->first->bind(); +void Mesh::attributePointerImplementationDefault(const Attribute&) {} - /* Bind all attributes to this buffer */ - for(vector::const_iterator ait = attributes.begin(); ait != attributes.end(); ++ait) - #ifndef MAGNUM_TARGET_GLES - if(TypeInfo::isIntegral(ait->type)) - glVertexAttribIPointer(ait->attribute, ait->size, static_cast(ait->type), ait->stride, ait->pointer); - else - #endif - glVertexAttribPointer(ait->attribute, ait->size, static_cast(ait->type), GL_FALSE, ait->stride, ait->pointer); - } +void Mesh::attributePointerImplementationVAO(const Attribute& attribute) { + bindVAO(vao); + vertexAttribPointer(attribute); +} + +#ifndef MAGNUM_TARGET_GLES +void Mesh::attributePointerImplementationDSA(const Attribute& attribute) { + glEnableVertexArrayAttribEXT(vao, attribute.location); + glVertexArrayVertexAttribOffsetEXT(vao, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.normalized, attribute.stride, attribute.offset); } #endif -void Mesh::bindAttribute(Buffer* buffer, GLuint attribute, GLint size, Type type) { - /* The mesh is finalized or attribute is already bound, nothing to do */ - if(finalized || _attributes.find(attribute) != _attributes.end()) return; +#ifndef MAGNUM_TARGET_GLES2 +void Mesh::attributePointerImplementationDefault(const IntegerAttribute&) {} - /* If buffer is not managed by this mesh, nothing to do */ - auto found = _buffers.find(buffer); - if(found == _buffers.end()) return; +void Mesh::attributePointerImplementationVAO(const IntegerAttribute& attribute) { + bindVAO(vao); + vertexAttribPointer(attribute); +} - Attribute a; - a.attribute = attribute; - a.size = size; - a.type = type; - a.stride = 0; - a.pointer = nullptr; +#ifndef MAGNUM_TARGET_GLES +void Mesh::attributePointerImplementationDSA(const IntegerAttribute& attribute) { + glEnableVertexArrayAttribEXT(vao, attribute.location); + glVertexArrayVertexAttribIOffsetEXT(vao, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.stride, attribute.offset); +} +#endif - found->second.second.push_back(a); - _attributes.insert(attribute); +#ifndef MAGNUM_TARGET_GLES +void Mesh::attributePointerImplementationDefault(const LongAttribute&) {} + +void Mesh::attributePointerImplementationVAO(const LongAttribute& attribute) { + bindVAO(vao); + vertexAttribPointer(attribute); } +void Mesh::attributePointerImplementationDSA(const LongAttribute& attribute) { + glEnableVertexArrayAttribEXT(vao, attribute.location); + glVertexArrayVertexAttribLOffsetEXT(vao, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.stride, attribute.offset); +} +#endif +#endif + +void Mesh::bindImplementationDefault() { + for(const Attribute& attribute: attributes) + vertexAttribPointer(attribute); + + #ifndef MAGNUM_TARGET_GLES2 + for(const IntegerAttribute& attribute: integerAttributes) + vertexAttribPointer(attribute); + + #ifndef MAGNUM_TARGET_GLES + for(const LongAttribute& attribute: longAttributes) + vertexAttribPointer(attribute); + #endif + #endif +} + +void Mesh::bindImplementationVAO() { + bindVAO(vao); +} + +void Mesh::unbindImplementationDefault() { + for(const Attribute& attribute: attributes) + glDisableVertexAttribArray(attribute.location); + + #ifndef MAGNUM_TARGET_GLES2 + for(const IntegerAttribute& attribute: integerAttributes) + glDisableVertexAttribArray(attribute.location); + + #ifndef MAGNUM_TARGET_GLES + for(const LongAttribute& attribute: longAttributes) + glDisableVertexAttribArray(attribute.location); + #endif + #endif +} + +void Mesh::unbindImplementationVAO() {} + } diff --git a/src/Mesh.h b/src/Mesh.h index e02b026c1..78a1ee686 100644 --- a/src/Mesh.h +++ b/src/Mesh.h @@ -19,48 +19,181 @@ * @brief Class Magnum::Mesh */ -#include #include -#include +#include -#include "Magnum.h" +#include "AbstractShaderProgram.h" #include "TypeTraits.h" namespace Magnum { class Buffer; +class Context; /** -@brief Base class for managing non-indexed meshes - -VAOs are used for desktop OpenGL (not in OpenGL ES). -@requires_gl30 Extension @extension{APPLE,vertex_array_object} -@requires_gl30 Extension @extension{EXT,gpu_shader4} (for unsigned integer attributes) - -@todo Support for normalized values (e.g. for color as char[4] passed to - shader as floating-point vec4) -@todo Support for provoking vertex (OpenGL 3.2, @extension{ARB,provoking_vertex}) -@todo Support for packed unsigned integer types for attributes (OpenGL 3.3, @extension{ARB,vertex_type_2_10_10_10_rev}) -@todo Support for fixed precision type for attributes (OpenGL 4.1, @extension{ARB,ES2_compatibility}) -@todo Support for double type for attributes (OpenGL 4.1, @extension{ARB,vertex_attrib_64bit}) +@brief Non-indexed mesh + +@section Mesh-configuration Mesh configuration + +To properly configure mesh, you have to set primitive either in constructor or +using setPrimitive() and call setVertexCount(). Then create vertex buffers, +and them with vertex data. You can also use MeshTools::interleave() to +conveniently set vertex count and buffer data. At last assign them to mesh and +@ref AbstractShaderProgram::Attribute "shader attributes" using +addVertexBuffer(), addInterleavedVertexBuffer() or addVertexBufferStride(). + +Note that the buffer is not managed (e.g. deleted on destruction) by the mesh, +so you have to manage it on your own. On the other hand it allows you to use +one buffer for more meshes (each mesh for example configured for different +shader) or store more than only vertex data in one buffer. + +Example usage -- filling buffer with position data, configuring the mesh and +assigning the buffer to mesh to use with custom shader: +@code +class MyShader: public AbstractShaderProgram { + public: + typedef Attribute<0, Point3D> Position; + + // ... +}; +Buffer* buffer; +Mesh* mesh; + +static constexpr Point3D positions[30] = { + // ... +}; +buffer->setData(positions, Buffer::Usage::StaticDraw); + +mesh->setPrimitve(Mesh::Primitive::Triangles) + ->setVertexCount(30) + ->addVertexBuffer(buffer, MyShader::Position()); +@endcode + +Example usage -- creating a plane mesh and assigning buffer with interleaved +vertex attributes for use with Shaders::PhongShader: +@code +Buffer* buffer; +Mesh* mesh; + +Primitives::Plane plane; +MeshTools::interleave(mesh, buffer, Buffer::Usage::StaticDraw, *plane.positions(0), *plane.normals(0)); +mesh->setPrimitive(plane.primitive()) + ->addInterleavedVertexBuffer(buffer, 0, Shaders::PhongShader::Position(), Shaders::PhongShader::Normal()); +@endcode + +Example usage -- passing color attribute as normalized unsigned byte with BGRA +component ordering (e.g. directly from @ref Trade::TgaImporter "TGA file"): +@code +class MyShader: public AbstractShaderProgram { + public: + typedef Attribute<1, Color4> Color; + + // ... +}; +Buffer* buffer; +Mesh* mesh; + +mesh->addVertexBuffer(buffer, MyShader::Color(Type::UsignedByte, MyShader::Color::Normalized|MyShader::Color::BGRA)); +@endcode + +@section Mesh-drawing Rendering meshes + +Basic workflow is to set up respective shader (see @ref AbstractShaderProgram-rendering-workflow "AbstractShaderProgram documentation" for more infromation) and call Mesh::draw(). + +@section Mesh-performance-optimization Performance optimizations + +If @extension{APPLE,vertex_array_object} is supported, VAOs are used instead +of binding the buffers and specifying vertex attribute pointers in each +draw() call. The engine tracks currently bound VAO to avoid unnecessary calls +to @fn_gl{BindVertexArray}. + +If extension @extension{EXT,direct_state_access} and VAOs are available, +DSA functions are used for specifying attribute locations to avoid unnecessary +calls to @fn_gl{BindBuffer} and @fn_gl{BindVertexArray}. See documentation of +addVertexBuffer(), addInterleavedVertexBuffer(), addVertexBufferStride() for +more information. + @todo Support for indirect draw buffer (OpenGL 4.0, @extension{ARB,draw_indirect}) @todo Redo in a way that allows glMultiDrawArrays, glDrawArraysInstanced etc. */ class MAGNUM_EXPORT Mesh { + friend class IndexedMesh; + friend class Context; + Mesh(const Mesh& other) = delete; Mesh& operator=(const Mesh& other) = delete; public: + /** @name Polygon drawing settings */ + + /** + * @brief Front facing polygon winding + * + * @see setFrontFace() + */ + enum FrontFace: GLenum { + /** @brief Counterclockwise polygons are front facing (default). */ + CounterClockWise = GL_CCW, + + /** @brief Clockwise polygons are front facing. */ + ClockWise = GL_CW + }; + + /** + * @brief Set front-facing polygon winding + * + * Initial value is `FrontFace::%CounterClockWise`. + * @see @fn_gl{FrontFace} + */ + inline static void setFrontFace(FrontFace mode) { + glFrontFace(static_cast(mode)); + } + + #ifndef MAGNUM_TARGET_GLES + /** + * @brief Provoking vertex + * + * @see setProvokingVertex() + * @requires_gl OpenGL ES behaves always like + * ProvokingMode::%LastVertexConvention. + * @requires_gl32 Extension @extension{ARB,provoking_vertex}. Older + * versions behave always like + * ProvokingMode::%LastVertexConvention. + */ + enum class ProvokingVertex: GLenum { + /** @brief Use first vertex of each polygon. */ + FirstVertexConvention = GL_FIRST_VERTEX_CONVENTION, + + /** @brief Use last vertex of each polygon (default). */ + LastVertexConvention = GL_LAST_VERTEX_CONVENTION + }; + + /** + * @brief Set provoking vertex + * + * Initial value is ProvokingMode::%LastVertexConvention. + * @see @fn_gl{ProvokingVertex} + * @requires_gl OpenGL ES behaves always like the default. + * @requires_gl32 Extension @extension{ARB,provoking_vertex}. Older + * versions behave always like the default. + */ + inline static void setProvokingVertex(ProvokingVertex mode) { + glProvokingVertex(static_cast(mode)); + } + #endif + #ifndef MAGNUM_TARGET_GLES /** * @brief Polygon mode * * @see setPolygonMode() - * @requires_gl + * @requires_gl OpenGL ES behaves always like + * PolygonMode::%Fill. See setPrimitive() for possible + * workaround. */ enum class PolygonMode: GLenum { /** - * Interior of the polygon is filled. + * Interior of the polygon is filled (default). */ Fill = GL_FILL, @@ -77,81 +210,74 @@ class MAGNUM_EXPORT Mesh { }; #endif + #ifndef MAGNUM_TARGET_GLES /** - * @brief Primitive type + * @brief Set polygon drawing mode * - * @see primitive(), setPrimitive() + * Initial value is `PolygonMode::%Fill`. + * @see @fn_gl{PolygonMode} + * @requires_gl OpenGL ES behaves always like the default. See + * setPrimitive() for possible workaround. */ - enum class Primitive: GLenum { - /** - * Single points - */ - Points = GL_POINTS, - - /** - * Each pair of vertices defines a single line, lines aren't - * connected together. - */ - Lines = GL_LINES, - - /** - * Polyline - */ - LineStrip = GL_LINE_STRIP, + inline static void setPolygonMode(PolygonMode mode) { + glPolygonMode(GL_FRONT_AND_BACK, static_cast(mode)); + } + #endif - /** - * Polyline, last vertex is connected to first. - */ - LineLoop = GL_LINE_LOOP, + /** + * @brief Mode affected by polygon offset + * + * @see setPolygonOffsetMode(), setPolygonOffset() + */ + enum class PolygonOffsetMode: GLenum { + /** Offset filled polygons. */ + Fill = GL_POLYGON_OFFSET_FILL - /** - * Each three vertices define one triangle. - */ - Triangles = GL_TRIANGLES, + #ifndef MAGNUM_TARGET_GLES + , /** - * First three vertices define first triangle, each following - * vertex defines another triangle. + * Offset lines. + * @requires_gl Only PolygonOffset::%Fill is supported. */ - TriangleStrip = GL_TRIANGLE_STRIP, + Line = GL_POLYGON_OFFSET_LINE, /** - * First vertex is center, each following vertex is connected to - * previous and center vertex. + * Offset points. + * @requires_gl Only PolygonOffset::%Fill is supported. */ - TriangleFan = GL_TRIANGLE_FAN + Point = GL_POLYGON_OFFSET_POINT + #endif }; /** - * @brief Buffer type + * @brief Enable/disable polygon offset for given mode * - * If storing more than one attribute data in the buffer, the data of - * one attribute can be either kept together or interleaved with data - * for another attributes, so data for every vertex will be in one - * continuous place. - * @see addBuffer() + * Initially disabled for all modes. + * @see setPolygonOffset(), @fn_gl{Enable}/@fn_gl{Disable} */ - enum class BufferType: bool { - Interleaved, /**< Interleaved buffer */ - NonInterleaved /**< Non-interleaved buffer */ - }; + inline static void setPolygonOffsetMode(PolygonOffsetMode mode, bool enabled) { + enabled ? glEnable(static_cast(mode)) : glDisable(static_cast(mode)); + } - #ifndef MAGNUM_TARGET_GLES /** - * @brief Set polygon drawing mode + * @brief Set polygon offset + * @param factor Scale factor + * @param units Offset units * - * Initial value is PolygonMode::Fill. - * @requires_gl + * @attention You have to call setPolygonOffsetMode() to enable + * polygon offset for desired polygon modes. + * @see @fn_gl{PolygonOffset} */ - inline static void setPolygonMode(PolygonMode mode) { - glPolygonMode(GL_FRONT_AND_BACK, static_cast(mode)); + inline static void setPolygonOffset(GLfloat factor, GLfloat units) { + glPolygonOffset(factor, units); } - #endif /** * @brief Set line width * - * Initial value is 1. + * Initial value is `1.0f`. + * @see @fn_gl{LineWidth} */ inline static void setLineWidth(GLfloat width) { glLineWidth(width); @@ -161,7 +287,8 @@ class MAGNUM_EXPORT Mesh { /** * @brief Set point size * - * @see setProgramPointSize() + * Initial value is `1.0f`. + * @see setProgramPointSize(), @fn_gl{PointSize} * @requires_gl Set directly in vertex shader using @c gl_PointSize * builtin variable. */ @@ -173,38 +300,72 @@ class MAGNUM_EXPORT Mesh { * @brief Enable/disable programmable point size * * If enabled, the point size is taken from vertex/geometry shader - * builtin `gl_PointSize`. - * @see setPointSize() - * @requires_gl Always enabled. + * builtin `gl_PointSize`. Initially disabled on desktop OpenGL. + * @see setPointSize(), @fn_gl{Enable}/@fn_gl{Disable} with @def_gl{PROGRAM_POINT_SIZE} + * @requires_gl Always enabled on OpenGL ES. */ inline static void setProgramPointSize(bool enabled) { enabled ? glEnable(GL_PROGRAM_POINT_SIZE) : glDisable(GL_PROGRAM_POINT_SIZE); } #endif + /*@}*/ + /** - * @brief Implicit constructor - * @param primitive Primitive type + * @brief Primitive type * - * Allows creating the object without knowing anything about mesh - * data. Note that you have to call setVertexCount() manually for mesh - * to draw properly. + * @see primitive(), setPrimitive() */ - inline Mesh(Primitive primitive = Primitive::Triangles): _primitive(primitive), _vertexCount(0), finalized(false) { - #ifndef MAGNUM_TARGET_GLES - glGenVertexArrays(1, &vao); - #endif - } + enum class Primitive: GLenum { + /** + * Single points + */ + Points = GL_POINTS, + + /** + * Each pair of vertices defines a single line, lines aren't + * connected together. + */ + Lines = GL_LINES, + + /** + * Polyline + */ + LineStrip = GL_LINE_STRIP, + + /** + * Polyline, last vertex is connected to first. + */ + LineLoop = GL_LINE_LOOP, + + /** + * Each three vertices define one triangle. + */ + Triangles = GL_TRIANGLES, + + /** + * First three vertices define first triangle, each following + * vertex defines another triangle. + */ + TriangleStrip = GL_TRIANGLE_STRIP, + + /** + * First vertex is center, each following vertex is connected to + * previous and center vertex. + */ + TriangleFan = GL_TRIANGLE_FAN + }; /** * @brief Constructor * @param primitive Primitive type - * @param vertexCount Vertex count + * + * Creates mesh with no vertex buffers and zero vertex count. + * @see setPrimitive(), setVertexCount(), @fn_gl{GenVertexArrays} (if + * @extension{APPLE,vertex_array_object} is available) */ - inline Mesh(Primitive primitive, GLsizei vertexCount): _primitive(primitive), _vertexCount(vertexCount), finalized(false) { - #ifndef MAGNUM_TARGET_GLES - glGenVertexArrays(1, &vao); - #endif + inline Mesh(Primitive primitive = Primitive::Triangles): _primitive(primitive), _vertexCount(0) { + (this->*createImplementation)(); } /** @brief Move constructor */ @@ -213,140 +374,370 @@ class MAGNUM_EXPORT Mesh { /** * @brief Destructor * - * Deletes all associated buffers. + * @see @fn_gl{DeleteVertexArrays} (if + * @extension{APPLE,vertex_array_object} is available) */ - inline virtual ~Mesh() { destroy(); } + virtual ~Mesh(); /** @brief Move assignment */ Mesh& operator=(Mesh&& other); - /** - * @brief Whether the mesh is finalized - * - * When the mesh is finalized, no new attributes can be bound. - */ - inline bool isFinalized() const { return finalized; } - /** @brief Primitive type */ inline Primitive primitive() const { return _primitive; } - /** @brief Set primitive type */ - inline void setPrimitive(Primitive primitive) { _primitive = primitive; } + /** + * @brief Set primitive type + * @return Pointer to self (for method chaining) + */ + inline Mesh* setPrimitive(Primitive primitive) { + _primitive = primitive; + return this; + } /** @brief Vertex count */ inline GLsizei vertexCount() const { return _vertexCount; } /** * @brief Set vertex count + * @return Pointer to self (for method chaining) * - * This forces recalculation of attribute positions upon next drawing. + * @attention All bound attributes are reset after calling this + * function, so you must call + * addVertexBuffer()/addInterleavedVertexBuffer() afterwards. + * @see MeshTools::interleave() */ - inline void setVertexCount(GLsizei vertexCount) { - _vertexCount = vertexCount; - finalized = false; - } + Mesh* setVertexCount(GLsizei vertexCount); /** - * @brief Add buffer - * @param interleaved Whether the buffer is interleaved + * @brief Add buffer with non-interleaved vertex attributes for use with given shader + * + * Attribute list is combination of + * @ref AbstractShaderProgram::Attribute "attribute definitions" + * (specified in implementation of given shader) and offsets between + * attribute arrays. + * + * See @ref Mesh-configuration "class documentation" for simple usage + * example. For more involved example imagine that you have buffer + * with 35 bytes of some other data at the beginning (possibly material + * configuration), then position array, then texture coordinate array + * and then normal array. You want to draw it with Shaders::PhongShader, + * but it accepts only position and normal, so you have to skip the + * texture coordinate array: + * @code + * Mesh* mesh; + * Buffer* buffer; + * mesh->addVertexBuffer(buffer, + * 35, // skip other data + * Shaders::PhongShader::Position(), // position array + * sizeof(Vector2)*mesh->vertexCount(), // skip texture coordinate array + * Shaders::PhongShader::Normal()); // normal array + * @endcode * - * Adds new buffer to the mesh. The buffer can be then filled with - * Buffer::setData(). See also isInterleaved(). + * Vou can also achieve the same effect by calling this function more + * times with absolute offsets: + * @code + * mesh->addVertexBuffer(buffer, 35, Shaders::PhongShader::Position()); + * ->addVertexBuffer(buffer, 35 + (sizeof(Shaders::PhongShader::Position::Type) + sizeof(Vector2))* + * mesh->vertexCount(), Shaders::PhongShader::Normal()); + * @endcode * - * @todo Move interleaveability to Buffer itself? + * @attention Non-zero vertex count must be set before calling this + * function. + * @attention The buffer passed as parameter is not managed by the + * mesh, you must ensure it will exist for whole lifetime of the + * mesh and delete it afterwards. + * + * @see addInterleavedVertexBuffer(), addVertexBufferStride(), + * @fn_gl{BindVertexArray}, @fn_gl{EnableVertexAttribArray}, + * @fn_gl{BindBuffer}, @fn_gl{VertexAttribPointer} or + * @fn_gl_extension{EnableVertexArrayAttrib,EXT,direct_state_access}, + * @fn_gl_extension{VertexArrayVertexAttribOffset,EXT,direct_state_access} + * if @extension{APPLE,vertex_array_object} is available */ - Buffer* addBuffer(BufferType interleaved); + template inline Mesh* addVertexBuffer(Buffer* buffer, const T&... attributes) { + CORRADE_ASSERT(_vertexCount != 0, "Mesh: vertex count must be set before binding attributes", this); + + addVertexBufferInternal(buffer, 0, attributes...); + return this; + } /** - * @brief Whether given buffer is interleaved - * @return True if the buffer belongs to the mesh and the buffer is - * interleaved, false otherwise. + * @brief Add buffer with interleaved vertex attributes for use with given shader * - * See also addBuffer(). + * Parameter @p offset is offset of the interleaved array from the + * beginning, attribute list is combination of + * @ref AbstractShaderProgram::Attribute "attribute definitions" + * (specified in implementation of given shader) and offsets between + * attributes. + * + * See @ref Mesh-configuration "class documentation" for simple usage + * example. For more involved example imagine that you have buffer + * with 35 bytes of some other data at the beginning (possibly material + * configuration) and then the interleaved vertex array. Each vertex + * consists of weight, position, texture coordinate and normal. You + * want to draw it with Shaders::PhongShader, but it accepts only + * position and normal, so you have to skip weight and texture + * coordinate in each vertex: + * @code + * Mesh* mesh; + * Buffer* buffer; + * mesh->addInterleavedVertexBuffer(buffer, + * 35, // skip other data + * sizeof(GLfloat), // skip vertex weight + * Shaders::PhongShader::Position(), // vertex position + * sizeof(Vector2), // skip texture coordinates + * Shaders::PhongShader::Normal()); // vertex normal + * @endcode + * + * You can also achieve the same effect by calling addVertexBufferStride() + * more times with absolute offset from the beginning and stride + * between vertex attributes: + * @code + * GLsizei stride = // size of one vertex + * sizeof(GLfloat) + + * sizeof(Shaders::PhongShader::Position::Type) + + * sizeof(Vector2) + + * sizeof(Shaders::PhongShader::Normal::Type); + * + * mesh->addVertexBufferStride(buffer, 35 + sizeof(GLfloat), + * stride, Shaders::PhongShader::Position()); + * ->addVertexBufferStride(buffer, 35 + sizeof(GLfloat) + + * sizeof(Shaders::PhongShader::Position::Type) + sizeof(Vector2), + * stride, Shaders::PhongShader::Normal()); + * @endcode + * + * @attention The buffer passed as parameter is not managed by the + * mesh, you must ensure it will exist for whole lifetime of the + * mesh and delete it afterwards. + * + * @see addVertexBufferStride(), addVertexBuffer(), + * @fn_gl{BindVertexArray}, @fn_gl{EnableVertexAttribArray}, + * @fn_gl{BindBuffer}, @fn_gl{VertexAttribPointer} or + * @fn_gl_extension{EnableVertexArrayAttrib,EXT,direct_state_access}, + * @fn_gl_extension{VertexArrayVertexAttribOffset,EXT,direct_state_access} + * if @extension{APPLE,vertex_array_object} is available */ - inline bool isInterleaved(Buffer* buffer) const { - auto found = _buffers.find(buffer); - return found != _buffers.end() && found->second.first == BufferType::Interleaved; + template inline Mesh* addInterleavedVertexBuffer(Buffer* buffer, GLintptr offset, const T&... attributes) { + addInterleavedVertexBufferInternal(buffer, offset, strideOfInterleaved(attributes...), attributes...); + return this; } /** - * @brief Bind attribute - * @tparam attribute Attribute, defined in the shader - * @param buffer Buffer where bind the attribute to (pointer - * returned by addBuffer()) + * @brief Add buffer with interleaved vertex attributes for use with given shader * - * Binds attribute of given type with given buffer. If the attribute is - * already bound, given buffer isn't managed with this mesh (wasn't - * initialized with addBuffer) or the mesh was already drawn, the - * function does nothing. + * See addInterleavedVertexBuffer() for more information. */ - template inline void bindAttribute(Buffer* buffer) { - bindAttribute(buffer, Attribute::Location, TypeTraits::count(), TypeTraits::type()); + template inline Mesh* addVertexBufferStride(Buffer* buffer, GLintptr offset, GLsizei stride, const AbstractShaderProgram::Attribute& attribute) { + addInterleavedVertexBufferInternal(buffer, offset, stride, attribute); + return this; } /** * @brief Draw the mesh * - * Expects an active shader with all uniforms set. + * Expects an active shader with all uniforms set. See + * @ref AbstractShaderProgram-rendering-workflow "AbstractShaderProgram documentation" + * for more information. + * @see @fn_gl{EnableVertexAttribArray}, @fn_gl{BindBuffer}, + * @fn_gl{VertexAttribPointer}, @fn_gl{DisableVertexAttribArray} + * or @fn_gl{BindVertexArray} (if @extension{APPLE,vertex_array_object} + * is available), @fn_gl{DrawArrays} */ virtual void draw(); - protected: + private: #ifndef DOXYGEN_GENERATING_OUTPUT - /** @brief Bind all buffers */ - void bindBuffers(); + struct MAGNUM_LOCAL Attribute { + Buffer* buffer; + GLuint location; + GLint size; + GLenum type; + bool normalized; + GLintptr offset; + GLsizei stride; + }; - /** @brief Bind vertex array or all buffers */ - void bind(); + #ifndef MAGNUM_TARGET_GLES2 + struct MAGNUM_LOCAL IntegerAttribute { + Buffer* buffer; + GLuint location; + GLint size; + GLenum type; + GLintptr offset; + GLsizei stride; + }; - /** @brief Unbind vertex array or all buffers */ - void unbind(); + #ifndef MAGNUM_TARGET_GLES + struct MAGNUM_LOCAL LongAttribute { + Buffer* buffer; + GLuint location; + GLint size; + GLenum type; + GLintptr offset; + GLsizei stride; + }; + #endif + #endif + #endif - /** - * @brief Finalize the mesh - * - * Computes location and stride of each attribute in its buffer. After - * this function is called, no new attribute can be bound. - */ - MAGNUM_LOCAL void finalize(); + static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context); + + /* Adding non-interleaved vertex attributes */ + template inline void addVertexBufferInternal(Buffer* buffer, GLintptr offset, const AbstractShaderProgram::Attribute& attribute, const U&... attributes) { + addVertexAttribute(buffer, attribute, offset, 0); + + /* Add size of this attribute array to offset for next attribute */ + addVertexBufferInternal(buffer, offset+TypeTraits::count()*TypeTraits::size()*_vertexCount, attributes...); + } + template inline void addVertexBufferInternal(Buffer* buffer, GLintptr offset, GLintptr gap, const T&... attributes) { + /* Add the gap to offset for next attribute */ + addVertexBufferInternal(buffer, offset+gap, attributes...); + } + inline void addVertexBufferInternal(Buffer*, GLintptr) {} + + /* Computing stride of interleaved vertex attributes */ + template inline static GLsizei strideOfInterleaved(const AbstractShaderProgram::Attribute&, const U&... attributes) { + return TypeTraits::count()*TypeTraits::size() + strideOfInterleaved(attributes...); + } + template inline static GLsizei strideOfInterleaved(GLintptr gap, const T&... attributes) { + return gap + strideOfInterleaved(attributes...); + } + inline static GLsizei strideOfInterleaved() { return 0; } + + /* Adding interleaved vertex attributes */ + template inline void addInterleavedVertexBufferInternal(Buffer* buffer, GLintptr offset, GLsizei stride, const AbstractShaderProgram::Attribute& attribute, const U&... attributes) { + addVertexAttribute(buffer, attribute, offset, stride); + + /* Add size of this attribute to offset for next attribute */ + addInterleavedVertexBufferInternal(buffer, offset+TypeTraits::count()*TypeTraits::size(), stride, attributes...); + } + template inline void addInterleavedVertexBufferInternal(Buffer* buffer, GLintptr offset, GLsizei stride, GLintptr gap, const T&... attributes) { + /* Add the gap to offset for next attribute */ + addInterleavedVertexBufferInternal(buffer, offset+gap, stride, attributes...); + } + inline void addInterleavedVertexBufferInternal(Buffer*, GLsizei, GLintptr) {} + + template inline void addVertexAttribute(typename std::enable_if::AttributeType, GLfloat>::value, Buffer*>::type buffer, const AbstractShaderProgram::Attribute& attribute, GLintptr offset, GLsizei stride) { + for(GLuint i = 0; i != Implementation::Attribute::vectorCount(); ++i) { + attributes.push_back({ + buffer, + location+i, + Implementation::Attribute::size(attribute.dataOptions()), + static_cast(attribute.dataType()), + !!(attribute.dataOptions() & AbstractShaderProgram::Attribute::DataOption::Normalized), + offset, + stride + }); + } + + (this->*attributePointerImplementation)(attributes.back()); + } + + #ifndef MAGNUM_TARGET_GLES2 + template inline void addVertexAttribute(typename std::enable_if::AttributeType>::value, Buffer*>::type buffer, const AbstractShaderProgram::Attribute& attribute, GLintptr offset, GLsizei stride) { + integerAttributes.push_back({ + buffer, + location, + Implementation::Attribute::size(), + static_cast(attribute.dataType()), + offset, + stride + }); + + (this->*attributeIPointerImplementation)(integerAttributes.back()); + } + + #ifndef MAGNUM_TARGET_GLES + template inline void addVertexAttribute(typename std::enable_if::AttributeType, GLdouble>::value, Buffer*>::type buffer, const AbstractShaderProgram::Attribute& attribute, GLintptr offset, GLsizei stride) { + for(GLuint i = 0; i != Implementation::Attribute::vectorCount(); ++i) { + longAttributes.push_back({ + buffer, + location+i, + Implementation::Attribute::size(), + static_cast(attribute.dataType()), + offset, + stride + }); + + (this->*attributeLPointerImplementation)(longAttributes.back()); + } + } + #endif #endif - private: - /** @brief Vertex attribute */ - struct MAGNUM_LOCAL Attribute { - GLuint attribute; /**< @brief %Attribute ID */ - GLint size; /**< @brief How many items of `type` are in the attribute */ - Type type; /**< @brief %Attribute item type */ - GLsizei stride; /**< @brief Distance of two adjacent attributes of this type in interleaved buffer */ - const GLvoid* pointer; /**< @brief Pointer to first attribute of this type in the buffer */ - }; + static void MAGNUM_LOCAL bindVAO(GLuint vao); + + void MAGNUM_LOCAL bind(); + inline void unbind() { + (this->*unbindImplementation)(); + } + + void MAGNUM_LOCAL vertexAttribPointer(const Attribute& attribute); + #ifndef MAGNUM_TARGET_GLES2 + void MAGNUM_LOCAL vertexAttribPointer(const IntegerAttribute& attribute); #ifndef MAGNUM_TARGET_GLES - GLuint vao; + void MAGNUM_LOCAL vertexAttribPointer(const LongAttribute& attribute); + #endif #endif - Primitive _primitive; - GLsizei _vertexCount; - bool finalized; - /** - * @brief Buffers with their attributes - * - * Map of associated buffers, evey buffer has: - * - boolean value which signalizes whether the buffer is interleaved - * - list of bound attributes - */ - std::map > > _buffers; + typedef void(Mesh::*CreateImplementation)(); + void MAGNUM_LOCAL createImplementationDefault(); + void MAGNUM_LOCAL createImplementationVAO(); + static CreateImplementation createImplementation; - /** - * @brief List of all bound attributes - * - * List of all bound attributes bound with bindAttribute(). - */ - std::set _attributes; + typedef void(Mesh::*DestroyImplementation)(); + void MAGNUM_LOCAL destroyImplementationDefault(); + void MAGNUM_LOCAL destroyImplementationVAO(); + static MAGNUM_LOCAL DestroyImplementation destroyImplementation; - MAGNUM_EXPORT void bindAttribute(Buffer* buffer, GLuint attribute, GLint size, Type type); + typedef void(Mesh::*AttributePointerImplementation)(const Attribute&); + void MAGNUM_LOCAL attributePointerImplementationDefault(const Attribute& attribute); + void MAGNUM_LOCAL attributePointerImplementationVAO(const Attribute& attribute); + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL attributePointerImplementationDSA(const Attribute& attribute); + #endif + static AttributePointerImplementation attributePointerImplementation; + + #ifndef MAGNUM_TARGET_GLES2 + typedef void(Mesh::*AttributeIPointerImplementation)(const IntegerAttribute&); + void MAGNUM_LOCAL attributePointerImplementationDefault(const IntegerAttribute& attribute); + void MAGNUM_LOCAL attributePointerImplementationVAO(const IntegerAttribute& attribute); + #ifndef MAGNUM_TARGET_GLES + void MAGNUM_LOCAL attributePointerImplementationDSA(const IntegerAttribute& attribute); + #endif + static AttributeIPointerImplementation attributeIPointerImplementation; - void destroy(); + #ifndef MAGNUM_TARGET_GLES + typedef void(Mesh::*AttributeLPointerImplementation)(const LongAttribute&); + void MAGNUM_LOCAL attributePointerImplementationDefault(const LongAttribute& attribute); + void MAGNUM_LOCAL attributePointerImplementationVAO(const LongAttribute& attribute); + void MAGNUM_LOCAL attributePointerImplementationDSA(const LongAttribute& attribute); + static AttributeLPointerImplementation attributeLPointerImplementation; + #endif + #endif + + typedef void(Mesh::*BindImplementation)(); + void MAGNUM_LOCAL bindImplementationDefault(); + void MAGNUM_LOCAL bindImplementationVAO(); + static MAGNUM_LOCAL BindImplementation bindImplementation; + + typedef void(Mesh::*UnbindImplementation)(); + void MAGNUM_LOCAL unbindImplementationDefault(); + void MAGNUM_LOCAL unbindImplementationVAO(); + static MAGNUM_LOCAL UnbindImplementation unbindImplementation; + + GLuint vao; + Primitive _primitive; + GLsizei _vertexCount; + + std::vector attributes; + #ifndef MAGNUM_TARGET_GLES2 + std::vector integerAttributes; + #ifndef MAGNUM_TARGET_GLES + std::vector longAttributes; + #endif + #endif }; } diff --git a/src/MeshTools/CMakeLists.txt b/src/MeshTools/CMakeLists.txt index 677c6370e..7384e1c8f 100644 --- a/src/MeshTools/CMakeLists.txt +++ b/src/MeshTools/CMakeLists.txt @@ -1,5 +1,6 @@ # Files shared between main library and unit test library set(MagnumMeshTools_SRCS + CompressIndices.cpp Tipsify.cpp) set(MagnumMeshTools_HEADERS Clean.h @@ -10,6 +11,7 @@ set(MagnumMeshTools_HEADERS Interleave.h Subdivide.h Tipsify.h + Transform.h magnumMeshToolsVisibility.h) if(NOT CMAKE_NO_OBJECT_TARGET) diff --git a/src/MeshTools/Clean.h b/src/MeshTools/Clean.h index c0ed5ce2f..09a68d58c 100644 --- a/src/MeshTools/Clean.h +++ b/src/MeshTools/Clean.h @@ -23,6 +23,7 @@ #include #include +#include "Math/Vector.h" #include "TypeTraits.h" namespace Magnum { namespace MeshTools { @@ -30,41 +31,41 @@ namespace Magnum { namespace MeshTools { #ifndef DOXYGEN_GENERATING_OUTPUT namespace Implementation { -template class Clean { +template class Clean { public: - inline Clean(std::vector& indices, std::vector& vertices): indices(indices), vertices(vertices) {} + inline Clean(std::vector& indices, std::vector& vertices): indices(indices), vertices(vertices) {} void operator()(typename Vertex::Type epsilon = TypeTraits::epsilon()) { if(indices.empty()) return; /* Get mesh bounds */ Vertex min, max; - for(size_t i = 0; i != Vertex::size; ++i) { + for(std::size_t i = 0; i != Vertex::Size; ++i) { min[i] = std::numeric_limits::max(); max[i] = std::numeric_limits::min(); } for(auto it = vertices.cbegin(); it != vertices.cend(); ++it) - for(size_t i = 0; i != vertexSize; ++i) + for(std::size_t i = 0; i != vertexSize; ++i) if((*it)[i] < min[i]) min[i] = (*it)[i]; else if((*it)[i] > max[i]) max[i] = (*it)[i]; - /* Make epsilon so large that size_t can index all vertices inside - mesh bounds. */ + /* Make epsilon so large that std::size_t can index all vertices + inside mesh bounds. */ Vertex size = max-min; - for(size_t i = 0; i != Vertex::size; ++i) - if(static_cast(size[i]/std::numeric_limits::max()) > epsilon) - epsilon = static_cast(size[i]/std::numeric_limits::max()); + for(std::size_t i = 0; i != Vertex::Size; ++i) + if(static_cast(size[i]/std::numeric_limits::max()) > epsilon) + epsilon = static_cast(size[i]/std::numeric_limits::max()); /* First go with original vertex coordinates, then move them by epsilon/2 in each direction. */ Vertex moved; - for(size_t moving = 0; moving <= vertexSize; ++moving) { + for(std::size_t moving = 0; moving <= vertexSize; ++moving) { /* Under each index is pointer to face which contains given vertex and index of vertex in the face. */ - std::unordered_map, HashedVertex, IndexHash> table; + std::unordered_map, HashedVertex, IndexHash> table; #ifndef CORRADE_GCC44_COMPATIBILITY /* Reserve space for all vertices */ @@ -74,15 +75,15 @@ template class Clean { /* Go through all faces' vertices */ for(auto it = indices.begin(); it != indices.end(); ++it) { /* Index of a vertex in vertexSize-dimensional table */ - size_t index[vertexSize]; - for(size_t ii = 0; ii != vertexSize; ++ii) + std::size_t index[vertexSize]; + for(std::size_t ii = 0; ii != vertexSize; ++ii) index[ii] = (vertices[*it][ii]+moved[ii]-min[ii])/epsilon; /* Try inserting the vertex into table, if it already exists, change vertex pointer of the face to already existing vertex */ HashedVertex v(*it, table.size()); - auto result = table.insert(std::pair, HashedVertex>(Math::Vector::from(index), v)); + auto result = table.insert(std::pair, HashedVertex>(Math::Vector::from(index), v)); *it = result.first->second.newIndex; } @@ -93,7 +94,7 @@ template class Clean { std::swap(newVertices, vertices); /* Move vertex coordinates by epsilon/2 in next direction */ - if(moving != Vertex::size) { + if(moving != Vertex::Size) { moved = Vertex(); moved[moving] = epsilon/2; } @@ -103,18 +104,18 @@ template class Clean { private: class IndexHash { public: - inline size_t operator()(const Math::Vector& data) const { - return *reinterpret_cast(Corrade::Utility::MurmurHash2()(reinterpret_cast(&data), sizeof(data)).byteArray()); + inline std::size_t operator()(const Math::Vector& data) const { + return *reinterpret_cast(Corrade::Utility::MurmurHash2()(reinterpret_cast(&data), sizeof(data)).byteArray()); } }; struct HashedVertex { - unsigned int oldIndex, newIndex; + std::uint32_t oldIndex, newIndex; - HashedVertex(unsigned int oldIndex, unsigned int newIndex): oldIndex(oldIndex), newIndex(newIndex) {} + HashedVertex(std::uint32_t oldIndex, std::uint32_t newIndex): oldIndex(oldIndex), newIndex(newIndex) {} }; - std::vector& indices; + std::vector& indices; std::vector& vertices; }; @@ -138,7 +139,7 @@ Removes duplicate vertices from the mesh. @todo Interpolate vertices, not collapse them to first in the cell @todo Ability to specify other attributes for interpolation */ -template inline void clean(std::vector& indices, std::vector& vertices, typename Vertex::Type epsilon = TypeTraits::epsilon()) { +template inline void clean(std::vector& indices, std::vector& vertices, typename Vertex::Type epsilon = TypeTraits::epsilon()) { Implementation::Clean(indices, vertices)(epsilon); } diff --git a/src/MeshTools/CombineIndexedArrays.h b/src/MeshTools/CombineIndexedArrays.h index 612e8fce3..a5d229614 100644 --- a/src/MeshTools/CombineIndexedArrays.h +++ b/src/MeshTools/CombineIndexedArrays.h @@ -33,17 +33,17 @@ namespace Implementation { class CombineIndexedArrays { public: - template std::vector operator()(const std::tuple&, std::vector&>&... indexedArrays) { + template std::vector operator()(const std::tuple&, std::vector&>&... indexedArrays) { /* Compute index count */ - size_t _indexCount = indexCount(std::get<0>(indexedArrays)...); + std::size_t _indexCount = indexCount(std::get<0>(indexedArrays)...); /* Resulting index array */ - std::vector result; + std::vector result; result.resize(_indexCount); std::iota(result.begin(), result.end(), 0); /* All index combinations */ - std::vector > indexCombinations(_indexCount); + std::vector > indexCombinations(_indexCount); writeCombinedIndices(indexCombinations, std::get<0>(indexedArrays)...); /* Make the combinations unique */ @@ -56,24 +56,24 @@ class CombineIndexedArrays { } private: - template inline static size_t indexCount(const std::vector& first, const std::vector&... next) { + template inline static std::size_t indexCount(const std::vector& first, const std::vector&... next) { CORRADE_ASSERT(sizeof...(next) == 0 || indexCount(next...) == first.size(), "MeshTools::combineIndexedArrays(): index arrays don't have the same length, nothing done.", 0); return first.size(); } - template static void writeCombinedIndices(std::vector>& output, const std::vector& first, const std::vector&... next) { + template static void writeCombinedIndices(std::vector>& output, const std::vector& first, const std::vector&... next) { /* Copy the data to output */ - for(size_t i = 0; i != output.size(); ++i) + for(std::size_t i = 0; i != output.size(); ++i) output[i][size-sizeof...(next)-1] = first[i]; writeCombinedIndices(output, next...); } - template static void writeCombinedArrays(const std::vector>& combinedIndices, std::vector& first, std::vector&... next) { + template static void writeCombinedArrays(const std::vector>& combinedIndices, std::vector& first, std::vector&... next) { /* Rewrite output array */ std::vector output; - for(size_t i = 0; i != combinedIndices.size(); ++i) + for(std::size_t i = 0; i != combinedIndices.size(); ++i) output.push_back(first[combinedIndices[i][size-sizeof...(next)-1]]); std::swap(output, first); @@ -81,9 +81,9 @@ class CombineIndexedArrays { } /* Terminator functions for recursive calls */ - inline static size_t indexCount() { return 0; } - template inline static void writeCombinedIndices(std::vector>&) {} - template inline static void writeCombinedArrays(const std::vector>&) {} + inline static std::size_t indexCount() { return 0; } + template inline static void writeCombinedIndices(std::vector>&) {} + template inline static void writeCombinedArrays(const std::vector>&) {} }; } @@ -105,19 +105,19 @@ avoid explicit verbose specification of tuple type, you can write it with help of some STL functions like shown below. Also if one index array is shader by more than one attribute array, just pass the index array more times. Example: @code -std::vector vertexIndices; -std::vector vertices; -std::vector normalTextureIndices; +std::vector vertexIndices; +std::vector positions; +std::vector normalTextureIndices; std::vector normals; std::vector textureCoordinates; -std::vector indices = MeshTools::combineIndexedArrays( - std::make_tuple(std::cref(vertexIndices), std::ref(vertices)), +std::vector indices = MeshTools::combineIndexedArrays( + std::make_tuple(std::cref(vertexIndices), std::ref(positions)), std::make_tuple(std::cref(normalTextureIndices), std::ref(normals)), std::make_tuple(std::cref(normalTextureIndices), std::ref(textureCoordinates)) ); @endcode -`vertices`, `normals` and `textureCoordinates` will then contain combined +`positions`, `normals` and `textureCoordinates` will then contain combined attributes indexed with `indices`. @attention All index arrays should have the same size, otherwise zero-length @@ -127,7 +127,7 @@ attributes indexed with `indices`. which parameter is index array and which is attribute array, mainly when both are of the same type. */ -template std::vector combineIndexedArrays(const std::tuple&, std::vector&>&... indexedArrays) { +template std::vector combineIndexedArrays(const std::tuple&, std::vector&>&... indexedArrays) { return Implementation::CombineIndexedArrays()(indexedArrays...); } diff --git a/src/MeshTools/CompressIndices.cpp b/src/MeshTools/CompressIndices.cpp new file mode 100644 index 000000000..f507bdf64 --- /dev/null +++ b/src/MeshTools/CompressIndices.cpp @@ -0,0 +1,68 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "CompressIndices.h" + +#include +#include +#include + +#include "IndexedMesh.h" +#include "SizeTraits.h" + +using namespace std; + +namespace Magnum { namespace MeshTools { + +#ifndef DOXYGEN_GENERATING_OUTPUT +namespace Implementation { + +std::tuple CompressIndices::operator()() const { + #ifndef CORRADE_GCC44_COMPATIBILITY + return SizeBasedCall(*std::max_element(indices.begin(), indices.end()))(indices); + #else + return SizeBasedCall, Compressor>(*std::max_element(indices.begin(), indices.end()))(indices); + #endif +} + +void CompressIndices::operator()(IndexedMesh* mesh, Buffer* buffer, Buffer::Usage usage) const { + size_t indexCount; + Type indexType; + char* data; + std::tie(indexCount, indexType, data) = operator()(); + + mesh->setIndexBuffer(buffer) + ->setIndexType(indexType) + ->setIndexCount(indices.size()); + buffer->setData(indexCount*TypeInfo::sizeOf(indexType), data, usage); + + delete[] data; +} + +template std::tuple CompressIndices::Compressor::run(const std::vector& indices) { + /* Create smallest possible version of index buffer */ + char* buffer = new char[indices.size()*sizeof(IndexType)]; + for(size_t i = 0; i != indices.size(); ++i) { + IndexType index = indices[i]; + memcpy(buffer+i*sizeof(IndexType), reinterpret_cast(&index), sizeof(IndexType)); + } + + return std::make_tuple(indices.size(), TypeTraits::indexType(), buffer); +} + +} +#endif + +}} diff --git a/src/MeshTools/CompressIndices.h b/src/MeshTools/CompressIndices.h index 6aacfc7aa..1ca638eba 100644 --- a/src/MeshTools/CompressIndices.h +++ b/src/MeshTools/CompressIndices.h @@ -19,60 +19,36 @@ * @brief Function Magnum::MeshTools::compressIndices() */ -#include -#include #include -#include +#include "Buffer.h" #include "TypeTraits.h" -#include "SizeTraits.h" -#include "IndexedMesh.h" -namespace Magnum { namespace MeshTools { +#include "magnumMeshToolsVisibility.h" + +namespace Magnum { + +class IndexedMesh; + +namespace MeshTools { #ifndef DOXYGEN_GENERATING_OUTPUT namespace Implementation { -class CompressIndices { +class MESHTOOLS_EXPORT CompressIndices { public: - CompressIndices(const std::vector& indices): indices(indices) {} + CompressIndices(const std::vector& indices): indices(indices) {} - inline std::tuple operator()() const { - #ifndef CORRADE_GCC44_COMPATIBILITY - return SizeBasedCall(*std::max_element(indices.begin(), indices.end()))(indices); - #else - return SizeBasedCall, Compressor>(*std::max_element(indices.begin(), indices.end()))(indices); - #endif - } + std::tuple operator()() const; - void operator()(IndexedMesh* mesh, Buffer::Usage usage) const { - size_t indexCount; - Type indexType; - char* data; - std::tie(indexCount, indexType, data) = operator()(); - - mesh->setIndexType(indexType); - mesh->setIndexCount(indices.size()); - mesh->indexBuffer()->setData(indexCount*TypeInfo::sizeOf(indexType), data, usage); - - delete[] data; - } + void operator()(IndexedMesh* mesh, Buffer* buffer, Buffer::Usage usage) const; private: struct Compressor { - template static std::tuple run(const std::vector& indices) { - /* Create smallest possible version of index buffer */ - char* buffer = new char[indices.size()*sizeof(IndexType)]; - for(size_t i = 0; i != indices.size(); ++i) { - IndexType index = indices[i]; - memcpy(buffer+i*sizeof(IndexType), reinterpret_cast(&index), sizeof(IndexType)); - } - - return std::make_tuple(indices.size(), TypeTraits::indexType(), buffer); - } + template static std::tuple run(const std::vector& indices); }; - const std::vector& indices; + const std::vector& indices; }; } @@ -86,38 +62,43 @@ class CompressIndices { This function takes index array and outputs them compressed to smallest possible size. For example when your indices have maximum number 463, it's -wasteful to store them in array of `unsigned int`s, array of `unsigned short`s -is sufficient. Size of the buffer can be computed from index count and type, -as shown below. Example usage: +wasteful to store them in array of 32bit integers, array of 16bit integers is +sufficient. Size of the buffer can be computed from index count and type, as +shown below. Example usage: @code -size_t indexCount; +std::size_t indexCount; Type indexType; char* data; std::tie(indexCount, indexType, data) = MeshTools::compressIndices(indices); -size_t dataSize = indexCount*TypeInfo::sizeOf(indexType); +std::size_t dataSize = indexCount*TypeInfo::sizeOf(indexType); // ... delete[] data; @endcode -See also compressIndices(IndexedMesh*, Buffer::Usage, const std::vector&), +See also compressIndices(IndexedMesh*, Buffer::Usage, const std::vector&), which writes the compressed data directly into index buffer of given mesh. */ -inline std::tuple compressIndices(const std::vector& indices) { +inline std::tuple compressIndices(const std::vector& indices) { return Implementation::CompressIndices{indices}(); } /** @brief Compress vertex indices and write them to index buffer @param mesh Output mesh +@param buffer Index buffer @param usage Index buffer usage @param indices Index array -The same as compressIndices(const std::vector&), but this -function writes the output to mesh's index buffer and updates index count and -type in the mesh accordingly. +The same as compressIndices(const std::vector&), but this +function writes the output to given index buffer and updates index count and +type in the mesh accordingly, so you don't have to call +IndexedMesh::setIndexBuffer(), IndexedMesh::setIndexCount() and +IndexedMesh::setIndexType() on your own. + +@see MeshTools::interleave() */ -inline void compressIndices(IndexedMesh* mesh, Buffer::Usage usage, const std::vector& indices) { - return Implementation::CompressIndices{indices}(mesh, usage); +inline void compressIndices(IndexedMesh* mesh, Buffer* buffer, Buffer::Usage usage, const std::vector& indices) { + return Implementation::CompressIndices{indices}(mesh, buffer, usage); } }} diff --git a/src/MeshTools/FlipNormals.cpp b/src/MeshTools/FlipNormals.cpp index b3807cfd8..acbc98d27 100644 --- a/src/MeshTools/FlipNormals.cpp +++ b/src/MeshTools/FlipNormals.cpp @@ -15,11 +15,13 @@ #include "FlipNormals.h" +#include "Math/Vector3.h" + using namespace std; namespace Magnum { namespace MeshTools { -void flipFaceWinding(vector& indices) { +void flipFaceWinding(vector& indices) { CORRADE_ASSERT(!(indices.size()%3), "MeshTools::flipNormals(): index count is not divisible by 3!", ); for(size_t i = 0; i != indices.size(); i += 3) diff --git a/src/MeshTools/FlipNormals.h b/src/MeshTools/FlipNormals.h index 191177945..c113e908d 100644 --- a/src/MeshTools/FlipNormals.h +++ b/src/MeshTools/FlipNormals.h @@ -19,7 +19,11 @@ * @brief Function Magnum::MeshTools::flipNormals() */ +#include +#include + #include "Magnum.h" + #include "magnumMeshToolsVisibility.h" namespace Magnum { namespace MeshTools { @@ -27,15 +31,15 @@ namespace Magnum { namespace MeshTools { /** @brief Flip face winding -The same as flipNormals(std::vector&, std::vector&), +The same as flipNormals(std::vector&, std::vector&), but flips only face winding. */ -void MESHTOOLS_EXPORT flipFaceWinding(std::vector& indices); +void MESHTOOLS_EXPORT flipFaceWinding(std::vector& indices); /** @brief Flip mesh normals -The same as flipNormals(std::vector&, std::vector&), +The same as flipNormals(std::vector&, std::vector&), but flips only normals, not face winding. */ void MESHTOOLS_EXPORT flipNormals(std::vector& normals); @@ -52,7 +56,7 @@ flipFaceWinding(), which flip normals or face winding only. @attention The function requires the mesh to have triangle faces, thus index count must be divisible by 3. */ -inline void flipNormals(std::vector& indices, std::vector& normals) { +inline void flipNormals(std::vector& indices, std::vector& normals) { flipFaceWinding(indices); flipNormals(normals); } diff --git a/src/MeshTools/GenerateFlatNormals.cpp b/src/MeshTools/GenerateFlatNormals.cpp index e52e4379e..918d19d68 100644 --- a/src/MeshTools/GenerateFlatNormals.cpp +++ b/src/MeshTools/GenerateFlatNormals.cpp @@ -15,23 +15,24 @@ #include "GenerateFlatNormals.h" +#include "Math/Point3D.h" #include "MeshTools/Clean.h" using namespace std; namespace Magnum { namespace MeshTools { -tuple, vector> generateFlatNormals(const std::vector< unsigned int >& indices, const vector< Vector4 >& vertices) { - CORRADE_ASSERT(!(indices.size()%3), "MeshTools::generateFlatNormals(): index count is not divisible by 3!", (tuple, vector>())); +tuple, vector> generateFlatNormals(const vector& indices, const vector& positions) { + CORRADE_ASSERT(!(indices.size()%3), "MeshTools::generateFlatNormals(): index count is not divisible by 3!", (tuple, vector>())); /* Create normal for every triangle (assuming counterclockwise winding) */ - vector normalIndices; + vector normalIndices; normalIndices.reserve(indices.size()); vector normals; normals.reserve(indices.size()/3); for(size_t i = 0; i != indices.size(); i += 3) { - Vector3 normal = Vector3::cross(vertices[indices[i+2]].xyz()-vertices[indices[i+1]].xyz(), - vertices[indices[i]].xyz()-vertices[indices[i+1]].xyz()).normalized(); + Vector3 normal = Vector3::cross(positions[indices[i+2]].xyz()-positions[indices[i+1]].xyz(), + positions[indices[i]].xyz()-positions[indices[i+1]].xyz()).normalized(); /* Use the same normal for all three vertices of the face */ normalIndices.push_back(normals.size()); diff --git a/src/MeshTools/GenerateFlatNormals.h b/src/MeshTools/GenerateFlatNormals.h index a5dfcbb9b..2e23dfa5e 100644 --- a/src/MeshTools/GenerateFlatNormals.h +++ b/src/MeshTools/GenerateFlatNormals.h @@ -19,9 +19,12 @@ * @brief Function Magnum::MeshTools::generateFlatNormals() */ +#include #include +#include #include "Magnum.h" + #include "magnumMeshToolsVisibility.h" namespace Magnum { namespace MeshTools { @@ -29,18 +32,18 @@ namespace Magnum { namespace MeshTools { /** @brief Generate flat normals @param indices Array of triangle face indexes -@param vertices Vertex array +@param positions Array of vertex positions @return Normal indices and vectors For each face generates one normal vector, removes duplicates before returning. Example usage: @code -std::vector vertexIndices; -std::vector vertices; +std::vector vertexIndices; +std::vector positions; -std::vector normalIndices; +std::vector normalIndices; std::vector normals; -std::tie(normalIndices, normals) = MeshTools::generateFlatNormals(vertexIndices, vertices); +std::tie(normalIndices, normals) = MeshTools::generateFlatNormals(vertexIndices, positions); @endcode You can then use combineIndexedArrays() to combine normal and vertex array to use the same indices. @@ -48,7 +51,7 @@ use the same indices. @attention Index count must be divisible by 3, otherwise zero length result is generated. */ -std::tuple, std::vector> MESHTOOLS_EXPORT generateFlatNormals(const std::vector& indices, const std::vector& vertices); +std::tuple, std::vector> MESHTOOLS_EXPORT generateFlatNormals(const std::vector& indices, const std::vector& positions); }} diff --git a/src/MeshTools/Interleave.h b/src/MeshTools/Interleave.h index 3c7408e52..6f85ef2b2 100644 --- a/src/MeshTools/Interleave.h +++ b/src/MeshTools/Interleave.h @@ -36,7 +36,7 @@ class Interleave { public: inline Interleave(): _attributeCount(0), _stride(0), _data(nullptr) {} - template std::tuple operator()(const T&... attributes) { + template std::tuple operator()(const T&... attributes) { /* Compute buffer size and stride */ _attributeCount = attributeCount(attributes...); if(_attributeCount) { @@ -53,8 +53,6 @@ class Interleave { } template void operator()(Mesh* mesh, Buffer* buffer, Buffer::Usage usage, const T&... attributes) { - CORRADE_ASSERT(mesh->isInterleaved(buffer), "MeshTools::interleave(): the buffer is not interleaved, nothing done", ); - operator()(attributes...); mesh->setVertexCount(_attributeCount); @@ -63,13 +61,19 @@ class Interleave { delete[] _data; } - template inline static size_t attributeCount(const T& first, const U&... next) { + /* Specialization for only one attribute array */ + template void operator()(Mesh* mesh, Buffer* buffer, Buffer::Usage usage, const T& attribute) { + mesh->setVertexCount(attribute.size()); + buffer->setData(attribute, usage); + } + + template inline static std::size_t attributeCount(const T& first, const U&... next) { CORRADE_ASSERT(sizeof...(next) == 0 || attributeCount(next...) == first.size(), "MeshTools::interleave(): attribute arrays don't have the same length, nothing done.", 0); return first.size(); } - template inline static size_t stride(const T&, const U&... next) { + template inline static std::size_t stride(const T&, const U&... next) { return sizeof(typename T::value_type) + stride(next...); } @@ -77,19 +81,19 @@ class Interleave { template void write(char* startingOffset, const T& first, const U&... next) { /* Copy the data to the buffer */ auto it = first.begin(); - for(size_t i = 0; i != _attributeCount; ++i, ++it) + for(std::size_t i = 0; i != _attributeCount; ++i, ++it) memcpy(startingOffset+i*_stride, reinterpret_cast(&*it), sizeof(typename T::value_type)); write(startingOffset+sizeof(typename T::value_type), next...); } /* Terminator functions for recursive calls */ - inline static size_t attributeCount() { return 0; } - inline static size_t stride() { return 0; } + inline static std::size_t attributeCount() { return 0; } + inline static std::size_t stride() { return 0; } inline void write(char*) {} - size_t _attributeCount; - size_t _stride; + std::size_t _attributeCount; + std::size_t _stride; char* _data; }; @@ -108,13 +112,13 @@ so data for each attribute are in continuous place in memory. Size of the data buffer can be computed from attribute count and stride, as shown below. Example usage: @code -std::vector vertices; +std::vector positions; std::vector textureCoordinates; -size_t attributeCount; -size_t stride; +std::size_t attributeCount; +std::size_t stride; char* data; -std::tie(attributeCount, stride, data) = MeshTools::interleave(vertices, textureCoordinates); -size_t dataSize = attributeCount*stride; +std::tie(attributeCount, stride, data) = MeshTools::interleave(positions, textureCoordinates); +std::size_t dataSize = attributeCount*stride; // ... delete[] data; @endcode @@ -124,14 +128,14 @@ The only requirements to attribute array type is that it must have typedef function `size()` returning count of elements. In most cases it will be `std::vector` or `std::array`. -See also interleave(Mesh*, Buffer*, Buffer::Usage, const std::vector&...), +See also interleave(Mesh*, Buffer*, Buffer::Usage, const T&...), which writes the interleaved array directly into buffer of given mesh. @attention Each passed array should have the same size, if not, resulting array has zero length. */ /* enable_if to avoid clash with overloaded function below */ -template inline typename std::enable_if::value, std::tuple>::type interleave(const T& attribute, const U&... attributes) { +template inline typename std::enable_if::value, std::tuple>::type interleave(const T& attribute, const U&... attributes) { return Implementation::Interleave()(attribute, attributes...); } @@ -142,12 +146,21 @@ template inline typename std::enable_ifsetData(attribute, usage); +mesh->setVertexCount(attribute.size()); +@endcode -@attention The buffer must be set as interleaved (see Mesh::addBuffer()), - otherwise this function does nothing. Binding the attributes to shader is - left to user. +@see MeshTools::compressIndices() */ template inline void interleave(Mesh* mesh, Buffer* buffer, Buffer::Usage usage, const T&... attributes) { return Implementation::Interleave()(mesh, buffer, usage, attributes...); diff --git a/src/MeshTools/Subdivide.h b/src/MeshTools/Subdivide.h index ab2c27dc8..8993bb4da 100644 --- a/src/MeshTools/Subdivide.h +++ b/src/MeshTools/Subdivide.h @@ -29,18 +29,18 @@ namespace Implementation { template class Subdivide { public: - inline Subdivide(std::vector& indices, std::vector& vertices): indices(indices), vertices(vertices) {} + inline Subdivide(std::vector& indices, std::vector& vertices): indices(indices), vertices(vertices) {} void operator()(Interpolator interpolator) { CORRADE_ASSERT(!(indices.size()%3), "MeshTools::subdivide(): index count is not divisible by 3!", ); - size_t indexCount = indices.size(); + std::size_t indexCount = indices.size(); indices.reserve(indices.size()*4); /* Subdivide each face to four new */ - for(size_t i = 0; i != indexCount; i += 3) { + for(std::size_t i = 0; i != indexCount; i += 3) { /* Interpolate each side */ - unsigned int newVertices[3]; + std::uint32_t newVertices[3]; for(int j = 0; j != 3; ++j) newVertices[j] = addVertex(interpolator(vertices[indices[i+j]], vertices[indices[i+(j+1)%3]])); @@ -60,21 +60,21 @@ template class Subdivide { addFace(indices[i], newVertices[0], newVertices[2]); addFace(newVertices[0], indices[i+1], newVertices[1]); addFace(newVertices[2], newVertices[1], indices[i+2]); - for(size_t j = 0; j != 3; ++j) + for(std::size_t j = 0; j != 3; ++j) indices[i+j] = newVertices[j]; } } private: - std::vector& indices; + std::vector& indices; std::vector& vertices; - unsigned int addVertex(const Vertex& v) { + std::uint32_t addVertex(const Vertex& v) { vertices.push_back(v); return vertices.size()-1; } - void addFace(unsigned int first, unsigned int second, unsigned int third) { + void addFace(std::uint32_t first, std::uint32_t second, std::uint32_t third) { indices.push_back(first); indices.push_back(second); indices.push_back(third); @@ -96,7 +96,7 @@ template class Subdivide { Goes through all triangle faces and subdivides them into four new. Cleaning duplicate vertices in the mesh is up to user. */ -template inline void subdivide(std::vector& indices, std::vector& vertices, Interpolator interpolator) { +template inline void subdivide(std::vector& indices, std::vector& vertices, Interpolator interpolator) { Implementation::Subdivide(indices, vertices)(interpolator); } diff --git a/src/MeshTools/Test/CMakeLists.txt b/src/MeshTools/Test/CMakeLists.txt index 830207055..0a4608faf 100644 --- a/src/MeshTools/Test/CMakeLists.txt +++ b/src/MeshTools/Test/CMakeLists.txt @@ -1,6 +1,6 @@ corrade_add_test2(MeshToolsCleanTest CleanTest.cpp) corrade_add_test2(MeshToolsCombineIndexedArraysTest CombineIndexedArraysTest.cpp) -corrade_add_test2(MeshToolsCompressIndicesTest CompressIndicesTest.cpp LIBRARIES Magnum) +corrade_add_test2(MeshToolsCompressIndicesTest CompressIndicesTest.cpp LIBRARIES MagnumMeshTools) corrade_add_test2(MeshToolsFlipNormalsTest FlipNormalsTest.cpp LIBRARIES MagnumMeshToolsTestLib) corrade_add_test2(MeshToolsGenerateFlatNormalsTest GenerateFlatNormalsTest.cpp LIBRARIES MagnumMeshToolsTestLib) corrade_add_test2(MeshToolsInterleaveTest InterleaveTest.cpp) diff --git a/src/MeshTools/Test/CleanTest.cpp b/src/MeshTools/Test/CleanTest.cpp index e8978e3c9..a180be5f3 100644 --- a/src/MeshTools/Test/CleanTest.cpp +++ b/src/MeshTools/Test/CleanTest.cpp @@ -28,13 +28,13 @@ CleanTest::CleanTest() { } void CleanTest::cleanMesh() { - vector vertices{1, 2, 1, 4}; - vector indices{0, 1, 2, 1, 2, 3}; - MeshTools::clean(indices, vertices); + vector positions{1, 2, 1, 4}; + vector indices{0, 1, 2, 1, 2, 3}; + MeshTools::clean(indices, positions); /* Verify cleanup */ - CORRADE_VERIFY(vertices == (vector{1, 2, 4})); - CORRADE_COMPARE(indices, (vector{0, 1, 0, 1, 0, 2})); + CORRADE_VERIFY(positions == (vector{1, 2, 4})); + CORRADE_COMPARE(indices, (vector{0, 1, 0, 1, 0, 2})); } }}} diff --git a/src/MeshTools/Test/CleanTest.h b/src/MeshTools/Test/CleanTest.h index 5663733d6..57169d736 100644 --- a/src/MeshTools/Test/CleanTest.h +++ b/src/MeshTools/Test/CleanTest.h @@ -28,18 +28,18 @@ class CleanTest: public Corrade::TestSuite::Tester { private: class Vector1 { public: - static const size_t size = 1; - typedef int Type; + static const std::size_t Size = 1; + typedef std::int32_t Type; Vector1(): data(0) {} - Vector1(int i): data(i) {} - int operator[](size_t) const { return data; } - int& operator[](size_t) { return data; } + Vector1(Type i): data(i) {} + Type operator[](std::size_t) const { return data; } + Type& operator[](std::size_t) { return data; } bool operator==(Vector1 i) const { return i.data == data; } Vector1 operator-(Vector1 i) const { return data-i.data; } private: - int data; + Type data; }; }; diff --git a/src/MeshTools/Test/CombineIndexedArraysTest.cpp b/src/MeshTools/Test/CombineIndexedArraysTest.cpp index 9cbdcc542..57211078b 100644 --- a/src/MeshTools/Test/CombineIndexedArraysTest.cpp +++ b/src/MeshTools/Test/CombineIndexedArraysTest.cpp @@ -33,29 +33,29 @@ CombineIndexedArraysTest::CombineIndexedArraysTest() { void CombineIndexedArraysTest::wrongIndexCount() { stringstream ss; Error::setOutput(&ss); - vector array; - vector result = MeshTools::combineIndexedArrays( - tuple&, vector&>(vector{0, 1, 0}, array), - tuple&, vector&>(vector{3, 4}, array)); + vector array; + vector result = MeshTools::combineIndexedArrays( + tuple&, vector&>(vector{0, 1, 0}, array), + tuple&, vector&>(vector{3, 4}, array)); CORRADE_COMPARE(result.size(), 0); CORRADE_COMPARE(ss.str(), "MeshTools::combineIndexedArrays(): index arrays don't have the same length, nothing done.\n"); } void CombineIndexedArraysTest::combine() { - vector array1{ 0, 1 }; - vector array2{ 0, 1, 2, 3, 4 }; - vector array3{ 0, 1, 2, 3, 4, 5, 6, 7 }; - - vector result = MeshTools::combineIndexedArrays( - tuple&, vector&>(vector{0, 1, 0}, array1), - tuple&, vector&>(vector{3, 4, 3}, array2), - tuple&, vector&>(vector{6, 7, 6}, array3)); - - CORRADE_COMPARE(result, (vector{0, 1, 0})); - CORRADE_COMPARE(array1, (vector{0, 1})); - CORRADE_COMPARE(array2, (vector{3, 4})); - CORRADE_COMPARE(array3, (vector{6, 7})); + vector array1{ 0, 1 }; + vector array2{ 0, 1, 2, 3, 4 }; + vector array3{ 0, 1, 2, 3, 4, 5, 6, 7 }; + + vector result = MeshTools::combineIndexedArrays( + tuple&, vector&>(vector{0, 1, 0}, array1), + tuple&, vector&>(vector{3, 4, 3}, array2), + tuple&, vector&>(vector{6, 7, 6}, array3)); + + CORRADE_COMPARE(result, (vector{0, 1, 0})); + CORRADE_COMPARE(array1, (vector{0, 1})); + CORRADE_COMPARE(array2, (vector{3, 4})); + CORRADE_COMPARE(array3, (vector{6, 7})); } }}} diff --git a/src/MeshTools/Test/CompressIndicesTest.cpp b/src/MeshTools/Test/CompressIndicesTest.cpp index 905918f1c..f50b7ce49 100644 --- a/src/MeshTools/Test/CompressIndicesTest.cpp +++ b/src/MeshTools/Test/CompressIndicesTest.cpp @@ -37,7 +37,7 @@ void CompressIndicesTest::compressChar() { Type indexType; char* data; tie(indexCount, indexType, data) = MeshTools::compressIndices( - vector{1, 2, 3, 0, 4}); + vector{1, 2, 3, 0, 4}); CORRADE_COMPARE(indexCount, 5); CORRADE_VERIFY(indexType == Type::UnsignedByte); @@ -52,7 +52,7 @@ void CompressIndicesTest::compressShort() { Type indexType; char* data; tie(indexCount, indexType, data) = MeshTools::compressIndices( - vector{1, 256, 0, 5}); + vector{1, 256, 0, 5}); CORRADE_COMPARE(indexCount, 4); CORRADE_VERIFY(indexType == Type::UnsignedShort); @@ -78,7 +78,7 @@ void CompressIndicesTest::compressInt() { Type indexType; char* data; tie(indexCount, indexType, data) = MeshTools::compressIndices( - vector{65536, 3, 2}); + vector{65536, 3, 2}); CORRADE_COMPARE(indexCount, 3); CORRADE_VERIFY(indexType == Type::UnsignedInt); diff --git a/src/MeshTools/Test/FlipNormalsTest.cpp b/src/MeshTools/Test/FlipNormalsTest.cpp index ec97f1da5..b900f39d5 100644 --- a/src/MeshTools/Test/FlipNormalsTest.cpp +++ b/src/MeshTools/Test/FlipNormalsTest.cpp @@ -17,6 +17,7 @@ #include +#include "Math/Vector3.h" #include "MeshTools/FlipNormals.h" CORRADE_TEST_MAIN(Magnum::MeshTools::Test::FlipNormalsTest) @@ -35,19 +36,19 @@ void FlipNormalsTest::wrongIndexCount() { stringstream ss; Error::setOutput(&ss); - vector indices{0, 1}; + vector indices{0, 1}; MeshTools::flipFaceWinding(indices); CORRADE_COMPARE(ss.str(), "MeshTools::flipNormals(): index count is not divisible by 3!\n"); } void FlipNormalsTest::flipFaceWinding() { - vector indices{0, 1, 2, + vector indices{0, 1, 2, 3, 4, 5}; MeshTools::flipFaceWinding(indices); - CORRADE_COMPARE(indices, (vector{0, 2, 1, - 3, 5, 4})); + CORRADE_COMPARE(indices, (vector{0, 2, 1, + 3, 5, 4})); } void FlipNormalsTest::flipNormals() { diff --git a/src/MeshTools/Test/GenerateFlatNormalsTest.cpp b/src/MeshTools/Test/GenerateFlatNormalsTest.cpp index 664cd2bdb..37ceeb245 100644 --- a/src/MeshTools/Test/GenerateFlatNormalsTest.cpp +++ b/src/MeshTools/Test/GenerateFlatNormalsTest.cpp @@ -17,6 +17,7 @@ #include +#include "Math/Point3D.h" #include "MeshTools/GenerateFlatNormals.h" CORRADE_TEST_MAIN(Magnum::MeshTools::Test::GenerateFlatNormalsTest) @@ -33,7 +34,7 @@ GenerateFlatNormalsTest::GenerateFlatNormalsTest() { void GenerateFlatNormalsTest::wrongIndexCount() { stringstream ss; Error::setOutput(&ss); - vector indices; + vector indices; vector normals; tie(indices, normals) = MeshTools::generateFlatNormals({ 0, 1 @@ -46,21 +47,19 @@ void GenerateFlatNormalsTest::wrongIndexCount() { void GenerateFlatNormalsTest::generate() { /* Two vertices connected by one edge, each winded in another direction */ - vector indices; + vector indices; vector normals; - vector vertices{ + tie(indices, normals) = MeshTools::generateFlatNormals({ + 0, 1, 2, + 1, 2, 3 + }, vector{ {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f} - }; - tie(indices, normals) = MeshTools::generateFlatNormals({ - 0, 1, 2, - 1, 2, 3 - }, vertices); - + }); - CORRADE_COMPARE(indices, (vector{ + CORRADE_COMPARE(indices, (vector{ 0, 0, 0, 1, 1, 1 })); diff --git a/src/MeshTools/Test/InterleaveTest.cpp b/src/MeshTools/Test/InterleaveTest.cpp index 9218a995f..b734ea39a 100644 --- a/src/MeshTools/Test/InterleaveTest.cpp +++ b/src/MeshTools/Test/InterleaveTest.cpp @@ -37,18 +37,18 @@ InterleaveTest::InterleaveTest() { void InterleaveTest::attributeCount() { stringstream ss; Error::setOutput(&ss); - CORRADE_COMPARE((Implementation::Interleave::attributeCount(vector{0, 1, 2}, - vector{0, 1, 2, 3, 4, 5})), size_t(0)); + CORRADE_COMPARE((Implementation::Interleave::attributeCount(vector{0, 1, 2}, + vector{0, 1, 2, 3, 4, 5})), size_t(0)); CORRADE_COMPARE(ss.str(), "MeshTools::interleave(): attribute arrays don't have the same length, nothing done.\n"); - CORRADE_COMPARE((Implementation::Interleave::attributeCount(vector{0, 1, 2}, - vector{3, 4, 5})), size_t(3)); + CORRADE_COMPARE((Implementation::Interleave::attributeCount(vector{0, 1, 2}, + vector{3, 4, 5})), size_t(3)); } void InterleaveTest::stride() { - CORRADE_COMPARE(Implementation::Interleave::stride(vector()), size_t(1)); - CORRADE_COMPARE(Implementation::Interleave::stride(vector()), size_t(4)); - CORRADE_COMPARE((Implementation::Interleave::stride(vector(), vector())), size_t(5)); + CORRADE_COMPARE(Implementation::Interleave::stride(vector()), size_t(1)); + CORRADE_COMPARE(Implementation::Interleave::stride(vector()), size_t(4)); + CORRADE_COMPARE((Implementation::Interleave::stride(vector(), vector())), size_t(5)); } void InterleaveTest::write() { @@ -56,9 +56,9 @@ void InterleaveTest::write() { size_t stride; char* data; tie(attributeCount, stride, data) = MeshTools::interleave( - vector{0, 1, 2}, - vector{3, 4, 5}, - vector{6, 7, 8}); + vector{0, 1, 2}, + vector{3, 4, 5}, + vector{6, 7, 8}); CORRADE_COMPARE(attributeCount, size_t(3)); CORRADE_COMPARE(stride, size_t(7)); diff --git a/src/MeshTools/Test/SubdivideCleanBenchmark.cpp b/src/MeshTools/Test/SubdivideCleanBenchmark.cpp index 6d6ec7307..fd56ef292 100644 --- a/src/MeshTools/Test/SubdivideCleanBenchmark.cpp +++ b/src/MeshTools/Test/SubdivideCleanBenchmark.cpp @@ -30,11 +30,11 @@ void SubdivideCleanBenchmark::subdivide() { Primitives::Icosphere<0> icosphere; /* Subdivide 5 times */ - MeshTools::subdivide(*icosphere.indices(), *icosphere.vertices(0), interpolator); - MeshTools::subdivide(*icosphere.indices(), *icosphere.vertices(0), interpolator); - MeshTools::subdivide(*icosphere.indices(), *icosphere.vertices(0), interpolator); - MeshTools::subdivide(*icosphere.indices(), *icosphere.vertices(0), interpolator); - MeshTools::subdivide(*icosphere.indices(), *icosphere.vertices(0), interpolator); + MeshTools::subdivide(*icosphere.indices(), *icosphere.positions(0), interpolator); + MeshTools::subdivide(*icosphere.indices(), *icosphere.positions(0), interpolator); + MeshTools::subdivide(*icosphere.indices(), *icosphere.positions(0), interpolator); + MeshTools::subdivide(*icosphere.indices(), *icosphere.positions(0), interpolator); + MeshTools::subdivide(*icosphere.indices(), *icosphere.positions(0), interpolator); } } @@ -43,13 +43,13 @@ void SubdivideCleanBenchmark::subdivideAndCleanMeshAfter() { Primitives::Icosphere<0> icosphere; /* Subdivide 5 times */ - MeshTools::subdivide(*icosphere.indices(), *icosphere.vertices(0), interpolator); - MeshTools::subdivide(*icosphere.indices(), *icosphere.vertices(0), interpolator); - MeshTools::subdivide(*icosphere.indices(), *icosphere.vertices(0), interpolator); - MeshTools::subdivide(*icosphere.indices(), *icosphere.vertices(0), interpolator); - MeshTools::subdivide(*icosphere.indices(), *icosphere.vertices(0), interpolator); + MeshTools::subdivide(*icosphere.indices(), *icosphere.positions(0), interpolator); + MeshTools::subdivide(*icosphere.indices(), *icosphere.positions(0), interpolator); + MeshTools::subdivide(*icosphere.indices(), *icosphere.positions(0), interpolator); + MeshTools::subdivide(*icosphere.indices(), *icosphere.positions(0), interpolator); + MeshTools::subdivide(*icosphere.indices(), *icosphere.positions(0), interpolator); - MeshTools::clean(*icosphere.indices(), *icosphere.vertices(0)); + MeshTools::clean(*icosphere.indices(), *icosphere.positions(0)); } } @@ -58,16 +58,16 @@ void SubdivideCleanBenchmark::subdivideAndCleanMeshBetween() { Primitives::Icosphere<0> icosphere; /* Subdivide 5 times */ - MeshTools::subdivide(*icosphere.indices(), *icosphere.vertices(0), interpolator); - MeshTools::clean(*icosphere.indices(), *icosphere.vertices(0)); - MeshTools::subdivide(*icosphere.indices(), *icosphere.vertices(0), interpolator); - MeshTools::clean(*icosphere.indices(), *icosphere.vertices(0)); - MeshTools::subdivide(*icosphere.indices(), *icosphere.vertices(0), interpolator); - MeshTools::clean(*icosphere.indices(), *icosphere.vertices(0)); - MeshTools::subdivide(*icosphere.indices(), *icosphere.vertices(0), interpolator); - MeshTools::clean(*icosphere.indices(), *icosphere.vertices(0)); - MeshTools::subdivide(*icosphere.indices(), *icosphere.vertices(0), interpolator); - MeshTools::clean(*icosphere.indices(), *icosphere.vertices(0)); + MeshTools::subdivide(*icosphere.indices(), *icosphere.positions(0), interpolator); + MeshTools::clean(*icosphere.indices(), *icosphere.positions(0)); + MeshTools::subdivide(*icosphere.indices(), *icosphere.positions(0), interpolator); + MeshTools::clean(*icosphere.indices(), *icosphere.positions(0)); + MeshTools::subdivide(*icosphere.indices(), *icosphere.positions(0), interpolator); + MeshTools::clean(*icosphere.indices(), *icosphere.positions(0)); + MeshTools::subdivide(*icosphere.indices(), *icosphere.positions(0), interpolator); + MeshTools::clean(*icosphere.indices(), *icosphere.positions(0)); + MeshTools::subdivide(*icosphere.indices(), *icosphere.positions(0), interpolator); + MeshTools::clean(*icosphere.indices(), *icosphere.positions(0)); } } diff --git a/src/MeshTools/Test/SubdivideTest.cpp b/src/MeshTools/Test/SubdivideTest.cpp index 611155a60..965c3ad36 100644 --- a/src/MeshTools/Test/SubdivideTest.cpp +++ b/src/MeshTools/Test/SubdivideTest.cpp @@ -35,26 +35,26 @@ void SubdivideTest::wrongIndexCount() { stringstream ss; Error::setOutput(&ss); - vector vertices; - vector indices{0, 1}; - MeshTools::subdivide(indices, vertices, interpolator); + vector positions; + vector indices{0, 1}; + MeshTools::subdivide(indices, positions, interpolator); CORRADE_COMPARE(ss.str(), "MeshTools::subdivide(): index count is not divisible by 3!\n"); } void SubdivideTest::subdivide() { - vector vertices{0, 2, 6, 8}; - vector indices{0, 1, 2, 1, 2, 3}; - MeshTools::subdivide(indices, vertices, interpolator); + vector positions{0, 2, 6, 8}; + vector indices{0, 1, 2, 1, 2, 3}; + MeshTools::subdivide(indices, positions, interpolator); CORRADE_COMPARE(indices.size(), 24); - CORRADE_VERIFY(vertices == (vector{0, 2, 6, 8, 1, 4, 3, 4, 7, 5})); - CORRADE_COMPARE(indices, (vector{4, 5, 6, 7, 8, 9, 0, 4, 6, 4, 1, 5, 6, 5, 2, 1, 7, 9, 7, 2, 8, 9, 8, 3})); + CORRADE_VERIFY(positions == (vector{0, 2, 6, 8, 1, 4, 3, 4, 7, 5})); + CORRADE_COMPARE(indices, (vector{4, 5, 6, 7, 8, 9, 0, 4, 6, 4, 1, 5, 6, 5, 2, 1, 7, 9, 7, 2, 8, 9, 8, 3})); - MeshTools::clean(indices, vertices); + MeshTools::clean(indices, positions); - /* Vertices 0, 1, 2, 3, 4, 5, 6, 7, 8 */ - CORRADE_COMPARE(vertices.size(), 9); + /* Positions 0, 1, 2, 3, 4, 5, 6, 7, 8 */ + CORRADE_COMPARE(positions.size(), 9); } }}} diff --git a/src/MeshTools/Test/SubdivideTest.h b/src/MeshTools/Test/SubdivideTest.h index af7c43484..b5ff7f0ef 100644 --- a/src/MeshTools/Test/SubdivideTest.h +++ b/src/MeshTools/Test/SubdivideTest.h @@ -29,18 +29,18 @@ class SubdivideTest: public Corrade::TestSuite::Tester { private: class Vector1 { public: - static const size_t size = 1; - typedef int Type; + static const std::size_t Size = 1; + typedef std::int32_t Type; Vector1(): data(0) {} - Vector1(int i): data(i) {} - int operator[](size_t) const { return data; } - int& operator[](size_t) { return data; } + Vector1(Type i): data(i) {} + Type operator[](std::size_t) const { return data; } + Type& operator[](std::size_t) { return data; } bool operator==(Vector1 i) const { return i.data == data; } Vector1 operator-(Vector1 i) const { return data-i.data; } private: - int data; + Type data; }; inline static Vector1 interpolator(Vector1 a, Vector1 b) { return (a[0]+b[0])/2; } diff --git a/src/MeshTools/Test/TipsifyTest.cpp b/src/MeshTools/Test/TipsifyTest.cpp index 40a2fbf6c..fc0a7c243 100644 --- a/src/MeshTools/Test/TipsifyTest.cpp +++ b/src/MeshTools/Test/TipsifyTest.cpp @@ -15,8 +15,6 @@ #include "TipsifyTest.h" -#include - #include "MeshTools/Tipsify.h" CORRADE_TEST_MAIN(Magnum::MeshTools::Test::TipsifyTest) @@ -69,10 +67,10 @@ TipsifyTest::TipsifyTest(): indices{ } void TipsifyTest::buildAdjacency() { - vector liveTriangleCount, neighborOffset, neighbors; + vector liveTriangleCount, neighborOffset, neighbors; Implementation::Tipsify(indices, vertexCount).buildAdjacency(liveTriangleCount, neighborOffset, neighbors); - CORRADE_COMPARE(liveTriangleCount, (vector{ + CORRADE_COMPARE(liveTriangleCount, (vector{ 1, 3, 3, 2, 4, 6, 6, 2, 2, 6, 6, 4, @@ -80,7 +78,7 @@ void TipsifyTest::buildAdjacency() { 1, 1, 1 })); - CORRADE_COMPARE(neighborOffset, (vector{ + CORRADE_COMPARE(neighborOffset, (vector{ 0, 1, 4, 7, 9, 13, 19, 25, 27, 29, 35, 41, @@ -88,7 +86,7 @@ void TipsifyTest::buildAdjacency() { 54, 55, 56, 57 })); - CORRADE_COMPARE(neighbors, (vector{ + CORRADE_COMPARE(neighbors, (vector{ 0, 0, 7, 11, 2, 7, 13, @@ -116,7 +114,7 @@ void TipsifyTest::buildAdjacency() { void TipsifyTest::tipsify() { MeshTools::tipsify(indices, vertexCount, 3); - CORRADE_COMPARE(indices, (vector{ + CORRADE_COMPARE(indices, (vector{ 4, 1, 0, 9, 5, 4, 1, 4, 5, diff --git a/src/MeshTools/Test/TipsifyTest.h b/src/MeshTools/Test/TipsifyTest.h index 70d7c06d3..978b60122 100644 --- a/src/MeshTools/Test/TipsifyTest.h +++ b/src/MeshTools/Test/TipsifyTest.h @@ -28,8 +28,8 @@ class TipsifyTest: public Corrade::TestSuite::Tester { void tipsify(); private: - std::vector indices; - size_t vertexCount; + std::vector indices; + std::size_t vertexCount; }; }}} diff --git a/src/MeshTools/Tipsify.cpp b/src/MeshTools/Tipsify.cpp index f26e9fdc2..62514767e 100644 --- a/src/MeshTools/Tipsify.cpp +++ b/src/MeshTools/Tipsify.cpp @@ -17,42 +17,44 @@ #include +using namespace std; + #ifndef DOXYGEN_GENERATING_OUTPUT namespace Magnum { namespace MeshTools { namespace Implementation { void Tipsify::operator()(size_t cacheSize) { /* Neighboring triangles for each vertex, per-vertex live triangle count */ - std::vector liveTriangleCount, neighborPosition, neighbors; + std::vector liveTriangleCount, neighborPosition, neighbors; buildAdjacency(liveTriangleCount, neighborPosition, neighbors); /* Global time, per-vertex caching timestamps, per-triangle emmited flag */ - unsigned int time = cacheSize+1; - std::vector timestamp(vertexCount); + uint32_t time = cacheSize+1; + std::vector timestamp(vertexCount); std::vector emitted(indices.size()/3); /* Dead-end vertex stack */ - std::stack deadEndStack; + std::stack deadEndStack; /* Output index buffer */ - std::vector outputIndices; + std::vector outputIndices; outputIndices.reserve(indices.size()); /* Starting vertex for fanning, cursor */ - unsigned int fanningVertex = 0; - unsigned int i = 0; + uint32_t fanningVertex = 0; + uint32_t i = 0; while(fanningVertex != 0xFFFFFFFFu) { /* Array with candidates for next fanning vertex (in 1-ring around fanning vertex) */ - std::vector candidates; + std::vector candidates; /* For all neighbors of fanning vertex */ - for(unsigned int ti = neighborPosition[fanningVertex], t = neighbors[ti]; ti != neighborPosition[fanningVertex+1]; t = neighbors[++ti]) { + for(uint32_t ti = neighborPosition[fanningVertex], t = neighbors[ti]; ti != neighborPosition[fanningVertex+1]; t = neighbors[++ti]) { /* Continue if already emitted */ if(emitted[t]) continue; emitted[t] = true; /* Write all vertices of the triangle to output buffer */ - for(unsigned int vi = 0, v = indices[t*3]; vi != 3; v = indices[++vi+t*3]) { + for(uint32_t vi = 0, v = indices[t*3]; vi != 3; v = indices[++vi+t*3]) { outputIndices.push_back(v); /* Add to dead end stack and candidates array */ @@ -73,9 +75,9 @@ void Tipsify::operator()(size_t cacheSize) { fanningVertex = 0xFFFFFFFFu; /* Go through candidates in 1-ring around fanning vertex */ - int candidatePriority = -1; + int32_t candidatePriority = -1; for(auto it = candidates.begin(); it != candidates.end(); ++it) { - unsigned int v = *it; + uint32_t v = *it; /* Skip if it doesn't have any live triangles */ if(!liveTriangleCount[v]) continue; @@ -83,7 +85,7 @@ void Tipsify::operator()(size_t cacheSize) { /* Get most fresh candidate which will still be in cache even after fanning. Every fanned triangle will generate at most two cache misses, thus 2*liveTriangleCount */ - int priority = 0; + int32_t priority = 0; if(time-timestamp[v]+2*liveTriangleCount[v] <= cacheSize) priority = time-timestamp[v]; if(priority > candidatePriority) { @@ -119,12 +121,12 @@ void Tipsify::operator()(size_t cacheSize) { std::swap(indices, outputIndices); } -void Tipsify::buildAdjacency(std::vector& liveTriangleCount, std::vector& neighborOffset, std::vector& neighbors) const { +void Tipsify::buildAdjacency(std::vector& liveTriangleCount, std::vector& neighborOffset, std::vector& neighbors) const { /* How many times is each vertex referenced == count of neighboring triangles for each vertex */ liveTriangleCount.clear(); liveTriangleCount.resize(vertexCount); - for(unsigned int i = 0; i != indices.size(); ++i) + for(size_t i = 0; i != indices.size(); ++i) ++liveTriangleCount[indices[i]]; /* Building offset array from counts. Neighbors for i-th vertex will at @@ -134,8 +136,8 @@ void Tipsify::buildAdjacency(std::vector& liveTriangleCount, std:: neighborOffset.clear(); neighborOffset.reserve(vertexCount+1); neighborOffset.push_back(0); - unsigned int sum = 0; - for(unsigned int i = 0; i != vertexCount; ++i) { + uint32_t sum = 0; + for(size_t i = 0; i != vertexCount; ++i) { neighborOffset.push_back(sum); sum += liveTriangleCount[i]; } @@ -144,7 +146,7 @@ void Tipsify::buildAdjacency(std::vector& liveTriangleCount, std:: positioning */ neighbors.clear(); neighbors.resize(sum); - for(unsigned int i = 0; i != indices.size(); ++i) + for(size_t i = 0; i != indices.size(); ++i) neighbors[neighborOffset[indices[i]+1]++] = i/3; } diff --git a/src/MeshTools/Tipsify.h b/src/MeshTools/Tipsify.h index d43f4e926..ca93c1297 100644 --- a/src/MeshTools/Tipsify.h +++ b/src/MeshTools/Tipsify.h @@ -19,7 +19,7 @@ * @brief Function Magnum::MeshTools::tipsify() */ -#include +#include #include #include "magnumMeshToolsVisibility.h" @@ -31,21 +31,22 @@ namespace Implementation { class MESHTOOLS_EXPORT Tipsify { public: - inline Tipsify(std::vector& indices, unsigned int vertexCount): indices(indices), vertexCount(vertexCount) {} + inline Tipsify(std::vector& indices, std::uint32_t vertexCount): indices(indices), vertexCount(vertexCount) {} - void operator()(size_t cacheSize); + void operator()(std::size_t cacheSize); /** * @brief Build vertex-triangle adjacency * * Computes count and indices of adjacent triangles for each vertex * (used internally). + * @todo Export only for unit test, hide otherwise */ - void buildAdjacency(std::vector& liveTriangleCount, std::vector& neighborOffset, std::vector& neighbors) const; + void buildAdjacency(std::vector& liveTriangleCount, std::vector& neighborOffset, std::vector& neighbors) const; private: - std::vector& indices; - const unsigned int vertexCount; + std::vector& indices; + const std::uint32_t vertexCount; }; } @@ -63,7 +64,7 @@ array for beter usage of post-transform vertex cache. Algorithm used: for Vertex Locality and Reduced Overdraw, SIGGRAPH 2007, http://gfx.cs.princeton.edu/pubs/Sander_2007_%3ETR/index.php*. */ -inline void tipsify(std::vector& indices, unsigned int vertexCount, size_t cacheSize) { +inline void tipsify(std::vector& indices, std::uint32_t vertexCount, std::size_t cacheSize) { Implementation::Tipsify(indices, vertexCount)(cacheSize); } diff --git a/src/MeshTools/Transform.h b/src/MeshTools/Transform.h new file mode 100644 index 000000000..9ad5b3ceb --- /dev/null +++ b/src/MeshTools/Transform.h @@ -0,0 +1,44 @@ +#ifndef Magnum_MeshTools_Transform_h +#define Magnum_MeshTools_Transform_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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. +*/ + +/** @file + * @brief Function Magnum::MeshTools::transform() + */ + +#include "Math/Matrix.h" + +namespace Magnum { namespace MeshTools { + +/** +@brief Transform vertices using given matrix + +Usable for mesh transformations that would otherwise negatively affect +dependent objects, such as (uneven) scaling. Example usage: + +@code +std::vector vertices; +MeshTools::transform(Matrix4::scaling({2.0f, 0.5f, 0.0f}), vertices); +@endcode +*/ +template inline void transform(const Math::Matrix& matrix, U& vertices) { + for(Math::Vector& vertex: vertices) + vertex = matrix*vertex; +} + +}} + +#endif diff --git a/src/Physics/AbstractShape.cpp b/src/Physics/AbstractShape.cpp index da42b21b7..23a15ec0d 100644 --- a/src/Physics/AbstractShape.cpp +++ b/src/Physics/AbstractShape.cpp @@ -17,7 +17,7 @@ namespace Magnum { namespace Physics { -bool AbstractShape::collides(const AbstractShape* other) const { +template bool AbstractShape::collides(const AbstractShape* other) const { /* Operate only with simpler types than this */ if(static_cast(other->type()) > static_cast(type())) return other->collides(this); @@ -25,4 +25,7 @@ bool AbstractShape::collides(const AbstractShape* other) const { return false; } +template class AbstractShape<2>; +template class AbstractShape<3>; + }} diff --git a/src/Physics/AbstractShape.h b/src/Physics/AbstractShape.h index 2af5cda40..6ac3bdf25 100644 --- a/src/Physics/AbstractShape.h +++ b/src/Physics/AbstractShape.h @@ -20,17 +20,56 @@ */ #include "Magnum.h" +#include "DimensionTraits.h" + #include "magnumPhysicsVisibility.h" namespace Magnum { namespace Physics { +#ifndef DOXYGEN_GENERATING_OUTPUT +namespace Implementation { + template struct ShapeDimensionTraits {}; + + template<> struct ShapeDimensionTraits<2> { + enum class Type { + Point, + Line, + LineSegment, + Sphere, + Capsule, + AxisAlignedBox, + Box, + ShapeGroup + }; + }; + + template<> struct ShapeDimensionTraits<3> { + enum class Type { + Point, + Line, + LineSegment, + Sphere, + Capsule, + AxisAlignedBox, + Box, + ShapeGroup, + Plane + }; + }; +} +#endif + /** @brief Base class for shapes See @ref collision-detection for brief introduction. +@see AbstractShape2D, AbstractShape3D */ -class PHYSICS_EXPORT AbstractShape { +template class PHYSICS_EXPORT AbstractShape { public: + /** @brief Dimension count */ + static const std::uint8_t Dimensions = dimensions; + /** * @brief Shape type * @@ -38,17 +77,21 @@ class PHYSICS_EXPORT AbstractShape { * the list provides collision detection for previous shapes, not * the other way around. */ + #ifdef DOXYGEN_GENERATING_OUTPUT enum class Type { - Point, - Line, - LineSegment, - Plane, - Sphere, - Capsule, - AxisAlignedBox, - Box, - ShapeGroup + Point, /**< Point */ + Line, /**< Line */ + LineSegment, /**< @ref LineSegment "Line segment" */ + Sphere, /**< Sphere */ + Capsule, /**< Capsule */ + AxisAlignedBox, /**< @ref AxisAlignedBox "Axis aligned box" */ + Box, /**< Box */ + ShapeGroup, /**< @ref ShapeGroup "Shape group" */ + Plane /**< Plane (3D only) */ }; + #else + typedef typename Implementation::ShapeDimensionTraits::Type Type; + #endif /** @brief Destructor */ virtual inline ~AbstractShape() {} @@ -62,7 +105,7 @@ class PHYSICS_EXPORT AbstractShape { * Applies transformation to user-defined shape properties and caches * them for later usage in collision detection. */ - virtual void applyTransformation(const Matrix4& transformation) = 0; + virtual void applyTransformation(const typename DimensionTraits::MatrixType& transformation) = 0; /** * @brief Detect collision with other shape @@ -72,9 +115,15 @@ class PHYSICS_EXPORT AbstractShape { * @internal If other shape is more complex than this, returns * `other->collides(this)`. */ - virtual bool collides(const AbstractShape* other) const; + virtual bool collides(const AbstractShape* other) const; }; +/** @brief Abstract two-dimensional shape */ +typedef AbstractShape<2> AbstractShape2D; + +/** @brief Abstract three-dimensional shape */ +typedef AbstractShape<3> AbstractShape3D; + }} #endif diff --git a/src/Physics/AxisAlignedBox.cpp b/src/Physics/AxisAlignedBox.cpp index faa81e229..63b288fcc 100644 --- a/src/Physics/AxisAlignedBox.cpp +++ b/src/Physics/AxisAlignedBox.cpp @@ -15,11 +15,17 @@ #include "AxisAlignedBox.h" +#include "Math/Matrix3.h" +#include "Math/Matrix4.h" + namespace Magnum { namespace Physics { -void AxisAlignedBox::applyTransformation(const Matrix4& transformation) { - _transformedPosition = (transformation*Vector4(_position)).xyz(); +template void AxisAlignedBox::applyTransformation(const typename DimensionTraits::MatrixType& transformation) { + _transformedPosition = (transformation*typename DimensionTraits::PointType(_position)).vector(); _transformedSize = transformation.rotationScaling()*_size; } +template class AxisAlignedBox<2>; +template class AxisAlignedBox<3>; + }} diff --git a/src/Physics/AxisAlignedBox.h b/src/Physics/AxisAlignedBox.h index a9ef1c13b..711491575 100644 --- a/src/Physics/AxisAlignedBox.h +++ b/src/Physics/AxisAlignedBox.h @@ -16,55 +16,71 @@ */ /** @file - * @brief Class Magnum::Physics::AxisAlignedBox + * @brief Class Magnum::Physics::AxisAlignedBox, typedef Magnum::Physics::AxisAlignedBox2D, Magnum::Physics.:AxisAlignedBox3D */ +#include "Math/Vector3.h" #include "AbstractShape.h" +#include "magnumCompatibility.h" + namespace Magnum { namespace Physics { -/** @brief Axis aligned box */ -class PHYSICS_EXPORT AxisAlignedBox: public AbstractShape { +/** +@brief Axis-aligned box + +@see AxisAlignedBox2D, AxisAlignedBox3D +*/ +template class PHYSICS_EXPORT AxisAlignedBox: public AbstractShape { public: /** @brief Constructor */ - inline AxisAlignedBox(const Vector3& position, const Vector3& size): _position(position), _transformedPosition(position), _size(size), _transformedSize(size) {} + inline AxisAlignedBox(const typename DimensionTraits::VectorType& position, const typename DimensionTraits::VectorType& size): _position(position), _transformedPosition(position), _size(size), _transformedSize(size) {} + + inline typename AbstractShape::Type type() const override { + return AbstractShape::Type::AxisAlignedBox; + } - void applyTransformation(const Matrix4& transformation); + void applyTransformation(const typename DimensionTraits::MatrixType& transformation) override; /** @brief Position */ - inline Vector3 position() const { return _position; } + inline typename DimensionTraits::VectorType position() const { + return _position; + } /** @brief Set position */ - inline void setPosition(const Vector3& position) { + inline void setPosition(const typename DimensionTraits::VectorType& position) { _position = position; } /** @brief Size */ - inline Vector3 size() const { return _size; } + inline typename DimensionTraits::VectorType size() const { return _size; } /** @brief Set size */ - inline void setSize(const Vector3& size) { + inline void setSize(const typename DimensionTraits::VectorType& size) { _size = size; } /** @brief Transformed position */ - inline Vector3 transformedPosition() const { + inline typename DimensionTraits::VectorType transformedPosition() const { return _transformedPosition; } /** @brief Transformed size */ - inline Vector3 transformedSize() const { + inline typename DimensionTraits::VectorType transformedSize() const { return _transformedSize; } - protected: - inline Type type() const { return Type::AxisAlignedBox; } - private: - Vector3 _position, _transformedPosition, + Math::Vector _position, _transformedPosition, _size, _transformedSize; }; +/** @brief Two-dimensional axis-aligned box */ +typedef AxisAlignedBox<2> AxisAlignedBox2D; + +/** @brief Three-dimensional axis-aligned box */ +typedef AxisAlignedBox<3> AxisAlignedBox3D; + }} #endif diff --git a/src/Physics/Box.cpp b/src/Physics/Box.cpp new file mode 100644 index 000000000..2b0eb5725 --- /dev/null +++ b/src/Physics/Box.cpp @@ -0,0 +1,30 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "Box.h" + +#include "Math/Matrix4.h" +#include "Math/Point3D.h" + +namespace Magnum { namespace Physics { + +template void Box::applyTransformation(const typename DimensionTraits::MatrixType& transformation) { + _transformedTransformation = (transformation*_transformation); +} + +template class Box<2>; +template class Box<3>; + +}} diff --git a/src/Physics/Box.h b/src/Physics/Box.h index 34535e7a6..d92ab64ab 100644 --- a/src/Physics/Box.h +++ b/src/Physics/Box.h @@ -16,43 +16,59 @@ */ /** @file - * @brief Class Magnum::Physics::Box + * @brief Class Magnum::Physics::Box, typedef Magnum::Physics::Box2D, Magnum::Physics::Box3D */ +#include "Math/Matrix3.h" +#include "Math/Matrix4.h" #include "AbstractShape.h" +#include "magnumCompatibility.h" + namespace Magnum { namespace Physics { -/** @brief Unit size box with assigned transformation matrix */ -class Box: public AbstractShape { +/** +@brief Unit-size box with assigned transformation matrix + +@see Box2D, Box3D +*/ +template class PHYSICS_EXPORT Box: public AbstractShape { public: /** @brief Constructor */ - inline Box(const Matrix4& transformation): _transformation(transformation), _transformedTransformation(transformation) {} + inline Box(const typename DimensionTraits::MatrixType& transformation): _transformation(transformation), _transformedTransformation(transformation) {} - inline void applyTransformation(const Matrix4& transformation) { - _transformedTransformation = transformation*_transformation; + inline typename AbstractShape::Type type() const override { + return AbstractShape::Type::Box; } + void applyTransformation(const typename DimensionTraits::MatrixType& transformation) override; + /** @brief Transformation */ - inline constexpr Matrix4 transformation() const { return _transformation; } + inline typename DimensionTraits::MatrixType transformation() const { + return _transformation; + } /** @brief Set transformation */ - inline Vector3 setTransformation(const Matrix4& transformation) { + inline void setTransformation(const typename DimensionTraits::MatrixType& transformation) { _transformation = transformation; } /** @brief Transformed transformation */ - inline constexpr Vector3 transformedTransformation() const { + inline typename DimensionTraits::MatrixType transformedTransformation() const { return _transformedTransformation; } - protected: - inline Type type() const { return Type::Box; } - private: - Vector3 _transformation, _transformedTransformation; + Math::Matrix _transformation, + _transformedTransformation; }; +/** @brief Two-dimensional box */ +typedef Box<2> Box2D; + +/** @brief Three-dimensional box */ +typedef Box<3> Box3D; + }} #endif diff --git a/src/Physics/CMakeLists.txt b/src/Physics/CMakeLists.txt index 8201d490b..1dc1bf4cf 100644 --- a/src/Physics/CMakeLists.txt +++ b/src/Physics/CMakeLists.txt @@ -1,20 +1,31 @@ set(MagnumPhysics_SRCS AbstractShape.cpp AxisAlignedBox.cpp + Box.cpp Capsule.cpp + DebugDrawResourceManager.cpp Line.cpp Plane.cpp + Point.cpp + ShapedObject.cpp + ShapedObjectGroup.cpp ShapeGroup.cpp - Sphere.cpp) + Sphere.cpp + + Implementation/AbstractDebugRenderer.cpp + Implementation/BoxRenderer.cpp) set(MagnumPhysics_HEADERS AbstractShape.h AxisAlignedBox.h Box.h Capsule.h + DebugDrawResourceManager.h Line.h LineSegment.h Plane.h Point.h + ShapedObject.h + ShapedObjectGroup.h ShapeGroup.h Sphere.h @@ -22,7 +33,7 @@ set(MagnumPhysics_HEADERS add_library(MagnumPhysics SHARED ${MagnumPhysics_SRCS}) -target_link_libraries(MagnumPhysics Magnum) +target_link_libraries(MagnumPhysics Magnum MagnumPrimitives MagnumSceneGraph MagnumShaders) install(TARGETS MagnumPhysics DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) install(FILES ${MagnumPhysics_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Physics) diff --git a/src/Physics/Capsule.cpp b/src/Physics/Capsule.cpp index 7c40dc206..0c9c1b288 100644 --- a/src/Physics/Capsule.cpp +++ b/src/Physics/Capsule.cpp @@ -15,36 +15,45 @@ #include "Capsule.h" +#include "Math/Constants.h" +#include "Math/Math.h" +#include "Math/Matrix3.h" +#include "Math/Matrix4.h" #include "Math/Geometry/Distance.h" +#include "Point.h" +#include "Sphere.h" using namespace Magnum::Math::Geometry; namespace Magnum { namespace Physics { -void Capsule::applyTransformation(const Matrix4& transformation) { - _transformedA = (transformation*Vector4(_a)).xyz(); - _transformedB = (transformation*Vector4(_b)).xyz(); - float scaling = (transformation.rotationScaling()*Vector3(1/Math::Constants::sqrt3())).length(); +template void Capsule::applyTransformation(const typename DimensionTraits::MatrixType& transformation) { + _transformedA = (transformation*typename DimensionTraits::PointType(_a)).vector(); + _transformedB = (transformation*typename DimensionTraits::PointType(_b)).vector(); + float scaling = (transformation.rotationScaling()*typename DimensionTraits::VectorType(1/Math::Constants::sqrt3())).length(); _transformedRadius = scaling*_radius; } -bool Capsule::collides(const AbstractShape* other) const { - if(other->type() == Type::Point) - return *this % *static_cast(other); - if(other->type() == Type::Sphere) - return *this % *static_cast(other); +template bool Capsule::collides(const AbstractShape* other) const { + if(other->type() == AbstractShape::Type::Point) + return *this % *static_cast*>(other); + if(other->type() == AbstractShape::Type::Sphere) + return *this % *static_cast*>(other); - return AbstractShape::collides(other); + return AbstractShape::collides(other); } -bool Capsule::operator%(const Point& other) const { +template bool Capsule::operator%(const Point& other) const { return Distance::lineSegmentPointSquared(transformedA(), transformedB(), other.transformedPosition()) < Math::pow<2>(transformedRadius()); } -bool Capsule::operator%(const Sphere& other) const { +template bool Capsule::operator%(const Sphere& other) const { return Distance::lineSegmentPointSquared(transformedA(), transformedB(), other.transformedPosition()) < Math::pow<2>(transformedRadius()+other.transformedRadius()); } +template class Capsule<2>; +template class Capsule<3>; + }} diff --git a/src/Physics/Capsule.h b/src/Physics/Capsule.h index 25ced6b53..c493f1db9 100644 --- a/src/Physics/Capsule.h +++ b/src/Physics/Capsule.h @@ -16,35 +16,58 @@ */ /** @file - * @brief Class Magnum::Physics::Capsule + * @brief Class Magnum::Physics::Capsule, typedef Magnum::Physics::Capsule2D, Magnum::Physics::Capsule3D */ +#include "Math/Vector3.h" #include "AbstractShape.h" -#include "Point.h" -#include "Sphere.h" + +#include "magnumCompatibility.h" namespace Magnum { namespace Physics { +template class Point; +template class Sphere; + /** @brief %Capsule defined by cylinder start and end point and radius Unlike other elements the capsule doesn't support asymmetric scaling. When applying transformation, the scale factor is averaged from all axes. +@see Capsule2D, Capsule3D */ -class PHYSICS_EXPORT Capsule: public AbstractShape { +template class PHYSICS_EXPORT Capsule: public AbstractShape { public: /** @brief Constructor */ - inline Capsule(const Vector3& a, const Vector3& b, float radius): _a(a), _transformedA(a), _b(b), _transformedB(b), _radius(radius), _transformedRadius(radius) {} + inline Capsule(const typename DimensionTraits::VectorType& a, const typename DimensionTraits::VectorType& b, float radius): _a(a), _transformedA(a), _b(b), _transformedB(b), _radius(radius), _transformedRadius(radius) {} + + inline typename AbstractShape::Type type() const override { + return AbstractShape::Type::Capsule; + } - void applyTransformation(const Matrix4& transformation); + void applyTransformation(const typename DimensionTraits::MatrixType& transformation) override; - bool collides(const AbstractShape* other) const; + bool collides(const AbstractShape* other) const override; - inline Vector3 a() const { return _a; } /**< @brief Start point */ - inline Vector3 b() const { return _a; } /**< @brief End point */ + /** @brief Start point */ + inline typename DimensionTraits::VectorType a() const { + return _a; + } + + /** @brief End point */ + inline typename DimensionTraits::VectorType b() const { + return _a; + } - inline void setA(const Vector3& a) { _a = a; } /**< @brief Set start point */ - inline void setB(const Vector3& b) { _b = b; } /**< @brief Set end point */ + /** @brief Set start point */ + inline void setA(const typename DimensionTraits::VectorType& a) { + _a = a; + } + + /** @brief Set end point */ + inline void setB(const typename DimensionTraits::VectorType& b) { + _b = b; + } /** @brief Radius */ inline float radius() const { return _radius; } @@ -53,10 +76,14 @@ class PHYSICS_EXPORT Capsule: public AbstractShape { inline void setRadius(float radius) { _radius = radius; } /** @brief Transformed first point */ - inline Vector3 transformedA() const { return _transformedA; } + inline typename DimensionTraits::VectorType transformedA() const { + return _transformedA; + } /** @brief Transformed second point */ - inline Vector3 transformedB() const { return _transformedB; } + inline typename DimensionTraits::VectorType transformedB() const { + return _transformedB; + } /** @brief Transformed radius */ inline float transformedRadius() const { @@ -64,25 +91,28 @@ class PHYSICS_EXPORT Capsule: public AbstractShape { } /** @brief Collision with point */ - bool operator%(const Point& other) const; + bool operator%(const Point& other) const; /** @brief Collision with sphere */ - bool operator%(const Sphere& other) const; - - protected: - inline Type type() const { return Type::Capsule; } + bool operator%(const Sphere& other) const; private: - Vector3 _a, _transformedA, + Math::Vector _a, _transformedA, _b, _transformedB; float _radius, _transformedRadius; }; +/** @brief Two-dimensional capsule */ +typedef Capsule<2> Capsule2D; + +/** @brief Three-dimensional capsule */ +typedef Capsule<3> Capsule3D; + /** @collisionoperator{Point,Capsule} */ -inline bool operator%(const Point& a, const Capsule& b) { return b % a; } +template inline bool operator%(const Point& a, const Capsule& b) { return b % a; } /** @collisionoperator{Sphere,Capsule} */ -inline bool operator%(const Sphere& a, const Capsule& b) { return b % a; } +template inline bool operator%(const Sphere& a, const Capsule& b) { return b % a; } }} diff --git a/src/Physics/DebugDrawResourceManager.cpp b/src/Physics/DebugDrawResourceManager.cpp new file mode 100644 index 000000000..f048a5816 --- /dev/null +++ b/src/Physics/DebugDrawResourceManager.cpp @@ -0,0 +1,60 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "DebugDrawResourceManager.h" + +#include "AbstractShaderProgram.h" +#include "Buffer.h" +#include "Mesh.h" +#include "Shaders/FlatShader.h" +#include "AbstractShape.h" +#include "Box.h" +#include "ShapedObject.h" +#include "ShapeGroup.h" +#include "Implementation/AbstractDebugRenderer.h" +#include "Implementation/BoxRenderer.h" + +namespace Magnum { + +template class ResourceManager; + +namespace Physics { + +SceneGraph::Object2D* DebugDrawResourceManager::createDebugRenderer(AbstractShape2D* shape, ResourceKey options) { + return createDebugMesh(nullptr, shape, options); +} + +SceneGraph::Object2D* DebugDrawResourceManager::createDebugMesh(SceneGraph::Object2D* parent, AbstractShape2D* shape, ResourceKey options) { + switch(shape->type()) { + case AbstractShape2D::Type::Box: + return new Implementation::BoxRenderer<2>(*static_cast(shape), options, parent); + case AbstractShape2D::Type::ShapeGroup: { + if(!parent) parent = new SceneGraph::Object2D; + ShapeGroup2D* group = static_cast(shape); + if(group->first()) createDebugMesh(parent, group->first(), options); + if(group->second()) createDebugMesh(parent, group->second(), options); + return parent; + } default: return nullptr; + } +} + +DebugDrawResourceManager::DebugDrawResourceManager() { + setFallback(new Options); + set("shader2d", new Shaders::FlatShader<2>, ResourceDataState::Final, ResourcePolicy::Resident); +} + +DebugDrawResourceManager::~DebugDrawResourceManager() {} + +}} diff --git a/src/Physics/DebugDrawResourceManager.h b/src/Physics/DebugDrawResourceManager.h new file mode 100644 index 000000000..db22e4221 --- /dev/null +++ b/src/Physics/DebugDrawResourceManager.h @@ -0,0 +1,124 @@ +#ifndef Magnum_Physics_DebugDrawResourceManager_h +#define Magnum_Physics_DebugDrawResourceManager_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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. +*/ + +/** @file + * @brief Class Magnum::Physics::DebugDrawResourceManager + */ + +#include "Magnum.h" +#include "Color.h" +#include "ResourceManager.h" + +#include "magnumPhysicsVisibility.h" + +namespace Magnum { + +class AbstractShaderProgram; +class Buffer; +class Mesh; + +#ifndef DOXYGEN_GENERATING_OUTPUT +namespace Physics { namespace Implementation { + struct Options { + Color3 color; + }; + template class AbstractDebugRenderer; +}} + +#ifndef WIN32 +extern template class PHYSICS_EXPORT ResourceManager; +#endif +#endif + +/** @todo fix extern template multiple definition linker errors in mingw32-gcc */ + +namespace SceneGraph { + class Object2D; + class Object3D; +} + +namespace Physics { + +template class AbstractShape; +typedef AbstractShape<2> AbstractShape2D; +typedef AbstractShape<3> AbstractShape3D; + +/** +@brief %Resource manager for physics debug draw + +Can create objects which draw object collision shape for debugging purposes. + +@section DebugDrawResourceManager-usage Basic usage +The manager must be instanced for the whole lifetime of debug draw objects. +To create debug draw objects, call createDebugRenderer() and add the resulting +object to the scene. You can specify options via Options struct - add it to +the manager and then create debug renderer with the same options key. This way +you can easily share the same options with more objects. If no options for +given key exist, default is used. + +Example code: +@code +// Instance the manager at first +DebugDrawResourceManager manager; + +// Create some options +auto o = new DebugDrawResourceManager::Options { + {1.0f, 0.0f, 0.0f} // Red color +}; +manager->set("red", o, ResourceDataState::Final, ResourcePolicy::Persistent); + +// Add debug draw object for given shape, use "red" options for it, don't +// forget to add it to the scene +ShapedObject2D* object; +DebugDrawResourceManager::createDebugRenderer(object->shape(), "red") + ->setParent(object); +@endcode +*/ +class PHYSICS_EXPORT DebugDrawResourceManager: public ResourceManager { + public: + #ifdef DOXYGEN_GENERATING_OUTPUT + /** @brief %Options */ + struct Options { + Color3 color; /**< @brief Color */ + }; + #else + typedef Implementation::Options Options; + #endif + + /** + * @brief Create debug renderer for given shape + * @param shape Shape for which to create debug renderer + * @param options Options resource key. See + * @ref DebugDrawResourceManager-usage "class documentation" for + * more information. + * + * Returned object is not parented to anything, you have to add it to + * desired scene yourself. + */ + static SceneGraph::Object2D* createDebugRenderer(AbstractShape2D* shape, ResourceKey options = ResourceKey()); + + DebugDrawResourceManager(); + + ~DebugDrawResourceManager(); + + private: + static SceneGraph::Object2D* createDebugMesh(SceneGraph::Object2D* parent, AbstractShape2D* shape, ResourceKey options); +}; + +}} + +#endif diff --git a/src/Physics/Implementation/AbstractDebugRenderer.cpp b/src/Physics/Implementation/AbstractDebugRenderer.cpp new file mode 100644 index 000000000..63235f8bb --- /dev/null +++ b/src/Physics/Implementation/AbstractDebugRenderer.cpp @@ -0,0 +1,30 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "AbstractDebugRenderer.h" + +#include "AbstractShaderProgram.h" +#include "Mesh.h" +#include "Physics/DebugDrawResourceManager.h" +#include "Shaders/FlatShader.h" + +namespace Magnum { namespace Physics { namespace Implementation { + +template AbstractDebugRenderer::AbstractDebugRenderer(ResourceKey shader, ResourceKey mesh, ResourceKey options, typename SceneGraph::AbstractObject::ObjectType* parent): SceneGraph::AbstractObject::ObjectType(parent), shader(DebugDrawResourceManager::instance()->get>(shader)), mesh(DebugDrawResourceManager::instance()->get(mesh)), options(DebugDrawResourceManager::instance()->get(options)) {} + +template class AbstractDebugRenderer<2>; +template class AbstractDebugRenderer<3>; + +}}} diff --git a/src/Physics/Implementation/AbstractDebugRenderer.h b/src/Physics/Implementation/AbstractDebugRenderer.h new file mode 100644 index 000000000..ed236b60d --- /dev/null +++ b/src/Physics/Implementation/AbstractDebugRenderer.h @@ -0,0 +1,50 @@ +#ifndef Magnum_Physics_Implementation_AbstractDebugRenderer_h +#define Magnum_Physics_Implementation_AbstractDebugRenderer_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "Color.h" +#include "ResourceManager.h" +#include "SceneGraph/Camera.h" + +namespace Magnum { + +class AbstractShaderProgram; +class Mesh; + +namespace Shaders { + template class FlatShader; +} + +namespace Physics { namespace Implementation { + +struct Options; + +template class AbstractDebugRenderer: public SceneGraph::AbstractObject::ObjectType { + public: + AbstractDebugRenderer(ResourceKey shader, ResourceKey mesh, ResourceKey options, typename SceneGraph::AbstractObject::ObjectType* parent); + + protected: + Resource> shader; + Resource mesh; + Resource options; +}; + +extern template class AbstractDebugRenderer<2>; +extern template class AbstractDebugRenderer<3>; + +}}} + +#endif diff --git a/src/Physics/Implementation/BoxRenderer.cpp b/src/Physics/Implementation/BoxRenderer.cpp new file mode 100644 index 000000000..472af6781 --- /dev/null +++ b/src/Physics/Implementation/BoxRenderer.cpp @@ -0,0 +1,81 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "BoxRenderer.h" + +#include "Buffer.h" +#include "Physics/Box.h" +#include "Physics/DebugDrawResourceManager.h" +#include "Primitives/Cube.h" +#include "Primitives/Square.h" +#include "Shaders/FlatShader.h" + +namespace Magnum { namespace Physics { namespace Implementation { + +namespace { + template struct BoxMesh {}; + + template<> struct BoxMesh<2> { + constexpr static char shader[] = "shader2d"; + constexpr static char key[] = "box2d"; + + static Mesh* mesh(Buffer* buffer) { + Primitives::Square square; + Mesh* mesh = new Mesh; + buffer->setData(*square.positions(0), Buffer::Usage::StaticDraw); + return mesh->setPrimitive(square.primitive()) + ->setVertexCount(square.positions(0)->size()) + ->addVertexBuffer(buffer, Shaders::FlatShader<2>::Position()); + } + }; + + template<> struct BoxMesh<3> { + constexpr static char shader[] = "shader3d"; + constexpr static char key[] = "box3d"; + + static Mesh* mesh(Buffer* buffer) { + Primitives::Cube cube; + Mesh* mesh = new Mesh; + buffer->setData(*cube.positions(0), Buffer::Usage::StaticDraw); + return mesh->setPrimitive(cube.primitive()) + ->setVertexCount(cube.positions(0)->size()) + ->addVertexBuffer(buffer, Shaders::FlatShader<2>::Position()); + } + }; +} + +constexpr char BoxMesh<2>::shader[]; +constexpr char BoxMesh<2>::key[]; +constexpr char BoxMesh<3>::shader[]; +constexpr char BoxMesh<3>::key[]; + +template BoxRenderer::BoxRenderer(Box& box, ResourceKey options, typename SceneGraph::AbstractObject::ObjectType* parent): AbstractDebugRenderer(BoxMesh::shader, BoxMesh::key, options, parent), buffer(DebugDrawResourceManager::instance()->get(BoxMesh::key)), box(box) { + if(!this->mesh) { + DebugDrawResourceManager::instance()->set(this->buffer.key(), new Buffer, ResourceDataState::Final, ResourcePolicy::Manual); + DebugDrawResourceManager::instance()->set(this->mesh.key(), BoxMesh::mesh(buffer), ResourceDataState::Final, ResourcePolicy::Manual); + } +} + +template void BoxRenderer::draw(const typename DimensionTraits::MatrixType&, typename SceneGraph::AbstractObject::CameraType* camera) { + this->shader->setTransformationProjection(camera->projectionMatrix()*box.transformedTransformation()) + ->setColor(this->options->color) + ->use(); + this->mesh->draw(); +} + +template class BoxRenderer<2>; +template class BoxRenderer<3>; + +}}} diff --git a/src/Physics/Implementation/BoxRenderer.h b/src/Physics/Implementation/BoxRenderer.h new file mode 100644 index 000000000..a04683ee4 --- /dev/null +++ b/src/Physics/Implementation/BoxRenderer.h @@ -0,0 +1,46 @@ +#ifndef Magnum_Physics_Implementation_BoxRenderer_h +#define Magnum_Physics_Implementation_BoxRenderer_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "AbstractDebugRenderer.h" + +namespace Magnum { + +class Buffer; + +namespace Physics { + +template class Box; + +namespace Implementation { + +template class BoxRenderer: public AbstractDebugRenderer { + public: + BoxRenderer(Box& box, ResourceKey options, typename SceneGraph::AbstractObject::ObjectType* parent); + + void draw(const typename DimensionTraits::MatrixType& transformation, typename SceneGraph::AbstractObject::CameraType* camera); + + private: + Resource buffer; + Box& box; +}; + +extern template class BoxRenderer<2>; +extern template class BoxRenderer<3>; + +}}} + +#endif diff --git a/src/Physics/Line.cpp b/src/Physics/Line.cpp index 0cf2ecc15..c067306c0 100644 --- a/src/Physics/Line.cpp +++ b/src/Physics/Line.cpp @@ -15,11 +15,18 @@ #include "Line.h" +#include "Math/Matrix3.h" +#include "Math/Matrix4.h" + namespace Magnum { namespace Physics { -void Line::applyTransformation(const Matrix4& transformation) { - _transformedA = (transformation*Vector4(_a)).xyz(); - _transformedB = (transformation*Vector4(_b)).xyz(); +template void Line::applyTransformation(const typename DimensionTraits::MatrixType& transformation) { + _transformedA = (transformation*typename DimensionTraits::PointType(_a)).vector(); + _transformedB = (transformation*typename DimensionTraits::PointType(_b)).vector(); } +/* Explicitly instantiate the templates */ +template class Line<2>; +template class Line<3>; + }} diff --git a/src/Physics/Line.h b/src/Physics/Line.h index 05b5c7f16..39cb70363 100644 --- a/src/Physics/Line.h +++ b/src/Physics/Line.h @@ -16,41 +16,74 @@ */ /** @file - * @brief Class Magnum::Physics::Line + * @brief Class Magnum::Physics::Line, typedef Magnum::Physics::Line2D, Magnum::Physics::Line3D */ +#include "Math/Vector3.h" #include "AbstractShape.h" +#include "magnumCompatibility.h" + namespace Magnum { namespace Physics { -/** @brief Infinite line, defined by two points */ -class PHYSICS_EXPORT Line: public AbstractShape { +/** +@brief Infinite line, defined by two points + +@see Line2D, Line3D +@todo collision detection of two Line2D +*/ +template class PHYSICS_EXPORT Line: public AbstractShape { public: /** @brief Constructor */ - inline Line(const Vector3& a, const Vector3& b): _a(a), _transformedA(a), _b(b), _transformedB(b) {} + inline Line(const typename DimensionTraits::VectorType& a, const typename DimensionTraits::VectorType& b): _a(a), _transformedA(a), _b(b), _transformedB(b) {} + + inline typename AbstractShape::Type type() const override { + return AbstractShape::Type::Line; + } + + void applyTransformation(const typename DimensionTraits::MatrixType& transformation) override; - void applyTransformation(const Matrix4& transformation); + /** @brief First point */ + inline typename DimensionTraits::VectorType a() const { + return _a; + } - inline Vector3 a() const { return _a; } /**< @brief First point */ - inline Vector3 b() const { return _a; } /**< @brief Second point */ + /** @brief Second point */ + inline typename DimensionTraits::VectorType b() const { + return _a; + } - inline void setA(const Vector3& a) { _a = a; } /**< @brief Set first point */ - inline void setB(const Vector3& b) { _b = b; } /**< @brief Set second point */ + /** @brief Set first point */ + inline void setA(const typename DimensionTraits::VectorType& a) { + _a = a; + } + + /** @brief Set second point */ + inline void setB(const typename DimensionTraits::VectorType& b) { + _b = b; + } /** @brief Transformed first point */ - inline Vector3 transformedA() const { return _transformedA; } + inline typename DimensionTraits::VectorType transformedA() const { + return _transformedA; + } /** @brief Transformed second point */ - inline Vector3 transformedB() const { return _transformedB; } - - protected: - inline Type type() const { return Type::Line; } + inline typename DimensionTraits::VectorType transformedB() const { + return _transformedB; + } private: - Vector3 _a, _transformedA, + Math::Vector _a, _transformedA, _b, _transformedB; }; +/** @brief Infinite two-dimensional line */ +typedef Line<2> Line2D; + +/** @brief Infinite three-dimensional line */ +typedef Line<3> Line3D; + }} #endif diff --git a/src/Physics/LineSegment.h b/src/Physics/LineSegment.h index c10a6d8f0..8c0d00242 100644 --- a/src/Physics/LineSegment.h +++ b/src/Physics/LineSegment.h @@ -16,23 +16,34 @@ */ /** @file - * @brief Class Magnum::Physics::LineSegment + * @brief Class Magnum::Physics::LineSegment, typedef Magnum::Physics::LineSegment2D, Magnum::Physics::LineSegment3D */ #include "Line.h" namespace Magnum { namespace Physics { -/** @brief %Line segment, defined by starting and ending point */ -class LineSegment: public Line { +/** +@brief %Line segment, defined by starting and ending point + +@see LineSegment2D, LineSegment3D +*/ +template class LineSegment: public Line { public: /** @brief Constructor */ - inline LineSegment(const Vector3& a, const Vector3& b): Line(a, b) {} + inline LineSegment(const typename DimensionTraits::VectorType& a, const typename DimensionTraits::VectorType& b): Line(a, b) {} - protected: - inline Type type() const { return Type::LineSegment; } + inline typename AbstractShape::Type type() const override { + return AbstractShape::Type::LineSegment; + } }; +/** @brief Two-dimensional line segment */ +typedef LineSegment<2> LineSegment2D; + +/** @brief Three-dimensional line segment */ +typedef LineSegment<3> LineSegment3D; + }} #endif diff --git a/src/Physics/Plane.cpp b/src/Physics/Plane.cpp index f8529bbf1..79ead18c7 100644 --- a/src/Physics/Plane.cpp +++ b/src/Physics/Plane.cpp @@ -17,7 +17,10 @@ #include +#include "Math/Matrix4.h" +#include "Math/Point3D.h" #include "Math/Geometry/Intersection.h" +#include "LineSegment.h" using namespace std; using namespace Magnum::Math::Geometry; @@ -25,25 +28,25 @@ using namespace Magnum::Math::Geometry; namespace Magnum { namespace Physics { void Plane::applyTransformation(const Matrix4& transformation) { - _transformedPosition = (transformation*Vector4(_position)).xyz(); + _transformedPosition = (transformation*Point3D(_position)).xyz(); _transformedNormal = transformation.rotation()*_normal; } -bool Plane::collides(const AbstractShape* other) const { +bool Plane::collides(const AbstractShape<3>* other) const { if(other->type() == Type::Line) - return *this % *static_cast(other); + return *this % *static_cast(other); if(other->type() == Type::LineSegment) - return *this % *static_cast(other); + return *this % *static_cast(other); return AbstractShape::collides(other); } -bool Plane::operator%(const Line& other) const { +bool Plane::operator%(const Line3D& other) const { float t = Intersection::planeLine(transformedPosition(), transformedNormal(), other.transformedA(), other.transformedB()); return t != t || (t != numeric_limits::infinity() && t != -numeric_limits::infinity()); } -bool Plane::operator%(const LineSegment& other) const { +bool Plane::operator%(const LineSegment3D& other) const { float t = Intersection::planeLine(transformedPosition(), transformedNormal(), other.transformedA(), other.transformedB()); return t > 0.0f && t < 1.0f; } diff --git a/src/Physics/Plane.h b/src/Physics/Plane.h index 883fc899e..c17114b16 100644 --- a/src/Physics/Plane.h +++ b/src/Physics/Plane.h @@ -19,22 +19,33 @@ * @brief Class Magnum::Physics::Plane */ +#include "Math/Vector3.h" #include "AbstractShape.h" -#include "Line.h" -#include "LineSegment.h" +#include "magnumCompatibility.h" namespace Magnum { namespace Physics { -/** @brief Infinite plane, defined by position and normal */ -class PHYSICS_EXPORT Plane: public AbstractShape { +template class Line; +typedef Line<3> Line3D; +template class LineSegment; +typedef LineSegment<3> LineSegment3D; + +/** @brief Infinite plane, defined by position and normal (3D only) */ +class PHYSICS_EXPORT Plane: public AbstractShape<3> { public: /** @brief Constructor */ inline Plane(const Vector3& position, const Vector3& normal): _position(position), _transformedPosition(position), _normal(normal), _transformedNormal(normal) {} - void applyTransformation(const Matrix4& transformation); + inline Type type() const override { return Type::Plane; } - bool collides(const AbstractShape* other) const; + #ifndef DOXYGEN_GENERATING_OUTPUT + void applyTransformation(const Matrix4& transformation) override; + bool collides(const AbstractShape<3>* other) const override; + #else + void applyTransformation(const typename DimensionTraits::MatrixType& transformation) override; + bool collides(const AbstractShape* other) const override; + #endif /** @brief Position */ inline Vector3 position() const { return _position; } @@ -63,13 +74,10 @@ class PHYSICS_EXPORT Plane: public AbstractShape { } /** @brief Collision with line */ - bool operator%(const Line& other) const; + bool operator%(const Line3D& other) const; /** @brief Collision with line segment */ - bool operator%(const LineSegment& other) const; - - protected: - inline Type type() const { return Type::Plane; } + bool operator%(const LineSegment3D& other) const; private: Vector3 _position, _transformedPosition, @@ -77,10 +85,10 @@ class PHYSICS_EXPORT Plane: public AbstractShape { }; /** @collisionoperator{Line,Plane} */ -inline bool operator%(const Line& a, const Plane& b) { return b % a; } +inline bool operator%(const Line3D& a, const Plane& b) { return b % a; } /** @collisionoperator{LineSegment,Plane} */ -inline bool operator%(const LineSegment& a, const Plane& b) { return b % a; } +inline bool operator%(const LineSegment3D& a, const Plane& b) { return b % a; } }} diff --git a/src/Physics/Point.cpp b/src/Physics/Point.cpp new file mode 100644 index 000000000..6ca6df6f4 --- /dev/null +++ b/src/Physics/Point.cpp @@ -0,0 +1,30 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "Point.h" + +#include "Math/Matrix3.h" +#include "Math/Matrix4.h" + +namespace Magnum { namespace Physics { + +template void Point::applyTransformation(const typename DimensionTraits::MatrixType& transformation) { + _transformedPosition = (transformation*typename DimensionTraits::PointType(_position)).vector(); +} + +template class Point<2>; +template class Point<3>; + +}} diff --git a/src/Physics/Point.h b/src/Physics/Point.h index 80e465fbc..142b315e0 100644 --- a/src/Physics/Point.h +++ b/src/Physics/Point.h @@ -16,43 +16,57 @@ */ /** @file - * @brief Class Magnum::Physics::Point + * @brief Class Magnum::Physics::Point, typedef Magnum::Physics::Point2D, Magnum::Physics::Point3D */ +#include "Math/Vector3.h" #include "AbstractShape.h" +#include "magnumCompatibility.h" + namespace Magnum { namespace Physics { -/** @brief %Point */ -class Point: public AbstractShape { +/** +@brief %Point + +@see Point2D, Point3D +*/ +template class PHYSICS_EXPORT Point: public AbstractShape { public: /** @brief Constructor */ - inline Point(const Vector3& position): _position(position), _transformedPosition(position) {} + inline Point(const typename DimensionTraits::VectorType& position): _position(position), _transformedPosition(position) {} - inline void applyTransformation(const Matrix4& transformation) { - _transformedPosition = (transformation*Vector4(_position)).xyz(); + inline typename AbstractShape::Type type() const override { + return AbstractShape::Type::Point; } + void applyTransformation(const typename DimensionTraits::MatrixType& transformation) override; + /** @brief Position */ - inline Vector3 position() const { return _position; } + inline typename DimensionTraits::VectorType position() const { + return _position; + } /** @brief Set position */ - inline void setPosition(const Vector3& position) { + inline void setPosition(const typename DimensionTraits::VectorType& position) { _position = position; } /** @brief Transformed position */ - inline Vector3 transformedPosition() const { + inline typename DimensionTraits::VectorType transformedPosition() const { return _transformedPosition; } - protected: - inline Type type() const { return Type::Point; } - private: - Vector3 _position, _transformedPosition; + Math::Vector _position, _transformedPosition; }; +/** @brief Two-dimensional point */ +typedef Point<2> Point2D; + +/** @brief Three-dimensional point */ +typedef Point<3> Point3D; + }} #endif diff --git a/src/Physics/ShapeGroup.cpp b/src/Physics/ShapeGroup.cpp index 32aaeaeb5..83a5f7178 100644 --- a/src/Physics/ShapeGroup.cpp +++ b/src/Physics/ShapeGroup.cpp @@ -17,49 +17,50 @@ namespace Magnum { namespace Physics { -ShapeGroup::ShapeGroup(ShapeGroup&& other): operation(other.operation), a(other.a), b(other.b) { - other.operation = AlwaysFalse; +template ShapeGroup::ShapeGroup(ShapeGroup&& other): operation(other.operation), a(other.a), b(other.b) { + other.operation = Implementation::GroupOperation::AlwaysFalse; other.a = nullptr; other.b = nullptr; } -ShapeGroup::~ShapeGroup() { - if(!(operation & RefA)) delete a; - if(!(operation & RefB)) delete b; +template ShapeGroup::~ShapeGroup() { + if(!(operation & Implementation::GroupOperation::RefA)) delete a; + if(!(operation & Implementation::GroupOperation::RefB)) delete b; } -ShapeGroup& ShapeGroup::operator=(ShapeGroup&& other) { - if(!(operation & RefA)) delete a; - if(!(operation & RefB)) delete b; +template ShapeGroup& ShapeGroup::operator=(ShapeGroup&& other) { + if(!(operation & Implementation::GroupOperation::RefA)) delete a; + if(!(operation & Implementation::GroupOperation::RefB)) delete b; operation = other.operation; a = other.a; b = other.b; - other.operation = AlwaysFalse; + other.operation = Implementation::GroupOperation::AlwaysFalse; other.a = nullptr; other.b = nullptr; return *this; } -void ShapeGroup::applyTransformation(const Matrix4& transformation) { +template void ShapeGroup::applyTransformation(const typename DimensionTraits::MatrixType& transformation) { if(a) a->applyTransformation(transformation); if(b) b->applyTransformation(transformation); } -bool ShapeGroup::collides(const AbstractShape* other) const { - switch(operation & ~RefAB) { - case Complement: return !a->collides(other); - case Union: return a->collides(other) || b->collides(other); - case Intersection: return a->collides(other) && b->collides(other); - case Difference: return a->collides(other) && !b->collides(other); - case Xor: return a->collides(other) != b->collides(other); - case FirstObjectOnly: return a->collides(other); +template bool ShapeGroup::collides(const AbstractShape* other) const { + switch(operation & ~Implementation::GroupOperation::RefAB) { + case Implementation::GroupOperation::And: return a->collides(other) && b->collides(other); + case Implementation::GroupOperation::Or: return a->collides(other) || b->collides(other); + case Implementation::GroupOperation::Not: return !a->collides(other); + case Implementation::GroupOperation::FirstObjectOnly: return a->collides(other); default: return false; } } +template class ShapeGroup<2>; +template class ShapeGroup<3>; + }} diff --git a/src/Physics/ShapeGroup.h b/src/Physics/ShapeGroup.h index 074474719..8a3533e84 100644 --- a/src/Physics/ShapeGroup.h +++ b/src/Physics/ShapeGroup.h @@ -16,67 +16,81 @@ */ /** @file - * @brief Class Magnum::Physics::ShapeGroup + * @brief Class Magnum::Physics::ShapeGroup, typedef Magnum::Physics::ShapeGroup2D, Magnum::Physics::ShapeGroup3D */ #include "AbstractShape.h" +#include +#include + +#include "magnumCompatibility.h" + namespace Magnum { namespace Physics { #ifndef DOXYGEN_GENERATING_OUTPUT -#define enableIfIsBaseType typename std::enable_if::value, ShapeGroup>::type -#define enableIfAreBaseType typename std::enable_if::value && std::is_base_of::value, ShapeGroup>::type +namespace Implementation { + enum GroupOperation { + RefA = 0x01, + RefB = 0x02, + RefAB = 0x03, +// Complement = 1 << 2, +// Union = 2 << 2, +// Intersection = 3 << 2, +// Difference = 4 << 2, +// Xor = 5 << 2, + And = 6 << 2, + Or = 7 << 2, + Not = 8 << 2, + FirstObjectOnly = 9 << 2, + AlwaysFalse = 10 << 2 + }; +} +#define enableIfIsBaseType typename std::enable_if, T>::value, ShapeGroup>::type +#define enableIfAreBaseType typename std::enable_if, T>::value && std::is_base_of, U>::value, ShapeGroup>::type #endif /** -@brief Collider group with defined set operation +@brief Shape group -Result of union, intersection, subtraction or XOR of two collider objects. +Result of logical operations on shapes. See @ref collision-detection for brief introduction. +@see ShapeGroup2D, ShapeGroup3D */ -class PHYSICS_EXPORT ShapeGroup: public AbstractShape { +template class PHYSICS_EXPORT ShapeGroup: public AbstractShape { #ifndef DOXYGEN_GENERATING_OUTPUT - template friend constexpr enableIfIsBaseType operator~(const T& a); - template friend constexpr enableIfIsBaseType operator~(T&& a); - template friend constexpr enableIfIsBaseType operator~(T& a); +// template friend constexpr operator~(const T& a) -> enableIfIsBaseType; +// template friend constexpr operator~(T&& a) -> enableIfIsBaseType; +// template friend constexpr operator~(T& a) -> enableIfIsBaseType; + template friend constexpr auto operator!(const T& a) -> enableIfIsBaseType; + template friend constexpr auto operator!(T&& a) -> enableIfIsBaseType; + template friend constexpr auto operator!(T& a) -> enableIfIsBaseType; #define friendOp(char) \ - template friend constexpr enableIfAreBaseType operator char(const T& a, const U& b); \ - template friend constexpr enableIfAreBaseType operator char(const T& a, U&& b); \ - template friend constexpr enableIfAreBaseType operator char(T&& a, const U& b); \ - template friend constexpr enableIfAreBaseType operator char(T&& a, U&& b); \ - template friend constexpr enableIfAreBaseType operator char(const T& a, std::reference_wrapper b); \ - template friend constexpr enableIfAreBaseType operator char(T&& a, std::reference_wrapper b); \ - template friend constexpr enableIfAreBaseType operator char(std::reference_wrapper a, const U& b); \ - template friend constexpr enableIfAreBaseType operator char(std::reference_wrapper a, U&& b); \ - template friend constexpr enableIfAreBaseType operator char(std::reference_wrapper a, std::reference_wrapper b); - friendOp(|) - friendOp(&) - friendOp(-) - friendOp(^) + template friend constexpr auto operator char(const T& a, const U& b) -> enableIfAreBaseType; \ + template friend constexpr auto operator char(const T& a, U&& b) -> enableIfAreBaseType; \ + template friend constexpr auto operator char(T&& a, const U& b) -> enableIfAreBaseType; \ + template friend constexpr auto operator char(T&& a, U&& b) -> enableIfAreBaseType; \ + template friend constexpr auto operator char(const T& a, std::reference_wrapper b) -> enableIfAreBaseType; \ + template friend constexpr auto operator char(T&& a, std::reference_wrapper b) -> enableIfAreBaseType; \ + template friend constexpr auto operator char(std::reference_wrapper a, const U& b) -> enableIfAreBaseType; \ + template friend constexpr auto operator char(std::reference_wrapper a, U&& b) -> enableIfAreBaseType; \ + template friend constexpr auto operator char(std::reference_wrapper a, std::reference_wrapper b) -> enableIfAreBaseType; +// friendOp(|) +// friendOp(&) +// friendOp(-) +// friendOp(^) + friendOp(&&) + friendOp(||) #undef friendOp #endif ShapeGroup(const ShapeGroup& other) = delete; ShapeGroup& operator=(const ShapeGroup& other) = delete; - private: - enum Operation { - RefA = 0x01, - RefB = 0x02, - RefAB = 0x03, - Complement = 1 << 2, - Union = 2 << 2, - Intersection = 3 << 2, - Difference = 4 << 2, - Xor = 5 << 2, - FirstObjectOnly = 6 << 2, - AlwaysFalse = 7 << 2 - }; - public: /** @brief Default constructor */ - inline ShapeGroup(): operation(AlwaysFalse), a(nullptr), b(nullptr) {} + inline ShapeGroup(): operation(Implementation::GroupOperation::AlwaysFalse), a(nullptr), b(nullptr) {} /** @brief Move constructor */ ShapeGroup(ShapeGroup&& other); @@ -87,85 +101,135 @@ class PHYSICS_EXPORT ShapeGroup: public AbstractShape { /** @brief Move assignment */ ShapeGroup& operator=(ShapeGroup&& other); - void applyTransformation(const Matrix4& transformation); + inline typename AbstractShape::Type type() const override { + return AbstractShape::Type::ShapeGroup; + } + + void applyTransformation(const typename DimensionTraits::MatrixType& transformation) override; - bool collides(const AbstractShape* other) const; + bool collides(const AbstractShape* other) const override; - protected: - virtual Type type() const { return Type::ShapeGroup; } + /** + * @brief First object in the group + * + * If there is no such object, returns `nullptr`. + */ + inline AbstractShape* first() { return a; } + + /** + * @brief Second object in the group + * + * If there is no such object, returns `nullptr`. + */ + inline AbstractShape* second() { return b; } private: - inline ShapeGroup(int operation, AbstractShape* a, AbstractShape* b): operation(operation), a(a), b(b) {} + inline ShapeGroup(int operation, AbstractShape* a, AbstractShape* b): operation(operation), a(a), b(b) {} int operation; - AbstractShape* a; - AbstractShape* b; + AbstractShape* a; + AbstractShape* b; }; -/** @brief Complement of shape */ -template inline constexpr enableIfIsBaseType operator~(const T& a) { - return ShapeGroup(ShapeGroup::Complement, new T(a), nullptr); +/** @brief Two-dimensional shape group */ +typedef ShapeGroup<2> ShapeGroup2D; + +/** @brief Three-dimensional shape group */ +typedef ShapeGroup<3> ShapeGroup3D; + +// /* @brief Complement of shape */ +// template inline constexpr enableIfIsBaseType operator~(const T& a) { +// return ShapeGroup(ShapeGroup::Complement, new T(a), nullptr); +// } +// #ifndef DOXYGEN_GENERATING_OUTPUT +// template inline constexpr enableIfIsBaseType operator~(T&& a) { +// return ShapeGroup(ShapeGroup::Complement, new T(std::forward(a)), nullptr); +// } +// template inline constexpr enableIfIsBaseType operator~(T& a) { +// return ShapeGroup(ShapeGroup::Complement|ShapeGroup::RefA, &a.get(), nullptr); +// } +// #endif + +/** @relates ShapeGroup +@brief Logical NOT of shape +*/ +template inline constexpr auto operator!(const T& a) -> enableIfIsBaseType { + return ShapeGroup(Implementation::GroupOperation::Not, new T(a), nullptr); } #ifndef DOXYGEN_GENERATING_OUTPUT -template inline constexpr enableIfIsBaseType operator~(T&& a) { - return ShapeGroup(ShapeGroup::Complement, new T(std::forward(a)), nullptr); +template inline constexpr auto operator!(T&& a) -> enableIfIsBaseType { + return ShapeGroup(Implementation::GroupOperation::Not, new T(std::forward(a)), nullptr); } -template inline constexpr enableIfIsBaseType operator~(T& a) { - return ShapeGroup(ShapeGroup::Complement|ShapeGroup::RefA, &a.get(), nullptr); +template inline constexpr auto operator!(T& a) -> enableIfIsBaseType { + return ShapeGroup(Implementation::GroupOperation::Not|Implementation::GroupOperation::RefA, &a.get(), nullptr); } #endif #ifdef DOXYGEN_GENERATING_OUTPUT -/** @brief Union of two shapes */ -template inline constexpr ShapeGroup operator&(T a, U b); - -/** -@brief Intersection of two shapes - -Collision with @p a is computed first, so this operation can be also used for -providing simplified version for shape @p b. See @ref CollisionDetectionShapeGroups -for an example. +// /* @brief Union of two shapes */ +// template inline constexpr ShapeGroup operator&(T a, U b); +// +// /* @brief Intersection of two shapes */ +// template inline constexpr ShapeGroup operator&(T a, U b); +// +// /* @brief Difference of two shapes */ +// template inline constexpr ShapeGroup operator-(T a, U b); +// +// /* @brief XOR of two shapes */ +// template inline constexpr ShapeGroup operator^(T a, U b); +/** @relates ShapeGroup +@brief Logical AND of two shapes + +[Short-circuit evaluation](http://en.wikipedia.org/wiki/Short-circuit_evaluation) +is used here, so this operation can be used for providing simplified shape +version, because collision with @p b is computed only if @p a collides. +See @ref collision-detection-shape-simplification for an example. */ -template inline constexpr ShapeGroup operator&(T a, U b); +template inline constexpr ShapeGroup operator&&(T a, U b); -/** @brief Difference of two shapes */ -template inline constexpr ShapeGroup operator-(T a, U b); +/** @relates ShapeGroup +@brief Logical OR of two shapes -/** @brief XOR of two shapes */ -template inline constexpr ShapeGroup operator^(T a, U b); +[Short-circuit evaluation](http://en.wikipedia.org/wiki/Short-circuit_evaluation) +is used, so if collision with @p a is detected, collision with @p b is not +computed. +*/ +template inline constexpr ShapeGroup operator||(T a, U b); #else #define op(type, char) \ -template inline constexpr enableIfAreBaseType operator char(const T& a, const U& b) { \ - return ShapeGroup(ShapeGroup::type, new T(a), new U(b)); \ +template inline constexpr auto operator char(const T& a, const U& b) -> enableIfAreBaseType { \ + return ShapeGroup(Implementation::GroupOperation::type, new T(a), new U(b)); \ } \ -template inline constexpr enableIfAreBaseType operator char(const T& a, U&& b) { \ - return ShapeGroup(ShapeGroup::type, new T(a), new U(std::forward(b))); \ +template inline constexpr auto operator char(const T& a, U&& b) -> enableIfAreBaseType { \ + return ShapeGroup(Implementation::GroupOperation::type, new T(a), new U(std::forward(b))); \ } \ -template inline constexpr enableIfAreBaseType operator char(T&& a, const U& b) { \ - return ShapeGroup(ShapeGroup::type, new T(std::forward(a)), new U(b)); \ +template inline constexpr auto operator char(T&& a, const U& b) -> enableIfAreBaseType { \ + return ShapeGroup(Implementation::GroupOperation::type, new T(std::forward(a)), new U(b)); \ } \ -template inline constexpr enableIfAreBaseType operator char(T&& a, U&& b) { \ - return ShapeGroup(ShapeGroup::type, new T(std::forward(a)), new U(std::forward(b))); \ +template inline constexpr auto operator char(T&& a, U&& b) -> enableIfAreBaseType { \ + return ShapeGroup(Implementation::GroupOperation::type, new T(std::forward(a)), new U(std::forward(b))); \ } \ -template inline constexpr enableIfAreBaseType operator char(const T& a, std::reference_wrapper b) { \ - return ShapeGroup(ShapeGroup::type|ShapeGroup::RefB, new T(a), &b.get()); \ +template inline constexpr auto operator char(const T& a, std::reference_wrapper b) -> enableIfAreBaseType { \ + return ShapeGroup(Implementation::GroupOperation::type|Implementation::GroupOperation::RefB, new T(a), &b.get()); \ } \ -template inline constexpr enableIfAreBaseType operator char(T&& a, std::reference_wrapper b) { \ - return ShapeGroup(ShapeGroup::type|ShapeGroup::RefB, new T(std::forward(a)), &b.get()); \ +template inline constexpr auto operator char(T&& a, std::reference_wrapper b) -> enableIfAreBaseType { \ + return ShapeGroup(Implementation::GroupOperation::type|Implementation::GroupOperation::RefB, new T(std::forward(a)), &b.get()); \ } \ -template inline constexpr enableIfAreBaseType operator char(std::reference_wrapper a, const U& b) { \ - return ShapeGroup(ShapeGroup::type|ShapeGroup::RefA, &a.get(), new U(b)); \ +template inline constexpr auto operator char(std::reference_wrapper a, const U& b) -> enableIfAreBaseType { \ + return ShapeGroup(Implementation::GroupOperation::type|Implementation::GroupOperation::RefA, &a.get(), new U(b)); \ } \ -template inline constexpr enableIfAreBaseType operator char(std::reference_wrapper a, U&& b) { \ - return ShapeGroup(ShapeGroup::type|ShapeGroup::RefA, &a.get(), new U(std::forward(b))); \ +template inline constexpr auto operator char(std::reference_wrapper a, U&& b) -> enableIfAreBaseType { \ + return ShapeGroup(Implementation::GroupOperation::type|Implementation::GroupOperation::RefA, &a.get(), new U(std::forward(b))); \ } \ -template inline constexpr enableIfAreBaseType operator char(std::reference_wrapper a, std::reference_wrapper b) { \ - return ShapeGroup(ShapeGroup::type|ShapeGroup::RefAB, &a.get(), &b.get()); \ +template inline constexpr auto operator char(std::reference_wrapper a, std::reference_wrapper b) -> enableIfAreBaseType { \ + return ShapeGroup(Implementation::GroupOperation::type|Implementation::GroupOperation::RefAB, &a.get(), &b.get()); \ } -op(Union, |) -op(Intersection, &) -op(Difference, -) -op(Xor, ^) +// op(Union, |) +// op(Intersection, &) +// op(Difference, -) +// op(Xor, ^) +op(And, &&) +op(Or, ||) #undef op #endif diff --git a/src/Physics/ShapedObject.cpp b/src/Physics/ShapedObject.cpp new file mode 100644 index 000000000..fb92ede11 --- /dev/null +++ b/src/Physics/ShapedObject.cpp @@ -0,0 +1,51 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "ShapedObject.h" + +#include + +#include "AbstractShape.h" +#include "ShapedObjectGroup.h" + +using namespace std; + +namespace Magnum { namespace Physics { + +template ShapedObject::ShapedObject(ShapedObjectGroup* group, typename SceneGraph::AbstractObject::ObjectType* parent): SceneGraph::AbstractObject::ObjectType(parent), group(group), _shape(nullptr) { + group->objects.push_back(this); +} + +template ShapedObject::~ShapedObject() { + group->objects.erase(find(group->objects.begin(), group->objects.end(), this)); + delete _shape; +} + +template void ShapedObject::setDirty() { + SceneGraph::AbstractObject::ObjectType::setDirty(); + + group->setDirty(); +} + +template void ShapedObject::clean(const typename DimensionTraits::MatrixType& absoluteTransformation) { + SceneGraph::AbstractObject::ObjectType::clean(absoluteTransformation); + + if(_shape) _shape->applyTransformation(absoluteTransformation); +} + +template class ShapedObject<2>; +template class ShapedObject<3>; + +}} diff --git a/src/Physics/ShapedObject.h b/src/Physics/ShapedObject.h new file mode 100644 index 000000000..b9763270f --- /dev/null +++ b/src/Physics/ShapedObject.h @@ -0,0 +1,97 @@ +#ifndef Magnum_Physics_ShapedObject_h +#define Magnum_Physics_ShapedObject_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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. +*/ + +/** @file + * @brief Class Magnum::Physics::ShapedObject + */ + +#include "SceneGraph/Object.h" + +#include "magnumPhysicsVisibility.h" + +namespace Magnum { namespace Physics { + +template class ShapedObjectGroup; +template class AbstractShape; + +/** +@brief Object with assigned shape + +@see ShapedObject2D, ShapedObject3D +*/ +template class PHYSICS_EXPORT ShapedObject: public SceneGraph::AbstractObject::ObjectType { + public: + /** + * @brief Constructor + * @param group Group this shaped object belongs to + * @param parent Parent object + * + * Creates object with no shape. + * @see setShape() + */ + ShapedObject(ShapedObjectGroup* group, typename SceneGraph::AbstractObject::ObjectType* parent = nullptr); + + /** + * @brief Destructor + * + * Deletes associated shape. + */ + ~ShapedObject(); + + /** @brief Object shape */ + inline AbstractShape* shape() { return _shape; } + inline const AbstractShape* shape() const { return _shape; } /**< @overload */ + + /** + * @brief Set object shape + * @return Pointer to self (for method chaining) + */ + inline ShapedObject* setShape(AbstractShape* shape) { + _shape = shape; + setDirty(); + return this; + } + + /** + * @copybrief SceneGraph::AbstractObject::setDirty() + * + * Marks shaped object group as dirty. + */ + void setDirty(); + + protected: + /** + * @copybrief SceneGraph::AbstractObject::clean() + * + * Applies transformation to associated shape. + */ + void clean(const typename DimensionTraits::MatrixType& absoluteTransformation); + + private: + ShapedObjectGroup* group; + AbstractShape* _shape; +}; + +/** @brief Two-dimensional shaped object */ +typedef ShapedObject<2> ShapedObject2D; + +/** @brief Three-dimensional shaped object */ +typedef ShapedObject<3> ShapedObject3D; + +}} + +#endif diff --git a/src/Physics/ShapedObjectGroup.cpp b/src/Physics/ShapedObjectGroup.cpp new file mode 100644 index 000000000..ae02018f5 --- /dev/null +++ b/src/Physics/ShapedObjectGroup.cpp @@ -0,0 +1,32 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "ShapedObjectGroup.h" + +#include "ShapedObject.h" + +namespace Magnum { namespace Physics { + +template void ShapedObjectGroup::setClean() { + for(ShapedObject* object: objects) + if(object->isDirty()) object->setClean(); + + dirty = false; +} + +template class ShapedObjectGroup<2>; +template class ShapedObjectGroup<3>; + +}} diff --git a/src/Physics/ShapedObjectGroup.h b/src/Physics/ShapedObjectGroup.h new file mode 100644 index 000000000..acd5fb96a --- /dev/null +++ b/src/Physics/ShapedObjectGroup.h @@ -0,0 +1,97 @@ +#ifndef Magnum_Physics_ShapedObjectGroup_h +#define Magnum_Physics_ShapedObjectGroup_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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. +*/ + +/** @file + * @brief Class Magnum::Physics::ShapedObjectGroup + */ + +#include +#include + +#include "magnumPhysicsVisibility.h" + +namespace Magnum { namespace Physics { + +template class ShapedObject; + +/** +@brief Group of shaped objects + +@ref ShapedObject "ShapedObject*D" instances are added to the group by +specifying it in the constructor. When the group is deleted, all objects +belogning to it are deleted too. +@see ShapedObjectGroup2D, ShapedObjectGroup3D +*/ +template class PHYSICS_EXPORT ShapedObjectGroup { + friend class ShapedObject; + + public: + /** + * @brief Constructor + * + * Marks the group as dirty. + */ + inline constexpr ShapedObjectGroup(): dirty(true) {} + + /** + * @brief Destructor + * + * Deletes all objects belogning to the group. + */ + inline virtual ~ShapedObjectGroup() { + for(auto i: objects) delete i; + } + + /** + * @brief Whether the group is dirty + * @return True if any object in the group is dirty, false otherwise. + */ + inline bool isDirty() const { return dirty; } + + /** + * @brief Set the group as dirty + * + * If some body in the group changes its transformation, it sets dirty + * status also on the group to indicate that the body and maybe also + * group state needs to be cleaned before computing collisions. + * + * @see setClean() + */ + inline void setDirty() { dirty = true; } + + /** + * @brief Set the group and all bodies as clean + * + * This function is called before computing any collisions to ensure + * all objects are cleaned. + */ + void setClean(); + + private: + std::vector*> objects; + bool dirty; +}; + +/** @brief Group of two-dimensional shaped objects */ +typedef ShapedObjectGroup<2> ShapedObjectGroup2D; + +/** @brief Group of three-dimensional shaped objects */ +typedef ShapedObjectGroup<3> ShapedObjectGroup3D; + +}} + +#endif diff --git a/src/Physics/Sphere.cpp b/src/Physics/Sphere.cpp index 334982b07..b0f578871 100644 --- a/src/Physics/Sphere.cpp +++ b/src/Physics/Sphere.cpp @@ -15,49 +15,70 @@ #include "Sphere.h" +#include "Math/Constants.h" +#include "Math/Math.h" +#include "Math/Matrix3.h" +#include "Math/Matrix4.h" #include "Math/Geometry/Distance.h" +#include "LineSegment.h" +#include "Point.h" using namespace Magnum::Math::Geometry; namespace Magnum { namespace Physics { -void Sphere::applyTransformation(const Matrix4& transformation) { - _transformedPosition = (transformation*Vector4(_position)).xyz(); - float scaling = (transformation.rotationScaling()*Vector3(1/Math::Constants::sqrt3())).length(); +namespace { + template static typename DimensionTraits::VectorType unitVector(); + + template<> inline Vector2 unitVector<2>() { + return Vector2(1/Math::Constants::sqrt2()); + } + + template<> inline Vector3 unitVector<3>() { + return Vector3(1/Math::Constants::sqrt3()); + } +} + +template void Sphere::applyTransformation(const typename DimensionTraits::MatrixType& transformation) { + _transformedPosition = (transformation*typename DimensionTraits::PointType(_position)).vector(); + float scaling = (transformation.rotationScaling()*unitVector()).length(); _transformedRadius = scaling*_radius; } -bool Sphere::collides(const AbstractShape* other) const { - if(other->type() == Type::Point) - return *this % *static_cast(other); - if(other->type() == Type::Line) - return *this % *static_cast(other); - if(other->type() == Type::LineSegment) - return *this % *static_cast(other); - if(other->type() == Type::Sphere) - return *this % *static_cast(other); - - return AbstractShape::collides(other); +template bool Sphere::collides(const AbstractShape* other) const { + if(other->type() == AbstractShape::Type::Point) + return *this % *static_cast*>(other); + if(other->type() == AbstractShape::Type::Line) + return *this % *static_cast*>(other); + if(other->type() == AbstractShape::Type::LineSegment) + return *this % *static_cast*>(other); + if(other->type() == AbstractShape::Type::Sphere) + return *this % *static_cast*>(other); + + return AbstractShape::collides(other); } -bool Sphere::operator%(const Point& other) const { +template bool Sphere::operator%(const Point& other) const { return (other.transformedPosition()-transformedPosition()).dot() < Math::pow<2>(transformedRadius()); } -bool Sphere::operator%(const Line& other) const { +template bool Sphere::operator%(const Line& other) const { return Distance::linePointSquared(other.transformedA(), other.transformedB(), transformedPosition()) < Math::pow<2>(transformedRadius()); } -bool Sphere::operator%(const LineSegment& other) const { +template bool Sphere::operator%(const LineSegment& other) const { return Distance::lineSegmentPointSquared(other.transformedA(), other.transformedB(), transformedPosition()) < Math::pow<2>(transformedRadius()); } -bool Sphere::operator%(const Sphere& other) const { +template bool Sphere::operator%(const Sphere& other) const { return (other.transformedPosition()-transformedPosition()).dot() < Math::pow<2>(transformedRadius()+other.transformedRadius()); } +template class Sphere<2>; +template class Sphere<3>; + }} diff --git a/src/Physics/Sphere.h b/src/Physics/Sphere.h index 20961d6b7..9a91966ca 100644 --- a/src/Physics/Sphere.h +++ b/src/Physics/Sphere.h @@ -16,36 +16,49 @@ */ /** @file - * @brief Class Magnum::Physics::Sphere + * @brief Class Magnum::Physics::Sphere, typedef Magnum::Physics::Sphere2D, Magnum::Physics::Sphere3D */ +#include "Math/Vector3.h" #include "AbstractShape.h" -#include "Point.h" -#include "Line.h" -#include "LineSegment.h" + +#include "magnumCompatibility.h" namespace Magnum { namespace Physics { +template class Line; +template class LineSegment; +template class Point; + /** @brief %Sphere defined by position and radius Unlike other elements the sphere doesn't support asymmetric scaling. When applying transformation, the scale factor is averaged from all axes. +@see Sphere2D, Sphere3D */ -class PHYSICS_EXPORT Sphere: public AbstractShape { +template class PHYSICS_EXPORT Sphere: public AbstractShape { public: /** @brief Constructor */ - inline Sphere(const Vector3& position, float radius): _position(position), _transformedPosition(position), _radius(radius), _transformedRadius(radius) {} + inline Sphere(const typename DimensionTraits::VectorType& position, float radius): _position(position), _transformedPosition(position), _radius(radius), _transformedRadius(radius) {} - void applyTransformation(const Matrix4& transformation); + inline typename AbstractShape::Type type() const override { + return AbstractShape::Type::Sphere; + } - bool collides(const AbstractShape* other) const; + void applyTransformation(const typename DimensionTraits::MatrixType& transformation) override; + + bool collides(const AbstractShape* other) const override; /** @brief Position */ - inline Vector3 position() const { return _position; } + inline typename DimensionTraits::VectorType position() const { + return _position; + } /** @brief Set position */ - inline void setPosition(const Vector3& position) { _position = position; } + inline void setPosition(const typename DimensionTraits::VectorType& position) { + _position = position; + } /** @brief Radius */ inline float radius() const { return _radius; } @@ -54,7 +67,7 @@ class PHYSICS_EXPORT Sphere: public AbstractShape { inline void setRadius(float radius) { _radius = radius; } /** @brief Transformed position */ - inline Vector3 transformedPosition() const { + inline typename DimensionTraits::VectorType transformedPosition() const { return _transformedPosition; } @@ -64,33 +77,37 @@ class PHYSICS_EXPORT Sphere: public AbstractShape { } /** @brief Collision with point */ - bool operator%(const Point& other) const; + bool operator%(const Point& other) const; /** @brief Collision with line */ - bool operator%(const Line& other) const; + bool operator%(const Line& other) const; /** @brief Collision with line segment */ - bool operator%(const LineSegment& other) const; + bool operator%(const LineSegment& other) const; /** @brief Collision with sphere */ - bool operator%(const Sphere& other) const; - - protected: - inline Type type() const { return Type::Sphere; } + bool operator%(const Sphere& other) const; private: - Vector3 _position, _transformedPosition; + Math::Vector _position, + _transformedPosition; float _radius, _transformedRadius; }; +/** @brief Two-dimensional sphere */ +typedef Sphere<2> Sphere2D; + +/** @brief Three-dimensional sphere */ +typedef Sphere<3> Sphere3D; + /** @collisionoperator{Point,Sphere} */ -inline bool operator%(const Point& a, const Sphere& b) { return b % a; } +template inline bool operator%(const Point& a, const Sphere& b) { return b % a; } /** @collisionoperator{Line,Sphere} */ -inline bool operator%(const Line& a, const Sphere& b) { return b % a; } +template inline bool operator%(const Line& a, const Sphere& b) { return b % a; } /** @collisionoperator{LineSegment,Sphere} */ -inline bool operator%(const LineSegment& a, const Sphere& b) { return b % a; } +template inline bool operator%(const LineSegment& a, const Sphere& b) { return b % a; } }} diff --git a/src/Physics/Test/AbstractShapeTest.h b/src/Physics/Test/AbstractShapeTest.h index 4ac72bdcc..2905ff296 100644 --- a/src/Physics/Test/AbstractShapeTest.h +++ b/src/Physics/Test/AbstractShapeTest.h @@ -17,6 +17,7 @@ #include +#include "Math/Matrix4.h" #include "Magnum.h" namespace Magnum { namespace Physics { namespace Test { diff --git a/src/Physics/Test/AxisAlignedBoxTest.cpp b/src/Physics/Test/AxisAlignedBoxTest.cpp index e62e3df6f..da5cd0894 100644 --- a/src/Physics/Test/AxisAlignedBoxTest.cpp +++ b/src/Physics/Test/AxisAlignedBoxTest.cpp @@ -15,6 +15,8 @@ #include "AxisAlignedBoxTest.h" +#include "Math/Constants.h" +#include "Math/Matrix4.h" #include "Physics/AxisAlignedBox.h" CORRADE_TEST_MAIN(Magnum::Physics::Test::AxisAlignedBoxTest) @@ -26,7 +28,7 @@ AxisAlignedBoxTest::AxisAlignedBoxTest() { } void AxisAlignedBoxTest::applyTransformation() { - Physics::AxisAlignedBox box({-1.0f, -2.0f, -3.0f}, {1.0f, 2.0f, 3.0f}); + Physics::AxisAlignedBox3D box({-1.0f, -2.0f, -3.0f}, {1.0f, 2.0f, 3.0f}); box.applyTransformation(Matrix4::scaling({2.0f, -1.0f, 1.5f})); CORRADE_COMPARE(box.transformedPosition(), Vector3(-2.0f, 2.0f, -4.5f)); diff --git a/src/Physics/Test/BoxTest.cpp b/src/Physics/Test/BoxTest.cpp new file mode 100644 index 000000000..32c04ff48 --- /dev/null +++ b/src/Physics/Test/BoxTest.cpp @@ -0,0 +1,36 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "BoxTest.h" + +#include "Math/Matrix4.h" +#include "Physics/Box.h" + +CORRADE_TEST_MAIN(Magnum::Physics::Test::BoxTest) + +namespace Magnum { namespace Physics { namespace Test { + +BoxTest::BoxTest() { + addTests(&BoxTest::applyTransformation); +} + +void BoxTest::applyTransformation() { + Physics::Box3D box(Matrix4::translation({1.0f, 2.0f, -3.0f})); + + box.applyTransformation(Matrix4::scaling({2.0f, -1.0f, 1.5f})); + CORRADE_COMPARE(box.transformedTransformation(), Matrix4::scaling({2.0f, -1.0f, 1.5f})*Matrix4::translation({1.0f, 2.0f, -3.0f})); +} + +}}} diff --git a/src/Physics/Test/BoxTest.h b/src/Physics/Test/BoxTest.h new file mode 100644 index 000000000..48781ad08 --- /dev/null +++ b/src/Physics/Test/BoxTest.h @@ -0,0 +1,31 @@ +#ifndef Magnum_Physics_Test_BoxTest_h +#define Magnum_Physics_Test_BoxTest_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 + +namespace Magnum { namespace Physics { namespace Test { + +class BoxTest: public Corrade::TestSuite::Tester { + public: + BoxTest(); + + void applyTransformation(); +}; + +}}} + +#endif diff --git a/src/Physics/Test/CMakeLists.txt b/src/Physics/Test/CMakeLists.txt index b182873a0..dd56a0631 100644 --- a/src/Physics/Test/CMakeLists.txt +++ b/src/Physics/Test/CMakeLists.txt @@ -1,7 +1,10 @@ corrade_add_test2(PhysicsAxisAlignedBoxTest AxisAlignedBoxTest.cpp LIBRARIES MagnumPhysics) +corrade_add_test2(PhysicsBoxTest BoxTest.cpp LIBRARIES MagnumPhysics) corrade_add_test2(PhysicsCapsuleTest CapsuleTest.cpp LIBRARIES MagnumPhysics) corrade_add_test2(PhysicsLineTest LineTest.cpp LIBRARIES MagnumPhysics) corrade_add_test2(PhysicsPlaneTest PlaneTest.cpp LIBRARIES MagnumPhysics) corrade_add_test2(PhysicsPointTest PointTest.cpp LIBRARIES MagnumPhysics) corrade_add_test2(PhysicsShapeGroupTest ShapeGroupTest.cpp LIBRARIES MagnumPhysics) corrade_add_test2(PhysicsSphereTest SphereTest.cpp LIBRARIES MagnumPhysics) + +corrade_add_test2(PhysicsShapedObjectTest ShapedObjectTest.cpp LIBRARIES MagnumPhysics) diff --git a/src/Physics/Test/CapsuleTest.cpp b/src/Physics/Test/CapsuleTest.cpp index 3c4d2ba8d..1d11fabc4 100644 --- a/src/Physics/Test/CapsuleTest.cpp +++ b/src/Physics/Test/CapsuleTest.cpp @@ -15,7 +15,10 @@ #include "CapsuleTest.h" +#include "Math/Constants.h" #include "Physics/Capsule.h" +#include "Physics/Point.h" +#include "Physics/Sphere.h" CORRADE_TEST_MAIN(Magnum::Physics::Test::CapsuleTest) @@ -27,7 +30,7 @@ CapsuleTest::CapsuleTest() { } void CapsuleTest::applyTransformation() { - Physics::Capsule capsule({1.0f, 2.0f, 3.0f}, {-1.0f, -2.0f, -3.0f}, 7.0f); + Physics::Capsule3D capsule({1.0f, 2.0f, 3.0f}, {-1.0f, -2.0f, -3.0f}, 7.0f); capsule.applyTransformation(Matrix4::rotation(deg(90.0f), Vector3::zAxis())); CORRADE_COMPARE(capsule.transformedA(), Vector3(-2.0f, 1.0f, 3.0f)); @@ -40,10 +43,10 @@ void CapsuleTest::applyTransformation() { } void CapsuleTest::collisionPoint() { - Physics::Capsule capsule({-1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, 2.0f); - Physics::Point point({2.0f, 0.0f, 0.0f}); - Physics::Point point1({2.9f, 1.0f, 0.0f}); - Physics::Point point2({1.0f, 3.1f, 0.0f}); + Physics::Capsule3D capsule({-1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, 2.0f); + Physics::Point3D point({2.0f, 0.0f, 0.0f}); + Physics::Point3D point1({2.9f, 1.0f, 0.0f}); + Physics::Point3D point2({1.0f, 3.1f, 0.0f}); randomTransformation(capsule); randomTransformation(point); @@ -56,10 +59,10 @@ void CapsuleTest::collisionPoint() { } void CapsuleTest::collisionSphere() { - Physics::Capsule capsule({-1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, 2.0f); - Physics::Sphere sphere({3.0f, 0.0f, 0.0f}, 0.9f); - Physics::Sphere sphere1({3.5f, 1.0f, 0.0f}, 0.6f); - Physics::Sphere sphere2({1.0f, 4.1f, 0.0f}, 1.0f); + Physics::Capsule3D capsule({-1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, 2.0f); + Physics::Sphere3D sphere({3.0f, 0.0f, 0.0f}, 0.9f); + Physics::Sphere3D sphere1({3.5f, 1.0f, 0.0f}, 0.6f); + Physics::Sphere3D sphere2({1.0f, 4.1f, 0.0f}, 1.0f); randomTransformation(capsule); randomTransformation(sphere); diff --git a/src/Physics/Test/LineTest.cpp b/src/Physics/Test/LineTest.cpp index b4badfba4..2a673d33c 100644 --- a/src/Physics/Test/LineTest.cpp +++ b/src/Physics/Test/LineTest.cpp @@ -15,6 +15,8 @@ #include "LineTest.h" +#include "Math/Constants.h" +#include "Math/Matrix4.h" #include "Physics/Line.h" CORRADE_TEST_MAIN(Magnum::Physics::Test::LineTest) @@ -26,7 +28,7 @@ LineTest::LineTest() { } void LineTest::applyTransformation() { - Physics::Line line({1.0f, 2.0f, 3.0f}, {-1.0f, -2.0f, -3.0f}); + Physics::Line3D line({1.0f, 2.0f, 3.0f}, {-1.0f, -2.0f, -3.0f}); line.applyTransformation(Matrix4::rotation(deg(90.0f), Vector3::zAxis())); CORRADE_COMPARE(line.transformedA(), Vector3(-2.0f, 1.0f, 3.0f)); CORRADE_COMPARE(line.transformedB(), Vector3(2.0f, -1.0f, -3.0f)); diff --git a/src/Physics/Test/PlaneTest.cpp b/src/Physics/Test/PlaneTest.cpp index 8b8e4ac4c..75170f84c 100644 --- a/src/Physics/Test/PlaneTest.cpp +++ b/src/Physics/Test/PlaneTest.cpp @@ -15,6 +15,9 @@ #include "PlaneTest.h" +#include "Math/Constants.h" +#include "Physics/LineSegment.h" +#include "Physics/Point.h" #include "Physics/Plane.h" CORRADE_TEST_MAIN(Magnum::Physics::Test::PlaneTest) @@ -42,9 +45,9 @@ void PlaneTest::applyTransformation() { void PlaneTest::collisionLine() { Physics::Plane plane(Vector3(), Vector3::yAxis()); - Physics::Line line({0.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}); - Physics::Line line2({0.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}); - Physics::Line line3({0.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}); + Physics::Line3D line({0.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}); + Physics::Line3D line2({0.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}); + Physics::Line3D line3({0.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}); randomTransformation(plane); randomTransformation(line); @@ -58,9 +61,9 @@ void PlaneTest::collisionLine() { void PlaneTest::collisionLineSegment() { Physics::Plane plane(Vector3(), Vector3::yAxis()); - Physics::LineSegment line({0.0f, -0.1f, 0.0f}, {0.0f, 7.0f, 0.0f}); - Physics::LineSegment line2({0.0f, 0.1f, 0.0f}, {0.0f, 7.0f, 0.0f}); - Physics::LineSegment line3({0.0f, -7.0f, 0.0f}, {0.0f, -0.1f, 0.0f}); + Physics::LineSegment3D line({0.0f, -0.1f, 0.0f}, {0.0f, 7.0f, 0.0f}); + Physics::LineSegment3D line2({0.0f, 0.1f, 0.0f}, {0.0f, 7.0f, 0.0f}); + Physics::LineSegment3D line3({0.0f, -7.0f, 0.0f}, {0.0f, -0.1f, 0.0f}); randomTransformation(plane); randomTransformation(line); diff --git a/src/Physics/Test/PointTest.cpp b/src/Physics/Test/PointTest.cpp index 5edff1469..f6e47e785 100644 --- a/src/Physics/Test/PointTest.cpp +++ b/src/Physics/Test/PointTest.cpp @@ -15,6 +15,7 @@ #include "PointTest.h" +#include "Math/Matrix4.h" #include "Physics/Point.h" CORRADE_TEST_MAIN(Magnum::Physics::Test::PointTest) @@ -26,7 +27,7 @@ PointTest::PointTest() { } void PointTest::applyTransformation() { - Physics::Point point({1.0f, 2.0f, 3.0f}); + Physics::Point3D point({1.0f, 2.0f, 3.0f}); point.applyTransformation(Matrix4::translation({5.0f, 6.0f, 7.0f})); CORRADE_COMPARE(point.transformedPosition(), Vector3(6.0f, 8.0f, 10.0f)); } diff --git a/src/Physics/Test/ShapeGroupTest.cpp b/src/Physics/Test/ShapeGroupTest.cpp index 178bac2dc..01e68e6c0 100644 --- a/src/Physics/Test/ShapeGroupTest.cpp +++ b/src/Physics/Test/ShapeGroupTest.cpp @@ -17,8 +17,9 @@ #include +#include "Math/Matrix4.h" #include "Physics/Point.h" -#include "Physics/Sphere.h" +#include "Physics/LineSegment.h" #include "Physics/ShapeGroup.h" using namespace std; @@ -33,12 +34,12 @@ ShapeGroupTest::ShapeGroupTest() { } void ShapeGroupTest::copy() { - ShapeGroup group; + ShapeGroup3D group; { - Physics::Point point({1.0f, 2.0f, 3.0f}); - Physics::Sphere sphere({2.0f, 1.0f, 30.0f}, 1.0f); + Physics::Point3D point({1.0f, 2.0f, 3.0f}); + Physics::LineSegment3D segment({2.0f, 1.0f, 30.0f}, {1.0f, -20.0f, 3.0f}); - group = ~(point|sphere); + group = !(point || segment); } /* Just to test that it doesn't crash */ @@ -48,15 +49,15 @@ void ShapeGroupTest::copy() { } void ShapeGroupTest::reference() { - Physics::Point point({1.0f, 2.0f, 3.0f}); - Physics::Sphere sphere({2.0f, 1.0f, 30.0f}, 1.0f); + Physics::Point3D point({1.0f, 2.0f, 3.0f}); + Physics::LineSegment3D segment({2.0f, 1.0f, 30.0f}, {1.0f, -20.0f, 3.0f}); - ShapeGroup group = ~(ref(point)|ref(sphere)); + ShapeGroup3D group = !(ref(point) || ref(segment)); group.applyTransformation(Matrix4::translation(Vector3(1.0f))); CORRADE_VERIFY((point.transformedPosition() == Vector3(2.0f, 3.0f, 4.0f))); - CORRADE_VERIFY((sphere.transformedPosition() == Vector3(3.0f, 2.0f, 31.0f))); + CORRADE_VERIFY((segment.transformedA() == Vector3(3.0f, 2.0f, 31.0f))); } }}} diff --git a/src/Physics/Test/ShapedObjectTest.cpp b/src/Physics/Test/ShapedObjectTest.cpp new file mode 100644 index 000000000..fec1e3c5a --- /dev/null +++ b/src/Physics/Test/ShapedObjectTest.cpp @@ -0,0 +1,59 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "ShapedObjectTest.h" + +#include "Physics/ShapedObjectGroup.h" +#include "Physics/ShapedObject.h" + +CORRADE_TEST_MAIN(Magnum::Physics::Test::ShapedObjectTest) + +namespace Magnum { namespace Physics { namespace Test { + +ShapedObjectTest::ShapedObjectTest() { + addTests(&ShapedObjectTest::clean); +} + +void ShapedObjectTest::clean() { + ShapedObjectGroup3D group; + + ShapedObject3D a(&group), b(&group); + + /* Everything is dirty at the beginning */ + CORRADE_VERIFY(group.isDirty()); + CORRADE_VERIFY(a.isDirty()); + CORRADE_VERIFY(b.isDirty()); + + /* Cleaning object will not clean anything other */ + a.setClean(); + CORRADE_VERIFY(group.isDirty()); + CORRADE_VERIFY(!a.isDirty()); + CORRADE_VERIFY(b.isDirty()); + + /* Setting group clean will clean whole group */ + a.setDirty(); + group.setClean(); + CORRADE_VERIFY(!group.isDirty()); + CORRADE_VERIFY(!a.isDirty()); + CORRADE_VERIFY(!b.isDirty()); + + /* Setting object dirty will set also the group, but not other objects */ + b.setDirty(); + CORRADE_VERIFY(group.isDirty()); + CORRADE_VERIFY(!a.isDirty()); + CORRADE_VERIFY(b.isDirty()); +} + +}}} diff --git a/src/Physics/Test/ShapedObjectTest.h b/src/Physics/Test/ShapedObjectTest.h new file mode 100644 index 000000000..81f49e406 --- /dev/null +++ b/src/Physics/Test/ShapedObjectTest.h @@ -0,0 +1,31 @@ +#ifndef Magnum_Physics_Test_ShapedObjectTest_h +#define Magnum_Physics_Test_ShapedObjectTest_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 + +namespace Magnum { namespace Physics { namespace Test { + +class ShapedObjectTest: public Corrade::TestSuite::Tester { + public: + ShapedObjectTest(); + + void clean(); +}; + +}}} + +#endif diff --git a/src/Physics/Test/SphereTest.cpp b/src/Physics/Test/SphereTest.cpp index 432c99db7..473be576c 100644 --- a/src/Physics/Test/SphereTest.cpp +++ b/src/Physics/Test/SphereTest.cpp @@ -15,6 +15,9 @@ #include "SphereTest.h" +#include "Math/Constants.h" +#include "Physics/LineSegment.h" +#include "Physics/Point.h" #include "Physics/Sphere.h" CORRADE_TEST_MAIN(Magnum::Physics::Test::SphereTest) @@ -30,7 +33,7 @@ SphereTest::SphereTest() { } void SphereTest::applyTransformation() { - Physics::Sphere sphere({1.0f, 2.0f, 3.0f}, 7.0f); + Physics::Sphere3D sphere({1.0f, 2.0f, 3.0f}, 7.0f); sphere.applyTransformation(Matrix4::rotation(deg(90.0f), Vector3::yAxis())); CORRADE_COMPARE(sphere.transformedPosition(), Vector3(3.0f, 2.0f, -1.0f)); @@ -47,9 +50,9 @@ void SphereTest::applyTransformation() { } void SphereTest::collisionPoint() { - Physics::Sphere sphere({1.0f, 2.0f, 3.0f}, 2.0f); - Physics::Point point({1.0f, 3.0f, 3.0f}); - Physics::Point point2({1.0f, 3.0f, 1.0f}); + Physics::Sphere3D sphere({1.0f, 2.0f, 3.0f}, 2.0f); + Physics::Point3D point({1.0f, 3.0f, 3.0f}); + Physics::Point3D point2({1.0f, 3.0f, 1.0f}); randomTransformation(sphere); randomTransformation(point); @@ -60,9 +63,9 @@ void SphereTest::collisionPoint() { } void SphereTest::collisionLine() { - Physics::Sphere sphere({1.0f, 2.0f, 3.0f}, 2.0f); - Physics::Line line({1.0f, 1.5f, 3.5f}, {1.0f, 2.5f, 2.5f}); - Physics::Line line2({1.0f, 2.0f, 5.1f}, {1.0f, 3.0f, 5.1f}); + Physics::Sphere3D sphere({1.0f, 2.0f, 3.0f}, 2.0f); + Physics::Line3D line({1.0f, 1.5f, 3.5f}, {1.0f, 2.5f, 2.5f}); + Physics::Line3D line2({1.0f, 2.0f, 5.1f}, {1.0f, 3.0f, 5.1f}); randomTransformation(sphere); randomTransformation(line); @@ -73,9 +76,9 @@ void SphereTest::collisionLine() { } void SphereTest::collisionLineSegment() { - Physics::Sphere sphere({1.0f, 2.0f, 3.0f}, 2.0f); - Physics::LineSegment line({1.0f, 2.0f, 4.9f}, {1.0f, 2.0f, 7.0f}); - Physics::LineSegment line2({1.0f, 2.0f, 5.1f}, {1.0f, 2.0f, 7.0f}); + Physics::Sphere3D sphere({1.0f, 2.0f, 3.0f}, 2.0f); + Physics::LineSegment3D line({1.0f, 2.0f, 4.9f}, {1.0f, 2.0f, 7.0f}); + Physics::LineSegment3D line2({1.0f, 2.0f, 5.1f}, {1.0f, 2.0f, 7.0f}); randomTransformation(sphere); randomTransformation(line); @@ -86,9 +89,9 @@ void SphereTest::collisionLineSegment() { } void SphereTest::collisionSphere() { - Physics::Sphere sphere({1.0f, 2.0f, 3.0f}, 2.0f); - Physics::Sphere sphere1({1.0f, 3.0f, 5.0f}, 1.0f); - Physics::Sphere sphere2({1.0f, 3.0f, 0.0f}, 1.0f); + Physics::Sphere3D sphere({1.0f, 2.0f, 3.0f}, 2.0f); + Physics::Sphere3D sphere1({1.0f, 3.0f, 5.0f}, 1.0f); + Physics::Sphere3D sphere2({1.0f, 3.0f, 0.0f}, 1.0f); randomTransformation(sphere); randomTransformation(sphere1); diff --git a/src/Primitives/CMakeLists.txt b/src/Primitives/CMakeLists.txt index 28d2aa07d..10d36351e 100644 --- a/src/Primitives/CMakeLists.txt +++ b/src/Primitives/CMakeLists.txt @@ -1,17 +1,22 @@ set(MagnumPrimitives_SRCS Capsule.cpp Cube.cpp + Cylinder.cpp Icosphere.cpp Plane.cpp + Square.cpp UVSphere.cpp) set(MagnumPrimitives_HEADERS Capsule.h Cube.h + Cylinder.h Icosphere.h Plane.h + Square.h UVSphere.h) add_library(MagnumPrimitives STATIC ${MagnumPrimitives_SRCS}) +set_target_properties(MagnumPrimitives PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") target_link_libraries(MagnumPrimitives Magnum) install(TARGETS MagnumPrimitives DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) diff --git a/src/Primitives/Capsule.cpp b/src/Primitives/Capsule.cpp index 5df5b13f7..266be7617 100644 --- a/src/Primitives/Capsule.cpp +++ b/src/Primitives/Capsule.cpp @@ -15,54 +15,62 @@ #include "Capsule.h" +#include "Math/Constants.h" +#include "Math/Point3D.h" + using namespace std; namespace Magnum { namespace Primitives { -Capsule::Capsule(unsigned int rings, unsigned int segments, GLfloat length, TextureCoords textureCoords): MeshData("", Mesh::Primitive::Triangles, new vector, {new vector()}, {new vector()}, textureCoords == TextureCoords::Generate ? vector*>{new vector()} : vector*>()), segments(segments), textureCoords(textureCoords) { - CORRADE_ASSERT(rings >= 1 && segments >= 3, "Capsule must have at least one ring and three segments", ); +Capsule::Capsule(std::uint32_t hemisphereRings, std::uint32_t cylinderRings, std::uint32_t segments, GLfloat length, TextureCoords textureCoords): MeshData3D("", Mesh::Primitive::Triangles, new vector, {new vector()}, {new vector()}, textureCoords == TextureCoords::Generate ? vector*>{new vector()} : vector*>()), segments(segments), textureCoords(textureCoords) { + CORRADE_ASSERT(hemisphereRings >= 1 && cylinderRings >= 1 && segments >= 3, "Capsule must have at least one hemisphere ring, one cylinder ring and three segments", ); GLfloat height = 2.0f+length; - GLfloat textureCoordsVIncrement = 1.0f/(rings*height); - GLfloat ringAngleIncrement = Math::Constants::pi()/(2*rings); + GLfloat hemisphereTextureCoordsVIncrement = 1.0f/(hemisphereRings*height); + GLfloat hemisphereRingAngleIncrement = Math::Constants::pi()/(2*hemisphereRings); /* Bottom cap vertex */ capVertex(-height/2, -1.0f, 0.0f); /* Rings of bottom hemisphere */ - vertexRings(rings, -length/2, -Math::Constants::pi()/2+ringAngleIncrement, ringAngleIncrement, textureCoordsVIncrement, textureCoordsVIncrement); + hemisphereVertexRings(hemisphereRings-1, -length/2, -Math::Constants::pi()/2+hemisphereRingAngleIncrement, hemisphereRingAngleIncrement, hemisphereTextureCoordsVIncrement, hemisphereTextureCoordsVIncrement); + + /* Rings of cylinder */ + cylinderVertexRings(cylinderRings+1, -length/2, length/cylinderRings, 1.0f/height, length/(cylinderRings*height)); /* Rings of top hemisphere */ - vertexRings(rings, length/2, 0.0f, ringAngleIncrement, (1.0f + length)/height, textureCoordsVIncrement); + hemisphereVertexRings(hemisphereRings-1, length/2, hemisphereRingAngleIncrement, hemisphereRingAngleIncrement, (1.0f + length)/height+hemisphereTextureCoordsVIncrement, hemisphereTextureCoordsVIncrement); /* Top cap vertex */ capVertex(height/2, 1.0f, 1.0f); /* Faces */ bottomFaceRing(); - faceRings(rings*2-1); + faceRings(hemisphereRings*2-2+cylinderRings); topFaceRing(); } +Capsule::Capsule(uint32_t segments, TextureCoords textureCoords): MeshData3D("", Mesh::Primitive::Triangles, new std::vector, {new std::vector()}, {new std::vector()}, textureCoords == TextureCoords::Generate ? std::vector*>{new std::vector()} : std::vector*>()), segments(segments), textureCoords(textureCoords) {} + void Capsule::capVertex(GLfloat y, GLfloat normalY, GLfloat textureCoordsV) { - vertices(0)->push_back({0.0f, y, 0.0f}); + positions(0)->push_back({0.0f, y, 0.0f}); normals(0)->push_back({0.0f, normalY, 0.0f}); if(textureCoords == TextureCoords::Generate) textureCoords2D(0)->push_back({0.5, textureCoordsV}); } -void Capsule::vertexRings(unsigned int count, GLfloat centerY, GLfloat startRingAngle, GLfloat ringAngleIncrement, GLfloat startTextureCoordsV, GLfloat textureCoordsVIncrement) { +void Capsule::hemisphereVertexRings(uint32_t count, GLfloat centerY, GLfloat startRingAngle, GLfloat ringAngleIncrement, GLfloat startTextureCoordsV, GLfloat textureCoordsVIncrement) { GLfloat segmentAngleIncrement = 2*Math::Constants::pi()/segments; GLfloat x, y, z; - for(unsigned int i = 0; i != count; ++i) { + for(uint32_t i = 0; i != count; ++i) { GLfloat ringAngle = startRingAngle + i*ringAngleIncrement; x = z = cos(ringAngle); y = sin(ringAngle); - for(unsigned int j = 0; j != segments; ++j) { + for(uint32_t j = 0; j != segments; ++j) { GLfloat segmentAngle = j*segmentAngleIncrement; - vertices(0)->push_back({x*sin(segmentAngle), centerY+y, z*cos(segmentAngle)}); + positions(0)->push_back({x*sin(segmentAngle), centerY+y, z*cos(segmentAngle)}); normals(0)->push_back({x*sin(segmentAngle), y, z*cos(segmentAngle)}); if(textureCoords == TextureCoords::Generate) @@ -71,15 +79,38 @@ void Capsule::vertexRings(unsigned int count, GLfloat centerY, GLfloat startRing /* Duplicate first segment in the ring for additional vertex for texture coordinate */ if(textureCoords == TextureCoords::Generate) { - vertices(0)->push_back((*vertices(0))[vertices(0)->size()-segments]); + positions(0)->push_back((*positions(0))[positions(0)->size()-segments]); normals(0)->push_back((*normals(0))[normals(0)->size()-segments]); textureCoords2D(0)->push_back({1.0f, startTextureCoordsV + i*textureCoordsVIncrement}); } } } +void Capsule::cylinderVertexRings(uint32_t count, GLfloat startY, GLfloat yIncrement, GLfloat startTextureCoordsV, GLfloat textureCoordsVIncrement) { + GLfloat segmentAngleIncrement = 2*Math::Constants::pi()/segments; + for(uint32_t i = 0; i != count; ++i) { + for(uint32_t j = 0; j != segments; ++j) { + GLfloat segmentAngle = j*segmentAngleIncrement; + positions(0)->push_back({sin(segmentAngle), startY, cos(segmentAngle)}); + normals(0)->push_back({sin(segmentAngle), 0.0f, cos(segmentAngle)}); + + if(textureCoords == TextureCoords::Generate) + textureCoords2D(0)->push_back({j*1.0f/segments, startTextureCoordsV + i*textureCoordsVIncrement}); + } + + /* Duplicate first segment in the ring for additional vertex for texture coordinate */ + if(textureCoords == TextureCoords::Generate) { + positions(0)->push_back((*positions(0))[positions(0)->size()-segments]); + normals(0)->push_back((*normals(0))[normals(0)->size()-segments]); + textureCoords2D(0)->push_back({1.0f, startTextureCoordsV + i*textureCoordsVIncrement}); + } + + startY += yIncrement; + } +} + void Capsule::bottomFaceRing() { - for(unsigned int j = 0; j != segments; ++j) { + for(uint32_t j = 0; j != segments; ++j) { /* Bottom vertex */ indices()->push_back(0); @@ -92,16 +123,16 @@ void Capsule::bottomFaceRing() { } } -void Capsule::faceRings(unsigned int count) { - unsigned int vertexSegments = segments + (textureCoords == TextureCoords::Generate ? 1 : 0); +void Capsule::faceRings(uint32_t count, uint32_t offset) { + uint32_t vertexSegments = segments + (textureCoords == TextureCoords::Generate ? 1 : 0); - for(unsigned int i = 0; i != count; ++i) { - for(unsigned int j = 0; j != segments; ++j) { - unsigned int bottomLeft = i*vertexSegments+j+1; - unsigned int bottomRight = ((j != segments-1 || textureCoords == TextureCoords::Generate) ? - i*vertexSegments+j+2 : i*segments+1); - unsigned int topLeft = bottomLeft+vertexSegments; - unsigned int topRight = bottomRight+vertexSegments; + for(uint32_t i = 0; i != count; ++i) { + for(uint32_t j = 0; j != segments; ++j) { + uint32_t bottomLeft = i*vertexSegments+j+offset; + uint32_t bottomRight = ((j != segments-1 || textureCoords == TextureCoords::Generate) ? + i*vertexSegments+j+1+offset : i*segments+offset); + uint32_t topLeft = bottomLeft+vertexSegments; + uint32_t topRight = bottomRight+vertexSegments; indices()->push_back(bottomLeft); indices()->push_back(bottomRight); @@ -114,9 +145,9 @@ void Capsule::faceRings(unsigned int count) { } void Capsule::topFaceRing() { - unsigned int vertexSegments = segments + (textureCoords == TextureCoords::Generate ? 1 : 0); + uint32_t vertexSegments = segments + (textureCoords == TextureCoords::Generate ? 1 : 0); - for(unsigned int j = 0; j != segments; ++j) { + for(uint32_t j = 0; j != segments; ++j) { /* Bottom left vertex */ indices()->push_back(normals(0)->size()-vertexSegments+j-1); diff --git a/src/Primitives/Capsule.h b/src/Primitives/Capsule.h index 3923beba1..76dd89984 100644 --- a/src/Primitives/Capsule.h +++ b/src/Primitives/Capsule.h @@ -19,17 +19,19 @@ * @brief Class Magnum::Primitives::Capsule */ -#include "Trade/MeshData.h" +#include "Trade/MeshData3D.h" namespace Magnum { namespace Primitives { /** -@brief %Capsule primitive +@brief 3D capsule primitive -Cylinder along Y axis with hemispheres instead of caps. +Cylinder along Y axis with hemispheres instead of caps. Indexed triangle mesh +with normals and optional 2D texture coordinates. */ -class Capsule: public Trade::MeshData { +class Capsule: public Trade::MeshData3D { friend class UVSphere; + friend class Cylinder; public: /** @brief Whether to generate texture coordinates */ @@ -40,8 +42,10 @@ class Capsule: public Trade::MeshData { /** * @brief Constructor - * @param rings Number of (face) rings for each hemisphere. + * @param hemisphereRings Number of (face) rings for each hemisphere. * Must be larger or equal to 1. + * @param cylinderRings Number of (face) rings for cylinder. Must be + * larger or equal to 1. * @param segments Number of (face) segments. Must be larger or equal to 3. * @param length Length of the capsule, excluding hemispheres. * @param textureCoords Whether to generate texture coordinates. @@ -49,18 +53,19 @@ class Capsule: public Trade::MeshData { * If texture coordinates are generated, vertices of one segment are * duplicated for texture wrapping. */ - Capsule(unsigned int rings, unsigned int segments, GLfloat length, TextureCoords textureCoords = TextureCoords::DontGenerate); + Capsule(std::uint32_t hemisphereRings, std::uint32_t cylinderRings, std::uint32_t segments, GLfloat length, TextureCoords textureCoords = TextureCoords::DontGenerate); private: - inline Capsule(unsigned int segments, TextureCoords textureCoords): MeshData("", Mesh::Primitive::Triangles, new std::vector, {new std::vector()}, {new std::vector()}, textureCoords == TextureCoords::Generate ? std::vector*>{new std::vector()} : std::vector*>()), segments(segments), textureCoords(textureCoords) {} + Capsule(std::uint32_t segments, TextureCoords textureCoords); void capVertex(GLfloat y, GLfloat normalY, GLfloat textureCoordsV); - void vertexRings(unsigned int count, GLfloat centerY, GLfloat startRingAngle, GLfloat ringAngleIncrement, GLfloat startTextureCoordsV, GLfloat textureCoordsVIncrement); + void hemisphereVertexRings(std::uint32_t count, GLfloat centerY, GLfloat startRingAngle, GLfloat ringAngleIncrement, GLfloat startTextureCoordsV, GLfloat textureCoordsVIncrement); + void cylinderVertexRings(std::uint32_t count, GLfloat startY, GLfloat yIncrement, GLfloat startTextureCoordsV, GLfloat textureCoordsVIncrement); void bottomFaceRing(); - void faceRings(unsigned int count); + void faceRings(std::uint32_t count, std::uint32_t offset = 1); void topFaceRing(); - unsigned int segments; + std::uint32_t segments; TextureCoords textureCoords; }; diff --git a/src/Primitives/Cube.cpp b/src/Primitives/Cube.cpp index ef908bf5c..739f2e6dd 100644 --- a/src/Primitives/Cube.cpp +++ b/src/Primitives/Cube.cpp @@ -15,11 +15,13 @@ #include "Cube.h" +#include "Math/Point3D.h" + using namespace std; namespace Magnum { namespace Primitives { -Cube::Cube(): MeshData("", Mesh::Primitive::Triangles, new vector{ +Cube::Cube(): MeshData3D("", Mesh::Primitive::Triangles, new vector{ 0, 2, 1, 2, 3, 1, 1, 3, 5, @@ -32,7 +34,7 @@ Cube::Cube(): MeshData("", Mesh::Primitive::Triangles, new vector{ 2, 6, 7, 4, 1, 5, 4, 0, 1 -}, {new vector}, {new vector{ +}, {new vector}, {new vector{ {-1.0f, -1.0f, -1.0f}, { 1.0f, -1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, @@ -42,7 +44,7 @@ Cube::Cube(): MeshData("", Mesh::Primitive::Triangles, new vector{ {-1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 1.0f} }}, {}) { - vertices(0)->assign(normals(0)->begin(), normals(0)->end()); + positions(0)->assign(normals(0)->begin(), normals(0)->end()); } }} diff --git a/src/Primitives/Cube.h b/src/Primitives/Cube.h index bacc1829c..e3ed55951 100644 --- a/src/Primitives/Cube.h +++ b/src/Primitives/Cube.h @@ -19,12 +19,17 @@ * @brief Class Magnum::Primitives::Cube */ -#include "Trade/MeshData.h" +#include "Trade/MeshData3D.h" namespace Magnum { namespace Primitives { -/** @brief %Cube primitive */ -class Cube: public Trade::MeshData { +/** +@brief 3D cube primitive + +Indexed triangle mesh with smooth normals. +@todo Does anyone EVER want smooth normals on a cube?! +*/ +class Cube: public Trade::MeshData3D { public: /** @brief Constructor */ Cube(); diff --git a/src/Primitives/Cylinder.cpp b/src/Primitives/Cylinder.cpp new file mode 100644 index 000000000..ebe23b35c --- /dev/null +++ b/src/Primitives/Cylinder.cpp @@ -0,0 +1,71 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "Cylinder.h" + +#include "Math/Constants.h" + +using namespace std; + +namespace Magnum { namespace Primitives { + +Cylinder::Cylinder(uint32_t rings, uint32_t segments, GLfloat length, Flags flags): Capsule(segments, flags & Flag::GenerateTextureCoords ? TextureCoords::Generate : TextureCoords::DontGenerate) { + CORRADE_ASSERT(rings >= 1 && segments >= 3, "Cylinder must have at least one ring and three segments", ); + + GLfloat y = length*0.5f; + GLfloat textureCoordsV = flags & Flag::CapEnds ? 1.0f/(length+2.0f) : 0.0f; + + /* Bottom cap */ + if(flags & Flag::CapEnds) { + capVertex(-y, -1.0f, 0.0f); + capVertexRing(-y, textureCoordsV, Vector3::yAxis(-1.0f)); + } + + /* Vertex rings */ + cylinderVertexRings(rings+1, -y, length/rings, textureCoordsV, length/(rings*(flags & Flag::CapEnds ? length + 2.0f : length))); + + /* Top cap */ + if(flags & Flag::CapEnds) { + capVertexRing(y, 1.0f - textureCoordsV, Vector3::yAxis(1.0f)); + capVertex(y, 1.0f, 1.0f); + } + + /* Faces */ + if(flags & Flag::CapEnds) bottomFaceRing(); + faceRings(rings, flags & Flag::CapEnds ? 1 : 0); + if(flags & Flag::CapEnds) topFaceRing(); +} + +void Cylinder::capVertexRing(GLfloat y, GLfloat textureCoordsV, const Vector3& normal) { + GLfloat segmentAngleIncrement = 2*Math::Constants::pi()/segments; + + for(uint32_t i = 0; i != segments; ++i) { + GLfloat segmentAngle = i*segmentAngleIncrement; + positions(0)->push_back({sin(segmentAngle), y, cos(segmentAngle)}); + normals(0)->push_back(normal); + + if(textureCoords == TextureCoords::Generate) + textureCoords2D(0)->push_back({i*1.0f/segments, textureCoordsV}); + } + + /* Duplicate first segment in the ring for additional vertex for texture coordinate */ + if(textureCoords == TextureCoords::Generate) { + positions(0)->push_back((*positions(0))[positions(0)->size()-segments]); + normals(0)->push_back(normal); + textureCoords2D(0)->push_back({1.0f, textureCoordsV}); + } +} + +}} diff --git a/src/Primitives/Cylinder.h b/src/Primitives/Cylinder.h new file mode 100644 index 000000000..29da7a73b --- /dev/null +++ b/src/Primitives/Cylinder.h @@ -0,0 +1,71 @@ +#ifndef Magnum_Primitives_Cylinder_h +#define Magnum_Primitives_Cylinder_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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. +*/ + +/** @file + * @brief Class Magnum::Primitives::UVSphere + */ + +#include + +#include "Primitives/Capsule.h" + +namespace Magnum { namespace Primitives { + +/** +@brief 3D cylinder primitive + +Indexed triangle mesh with normals, optional 2D texture coordinates and +optional capped ends. +*/ +class Cylinder: public Capsule { + public: + /** + * @brief %Flags + * + * @see Flags, Cylinder() + */ + enum class Flag { + GenerateTextureCoords = 1, /**< @brief Generate texture coordinates */ + CapEnds /**< @brief Cap ends */ + }; + + /** @brief %Flags */ + typedef Corrade::Containers::EnumSet Flags; + + /** + * @brief Constructor + * @param rings Number of (face) rings. Must be larger or + * equal to 1. + * @param segments Number of (face) segments. Must be larger or + * equal to 3. + * @param length Cylinder length + * @param flags Flags + * + * If texture coordinates are generated, vertices of one segment are + * duplicated for texture wrapping. + */ + Cylinder(std::uint32_t rings, std::uint32_t segments, GLfloat length, Flags flags = Flags()); + + private: + void capVertexRing(GLfloat y, GLfloat textureCoordsV, const Vector3& normal); +}; + +CORRADE_ENUMSET_OPERATORS(Cylinder::Flags) + +}} + +#endif diff --git a/src/Primitives/Icosphere.cpp b/src/Primitives/Icosphere.cpp index 7e667d141..379365e18 100644 --- a/src/Primitives/Icosphere.cpp +++ b/src/Primitives/Icosphere.cpp @@ -15,11 +15,13 @@ #include "Icosphere.h" +#include "Math/Vector4.h" + using namespace std; namespace Magnum { namespace Primitives { -Icosphere<0>::Icosphere(): MeshData("", Mesh::Primitive::Triangles, new vector{ +Icosphere<0>::Icosphere(): MeshData3D("", Mesh::Primitive::Triangles, new vector{ 1, 2, 6, 1, 7, 2, 3, 4, 5, @@ -40,7 +42,7 @@ Icosphere<0>::Icosphere(): MeshData("", Mesh::Primitive::Triangles, new vector}, {new vector{ +}, {new vector}, {new vector{ Vector3(0, -0.525731f, 0.850651f), Vector3(0.850651f, 0, 0.525731f), Vector3(0.850651f, 0, -0.525731f), @@ -54,7 +56,7 @@ Icosphere<0>::Icosphere(): MeshData("", Mesh::Primitive::Triangles, new vectorassign(normals(0)->begin(), normals(0)->end()); + positions(0)->assign(normals(0)->begin(), normals(0)->end()); } }} diff --git a/src/Primitives/Icosphere.h b/src/Primitives/Icosphere.h index aaf284cc3..a9e050f68 100644 --- a/src/Primitives/Icosphere.h +++ b/src/Primitives/Icosphere.h @@ -19,43 +19,47 @@ * @brief Class Magnum::Primitives::Icosphere */ -#include "Trade/MeshData.h" +#include "Math/Vector3.h" #include "MeshTools/Subdivide.h" #include "MeshTools/Clean.h" +#include "Trade/MeshData3D.h" namespace Magnum { namespace Primitives { -template class Icosphere; +template class Icosphere; /** -@brief %Icosphere primitive with zero subdivisions +@brief 3D icosphere primitive with zero subdivisions +Indexed triangle mesh with normals. @todo Use own computed (and more precise) icosahedron data, not these stolen from Blender. */ -template<> class Icosphere<0>: public Trade::MeshData { +template<> class Icosphere<0>: public Trade::MeshData3D { public: /** @brief Constructor */ Icosphere(); }; /** - * @brief %Icosphere primitive - * @tparam subdivisions Number of subdivisions - */ +@brief 3D icosphere primitive +@tparam subdivisions Number of subdivisions + +Indexed triangle mesh with normals. +*/ #ifndef DOXYGEN_GENERATING_OUTPUT -template class Icosphere: public Icosphere<0> { +template class Icosphere: public Icosphere<0> { #else -template class Icosphere { +template class Icosphere { #endif public: /** @brief Constructor */ Icosphere() { - for(size_t i = 0; i != subdivisions; ++i) + for(std::size_t i = 0; i != subdivisions; ++i) MeshTools::subdivide(*indices(), *normals(0), interpolator); MeshTools::clean(*indices(), *normals(0)); - vertices(0)->assign(normals(0)->begin(), normals(0)->end()); + positions(0)->assign(normals(0)->begin(), normals(0)->end()); } #ifndef DOXYGEN_GENERATING_OUTPUT diff --git a/src/Primitives/Plane.cpp b/src/Primitives/Plane.cpp index e6216bf37..99627bab1 100644 --- a/src/Primitives/Plane.cpp +++ b/src/Primitives/Plane.cpp @@ -15,11 +15,13 @@ #include "Plane.h" +#include "Math/Point3D.h" + using namespace std; namespace Magnum { namespace Primitives { -Plane::Plane(): MeshData("", Mesh::Primitive::TriangleStrip, nullptr, {new vector{ +Plane::Plane(): MeshData3D("", Mesh::Primitive::TriangleStrip, nullptr, {new vector{ {1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, {-1.0f, -1.0f, 0.0f}, diff --git a/src/Primitives/Plane.h b/src/Primitives/Plane.h index d21eee942..1cdb6f104 100644 --- a/src/Primitives/Plane.h +++ b/src/Primitives/Plane.h @@ -19,16 +19,16 @@ * @brief Class Magnum::Primitives::Plane */ -#include "Trade/MeshData.h" +#include "Trade/MeshData3D.h" namespace Magnum { namespace Primitives { /** -@brief %Plane primitive +@brief 3D plane primitive -2x2 plane with normals in positive Z direction. +2x2 plane as triangle strip, non-indexed with normals in positive Z direction. */ -class Plane: public Trade::MeshData { +class Plane: public Trade::MeshData3D { public: /** @brief Constructor */ Plane(); diff --git a/src/Primitives/Square.cpp b/src/Primitives/Square.cpp new file mode 100644 index 000000000..1855bcd6e --- /dev/null +++ b/src/Primitives/Square.cpp @@ -0,0 +1,31 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "Square.h" + +#include "Math/Point2D.h" + +using namespace std; + +namespace Magnum { namespace Primitives { + +Square::Square(): MeshData2D("", Mesh::Primitive::TriangleStrip, nullptr, {new vector{ + {1.0f, -1.0f}, + {1.0f, 1.0f}, + {-1.0f, -1.0f}, + {-1.0f, 1.0f} +}}, {}) {} + +}} diff --git a/src/Primitives/Square.h b/src/Primitives/Square.h new file mode 100644 index 000000000..d83520580 --- /dev/null +++ b/src/Primitives/Square.h @@ -0,0 +1,39 @@ +#ifndef Magnum_Primitives_Square_h +#define Magnum_Primitives_Square_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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. +*/ + +/** @file + * @brief Class Magnum::Primitives::Square + */ + +#include "Trade/MeshData2D.h" + +namespace Magnum { namespace Primitives { + +/** +@brief 2D square primitive + +2x2 square as triangle strip, non-indexed. +*/ +class Square: public Trade::MeshData2D { + public: + /** @brief Constructor */ + Square(); +}; + +}} + +#endif diff --git a/src/Primitives/Test/CMakeLists.txt b/src/Primitives/Test/CMakeLists.txt index e30186313..c8374ccd0 100644 --- a/src/Primitives/Test/CMakeLists.txt +++ b/src/Primitives/Test/CMakeLists.txt @@ -1,2 +1,3 @@ corrade_add_test2(PrimitivesCapsuleTest CapsuleTest.cpp LIBRARIES MagnumPrimitives) corrade_add_test2(PrimitivesUVSphereTest UVSphereTest.cpp LIBRARIES MagnumPrimitives) +corrade_add_test2(PrimitivesCylinderTest CylinderTest.cpp LIBRARIES MagnumPrimitives) diff --git a/src/Primitives/Test/CapsuleTest.cpp b/src/Primitives/Test/CapsuleTest.cpp index a2cc760dd..1f6fb6183 100644 --- a/src/Primitives/Test/CapsuleTest.cpp +++ b/src/Primitives/Test/CapsuleTest.cpp @@ -18,9 +18,13 @@ #include "CapsuleTest.h" +#include + +#include "Math/Point3D.h" #include "Primitives/Capsule.h" using namespace std; +using Corrade::TestSuite::Compare::Container; CORRADE_TEST_MAIN(Magnum::Primitives::Test::CapsuleTest) @@ -32,123 +36,143 @@ CapsuleTest::CapsuleTest() { } void CapsuleTest::withoutTextureCoords() { - Capsule capsule(2, 3, 1.0f); + Capsule capsule(2, 2, 3, 1.0f); + + CORRADE_COMPARE_AS(*capsule.positions(0), (vector{ + {0.0f, -1.5f, 0.0f}, - CORRADE_COMPARE(*capsule.vertices(0), (vector{ - Vector4(0.0f, -1.5f, 0.0f), + {0.0f, -1.20711f, 0.707107f}, + {0.612372f, -1.20711f, -0.353553f}, + {-0.612373f, -1.20711f, -0.353553f}, - Vector4(0.0f, -1.20711f, 0.707107f), - Vector4(0.612372f, -1.20711f, -0.353553f), - Vector4(-0.612373f, -1.20711f, -0.353553f), + {0.0f, -0.5f, 1.0f}, + {0.866025f, -0.5f, -0.5f}, + {-0.866025f, -0.5f, -0.5f}, - Vector4(0.0f, -0.5f, 1.0f), - Vector4(0.866025f, -0.5f, -0.5f), - Vector4(-0.866025f, -0.5f, -0.5f), + {0.0f, 0.0f, 1.0f}, + {0.866025f, 0.0f, -0.5f}, + {-0.866025f, 0.0f, -0.5f}, - Vector4(0.0f, 0.5f, 1.0f), - Vector4(0.866025f, 0.5f, -0.5f), - Vector4(-0.866025f, 0.5f, -0.5f), + {0.0f, 0.5f, 1.0f}, + {0.866025f, 0.5f, -0.5f}, + {-0.866025f, 0.5f, -0.5f}, - Vector4(0.0f, 1.20711f, 0.707107f), - Vector4(0.612372f, 1.20711f, -0.353553f), - Vector4(-0.612372f, 1.20711f, -0.353553f), + {0.0f, 1.20711f, 0.707107f}, + {0.612372f, 1.20711f, -0.353553f}, + {-0.612372f, 1.20711f, -0.353553f}, - Vector4(0.0f, 1.5f, 0.0f) - })); + {0.0f, 1.5f, 0.0f} + }), Container); - CORRADE_COMPARE(*capsule.normals(0), (vector{ - Vector3(0.0f, -1.0f, 0.0f), + CORRADE_COMPARE_AS(*capsule.normals(0), (vector{ + {0.0f, -1.0f, 0.0f}, - Vector3(0.0f, -0.707107f, 0.707107f), - Vector3(0.612372f, -0.707107f, -0.353553f), - Vector3(-0.612373f, -0.707107f, -0.353553f), + {0.0f, -0.707107f, 0.707107f}, + {0.612372f, -0.707107f, -0.353553f}, + {-0.612373f, -0.707107f, -0.353553f}, - Vector3(0.0f, 0.0f, 1.0f), - Vector3(0.866025f, 0.0f, -0.5f), - Vector3(-0.866025f, 0.0f, -0.5f), + {0.0f, 0.0f, 1.0f}, + {0.866025f, 0.0f, -0.5f}, + {-0.866025f, 0.0f, -0.5f}, - Vector3(0.0f, 0.0f, 1.0f), - Vector3(0.866025f, 0.0f, -0.5f), - Vector3(-0.866025f, 0.0f, -0.5f), + {0.0f, 0.0f, 1.0f}, + {0.866025f, 0.0f, -0.5f}, + {-0.866025f, 0.0f, -0.5f}, - Vector3(0.0f, 0.707107f, 0.707107f), - Vector3(0.612372f, 0.707107f, -0.353553f), - Vector3(-0.612372f, 0.707107f, -0.353553f), + {0.0f, 0.0f, 1.0f}, + {0.866025f, 0.0f, -0.5f}, + {-0.866025f, 0.0f, -0.5f}, - Vector3(0.0f, 1.0f, 0.0f) - })); + {0.0f, 0.707107f, 0.707107f}, + {0.612372f, 0.707107f, -0.353553f}, + {-0.612372f, 0.707107f, -0.353553f}, - CORRADE_COMPARE(*capsule.indices(), (vector{ + {0.0f, 1.0f, 0.0f} + }), Container); + + CORRADE_COMPARE_AS(*capsule.indices(), (vector{ 0, 2, 1, 0, 3, 2, 0, 1, 3, 1, 2, 5, 1, 5, 4, 2, 3, 6, 2, 6, 5, 3, 1, 4, 3, 4, 6, 4, 5, 8, 4, 8, 7, 5, 6, 9, 5, 9, 8, 6, 4, 7, 6, 7, 9, 7, 8, 11, 7, 11, 10, 8, 9, 12, 8, 12, 11, 9, 7, 10, 9, 10, 12, - 10, 11, 13, 11, 12, 13, 12, 10, 13 - })); + 10, 11, 14, 10, 14, 13, 11, 12, 15, 11, 15, 14, 12, 10, 13, 12, 13, 15, + 13, 14, 16, 14, 15, 16, 15, 13, 16 + }), Container); } void CapsuleTest::withTextureCoords() { - Capsule capsule(2, 3, 1.0f, Capsule::TextureCoords::Generate); - - CORRADE_COMPARE(*capsule.vertices(0), (vector{ - Vector4(0.0f, -1.5f, 0.0f), - - Vector4(0.0f, -1.20711f, 0.707107f), - Vector4(0.612372f, -1.20711f, -0.353553f), - Vector4(-0.612373f, -1.20711f, -0.353553f), - Vector4(0.0f, -1.20711f, 0.707107f), - - Vector4(0.0f, -0.5f, 1.0f), - Vector4(0.866025f, -0.5f, -0.5f), - Vector4(-0.866025f, -0.5f, -0.5f), - Vector4(0.0f, -0.5f, 1.0f), - - Vector4(0.0f, 0.5f, 1.0f), - Vector4(0.866025f, 0.5f, -0.5f), - Vector4(-0.866025f, 0.5f, -0.5f), - Vector4(0.0f, 0.5f, 1.0f), - - Vector4(0.0f, 1.20711f, 0.707107f), - Vector4(0.612372f, 1.20711f, -0.353553f), - Vector4(-0.612372f, 1.20711f, -0.353553f), - Vector4(0.0f, 1.20711f, 0.707107f), - - Vector4(0.0f, 1.5f, 0.0f) - })); - - CORRADE_COMPARE(*capsule.textureCoords2D(0), (vector{ - Vector2(0.5f, 0.0f), - - Vector2(0.0f, 0.166667f), - Vector2(0.333333f, 0.166667f), - Vector2(0.666667f, 0.166667f), - Vector2(1.0f, 0.166667f), - - Vector2(0.0f, 0.333333f), - Vector2(0.333333f, 0.333333f), - Vector2(0.666667f, 0.333333f), - Vector2(1.0f, 0.333333f), - - Vector2(0.0f, 0.666667f), - Vector2(0.333333f, 0.666667f), - Vector2(0.666667f, 0.666667f), - Vector2(1.0f, 0.666667f), - - Vector2(0.0f, 0.833333f), - Vector2(0.333333f, 0.833333f), - Vector2(0.666667f, 0.833333f), - Vector2(1.0f, 0.833333f), - - Vector2(0.5f, 1.0f) - })); - - CORRADE_COMPARE(*capsule.indices(), (vector{ + Capsule capsule(2, 2, 3, 1.0f, Capsule::TextureCoords::Generate); + + CORRADE_COMPARE_AS(*capsule.positions(0), (vector{ + {0.0f, -1.5f, 0.0f}, + + {0.0f, -1.20711f, 0.707107f}, + {0.612372f, -1.20711f, -0.353553f}, + {-0.612373f, -1.20711f, -0.353553f}, + {0.0f, -1.20711f, 0.707107f}, + + {0.0f, -0.5f, 1.0f}, + {0.866025f, -0.5f, -0.5f}, + {-0.866025f, -0.5f, -0.5f}, + {0.0f, -0.5f, 1.0f}, + + {0.0f, 0.0f, 1.0f}, + {0.866025f, 0.0f, -0.5f}, + {-0.866025f, 0.0f, -0.5f}, + {0.0f, 0.0f, 1.0f}, + + {0.0f, 0.5f, 1.0f}, + {0.866025f, 0.5f, -0.5f}, + {-0.866025f, 0.5f, -0.5f}, + {0.0f, 0.5f, 1.0f}, + + {0.0f, 1.20711f, 0.707107f}, + {0.612372f, 1.20711f, -0.353553f}, + {-0.612372f, 1.20711f, -0.353553f}, + {0.0f, 1.20711f, 0.707107f}, + + {0.0f, 1.5f, 0.0f} + }), Container); + + CORRADE_COMPARE_AS(*capsule.textureCoords2D(0), (vector{ + {0.5f, 0.0f}, + + {0.0f, 0.166667f}, + {0.333333f, 0.166667f}, + {0.666667f, 0.166667f}, + {1.0f, 0.166667f}, + + {0.0f, 0.333333f}, + {0.333333f, 0.333333f}, + {0.666667f, 0.333333f}, + {1.0f, 0.333333f}, + + {0.0f, 0.5f}, + {0.333333f, 0.5f}, + {0.666667f, 0.5f}, + {1.0f, 0.5f}, + + {0.0f, 0.666667f}, + {0.333333f, 0.666667f}, + {0.666667f, 0.666667f}, + {1.0f, 0.666667f}, + + {0.0f, 0.833333f}, + {0.333333f, 0.833333f}, + {0.666667f, 0.833333f}, + {1.0f, 0.833333f}, + + {0.5f, 1.0f} + }), Container); + + CORRADE_COMPARE_AS(*capsule.indices(), (vector{ 0, 2, 1, 0, 3, 2, 0, 4, 3, 1, 2, 6, 1, 6, 5, 2, 3, 7, 2, 7, 6, 3, 4, 8, 3, 8, 7, 5, 6, 10, 5, 10, 9, 6, 7, 11, 6, 11, 10, 7, 8, 12, 7, 12, 11, 9, 10, 14, 9, 14, 13, 10, 11, 15, 10, 15, 14, 11, 12, 16, 11, 16, 15, - 13, 14, 17, 14, 15, 17, 15, 16, 17 - })); + 13, 14, 18, 13, 18, 17, 14, 15, 19, 14, 19, 18, 15, 16, 20, 15, 20, 19, + 17, 18, 21, 18, 19, 21, 19, 20, 21 + }), Container); } }}} diff --git a/src/Primitives/Test/CylinderTest.cpp b/src/Primitives/Test/CylinderTest.cpp new file mode 100644 index 000000000..f7f919cae --- /dev/null +++ b/src/Primitives/Test/CylinderTest.cpp @@ -0,0 +1,176 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "CylinderTest.h" + +#include + +#include "Math/Point3D.h" +#include "Primitives/Cylinder.h" + +using namespace std; +using Corrade::TestSuite::Compare::Container; + +CORRADE_TEST_MAIN(Magnum::Primitives::Test::CylinderTest) + +namespace Magnum { namespace Primitives { namespace Test { + +CylinderTest::CylinderTest() { + addTests(&CylinderTest::withoutAnything, + &CylinderTest::withTextureCoordsAndCaps); +} + +void CylinderTest::withoutAnything() { + Cylinder cylinder(2, 3, 3.0f); + + CORRADE_COMPARE_AS(*cylinder.positions(0), (vector{ + {0.0f, -1.5f, 1.0f}, + {0.866025f, -1.5f, -0.5f}, + {-0.866025f, -1.5f, -0.5f}, + + {0.0f, 0.0f, 1.0f}, + {0.866025f, 0.0f, -0.5f}, + {-0.866025f, 0.0f, -0.5f}, + + {0.0f, 1.5f, 1.0f}, + {0.866025f, 1.5f, -0.5f}, + {-0.866025f, 1.5f, -0.5f} + }), Container); + + CORRADE_COMPARE_AS(*cylinder.normals(0), (vector{ + {0.0f, 0.0f, 1.0f}, + {0.866025f, 0.0f, -0.5f}, + {-0.866025f, 0.0f, -0.5f}, + + {0.0f, 0.0f, 1.0f}, + {0.866025f, 0.0f, -0.5f}, + {-0.866025f, 0.0f, -0.5f}, + + {0.0f, 0.0f, 1.0f}, + {0.866025f, 0.0f, -0.5f}, + {-0.866025f, 0.0f, -0.5f} + }), Container); + + CORRADE_COMPARE_AS(*cylinder.indices(), (vector{ + 0, 1, 4, 0, 4, 3, 1, 2, 5, 1, 5, 4, 2, 0, 3, 2, 3, 5, + 3, 4, 7, 3, 7, 6, 4, 5, 8, 4, 8, 7, 5, 3, 6, 5, 6, 8 + }), Container); +} + +void CylinderTest::withTextureCoordsAndCaps() { + Cylinder cylinder(2, 3, 3.0f, Cylinder::Flag::GenerateTextureCoords|Cylinder::Flag::CapEnds); + + CORRADE_COMPARE_AS(*cylinder.positions(0), (vector{ + {0.0f, -1.5f, 0.0f}, + + {0.0f, -1.5f, 1.0f}, + {0.866025f, -1.5f, -0.5f}, + {-0.866025f, -1.5f, -0.5f}, + {0.0f, -1.5f, 1.0f}, + + {0.0f, -1.5f, 1.0f}, + {0.866025f, -1.5f, -0.5f}, + {-0.866025f, -1.5f, -0.5f}, + {0.0f, -1.5f, 1.0f}, + + {0.0f, 0.0f, 1.0f}, + {0.866025f, 0.0f, -0.5f}, + {-0.866025f, 0.0f, -0.5f}, + {0.0f, 0.0f, 1.0f}, + + {0.0f, 1.5f, 1.0f}, + {0.866025f, 1.5f, -0.5f}, + {-0.866025f, 1.5f, -0.5f}, + {0.0f, 1.5f, 1.0f}, + + {0.0f, 1.5f, 1.0f}, + {0.866025f, 1.5f, -0.5f}, + {-0.866025f, 1.5f, -0.5f}, + {0.0f, 1.5f, 1.0f}, + + {0.0f, 1.5f, 0.0f} + }), Container); + + CORRADE_COMPARE_AS(*cylinder.normals(0), (vector{ + {0.0f, -1.0f, 0.0f}, + + {0.0f, -1.0f, 0.0f}, + {0.0f, -1.0f, 0.0f}, + {0.0f, -1.0f, 0.0f}, + {0.0f, -1.0f, 0.0f}, + + {0.0f, 0.0f, 1.0f}, + {0.866025f, 0.0f, -0.5f}, + {-0.866025f, 0.0f, -0.5f}, + {0.0f, 0.0f, 1.0f}, + + {0.0f, 0.0f, 1.0f}, + {0.866025f, 0.0f, -0.5f}, + {-0.866025f, 0.0f, -0.5f}, + {0.0f, 0.0f, 1.0f}, + + {0.0f, 0.0f, 1.0f}, + {0.866025f, 0.0f, -0.5f}, + {-0.866025f, 0.0f, -0.5f}, + {0.0f, 0.0f, 1.0f}, + + {0.0f, 1.0f, 0.0f}, + {0.0f, 1.0f, 0.0f}, + {0.0f, 1.0f, 0.0f}, + {0.0f, 1.0f, 0.0f}, + + {0.0f, 1.0f, 0.0f}, + }), Container); + + CORRADE_COMPARE_AS(*cylinder.textureCoords2D(0), (vector{ + {0.5f, 0.0f}, + + {0.0f, 0.2f}, + {0.333333f, 0.2f}, + {0.666667f, 0.2f}, + {1.0f, 0.2f}, + + {0.0f, 0.2f}, + {0.333333f, 0.2f}, + {0.666667f, 0.2f}, + {1.0f, 0.2f}, + + {0.0f, 0.5f}, + {0.333333f, 0.5f}, + {0.666667f, 0.5f}, + {1.0f, 0.5f}, + + {0.0f, 0.8f}, + {0.333333f, 0.8f}, + {0.666667f, 0.8f}, + {1.0f, 0.8f}, + + {0.0f, 0.8f}, + {0.333333f, 0.8f}, + {0.666667f, 0.8f}, + {1.0f, 0.8f}, + + {0.5f, 1.0f} + }), Container); + + CORRADE_COMPARE_AS(*cylinder.indices(), (vector{ + 0, 2, 1, 0, 3, 2, 0, 4, 3, + 1, 2, 6, 1, 6, 5, 2, 3, 7, 2, 7, 6, 3, 4, 8, 3, 8, 7, + 5, 6, 10, 5, 10, 9, 6, 7, 11, 6, 11, 10, 7, 8, 12, 7, + 12, 11, 17, 18, 21, 18, 19, 21, 19, 20, 21 + }), Container); +} + +}}} diff --git a/src/Primitives/Test/CylinderTest.h b/src/Primitives/Test/CylinderTest.h new file mode 100644 index 000000000..0d575bc23 --- /dev/null +++ b/src/Primitives/Test/CylinderTest.h @@ -0,0 +1,32 @@ +#ifndef Magnum_Primitives_Test_CylinderTest_h +#define Magnum_Primitives_Test_CylinderTest_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 + +namespace Magnum { namespace Primitives { namespace Test { + +class CylinderTest: public Corrade::TestSuite::Tester { + public: + CylinderTest(); + + void withoutAnything(); + void withTextureCoordsAndCaps(); +}; + +}}} + +#endif diff --git a/src/Primitives/Test/UVSphereTest.cpp b/src/Primitives/Test/UVSphereTest.cpp index 3fb613c61..1599eeb0d 100644 --- a/src/Primitives/Test/UVSphereTest.cpp +++ b/src/Primitives/Test/UVSphereTest.cpp @@ -15,9 +15,13 @@ #include "UVSphereTest.h" +#include + +#include "Math/Point3D.h" #include "Primitives/UVSphere.h" using namespace std; +using Corrade::TestSuite::Compare::Container; CORRADE_TEST_MAIN(Magnum::Primitives::Test::UVSphereTest) @@ -31,81 +35,81 @@ UVSphereTest::UVSphereTest() { void UVSphereTest::withoutTextureCoords() { UVSphere sphere(3, 3); - CORRADE_COMPARE(*sphere.vertices(0), (vector{ - Vector4(0.0f, -1.0f, 0.0f), + CORRADE_COMPARE_AS(*sphere.positions(0), (vector{ + {0.0f, -1.0f, 0.0f}, - Vector4(0.0f, -0.5f, 0.866025f), - Vector4(0.75f, -0.5f, -0.433013f), - Vector4(-0.75f, -0.5f, -0.433013f), + {0.0f, -0.5f, 0.866025f}, + {0.75f, -0.5f, -0.433013f}, + {-0.75f, -0.5f, -0.433013f}, - Vector4(0, 0.5f, 0.866025f), - Vector4(0.75f, 0.5f, -0.433013f), - Vector4(-0.75f, 0.5f, -0.433013f), + {0, 0.5f, 0.866025f}, + {0.75f, 0.5f, -0.433013f}, + {-0.75f, 0.5f, -0.433013f}, - Vector4(0.0f, 1.0f, 0.0f) - })); + {0.0f, 1.0f, 0.0f} + }), Container); - CORRADE_COMPARE(*sphere.normals(0), (vector{ - Vector3(0.0f, -1.0f, 0.0f), + CORRADE_COMPARE_AS(*sphere.normals(0), (vector{ + {0.0f, -1.0f, 0.0f}, - Vector3(0.0f, -0.5f, 0.866025f), - Vector3(0.75f, -0.5f, -0.433013f), - Vector3(-0.75f, -0.5f, -0.433013f), + {0.0f, -0.5f, 0.866025f}, + {0.75f, -0.5f, -0.433013f}, + {-0.75f, -0.5f, -0.433013f}, - Vector3(0, 0.5f, 0.866025f), - Vector3(0.75f, 0.5f, -0.433013f), - Vector3(-0.75f, 0.5f, -0.433013f), + {0, 0.5f, 0.866025f}, + {0.75f, 0.5f, -0.433013f}, + {-0.75f, 0.5f, -0.433013f}, - Vector3(0.0f, 1.0f, 0.0f) - })); + {0.0f, 1.0f, 0.0f} + }), Container); - CORRADE_COMPARE(*sphere.indices(), (vector{ + CORRADE_COMPARE_AS(*sphere.indices(), (vector{ 0, 2, 1, 0, 3, 2, 0, 1, 3, 1, 2, 5, 1, 5, 4, 2, 3, 6, 2, 6, 5, 3, 1, 4, 3, 4, 6, 4, 5, 7, 5, 6, 7, 6, 4, 7 - })); + }), Container); } void UVSphereTest::withTextureCoords() { UVSphere sphere(3, 3, UVSphere::TextureCoords::Generate); - CORRADE_COMPARE(*sphere.vertices(0), (vector{ - Vector4(0.0f, -1.0f, 0.0f), + CORRADE_COMPARE_AS(*sphere.positions(0), (vector{ + {0.0f, -1.0f, 0.0f}, - Vector4(0.0f, -0.5f, 0.866025f), - Vector4(0.75f, -0.5f, -0.433013f), - Vector4(-0.75f, -0.5f, -0.433013f), - Vector4(0.0f, -0.5f, 0.866025f), + {0.0f, -0.5f, 0.866025f}, + {0.75f, -0.5f, -0.433013f}, + {-0.75f, -0.5f, -0.433013f}, + {0.0f, -0.5f, 0.866025f}, - Vector4(0.0f, 0.5f, 0.866025f), - Vector4(0.75f, 0.5f, -0.433013f), - Vector4(-0.75f, 0.5f, -0.433013f), - Vector4(0.0f, 0.5f, 0.866025f), + {0.0f, 0.5f, 0.866025f}, + {0.75f, 0.5f, -0.433013f}, + {-0.75f, 0.5f, -0.433013f}, + {0.0f, 0.5f, 0.866025f}, - Vector4(0.0f, 1.0f, 0.0f) - })); + {0.0f, 1.0f, 0.0f} + }), Container); - CORRADE_COMPARE(*sphere.textureCoords2D(0), (vector{ - Vector2(0.5f, 0.0f), + CORRADE_COMPARE_AS(*sphere.textureCoords2D(0), (vector{ + {0.5f, 0.0f}, - Vector2(0.0f, 0.333333f), - Vector2(0.333333f, 0.333333f), - Vector2(0.666667f, 0.333333f), - Vector2(1.0f, 0.333333f), + {0.0f, 0.333333f}, + {0.333333f, 0.333333f}, + {0.666667f, 0.333333f}, + {1.0f, 0.333333f}, - Vector2(0.0f, 0.666667f), - Vector2(0.333333f, 0.666667f), - Vector2(0.666667f, 0.666667f), - Vector2(1.0f, 0.666667f), + {0.0f, 0.666667f}, + {0.333333f, 0.666667f}, + {0.666667f, 0.666667f}, + {1.0f, 0.666667f}, - Vector2(0.5f, 1.0f) - })); + {0.5f, 1.0f} + }), Container); - CORRADE_COMPARE(*sphere.indices(), (vector{ + CORRADE_COMPARE_AS(*sphere.indices(), (vector{ 0, 2, 1, 0, 3, 2, 0, 4, 3, 1, 2, 6, 1, 6, 5, 2, 3, 7, 2, 7, 6, 3, 4, 8, 3, 8, 7, 5, 6, 9, 6, 7, 9, 7, 8, 9 - })); + }), Container); } }}} diff --git a/src/Primitives/UVSphere.cpp b/src/Primitives/UVSphere.cpp index 825a5ee26..e82814264 100644 --- a/src/Primitives/UVSphere.cpp +++ b/src/Primitives/UVSphere.cpp @@ -15,11 +15,15 @@ #include "UVSphere.h" +#include + +#include "Math/Constants.h" + using namespace std; namespace Magnum { namespace Primitives { -UVSphere::UVSphere(unsigned int rings, unsigned int segments, TextureCoords textureCoords): Capsule(segments, textureCoords) { +UVSphere::UVSphere(uint32_t rings, uint32_t segments, TextureCoords textureCoords): Capsule(segments, textureCoords) { CORRADE_ASSERT(rings >= 2 && segments >= 3, "UVSphere must have at least two rings and three segments", ); GLfloat textureCoordsVIncrement = 1.0f/rings; @@ -29,7 +33,7 @@ UVSphere::UVSphere(unsigned int rings, unsigned int segments, TextureCoords text capVertex(-1.0f, -1.0f, 0.0f); /* Vertex rings */ - vertexRings(rings-1, 0.0f, -Math::Constants::pi()/2+ringAngleIncrement, ringAngleIncrement, textureCoordsVIncrement, textureCoordsVIncrement); + hemisphereVertexRings(rings-1, 0.0f, -Math::Constants::pi()/2+ringAngleIncrement, ringAngleIncrement, textureCoordsVIncrement, textureCoordsVIncrement); /* Top cap vertex */ capVertex(1.0f, 1.0f, 1.0f); diff --git a/src/Primitives/UVSphere.h b/src/Primitives/UVSphere.h index 4e6be3b63..8d2f01054 100644 --- a/src/Primitives/UVSphere.h +++ b/src/Primitives/UVSphere.h @@ -23,7 +23,11 @@ namespace Magnum { namespace Primitives { -/** @brief UV Sphere primitive */ +/** +@brief 3D UV sphere primitive + +Indexed triangle mesh with normals and optional 2D texture coordinates. +*/ class UVSphere: public Capsule { public: /** @@ -35,7 +39,7 @@ class UVSphere: public Capsule { * If texture coordinates are generated, vertices of one segment are * duplicated for texture wrapping. */ - UVSphere(unsigned int rings, unsigned int segments, TextureCoords textureCoords = TextureCoords::DontGenerate); + UVSphere(std::uint32_t rings, std::uint32_t segments, TextureCoords textureCoords = TextureCoords::DontGenerate); }; }} diff --git a/src/Profiler.h b/src/Profiler.h index a3da6ef56..3be943bd6 100644 --- a/src/Profiler.h +++ b/src/Profiler.h @@ -16,7 +16,7 @@ */ /** @file - * @brief Class Profiler + * @brief Class Magnum::Profiler */ #include @@ -95,7 +95,7 @@ class MAGNUM_EXPORT Profiler { * * @see otherSection, addSection(), start(Section) */ - typedef unsigned int Section; + typedef std::uint32_t Section; /** * @brief Default section @@ -115,7 +115,7 @@ class MAGNUM_EXPORT Profiler { * is 60. * @attention This function cannot be called if profiling is enabled. */ - void setMeasureDuration(size_t frames); + void setMeasureDuration(std::size_t frames); /** * @brief Add named section @@ -193,7 +193,7 @@ class MAGNUM_EXPORT Profiler { void save(); bool enabled; - size_t measureDuration, currentFrame, frameCount; + std::size_t measureDuration, currentFrame, frameCount; std::vector sections; std::vector frameData; std::vector totalData; diff --git a/src/Query.cpp b/src/Query.cpp index e0889ac68..1b9fc86bc 100644 --- a/src/Query.cpp +++ b/src/Query.cpp @@ -17,45 +17,62 @@ namespace Magnum { -#ifndef MAGNUM_TARGET_GLES bool AbstractQuery::resultAvailable() { + /** @todo Re-enable when extension wrangler is available for ES */ + #ifndef MAGNUM_TARGET_GLES2 GLuint result; - glGetQueryObjectuiv(query, GL_QUERY_RESULT_AVAILABLE, &result); + glGetQueryObjectuiv(_id, GL_QUERY_RESULT_AVAILABLE, &result); return result == GL_TRUE; + #else + return false; + #endif } template<> bool AbstractQuery::result() { + /** @todo Re-enable when extension wrangler is available for ES */ + #ifndef MAGNUM_TARGET_GLES2 GLuint result; - glGetQueryObjectuiv(query, GL_QUERY_RESULT, &result); + glGetQueryObjectuiv(_id, GL_QUERY_RESULT, &result); return result == GL_TRUE; + #else + return false; + #endif } template<> GLuint AbstractQuery::result() { + /** @todo Re-enable when extension wrangler is available for ES */ + #ifndef MAGNUM_TARGET_GLES2 GLuint result; - glGetQueryObjectuiv(query, GL_QUERY_RESULT, &result); + glGetQueryObjectuiv(_id, GL_QUERY_RESULT, &result); return result; + #else + return 0; + #endif } +#ifndef MAGNUM_TARGET_GLES template<> GLint AbstractQuery::result() { GLint result; - glGetQueryObjectiv(query, GL_QUERY_RESULT, &result); + glGetQueryObjectiv(_id, GL_QUERY_RESULT, &result); return result; } template<> GLuint64 AbstractQuery::result() { GLuint64 result; - glGetQueryObjectui64v(query, GL_QUERY_RESULT, &result); + glGetQueryObjectui64v(_id, GL_QUERY_RESULT, &result); return result; } template<> GLint64 AbstractQuery::result() { GLint64 result; - glGetQueryObjecti64v(query, GL_QUERY_RESULT, &result); + glGetQueryObjecti64v(_id, GL_QUERY_RESULT, &result); return result; } +#endif +#ifndef MAGNUM_TARGET_GLES2 void Query::begin(Query::Target target) { - glBeginQuery(static_cast(target), query); + glBeginQuery(static_cast(target), id()); this->target = new Target(target); } @@ -66,19 +83,25 @@ void Query::end() { delete target; target = nullptr; } +#endif void SampleQuery::begin(SampleQuery::Target target) { - glBeginQuery(static_cast(target), query); + /** @todo Re-enable when extension wrangler is available for ES */ + #ifndef MAGNUM_TARGET_GLES2 + glBeginQuery(static_cast(target), id()); + #endif this->target = new Target(target); } void SampleQuery::end() { if(!target) return; + /** @todo Re-enable when extension wrangler is available for ES */ + #ifndef MAGNUM_TARGET_GLES2 glEndQuery(static_cast(*target)); + #endif delete target; target = nullptr; } -#endif } diff --git a/src/Query.h b/src/Query.h index 32413b2bf..4657775c4 100644 --- a/src/Query.h +++ b/src/Query.h @@ -21,15 +21,16 @@ #include "Magnum.h" +#include "magnumVisibility.h" + namespace Magnum { -#ifndef MAGNUM_TARGET_GLES /** @brief Base class for queries See Query, SampleQuery, TimeQuery documentation for more information. @todo Support for AMD's query buffer (@extension{AMD,query_buffer_object}) -@requires_gl +@requires_gles30 %Extension @es_extension{EXT,occlusion_query_boolean} */ class MAGNUM_EXPORT AbstractQuery { public: @@ -37,18 +38,25 @@ class MAGNUM_EXPORT AbstractQuery { * @brief Constructor * * Generates one OpenGL query. + * @see @fn_gl{GenQueries} */ - inline AbstractQuery() { glGenQueries(1, &query); } + inline AbstractQuery() { glGenQueries(1, &_id); } /** * @brief Destructor * * Deletes assigned OpenGL query. + * @see @fn_gl{DeleteQueries} */ - virtual inline ~AbstractQuery() { glDeleteQueries(1, &query); } + virtual inline ~AbstractQuery() { glDeleteQueries(1, &_id); } + + /** @brief OpenGL query ID */ + inline GLuint id() const { return _id; } /** * @brief Whether the result is available + * + * @see @fn_gl{GetQueryObject} with @def_gl{QUERY_RESULT_AVAILABLE} */ bool resultAvailable(); @@ -59,24 +67,29 @@ class MAGNUM_EXPORT AbstractQuery { * * Note that this function is blocking until the result is available. * See resultAvailable(). - * + * @see @fn_gl{GetQueryObject} with @def_gl{QUERY_RESULT} * @requires_gl33 Extension @extension{ARB,timer_query} (result type `GLuint64` and `GLint64`) + * @requires_gl Result types @c GLint, @c GLuint64 and @c GLint64 are + * not available in OpenGL ES. */ template T result(); - protected: - GLuint query; /**< @brief OpenGL internal query ID */ + private: + GLuint _id; }; #ifndef DOXYGEN_GENERATING_OUTPUT template<> bool MAGNUM_EXPORT AbstractQuery::result(); template<> GLuint MAGNUM_EXPORT AbstractQuery::result(); +#ifndef MAGNUM_TARGET_GLES template<> GLint MAGNUM_EXPORT AbstractQuery::result(); template<> GLuint64 MAGNUM_EXPORT AbstractQuery::result(); template<> GLint64 MAGNUM_EXPORT AbstractQuery::result(); #endif +#endif +#ifndef MAGNUM_TARGET_GLES2 /** @brief %Query for primitives and elapsed time @@ -96,28 +109,37 @@ if(!q.resultAvailable()) { // ...or block until the result is available GLuint primitiveCount = q.result(); @endcode -@requires_gl @requires_gl30 Extension @extension{EXT,transform_feedback} +@requires_gles30 Only sample queries are available on OpenGL ES 2.0. */ class MAGNUM_EXPORT Query: public AbstractQuery { public: /** @brief %Query target */ enum Target: GLenum { + #ifndef MAGNUM_TARGET_GLES /** * Count of primitives generated from vertex shader or geometry * shader. + * @requires_gl Only transform feedback query is available in + * OpenGL ES. */ PrimitivesGenerated = GL_PRIMITIVES_GENERATED, + #endif /** Count of primitives written to transform feedback buffer. */ - TransformFeedbackPrimitivesWritten = GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, + TransformFeedbackPrimitivesWritten = GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN + + #ifndef MAGNUM_TARGET_GLES + , /** * Elapsed time - * * @requires_gl33 Extension @extension{ARB,timer_query} + * @requires_gl Only transform feedback query is available in + * OpenGL ES. */ TimeElapsed = GL_TIME_ELAPSED + #endif }; inline Query(): target(nullptr) {} @@ -128,6 +150,7 @@ class MAGNUM_EXPORT Query: public AbstractQuery { * @brief Begin query * * Begins counting of given @p target until end() is called. + * @see @fn_gl{BeginQuery} */ void begin(Target target); @@ -135,12 +158,14 @@ class MAGNUM_EXPORT Query: public AbstractQuery { * @brief End query * * The result can be then retrieved by calling result(). + * @see @fn_gl{EndQuery} */ void end(); private: Target* target; }; +#endif /** @brief %Query for samples @@ -176,27 +201,42 @@ q.beginConditionalRender(SampleQuery::ConditionalRenderMode::Wait); // render full version of the object only if the query returns nonzero result q.endConditionalRender(); @endcode -@requires_gl +@requires_gles30 %Extension @es_extension{EXT,occlusion_query_boolean} */ class MAGNUM_EXPORT SampleQuery: public AbstractQuery { public: /** @brief %Query target */ enum Target: GLenum { - /** Count of samples passed from fragment shader */ + #ifndef MAGNUM_TARGET_GLES + /** + * Count of samples passed from fragment shader + * @requires_gl Only boolean query is available in OpenGL ES. + */ SamplesPassed = GL_SAMPLES_PASSED, + #endif /** * Whether any samples passed from fragment shader - * * @requires_gl33 Extension @extension{ARB,occlusion_query2} */ - AnySamplesPassed = GL_ANY_SAMPLES_PASSED + AnySamplesPassed = GL_ANY_SAMPLES_PASSED, + + /** + * Whether any samples passed from fragment shader (conservative) + * + * An implementation may choose a less precise version of the + * test at the expense of some false positives. + * @requires_gl43 Extension @extension{ARB,ES3_compatibility} + */ + AnySamplesPassedConservative = GL_ANY_SAMPLES_PASSED_CONSERVATIVE }; + #ifndef MAGNUM_TARGET_GLES /** * @brief Conditional render mode * * @requires_gl30 Extension @extension{NV,conditional_render} + * @requires_gl Conditional rendering is not available in OpenGL ES. */ enum class ConditionalRenderMode: GLenum { /** @@ -223,6 +263,7 @@ class MAGNUM_EXPORT SampleQuery: public AbstractQuery { */ ByRegionNoWait = GL_QUERY_BY_REGION_NO_WAIT }; + #endif inline SampleQuery(): target(nullptr) {} @@ -234,28 +275,35 @@ class MAGNUM_EXPORT SampleQuery: public AbstractQuery { /** @copydoc Query::end() */ void end(); + #ifndef MAGNUM_TARGET_GLES /** * @brief Begin conditional rendering based on result value * + * @see @fn_gl{BeginConditionalRender} * @requires_gl30 Extension @extension{NV,conditional_render} + * @requires_gl Conditional rendering is not available in OpenGL ES. */ inline void beginConditionalRender(ConditionalRenderMode mode) { - glBeginConditionalRender(query, static_cast(mode)); + glBeginConditionalRender(id(), static_cast(mode)); } /** * @brief End conditional render * + * @see @fn_gl{EndConditionalRender} * @requires_gl30 Extension @extension{NV,conditional_render} + * @requires_gl Conditional rendering is not available in OpenGL ES. */ inline void endConditionalRender() { glEndConditionalRender(); } + #endif private: Target* target; }; +#ifndef MAGNUM_TARGET_GLES /** @brief %Query for elapsed time @@ -286,17 +334,20 @@ GLuint timeElapsed1 = tmp-q1.result(); GLuint timeElapsed2 = q3.result()-tmp; @endcode Using this query results in fewer OpenGL calls when doing more measures. -@requires_gl @requires_gl33 Extension @extension{ARB,timer_query} +@requires_gl Timer query is not available in OpenGL ES. */ class TimeQuery: public AbstractQuery { public: - /** @brief Query timestamp */ + /** + * @brief Query timestamp + * + * @see @fn_gl{QueryCounter} with @def_gl{TIMESTAMP} + */ inline void timestamp() { - glQueryCounter(query, GL_TIMESTAMP); + glQueryCounter(id(), GL_TIMESTAMP); } }; - #endif } diff --git a/src/Renderbuffer.cpp b/src/Renderbuffer.cpp index f7d2c4f11..aa08c7b63 100644 --- a/src/Renderbuffer.cpp +++ b/src/Renderbuffer.cpp @@ -17,8 +17,8 @@ namespace Magnum { -#ifndef MAGNUM_TARGET_GLES Renderbuffer::InternalFormat::InternalFormat(Components components, ComponentType type) { + #ifndef MAGNUM_TARGET_GLES #define internalFormatSwitch(c) switch(type) { \ case ComponentType::UnsignedByte: \ internalFormat = GL_##c##8UI; break; \ @@ -41,6 +41,28 @@ Renderbuffer::InternalFormat::InternalFormat(Components components, ComponentTyp case ComponentType::NormalizedUnsignedShort: \ internalFormat = GL_##c##16; 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; \ + } + #endif if(components == Components::Red) internalFormatSwitch(R) else if(components == Components::RedGreen) @@ -49,6 +71,5 @@ Renderbuffer::InternalFormat::InternalFormat(Components components, ComponentTyp internalFormatSwitch(RGBA) #undef internalFormatSwitch } -#endif } diff --git a/src/Renderbuffer.h b/src/Renderbuffer.h index 35854aba3..a2da42736 100644 --- a/src/Renderbuffer.h +++ b/src/Renderbuffer.h @@ -19,8 +19,11 @@ * @brief Class Magnum::Renderbuffer */ +#include "Math/Vector2.h" #include "Magnum.h" +#include "magnumVisibility.h" + namespace Magnum { /** @@ -39,12 +42,11 @@ class Renderbuffer { public: /** @{ @name Internal renderbuffer formats */ - #ifndef MAGNUM_TARGET_GLES /** * @copybrief AbstractTexture::Components * * Like AbstractTexture::Components, without three-component RGB. - * @requires_gl + * @requires_gles30 (no extension providing this functionality) */ enum class Components { Red, RedGreen, RGBA @@ -55,13 +57,16 @@ class Renderbuffer { * * Like AbstractTexture::ComponentType, without normalized signed * types. - * @requires_gl + * @requires_gles30 (no extension providing this functionality) */ enum class ComponentType { UnsignedByte, Byte, UnsignedShort, Short, UnsignedInt, Int, Half, - Float, NormalizedUnsignedByte, NormalizedUnsignedShort + Float, NormalizedUnsignedByte + + #ifndef MAGNUM_TARGET_GLES + , NormalizedUnsignedShort + #endif }; - #endif /** * @copybrief AbstractTexture::Format @@ -71,23 +76,18 @@ class Renderbuffer { * compressed formats, but with added separate stencil index. */ enum class Format: GLenum { - #ifndef MAGNUM_TARGET_GLES - Red = GL_RED, RedGreen = GL_RG, - #endif - - RGBA = GL_RGBA, + Red = GL_RED, RedGreen = GL_RG, RGBA = GL_RGBA, #ifndef MAGNUM_TARGET_GLES - BGRA = GL_BGRA, SRGBA = GL_SRGB8_ALPHA8, - RGB10Alpha2 = GL_RGB10_A2, RGB10AlphaUnsigned2 = GL_RGB10_A2UI, + BGRA = GL_BGRA, #endif - RGB5Alpha1 = GL_RGB5_A1, RGBA4 = GL_RGBA4, - - #ifndef MAGNUM_TARGET_GLES - RFloat11GFloat11BFloat10 = GL_R11F_G11F_B10F, - #endif + SRGBA = GL_SRGB8_ALPHA8, RGB10Alpha2 = GL_RGB10_A2, + RGB10AlphaUnsigned2 = GL_RGB10_A2UI, RGB5Alpha1 = GL_RGB5_A1, + RGBA4 = GL_RGBA4, RFloat11GFloat11BFloat10 = GL_R11F_G11F_B10F, + /* 1.5.6 <= GLEW < 1.8.0 doesn't have this, even if there is + GL_ARB_ES2_compatibility */ #if defined(GL_RGB565) || defined(DOXYGEN_GENERATING_OUTPUT) RGB565 = GL_RGB565, #endif @@ -156,10 +156,8 @@ class Renderbuffer { /** @copydoc AbstractTexture::InternalFormat */ class MAGNUM_EXPORT InternalFormat { public: - #ifndef MAGNUM_TARGET_GLES /** @copydoc AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Components, AbstractTexture::ComponentType) */ InternalFormat(Components components, ComponentType type); - #endif /** @copydoc AbstractTexture::InternalFormat::InternalFormat(AbstractTexture::Format) */ inline constexpr InternalFormat(Format format): internalFormat(static_cast(format)) {} @@ -181,8 +179,9 @@ class Renderbuffer { * @brief Constructor * * Generates new OpenGL renderbuffer. + * @see @fn_gl{GenRenderbuffers} */ - Renderbuffer() { + inline Renderbuffer() { glGenRenderbuffers(1, &renderbuffer); } @@ -190,15 +189,20 @@ class Renderbuffer { * @brief Destructor * * Deletes associated OpenGL renderbuffer. + * @see @fn_gl{DeleteRenderbuffers} */ - ~Renderbuffer() { + inline ~Renderbuffer() { glDeleteRenderbuffers(1, &renderbuffer); } /** @brief OpenGL internal renderbuffer ID */ inline GLuint id() const { return renderbuffer; } - /** @brief Bind renderbuffer */ + /** + * @brief Bind renderbuffer + * + * @see @fn_gl{BindRenderbuffer} + */ inline void bind() { glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); } @@ -207,6 +211,8 @@ class Renderbuffer { * @brief Set renderbuffer storage * @param internalFormat Internal format * @param size Renderbuffer size + * + * @see bind(), @fn_gl{RenderbufferStorage} */ inline void setStorage(InternalFormat internalFormat, const Math::Vector2& size) { bind(); @@ -217,11 +223,10 @@ class Renderbuffer { GLuint renderbuffer; }; -#ifndef MAGNUM_TARGET_GLES /** @relates Renderbuffer @brief Convertor of component count and data type to InternalFormat -@requires_gl +@requires_gles30 (no extension providing this functionality) */ inline Renderbuffer::InternalFormat operator|(Renderbuffer::Components components, Renderbuffer::ComponentType type) { return Renderbuffer::InternalFormat(components, type); @@ -232,7 +237,6 @@ inline Renderbuffer::InternalFormat operator|(Renderbuffer::Components component inline Renderbuffer::InternalFormat operator|(Renderbuffer::ComponentType type, Renderbuffer::Components components) { return Renderbuffer::InternalFormat(components, type); } -#endif } diff --git a/src/ResourceManager.h b/src/ResourceManager.h new file mode 100644 index 000000000..d5f9b4e34 --- /dev/null +++ b/src/ResourceManager.h @@ -0,0 +1,568 @@ +#ifndef Magnum_ResourceManager_h +#define Magnum_ResourceManager_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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. +*/ + +/** @file + * @brief Class Magnum::ResourceManager, Magnum::ResourceKey, Magnum::Resource, enum Magnum::ResourceState, Magnum::ResourceDataState, Magnum::ResourcePolicy + */ + +#include +#include + +namespace Magnum { + +/** @relates ResourceManager + * @brief %Resource state + * + * @see Resource::state(), ResourceManager::state() + */ +enum class ResourceState { + /** The resource is not yet loaded. */ + NotLoaded, + + /** The resource is not yet loaded and fallback resource is used instead. */ + Fallback, + + /** The resource is loaded, but can be changed by the manager at any time. */ + Mutable, + + /** The resource is loaded and won't be changed by the manager anymore. */ + Final +}; + +/** @relates ResourceManager + * @brief %Resource data state + * + * @see ResourceManager::set() + */ +enum class ResourceDataState { + /** + * The resource can be changed by the manager in the future. This is + * slower, as Resource needs to ask the manager for new version every time + * the data are accessed, but allows changing the data for e.g. debugging + * purposes. + */ + Mutable = int(ResourceState::Mutable), + + /** + * The resource cannot be changed by the manager in the future. This is + * faster, as Resource instances will ask for the data only one time, thus + * suitable for production code. + */ + Final = int(ResourceState::Final) +}; + +/** @relates ResourceManager +@brief %Resource policy + +@see ResourceManager::set(), ResourceManager::free() + */ +enum class ResourcePolicy { + /** The resource will stay resident for whole lifetime of resource manager. */ + Resident, + + /** + * The resource will be unloaded when manually calling + * ResourceManager::free() if nothing references it. + */ + Manual, + + /** The resource will be unloaded when last reference to it is gone. */ + ReferenceCounted +}; + +/** +@brief Key for accessing resource + +@see ResourceManager::referenceCount(), ResourceManager::state(), + ResourceManager::get(), ResourceManager::set(), Resource::key() +*/ +class ResourceKey: public Corrade::Utility::MurmurHash2::Digest { + public: + /** + * @brief Default constructor + * + * The same as calling other constructors with empty string. + */ + inline ResourceKey(): Corrade::Utility::MurmurHash2::Digest(Corrade::Utility::MurmurHash2()("")) {} + + /** @brief Constructor */ + inline ResourceKey(const std::string& key): Corrade::Utility::MurmurHash2::Digest(Corrade::Utility::MurmurHash2()(key)) {} + + /** + * @brief Constructor + * @todo constexpr + */ + template inline constexpr ResourceKey(const char(&key)[size]): Corrade::Utility::MurmurHash2::Digest(Corrade::Utility::MurmurHash2()(key)) {} +}; + +template class Resource; + +#ifndef DOXYGEN_GENERATING_OUTPUT +namespace Implementation { + struct ResourceKeyHash { + inline std::size_t operator()(ResourceKey key) const { + return *reinterpret_cast(key.byteArray()); + } + }; + + template class ResourceManagerData { + ResourceManagerData(const ResourceManagerData&) = delete; + ResourceManagerData(ResourceManagerData&&) = delete; + ResourceManagerData& operator=(const ResourceManagerData&) = delete; + ResourceManagerData& operator=(ResourceManagerData&&) = delete; + + public: + struct Data { + Data(const Data&) = delete; + Data& operator=(const Data&) = delete; + Data& operator=(Data&&) = delete; + + inline Data(): data(nullptr), state(ResourceDataState::Mutable), policy(ResourcePolicy::Manual), referenceCount(0) {} + + Data(Data&& other): data(other.data), state(other.state), policy(other.policy), referenceCount(other.referenceCount) { + other.data = nullptr; + other.referenceCount = 0; + } + + ~Data() { + CORRADE_ASSERT(referenceCount == 0, "ResourceManager: cannot destruct it while data are still referenced", ); + delete data; + } + + T* data; + ResourceDataState state; + ResourcePolicy policy; + std::size_t referenceCount; + }; + + inline virtual ~ResourceManagerData() { + delete _fallback; + } + + inline std::size_t lastChange() const { return _lastChange; } + + inline std::size_t count() const { return _data.size(); } + + std::size_t referenceCount(ResourceKey key) const { + auto it = _data.find(key); + if(it == _data.end()) return 0; + return it->second.referenceCount; + } + + ResourceState state(ResourceKey key) const { + auto it = _data.find(key); + if(it == _data.end() || !it->second.data) + return _fallback ? ResourceState::Fallback : ResourceState::NotLoaded; + else + return static_cast(it->second.state); + } + + template inline Resource get(ResourceKey key) { + return Resource(this, key); + } + + void set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy) { + auto it = _data.find(key); + + /* Cannot change resource with already final state */ + CORRADE_ASSERT(it == _data.end() || it->second.state != ResourceDataState::Final, "ResourceManager: cannot change already final resource", ); + + /* If nothing is referencing reference-counted resource, we're done */ + if(policy == ResourcePolicy::ReferenceCounted && (it == _data.end() || it->second.referenceCount == 0)) { + Corrade::Utility::Warning() << "ResourceManager: Reference-counted resource with key" << key << "isn't referenced from anywhere, deleting it immediately"; + delete data; + + /* Delete also already present resource (it could be here + because previous policy could be other than + ReferenceCounted) */ + if(it != _data.end()) _data.erase(it); + + return; + + /* Insert it, if not already here */ + } else if(it == _data.end()) + it = _data.insert(std::make_pair(key, Data())).first; + + /* Replace previous data */ + delete it->second.data; + it->second.data = data; + it->second.state = state; + it->second.policy = policy; + ++_lastChange; + } + + inline void setFallback(T* data) { + delete _fallback; + _fallback = data; + } + + void free() { + /* Delete all non-referenced non-resident resources */ + for(auto it = _data.begin(); it != _data.end(); ) { + if(it->second.policy != ResourcePolicy::Resident && !it->second.referenceCount) + it = _data.erase(it); + else ++it; + } + } + + inline T* fallback() const { return _fallback; } + + inline const Data& data(ResourceKey key) { + return _data[key]; + } + + inline void incrementReferenceCount(ResourceKey key) { + ++_data[key].referenceCount; + } + + inline void decrementReferenceCount(ResourceKey key) { + auto it = _data.find(key); + + /* Free the resource if it is reference counted */ + if(--it->second.referenceCount == 0 && it->second.policy == ResourcePolicy::ReferenceCounted) + _data.erase(it); + } + + protected: + inline ResourceManagerData(): _fallback(nullptr), _lastChange(0) {} + + private: + std::unordered_map _data; + T* _fallback; + std::size_t _lastChange; + }; +} +#endif + +/** +@brief %Resource reference + +See ResourceManager for more information. +*/ +template class Resource { + friend class Implementation::ResourceManagerData; + + public: + /** + * @brief Default constructor + * + * Creates empty resource. Resources are acquired from the manager by + * calling ResourceManager::get(). + */ + inline Resource(): manager(nullptr), lastCheck(0), _state(ResourceState::Final), data(nullptr) {} + + /** @brief Copy constructor */ + inline Resource(const Resource& other): manager(other.manager), _key(other._key), lastCheck(other.lastCheck), _state(other._state), data(other.data) { + if(manager) manager->incrementReferenceCount(_key); + } + + /** @brief Move constructor */ + inline Resource(Resource&& other): manager(other.manager), _key(other._key), lastCheck(other.lastCheck), _state(other._state), data(other.data) { + other.manager = nullptr; + } + + /** @brief Destructor */ + inline ~Resource() { + if(manager) manager->decrementReferenceCount(_key); + } + + /** @brief Assignment operator */ + Resource& operator=(const Resource& other) { + if(manager) manager->decrementReferenceCount(_key); + + manager = other.manager; + _key = other._key; + lastCheck = other.lastCheck; + _state = other._state; + data = other.data; + + if(manager) manager->incrementReferenceCount(_key); + return *this; + } + + /** @brief Assignment move operator */ + Resource& operator=(Resource&& other) { + if(manager) manager->decrementReferenceCount(_key); + + manager = other.manager; + _key = other._key; + lastCheck = other.lastCheck; + _state = other._state; + data = other.data; + + other.manager = nullptr; + return *this; + } + + /** @brief Resource key */ + inline ResourceKey key() const { return _key; } + + /** + * @brief %Resource state + * + * @see operator bool() + */ + inline ResourceState state() { + acquire(); + return _state; + } + + /** + * @brief Whether the resource is available + * @return False when resource is not loaded and no fallback is + * available, true otherwise. + * + * @see state() + */ + inline operator bool() { + acquire(); + return data; + } + + /** @brief %Resource data */ + inline U& operator*() { + acquire(); + return *static_cast(data); + } + + /** @brief %Resource data */ + inline U* operator->() { + acquire(); + return static_cast(data); + } + + /** @brief %Resource data */ + inline operator U*() { + acquire(); + return static_cast(data); + } + + private: + inline Resource(Implementation::ResourceManagerData* manager, ResourceKey key): manager(manager), _key(key), lastCheck(0), _state(ResourceState::NotLoaded), data(nullptr) { + manager->incrementReferenceCount(key); + } + + void acquire() { + /* The data are already final, nothing to do */ + if(_state == ResourceState::Final) return; + + /* Nothing changed since last check */ + if(manager->lastChange() < lastCheck) return; + + /* Acquire new data and save last check time */ + const typename Implementation::ResourceManagerData::Data& d = manager->data(_key); + lastCheck = manager->lastChange(); + + /* Try to get the data */ + if((data = d.data)) + _state = static_cast(d.state); + else if((data = manager->fallback())) + _state = ResourceState::Fallback; + else + _state = ResourceState::NotLoaded; + } + + Implementation::ResourceManagerData* manager; + ResourceKey _key; + std::size_t lastCheck; + ResourceState _state; + T* data; +}; + +/** +@brief %Resource manager + +Provides storage for arbitrary set of types, accessible globally using +instance(). + +Each resource is referenced from Resource class. For optimizing performance, +each resource can be set as mutable or final. Mutable resources can be +modified by the manager and thus each %Resource instance asks the manager for +modifications on each access. On the other hand, final resources cannot be +modified by the manager, so %Resource instances don't have to ask the manager +every time, which is faster. + +It's possible to provide fallback for resources which are not available using +setFallback(). Accessing data of such resources will access the fallback +instead of failing on null pointer dereference. Availability and state of each +resource can be queried through function state() on the manager or +Resource::state() on each resource. + +The resources can be managed in three ways - resident resources, which stay in +memory for whole lifetime of the manager, manually managed resources, which +can be deleted by calling free() if nothing references them anymore, and +reference counted resources, which are deleted as soon as the last reference +to them is removed. + +%Resource state and policy is configured when setting the resource data in +set() and can be changed each time the data are updated, although already +final resources cannot obviously be set as mutable again. + +Basic usage is: +- Typedef'ing manager of desired types, creating its instance. +@code +typedef ResourceManager MyResourceManager; +MyResourceManager manager; +@endcode +- Filling the manager with resource data and acquiring the resources. Note + that a resource can be acquired with get() even before the manager contains + the data for it, as long as the resource data are not accessed (or fallback + is provided). +@code +MyResourceManager* manager = MyResourceManager::instance(); +Resource texture(manager->get("texture")); +Resource shader(manager->get("shader")); +Resource cube(manager->get("cube")); + +// The manager doesn't have data for the cube yet, add them +if(!cube) { + Mesh* mesh = new Mesh; + // ... + manager->set(cube.key(), mesh, ResourceDataState::Final, ResourcePolicy::Resident); +} +@endcode +- Using the resource data. +@code +shader->use(); +texture->bind(layer); +cube->draw(); +@endcode +- Destroying resource references and deleting manager instance when nothing + references the resources anymore. +*/ +template class ResourceManager: protected Implementation::ResourceManagerData... { + public: + /** @brief Global instance */ + inline static ResourceManager* instance() { return _instance; } + + /** + * @brief Constructor + * + * Sets global instance pointer to itself. + * @attention Only one instance of given ResourceManager type can be + * created. + * @see instance() + */ + inline ResourceManager() { + CORRADE_ASSERT(!_instance, "ResourceManager: another instance is already created!", ); + _instance = this; + } + + /** + * @brief Destructor + * + * Sets global instance pointer to `nullptr`. + * @see instance() + */ + inline ~ResourceManager() { _instance = nullptr; } + + /** @brief Count of resources of given type */ + template inline std::size_t count() { + return this->Implementation::ResourceManagerData::count(); + } + + /** + * @brief Get resource reference + * + * In some cases it's desirable to store various different types under + * one base type for memory efficiency reasons. To avoid putting the + * responsibility of proper casting on the user, the acquired resource + * can be defined to cast the type automatically when accessing the + * data. This is commonly used for shaders, e.g.: + * @code + * Resource shader = manager->get("shader"); + * @endcode + */ + template inline Resource get(ResourceKey key) { + return this->Implementation::ResourceManagerData::template get(key); + } + + /** + * @brief Reference count of given resource + * + * @see set() + */ + template inline std::size_t referenceCount(ResourceKey key) const { + return this->Implementation::ResourceManagerData::referenceCount(key); + } + + /** + * @brief %Resource state + * + * @see set(), Resource::state() + */ + template inline ResourceState state(ResourceKey key) const { + return this->Implementation::ResourceManagerData::state(key); + } + + /** + * @brief Set resource data + * + * If @p policy is set to `ResourcePolicy::ReferenceCounted`, there + * must be already at least one reference to given resource, otherwise + * the data will be deleted immediately and no resource will be + * added. To avoid spending unnecessary loading time, add + * reference-counted resources only if they are already referenced: + * @code + * if(manager.referenceCount("myresource")) { + * // load data... + * manager.set("myresource", data, state, ResourcePolicy::ReferenceCounted); + * } + * @endcode + * @attention If resource state is already `ResourceState::Final`, + * subsequent updates are not possible. + * @see referenceCount(), state() + */ + template inline void set(ResourceKey key, T* data, ResourceDataState state, ResourcePolicy policy) { + this->Implementation::ResourceManagerData::set(key, data, state, policy); + } + + /** @brief Set fallback for not found resources */ + template inline void setFallback(T* data) { + return this->Implementation::ResourceManagerData::setFallback(data); + } + + /** @brief Free all resources of given type which are not referenced */ + template inline void free() { + return this->Implementation::ResourceManagerData::free(); + } + + /** @brief Free all resources which are not referenced */ + inline void free() { + freeInternal(std::common_type()...); + } + + private: + template inline void freeInternal(std::common_type, std::common_type... t) { + free(); + freeInternal(t...); + } + inline void freeInternal() const {} + + static ResourceManager* _instance; +}; + +/** @debugoperator{Magnum::ResourceKey} */ +template Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const ResourceKey& value) { + return debug << static_cast&>(value); +} + +template ResourceManager* ResourceManager::_instance(nullptr); + +} + +#endif diff --git a/src/SceneGraph/Camera.cpp b/src/SceneGraph/Camera.cpp index 7b8e7d83c..d51a9ff7b 100644 --- a/src/SceneGraph/Camera.cpp +++ b/src/SceneGraph/Camera.cpp @@ -14,7 +14,6 @@ */ #include "Camera.h" -#include "Framebuffer.h" #include "Scene.h" using namespace std; @@ -33,7 +32,7 @@ template MatrixType aspectRatioFix(AspectRatioPolicy aspectRat /* Extend on larger side = scale larger side down Clip on smaller side = scale smaller side up */ - return Camera::aspectRatioScale( + return Camera::aspectRatioScale( (relativeAspectRatio.x() > relativeAspectRatio.y()) == (aspectRatioPolicy == AspectRatioPolicy::Extend) ? Vector2(relativeAspectRatio.y()/relativeAspectRatio.x(), 1.0f) : Vector2(1.0f, relativeAspectRatio.x()/relativeAspectRatio.y())); @@ -46,50 +45,53 @@ template Matrix4 aspectRatioFix(AspectRatioPolicy, const Vector2&, cons } #endif -template Camera::Camera(ObjectType* parent): ObjectType(parent), _aspectRatioPolicy(AspectRatioPolicy::NotPreserved) {} +template AbstractCamera::AbstractCamera(typename AbstractObject::ObjectType* parent): AbstractObject::ObjectType(parent), _aspectRatioPolicy(AspectRatioPolicy::NotPreserved) {} -template void Camera::setViewport(const Math::Vector2& size) { - Framebuffer::setViewport(Math::Vector2{0, 0}, size); +template typename AbstractObject::CameraType* AbstractCamera::setAspectRatioPolicy(AspectRatioPolicy policy) { + _aspectRatioPolicy = policy; + fixAspectRatio(); + return static_cast::CameraType*>(this); +} +template void AbstractCamera::setViewport(const Math::Vector2& size) { _viewport = size; fixAspectRatio(); } -template void Camera::clean(const MatrixType& absoluteTransformation) { - ObjectType::clean(absoluteTransformation); +template void AbstractCamera::clean(const typename DimensionTraits::MatrixType& absoluteTransformation) { + AbstractObject::ObjectType::clean(absoluteTransformation); _cameraMatrix = absoluteTransformation.inverted(); } -template void Camera::draw() { - SceneType* s = this->scene(); +template void AbstractCamera::draw() { + typename AbstractObject::SceneType* s = this->scene(); CORRADE_ASSERT(s, "Camera: cannot draw without camera attached to scene", ); - Framebuffer::clear(); - /* Recursively draw child objects */ drawChildren(s, cameraMatrix()); } -template void Camera::drawChildren(ObjectType* object, const MatrixType& transformationMatrix) { - for(ObjectType* i = object->firstChild(); i; i = i->nextSibling()) { +template void AbstractCamera::drawChildren(typename AbstractObject::ObjectType* object, const typename DimensionTraits::MatrixType& transformationMatrix) { + for(typename AbstractObject::ObjectType* i = object->firstChild(); i; i = i->nextSibling()) { /* Transformation matrix for the object */ - MatrixType matrix = transformationMatrix*i->transformation(); + typename DimensionTraits::MatrixType matrix = transformationMatrix*i->transformation(); /* Draw the object and its children */ - i->draw(matrix, static_cast(this)); + i->draw(matrix, static_cast::CameraType*>(this)); drawChildren(i, matrix); } } -void Camera2D::setProjection(const Vector2& size) { +Camera2D* Camera2D::setProjection(const Vector2& size) { /* Scale the volume down so it fits in (-1, 1) in all directions */ rawProjectionMatrix = Matrix3::scaling(2.0f/size); fixAspectRatio(); + return this; } -void Camera3D::setOrthographic(const Vector2& size, GLfloat near, GLfloat far) { +Camera3D* Camera3D::setOrthographic(const Vector2& size, GLfloat near, GLfloat far) { _near = near; _far = far; @@ -104,9 +106,10 @@ void Camera3D::setOrthographic(const Vector2& size, GLfloat near, GLfloat far) { ); fixAspectRatio(); + return this; } -void Camera3D::setPerspective(GLfloat fov, GLfloat near, GLfloat far) { +Camera3D* Camera3D::setPerspective(GLfloat fov, GLfloat near, GLfloat far) { _near = near; _far = far; @@ -121,10 +124,11 @@ void Camera3D::setPerspective(GLfloat fov, GLfloat near, GLfloat far) { ); fixAspectRatio(); + return this; } /* Explicitly instantiate the templates */ -template class Camera; -template class Camera; +template class AbstractCamera<2>; +template class AbstractCamera<3>; }} diff --git a/src/SceneGraph/Camera.h b/src/SceneGraph/Camera.h index 2c29bd7f8..69427db5c 100644 --- a/src/SceneGraph/Camera.h +++ b/src/SceneGraph/Camera.h @@ -16,7 +16,7 @@ */ /** @file - * @brief Class Magnum::SceneGraph::Camera, Magnum::SceneGraph::Camera2D, Magnum::SceneGraph::Camera3D + * @brief Class Magnum::SceneGraph::AbstractCamera, Magnum::SceneGraph::Camera2D, Magnum::SceneGraph::Camera3D */ #include "Object.h" @@ -36,8 +36,6 @@ namespace Implementation { NotPreserved, Extend, Clip }; - template class Camera {}; - template MatrixType aspectRatioFix(AspectRatioPolicy aspectRatioPolicy, const Vector2& projectionScale, const Math::Vector2& viewport); /* These templates are instantiated in source file */ @@ -49,7 +47,7 @@ namespace Implementation { /** @brief %Camera object */ -template class SCENEGRAPH_EXPORT Camera: public ObjectType { +template class SCENEGRAPH_EXPORT AbstractCamera: public AbstractObject::ObjectType { public: /** * @brief Aspect ratio policy @@ -66,14 +64,19 @@ template::ObjectType* parent = nullptr); + + virtual ~AbstractCamera() = 0; /** @brief Aspect ratio policy */ inline AspectRatioPolicy aspectRatioPolicy() const { return _aspectRatioPolicy; } - /** @brief Set aspect ratio policy */ - void setAspectRatioPolicy(AspectRatioPolicy policy) { _aspectRatioPolicy = policy; } + /** + * @brief Set aspect ratio policy + * @return Pointer to self (for method chaining) + */ + typename AbstractObject::CameraType* setAspectRatioPolicy(AspectRatioPolicy policy); /** * @brief Camera matrix @@ -81,7 +84,7 @@ template::MatrixType cameraMatrix() { this->setClean(); return _cameraMatrix; } @@ -93,7 +96,7 @@ template::MatrixType projectionMatrix() const { return _projectionMatrix; } /** * @brief Size of (near) XY plane in current projection @@ -102,7 +105,6 @@ template& size); /** * @brief Draw the scene * - * Calls Framebuffer::clear() and draws the scene using drawChildren(). + * Draws the scene using drawChildren(). */ virtual void draw(); - using ObjectType::draw; /* Don't hide Object's draw() */ + using AbstractObject::ObjectType::draw; /* Don't hide Object's draw() */ protected: /** * Recalculates camera matrix. */ - void clean(const MatrixType& absoluteTransformation); + void clean(const typename DimensionTraits::MatrixType& absoluteTransformation); /** * @brief Draw object children * * Recursively draws all children of the object. */ - void drawChildren(ObjectType* object, const MatrixType& transformationMatrix); + void drawChildren(typename AbstractObject::ObjectType* object, const typename DimensionTraits::MatrixType& transformationMatrix); #ifndef DOXYGEN_GENERATING_OUTPUT inline void fixAspectRatio() { - _projectionMatrix = Implementation::aspectRatioFix(_aspectRatioPolicy, {rawProjectionMatrix[0].x(), rawProjectionMatrix[1].y()}, _viewport)*rawProjectionMatrix; + _projectionMatrix = Implementation::aspectRatioFix::MatrixType>(_aspectRatioPolicy, {rawProjectionMatrix[0].x(), rawProjectionMatrix[1].y()}, _viewport)*rawProjectionMatrix; } - MatrixType rawProjectionMatrix; + typename DimensionTraits::MatrixType rawProjectionMatrix; AspectRatioPolicy _aspectRatioPolicy; #endif private: - MatrixType _projectionMatrix; - MatrixType _cameraMatrix; + typename DimensionTraits::MatrixType _projectionMatrix; + typename DimensionTraits::MatrixType _cameraMatrix; Math::Vector2 _viewport; }; -#ifndef DOXYGEN_GENERATING_OUTPUT -/* These templates are instantiated in source file */ -extern template class SCENEGRAPH_EXPORT Camera; -extern template class SCENEGRAPH_EXPORT Camera; +template inline AbstractCamera::~AbstractCamera() {} +#ifndef DOXYGEN_GENERATING_OUTPUT namespace Implementation { + template class Camera {}; + template<> class Camera<2> { public: inline constexpr static Matrix3 aspectRatioScale(const Vector2& scale) { @@ -178,8 +179,12 @@ namespace Implementation { } #endif -/** @brief %Camera for two-dimensional scenes */ -class SCENEGRAPH_EXPORT Camera2D: public Camera { +/** +@brief %Camera for two-dimensional scenes + +@see Camera3D +*/ +class SCENEGRAPH_EXPORT Camera2D: public AbstractCamera<2> { public: /** * @brief Constructor @@ -188,20 +193,25 @@ class SCENEGRAPH_EXPORT Camera2D: public Camera { +/** +@brief %Camera for three-dimensional scenes + +@see Camera2D +*/ +class SCENEGRAPH_EXPORT Camera3D: public AbstractCamera<3> { public: /** * @brief Constructor @@ -210,28 +220,30 @@ class SCENEGRAPH_EXPORT Camera3D: public Camera ObjectType* Object::setParent(ObjectType* parent) { +template typename AbstractObject::ObjectType* AbstractObject::setParent(ObjectType* parent) { /* Skip if nothing to do or this is scene */ if(this->parent() == parent || isScene()) return static_cast(this); @@ -49,11 +49,11 @@ template(this); } -template MatrixType Object::absoluteTransformation(CameraType* camera) { +template typename DimensionTraits::MatrixType AbstractObject::absoluteTransformation(CameraType* camera) { /* Shortcut for absolute transformation of camera relative to itself */ - if(camera == this) return MatrixType(); + if(camera == this) return typename DimensionTraits::MatrixType(); - MatrixType t = _transformation; + typename DimensionTraits::MatrixType t = _transformation; ObjectType* p = parent(); while(p != nullptr) { @@ -77,7 +77,7 @@ template SceneType* Object::scene() { +template typename AbstractObject::SceneType* AbstractObject::scene() { /* Goes up the family tree until it finds object which is parent of itself (that's the scene) */ ObjectType* p = parent(); @@ -89,7 +89,7 @@ template ObjectType* Object::setTransformation(const MatrixType& transformation) { +template typename AbstractObject::ObjectType* AbstractObject::setTransformation(const typename DimensionTraits::MatrixType& transformation) { /* Setting transformation is forbidden for the scene */ /** @todo Assert for this? */ if(isScene()) return static_cast(this); @@ -99,7 +99,7 @@ template(this); } -template void Object::setDirty() { +template void AbstractObject::setDirty() { /* The object (and all its children) are already dirty, nothing to do */ if(dirty) return; @@ -110,7 +110,7 @@ templatesetDirty(); } -template void Object::setClean() { +template void AbstractObject::setClean() { /* The object (and all its parents) are already clean, nothing to do */ if(!dirty) return; @@ -130,7 +130,7 @@ templateabsoluteTransformation(); + typename DimensionTraits::MatrixType absoluteTransformation = o->absoluteTransformation(); o->clean(absoluteTransformation); while(!objects.empty()) { o = objects.top(); @@ -141,7 +141,7 @@ template; -template class Object; +template class AbstractObject<2>; +template class AbstractObject<3>; }} diff --git a/src/SceneGraph/Object.h b/src/SceneGraph/Object.h index b6a0d3861..86d10a5a0 100644 --- a/src/SceneGraph/Object.h +++ b/src/SceneGraph/Object.h @@ -16,17 +16,46 @@ */ /** @file - * @brief Class Magnum::SceneGraph::Object, Magnum::SceneGraph::Object2D, Magnum::SceneGraph::Object3D + * @brief Class Magnum::SceneGraph::AbstractObject, Magnum::SceneGraph::Object2D, Magnum::SceneGraph::Object3D */ #include +#include "Math/Matrix3.h" +#include "Math/Matrix4.h" #include "Magnum.h" +#include "DimensionTraits.h" #include "magnumSceneGraphVisibility.h" namespace Magnum { namespace SceneGraph { +class Camera2D; +class Camera3D; +class Object2D; +class Object3D; +template class Scene; +typedef Scene<2> Scene2D; +typedef Scene<3> Scene3D; + +#ifndef DOXYGEN_GENERATING_OUTPUT +namespace Implementation { + template struct ObjectDimensionTraits {}; + + template<> struct ObjectDimensionTraits<2> { + typedef Object2D ObjectType; + typedef Camera2D CameraType; + typedef Scene2D SceneType; + }; + + template<> struct ObjectDimensionTraits<3> { + typedef Object3D ObjectType; + typedef Camera3D CameraType; + typedef Scene3D SceneType; + }; +} +#endif + /** @todo User-specified Object implementation: - for front-to-back sorting, LoD changes etc. @@ -38,27 +67,38 @@ namespace Magnum { namespace SceneGraph { */ /** - * @brief Base for all positioned objects - * - * @todo Transform transformation when changing parent, so the object stays in - * place. +@brief Base for all positioned objects + +@todo Transform transformation when changing parent, so the object stays in +place. */ -template class SCENEGRAPH_EXPORT Object: public Corrade::Containers::LinkedList, public Corrade::Containers::LinkedListItem { +template class SCENEGRAPH_EXPORT AbstractObject: public Corrade::Containers::LinkedList::ObjectType>, public Corrade::Containers::LinkedListItem::ObjectType, typename Implementation::ObjectDimensionTraits::ObjectType> { #ifndef DOXYGEN_GENERATING_OUTPUT - Object(const Object& other) = delete; - Object(Object&& other) = delete; - Object& operator=(const Object& other) = delete; - Object& operator=(Object&& other) = delete; + AbstractObject(const AbstractObject& other) = delete; + AbstractObject(AbstractObject&& other) = delete; + AbstractObject& operator=(const AbstractObject& other) = delete; + AbstractObject& operator=(AbstractObject&& other) = delete; #endif public: + static const std::uint8_t Dimensions = dimensions; /**< @brief %Object dimension count */ + + /** @brief %Object type for given dimension count */ + typedef typename Implementation::ObjectDimensionTraits::ObjectType ObjectType; + + /** @brief %Camera type for given dimension count */ + typedef typename Implementation::ObjectDimensionTraits::CameraType CameraType; + + /** @brief %Scene type for given dimension count */ + typedef typename Implementation::ObjectDimensionTraits::SceneType SceneType; + /** * @brief Constructor * @param parent Parent object * * Sets all transformations to their default values. */ - inline Object(ObjectType* parent = nullptr): dirty(true) { + inline AbstractObject(ObjectType* parent = nullptr): dirty(true) { setParent(parent); } @@ -68,7 +108,7 @@ template::last(); } - /** @brief Set parent object */ + /** + * @brief Set parent object + * @return Pointer to self (for method chaining) + */ ObjectType* setParent(ObjectType* parent); /*@}*/ @@ -120,7 +163,7 @@ template::MatrixType transformation() const { return _transformation; } @@ -135,17 +178,21 @@ template::MatrixType absoluteTransformation(CameraType* camera = nullptr); - /** @brief Set transformation */ - ObjectType* setTransformation(const MatrixType& transformation); + /** + * @brief Set transformation + * @return Pointer to self (for method chaining) + */ + ObjectType* setTransformation(const typename DimensionTraits::MatrixType& transformation); /** * @brief Multiply transformation * @param transformation Transformation * @param type Transformation type + * @return Pointer to self (for method chaining) */ - inline ObjectType* multiplyTransformation(const MatrixType& transformation, Transformation type = Transformation::Global) { + inline ObjectType* multiplyTransformation(const typename DimensionTraits::MatrixType& transformation, Transformation type = Transformation::Global) { setTransformation(type == Transformation::Global ? transformation*_transformation : _transformation*transformation); return static_cast(this); @@ -162,7 +209,7 @@ template::MatrixType& transformationMatrix, CameraType* camera); /** @{ @name Caching helpers * @@ -237,7 +284,7 @@ template::MatrixType& absoluteTransformation); /*@}*/ @@ -255,36 +302,29 @@ template::previous; using Corrade::Containers::LinkedListItem::next; - MatrixType _transformation; + typename DimensionTraits::MatrixType _transformation; bool dirty; }; -/* Implementations for inline functions with unused parameters */ -template inline void Object::draw(const MatrixType&, CameraType*) {} -template inline void Object::clean(const MatrixType&) { dirty = false; } +template inline AbstractObject::~AbstractObject() {} -class Camera2D; -class Camera3D; -class Object2D; -class Object3D; -template class Scene; -typedef Scene Scene2D; -typedef Scene Scene3D; +/* Implementations for inline functions with unused parameters */ +template inline void AbstractObject::draw(const typename DimensionTraits::MatrixType&, CameraType*) {} +template inline void AbstractObject::clean(const typename DimensionTraits::MatrixType&) { dirty = false; } -#ifndef DOXYGEN_GENERATING_OUTPUT -/* These templates are instantiated in source file */ -extern template class SCENEGRAPH_EXPORT Object; -extern template class SCENEGRAPH_EXPORT Object; -#endif +/** +@brief Two-dimensional object -/** @brief Two-dimensional object */ -class SCENEGRAPH_EXPORT Object2D: public Object { +@see Object3D +*/ +class SCENEGRAPH_EXPORT Object2D: public AbstractObject<2> { public: - /** @copydoc Object::Object */ - inline Object2D(Object2D* parent = nullptr): Object(parent) {} + /** @copydoc AbstractObject::AbstractObject() */ + inline Object2D(Object2D* parent = nullptr): AbstractObject(parent) {} /** * @brief Translate object + * @return Pointer to self (for method chaining) * * Same as calling multiplyTransformation() with Matrix3::translation(). */ @@ -295,6 +335,7 @@ class SCENEGRAPH_EXPORT Object2D: public ObjectCorrade::Containers::LinkedList::move(this, under); @@ -324,14 +367,19 @@ class SCENEGRAPH_EXPORT Object2D: public Object { +/** +@brief Three-dimensional object + +@see Object2D +*/ +class SCENEGRAPH_EXPORT Object3D: public AbstractObject<3> { public: - /** @copydoc Object::Object */ - inline Object3D(Object3D* parent = nullptr): Object(parent) {} + /** @copydoc AbstractObject::AbstractObject() */ + inline Object3D(Object3D* parent = nullptr): AbstractObject(parent) {} /** * @brief Translate object + * @return Pointer to self (for method chaining) * * Same as calling multiplyTransformation() with Matrix4::translation(). */ @@ -342,6 +390,7 @@ class SCENEGRAPH_EXPORT Object3D: public Object class SCENEGRAPH_EXPORT Scene: public ObjectType { +/** +@brief %Scene + +@see Scene2D, Scene3D +*/ +template class SCENEGRAPH_EXPORT Scene: public AbstractObject::ObjectType { public: - /** @copydoc Object::isScene() */ + /** @copydoc AbstractObject::isScene() */ inline bool isScene() const { return true; } /** @todo Some deleted functions belong only to Scene2D, some only to Scene3D - what to do? */ #ifndef DOXYGEN_GENERATING_OUTPUT - void setParent(ObjectType* parent) = delete; - void setTransformation(const MatrixType& transformation) = delete; - void multiplyTransformation(const MatrixType& transformation, typename ObjectType::Transformation type = ObjectType::Transformation::Global) = delete; - void translate(const VectorType& vec, typename ObjectType::Transformation type = ObjectType::Transformation::Global) = delete; - void scale(const VectorType& vec, typename ObjectType::Transformation type = ObjectType::Transformation::Global) = delete; - void rotate(GLfloat angle, const VectorType& vec, typename ObjectType::Transformation type = ObjectType::Transformation::Global) = delete; + void setParent(typename AbstractObject::ObjectType* parent) = delete; + void setTransformation(const typename DimensionTraits::MatrixType& transformation) = delete; + void multiplyTransformation(const typename DimensionTraits::MatrixType& transformation, typename AbstractObject::Transformation type = (DimensionTraits::Transformation::Global)) = delete; + void translate(const typename DimensionTraits::VectorType& vec, typename AbstractObject::Transformation type = AbstractObject::Transformation::Global) = delete; + void scale(const typename DimensionTraits::VectorType& vec, typename AbstractObject::Transformation type = AbstractObject::Transformation::Global) = delete; + void rotate(GLfloat angle, const typename DimensionTraits::VectorType& vec, typename AbstractObject::Transformation type = AbstractObject::Transformation::Global) = delete; #endif private: - inline void draw(const MatrixType&, CameraType*) {} + inline void draw(const typename DimensionTraits::MatrixType&, typename AbstractObject::CameraType*) {} }; /** @brief Two-dimensional scene */ -typedef Scene Scene2D; +typedef Scene<2> Scene2D; /** @brief Three-dimensional scene */ -typedef Scene Scene3D; +typedef Scene<3> Scene3D; }} diff --git a/src/SceneGraph/Test/CameraTest.cpp b/src/SceneGraph/Test/CameraTest.cpp index 40dbcfa32..f7a111cf1 100644 --- a/src/SceneGraph/Test/CameraTest.cpp +++ b/src/SceneGraph/Test/CameraTest.cpp @@ -15,6 +15,7 @@ #include "CameraTest.h" +#include "Math/Constants.h" #include "SceneGraph/Camera.h" CORRADE_TEST_MAIN(Magnum::SceneGraph::Test::CameraTest) @@ -27,7 +28,8 @@ CameraTest::CameraTest() { &CameraTest::defaultProjection3D, &CameraTest::projection2D, &CameraTest::orthographic, - &CameraTest::perspective); + &CameraTest::perspective, + &CameraTest::projectionSizeViewport); } void CameraTest::fixAspectRatio() { @@ -135,4 +137,16 @@ void CameraTest::perspective() { CORRADE_COMPARE(camera.projectionSize(), Vector2(0.48015756f)); } +void CameraTest::projectionSizeViewport() { + Camera3D camera; + camera.setViewport({200, 300}); + CORRADE_COMPARE(camera.projectionSize(), Vector2(2.0f, 2.0f)); + + camera.setAspectRatioPolicy(Camera3D::AspectRatioPolicy::Extend); + CORRADE_COMPARE(camera.projectionSize(), Vector2(2.0f, 3.0f)); + + camera.setAspectRatioPolicy(Camera3D::AspectRatioPolicy::Clip); + CORRADE_COMPARE(camera.projectionSize(), Vector2(4.0f/3.0f, 2.0f)); +} + }}} diff --git a/src/SceneGraph/Test/CameraTest.h b/src/SceneGraph/Test/CameraTest.h index 2bf0e93b5..2ada59d3b 100644 --- a/src/SceneGraph/Test/CameraTest.h +++ b/src/SceneGraph/Test/CameraTest.h @@ -29,6 +29,7 @@ class CameraTest: public Corrade::TestSuite::Tester { void projection2D(); void orthographic(); void perspective(); + void projectionSizeViewport(); }; }}} diff --git a/src/SceneGraph/Test/ObjectTest.cpp b/src/SceneGraph/Test/ObjectTest.cpp index 77f5a7afa..c838704f8 100644 --- a/src/SceneGraph/Test/ObjectTest.cpp +++ b/src/SceneGraph/Test/ObjectTest.cpp @@ -14,11 +14,13 @@ */ #include "ObjectTest.h" -#include "SceneGraph/Camera.h" -#include "SceneGraph/Scene.h" #include +#include "Math/Constants.h" +#include "SceneGraph/Camera.h" +#include "SceneGraph/Scene.h" + using namespace std; CORRADE_TEST_MAIN(Magnum::SceneGraph::Test::ObjectTest) diff --git a/src/Shader.cpp b/src/Shader.cpp index 6646b2d47..ea4004814 100644 --- a/src/Shader.cpp +++ b/src/Shader.cpp @@ -16,6 +16,7 @@ #include "Shader.h" #include +#include #define COMPILER_MESSAGE_MAX_LENGTH 1024 @@ -28,6 +29,29 @@ using namespace std; namespace Magnum { +Shader::Shader(Version version, Type type): _type(type), _state(State::Initialized), shader(0) { + shader = glCreateShader(static_cast(_type)); + + switch(version) { + #ifndef MAGNUM_TARGET_GLES + case Version::GL210: addSource("#version 120\n"); break; + case Version::GL300: addSource("#version 130\n"); break; + case Version::GL310: addSource("#version 140\n"); break; + case Version::GL320: addSource("#version 150\n"); break; + case Version::GL330: addSource("#version 330\n"); break; + case Version::GL400: addSource("#version 400\n"); break; + case Version::GL410: addSource("#version 410\n"); break; + case Version::GL420: addSource("#version 420\n"); break; + case Version::GL430: addSource("#version 430\n"); break; + #else + case Version::GLES200: addSource("#version 100\n"); break; + case Version::GLES300: addSource("#version 300\n"); break; + #endif + + default: break; + } +} + Shader::Shader(Shader&& other): _type(other._type), _state(other._state), sources(other.sources), shader(other.shader) { other.shader = 0; } @@ -105,12 +129,11 @@ GLuint Shader::compile() { case Type::Vertex: err << "vertex"; break; #ifndef MAGNUM_TARGET_GLES case Type::Geometry: err << "geometry"; break; - #endif - case Type::Fragment: err << "fragment"; break; - #ifndef MAGNUM_TARGET_GLES case Type::TessellationControl: err << "tessellation control"; break; case Type::TessellationEvaluation: err << "tessellation evaluation"; break; + case Type::Compute: err << "compute"; break; #endif + case Type::Fragment: err << "fragment"; break; } /* Show error log and delete shader */ diff --git a/src/Shader.h b/src/Shader.h index cdb19b456..643674b77 100644 --- a/src/Shader.h +++ b/src/Shader.h @@ -19,11 +19,14 @@ * @brief Class Magnum::Shader */ -#include "Magnum.h" - #include #include +#include "Magnum.h" +#include "Context.h" + +#include "magnumVisibility.h" + namespace Magnum { /** @@ -45,24 +48,31 @@ class MAGNUM_EXPORT Shader { #ifndef MAGNUM_TARGET_GLES /** * Tessellation control shader - * @requires_gl * @requires_gl40 Extension @extension{ARB,tessellation_shader} + * @requires_gl Tessellation shaders are not available in OpenGL ES. */ TessellationControl = GL_TESS_CONTROL_SHADER, /** * Tessellation evaluation shader - * @requires_gl * @requires_gl40 Extension @extension{ARB,tessellation_shader} + * @requires_gl Tessellation shaders are not available in OpenGL ES. */ TessellationEvaluation = GL_TESS_EVALUATION_SHADER, /** * Geometry shader - * @requires_gl * @requires_gl32 Extension @extension{ARB,geometry_shader4} + * @requires_gl Geometry shaders are not available in OpenGL ES. */ Geometry = GL_GEOMETRY_SHADER, + + /** + * Compute shader + * @requires_gl43 Extension @extension{ARB,compute_shader} + * @requires_gl Compute shaders are not available in OpenGL ES. + */ + Compute = GL_COMPUTE_SHADER, #endif Fragment = GL_FRAGMENT_SHADER /**< Fragment shader */ @@ -77,59 +87,62 @@ class MAGNUM_EXPORT Shader { /** * @brief Load shader from source + * @param version Target version * @param type %Shader type * @param source %Shader source * @return Shader instance * * Loads the shader from one source. Shorthand for * @code - * Shader s(type); + * Shader s(version, type); * s.addData(data); * @endcode * Note that it is also possible to create shader from more than one * source. */ - inline static Shader fromData(Type type, const std::string& source) { - Shader s(type); + inline static Shader fromData(Version version, Type type, const std::string& source) { + Shader s(version, type); s.addSource(source); return s; } /** * @brief Load shader from file + * @param version Target version * @param type %Shader type - * @param filename %Source filename + * @param filename Source filename * @return Shader instance * * Loads the shader from from one file. Shorthand for * @code - * Shader s(type); + * Shader s(version, type); * s.addFile(filename); * @endcode * Note that it is also possible to create shader from more than one * source. */ - inline static Shader fromFile(Type type, const char* filename) { - Shader s(type); + inline static Shader fromFile(Version version, Type type, const char* filename) { + Shader s(version, type); s.addFile(filename); return s; } /** * @brief Constructor + * @param version Target version + * @param type %Shader type * - * Creates empty OpenGL shader. Sources can be added with addSource() - * or addFile(). - * @see fromData(), fromFile() + * Creates empty OpenGL shader and adds @c \#version directive at the + * beginning. Sources can be added with addSource() or addFile(). + * @see fromData(), fromFile(), @fn_gl{CreateShader} */ - inline Shader(Type type): _type(type), _state(State::Initialized), shader(0) { - shader = glCreateShader(static_cast(_type)); - } + Shader(Version version, Type type); /** * @brief Destructor * * Deletes associated OpenGL shader. + * @see @fn_gl{DeleteShader} */ inline ~Shader() { if(shader) glDeleteShader(shader); } @@ -183,7 +196,9 @@ class MAGNUM_EXPORT Shader { * before, it tries to compile it. If compilation fails or no sources * are present, returns 0. If the shader was compiled already, returns * already existing shader. - * @see state() + * @see state(), @fn_gl{ShaderSource}, @fn_gl{CompileShader}, + * @fn_gl{GetShader} with @def_gl{COMPILE_STATUS}, + * @fn_gl{GetShaderInfoLog} */ GLuint compile(); diff --git a/src/Shaders/CMakeLists.txt b/src/Shaders/CMakeLists.txt index 020acb2b7..926bc6238 100644 --- a/src/Shaders/CMakeLists.txt +++ b/src/Shaders/CMakeLists.txt @@ -1,8 +1,13 @@ -corrade_add_resource(MagnumShaders_RCS MagnumShaders PhongShader.frag PhongShader.vert) +corrade_add_resource(MagnumShaders_RCS MagnumShaders + FlatShader2D.vert FlatShader2D.frag + PhongShader.frag PhongShader.vert + compatibility.glsl) set(MagnumShaders_SRCS + FlatShader.cpp PhongShader.cpp ${MagnumShaders_RCS}) set(MagnumShaders_HEADERS + FlatShader.h PhongShader.h magnumShadersVisibility.h) diff --git a/src/Shaders/FlatShader.cpp b/src/Shaders/FlatShader.cpp new file mode 100644 index 000000000..69d15c3a0 --- /dev/null +++ b/src/Shaders/FlatShader.cpp @@ -0,0 +1,75 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "FlatShader.h" + +#include + +#include "Extensions.h" +#include "Shader.h" + +namespace Magnum { namespace Shaders { + +namespace { + template struct ShaderName {}; + + template<> struct ShaderName<2> { + constexpr static const char* Vertex = "FlatShader2D.vert"; + constexpr static const char* Fragment = "FlatShader2D.frag"; + }; + + template<> struct ShaderName<3> { + constexpr static const char* Vertex = "FlatShader3D.vert"; + constexpr static const char* Fragment = "FlatShader3D.frag"; + }; +} + +template FlatShader::FlatShader() { + Corrade::Utility::Resource rs("MagnumShaders"); + + #ifndef MAGNUM_TARGET_GLES + Version v = Context::current()->supportedVersion({/*Version::GL320, */Version::GL210}); + #else + Version v = Context::current()->supportedVersion({Version::GLES300, Version::GLES200}); + #endif + + Shader vertexShader(v, Shader::Type::Vertex); + vertexShader.addSource(rs.get("compatibility.glsl")); + vertexShader.addSource(rs.get(ShaderName::Vertex)); + attachShader(vertexShader); + + Shader fragmentShader(v, Shader::Type::Fragment); + fragmentShader.addSource(rs.get("compatibility.glsl")); + fragmentShader.addSource(rs.get(ShaderName::Fragment)); + attachShader(fragmentShader); + + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) { + #else + if(!Context::current()->isVersionSupported(Version::GLES300)) { + #endif + bindAttributeLocation(Position::Location, "position"); + } + + link(); + + transformationProjectionUniform = uniformLocation("transformationProjection"); + colorUniform = uniformLocation("color"); +} + +template class FlatShader<2>; +template class FlatShader<3>; + +}} diff --git a/src/Shaders/FlatShader.h b/src/Shaders/FlatShader.h new file mode 100644 index 000000000..bbdca99e5 --- /dev/null +++ b/src/Shaders/FlatShader.h @@ -0,0 +1,76 @@ +#ifndef Magnum_Shaders_FlatShader_h +#define Magnum_Shaders_FlatShader_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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. +*/ + +/** @file + * @brief Class Magnum::Shaders::FlatShader + */ + +#include "Math/Matrix3.h" +#include "Math/Matrix4.h" +#include "AbstractShaderProgram.h" +#include "Color.h" +#include "DimensionTraits.h" + +#include "magnumShadersVisibility.h" + +namespace Magnum { namespace Shaders { + +/** +@brief Flat shader + +Draws whole mesh with one color. +@see FlatShader2D, FlatShader3D +*/ +template class SHADERS_EXPORT FlatShader: public AbstractShaderProgram { + public: + /** @brief Vertex position */ + typedef Attribute<0, typename DimensionTraits::PointType> Position; + + FlatShader(); + + /** + * @brief Set transformation and projection matrix + * @return Pointer to self (for method chaining) + */ + FlatShader* setTransformationProjection(const typename DimensionTraits::MatrixType& matrix) { + setUniform(transformationProjectionUniform, matrix); + return this; + } + + /** + * @brief Set color + * @return Pointer to self (for method chaining) + */ + FlatShader* setColor(const Color3& color) { + setUniform(colorUniform, color); + return this; + } + + private: + GLint transformationProjectionUniform, + colorUniform; +}; + +/** @brief 2D flat shader */ +typedef FlatShader<2> FlatShader2D; + +/** @brief 3D flat shader */ +typedef FlatShader<3> FlatShader3D; + +}} + +#endif diff --git a/src/Shaders/FlatShader2D.frag b/src/Shaders/FlatShader2D.frag new file mode 100644 index 000000000..bdc52dd38 --- /dev/null +++ b/src/Shaders/FlatShader2D.frag @@ -0,0 +1,13 @@ +#ifndef NEW_GLSL +#define fragmentColor gl_FragColor +#endif + +uniform vec3 color; + +#ifndef NEW_GLSL +out vec4 fragmentColor; +#endif + +void main() { + fragmentColor = vec4(color, 1.0); +} diff --git a/src/Shaders/FlatShader2D.vert b/src/Shaders/FlatShader2D.vert new file mode 100644 index 000000000..60355d131 --- /dev/null +++ b/src/Shaders/FlatShader2D.vert @@ -0,0 +1,15 @@ +#ifndef NEW_GLSL +#define in attribute +#endif + +uniform mat3 transformationProjection; + +#ifdef EXPLICIT_ATTRIB_LOCATION +layout(location = 0) in vec3 position; +#else +in vec3 position; +#endif + +void main() { + gl_Position.xywz = vec4(transformationProjection*position, 0.0); +} diff --git a/src/Shaders/PhongShader.cpp b/src/Shaders/PhongShader.cpp index 378a3e664..394243dcb 100644 --- a/src/Shaders/PhongShader.cpp +++ b/src/Shaders/PhongShader.cpp @@ -17,12 +17,38 @@ #include +#include "Extensions.h" +#include "Shader.h" + namespace Magnum { namespace Shaders { PhongShader::PhongShader() { Corrade::Utility::Resource rs("MagnumShaders"); - attachShader(Shader::fromData(Shader::Type::Vertex, rs.get("PhongShader.vert"))); - attachShader(Shader::fromData(Shader::Type::Fragment, rs.get("PhongShader.frag"))); + + #ifndef MAGNUM_TARGET_GLES + Version v = Context::current()->supportedVersion({Version::GL320, Version::GL210}); + #else + Version v = Context::current()->supportedVersion({Version::GLES300, Version::GLES200}); + #endif + + Shader vertexShader(v, Shader::Type::Vertex); + vertexShader.addSource(rs.get("compatibility.glsl")); + vertexShader.addSource(rs.get("PhongShader.vert")); + attachShader(vertexShader); + + Shader fragmentShader(v, Shader::Type::Fragment); + fragmentShader.addSource(rs.get("compatibility.glsl")); + fragmentShader.addSource(rs.get("PhongShader.frag")); + attachShader(fragmentShader); + + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) { + #else + if(!Context::current()->isVersionSupported(Version::GLES300)) { + #endif + bindAttributeLocation(Position::Location, "position"); + bindAttributeLocation(Normal::Location, "normal"); + } link(); diff --git a/src/Shaders/PhongShader.frag b/src/Shaders/PhongShader.frag index 230af1736..638a1e3fa 100644 --- a/src/Shaders/PhongShader.frag +++ b/src/Shaders/PhongShader.frag @@ -1,4 +1,7 @@ -#version 330 +#ifndef NEW_GLSL +#define in varying +#define color gl_FragColor +#endif uniform vec3 ambientColor = vec3(0.0, 0.0, 0.0); uniform vec3 diffuseColor; @@ -10,7 +13,9 @@ in vec3 transformedNormal; in vec3 lightDirection; in vec3 cameraDirection; +#ifdef NEW_GLSL out vec4 color; +#endif void main() { /* Ambient color */ diff --git a/src/Shaders/PhongShader.h b/src/Shaders/PhongShader.h index ceb79af6b..5662c8f34 100644 --- a/src/Shaders/PhongShader.h +++ b/src/Shaders/PhongShader.h @@ -19,7 +19,10 @@ * @brief Class Magnum::Shaders::PhongShader */ +#include "Math/Matrix4.h" #include "AbstractShaderProgram.h" +#include "Color.h" + #include "magnumShadersVisibility.h" namespace Magnum { namespace Shaders { @@ -27,72 +30,95 @@ namespace Magnum { namespace Shaders { /** @brief Phong shader -@requires_gl33 The shader is written in GLSL 3.3, although it should be trivial - to port it to older versions. +If supported, uses GLSL 3.20 and @extension{ARB,explicit_attrib_location}, +otherwise falls back to GLSL 1.20. */ class SHADERS_EXPORT PhongShader: public AbstractShaderProgram { public: - typedef Attribute<0, Vector4> Vertex; /**< @brief Vertex position */ + typedef Attribute<0, Point3D> Position; /**< @brief Vertex position */ typedef Attribute<1, Vector3> Normal; /**< @brief Normal direction */ - /** @brief Constructor */ PhongShader(); /** - * @brief %Ambient color + * @brief Set ambient color + * @return Pointer to self (for method chaining) * * If not set, default value is `(0.0f, 0.0f, 0.0f)`. */ - inline void setAmbientColorUniform(const Vector3& color) { + inline PhongShader* setAmbientColor(const Color3& color) { setUniform(ambientColorUniform, color); + return this; } - /** @brief Diffuse color */ - inline void setDiffuseColorUniform(const Vector3& color) { + /** + * @brief Set diffuse color + * @return Pointer to self (for method chaining) + */ + inline PhongShader* setDiffuseColor(const Color3& color) { setUniform(diffuseColorUniform, color); + return this; } /** - * @brief Specular color + * @brief Set specular color + * @return Pointer to self (for method chaining) * * If not set, default value is `(1.0f, 1.0f, 1.0f)`. */ - inline void setSpecularColorUniform(const Vector3& color) { + inline PhongShader* setSpecularColor(const Color3& color) { setUniform(specularColorUniform, color); + return this; } /** - * @brief Shininess + * @brief Set shininess + * @return Pointer to self (for method chaining) * * The larger value, the harder surface (smaller specular highlight). * If not set, default value is `80.0f`. */ - inline void setShininessUniform(GLfloat shininess) { + inline PhongShader* setShininess(GLfloat shininess) { setUniform(shininessUniform, shininess); + return this; } - /** @brief Transformation matrix */ - inline void setTransformationMatrixUniform(const Matrix4& matrix) { + /** + * @brief Set transformation matrix + * @return Pointer to self (for method chaining) + */ + inline PhongShader* setTransformation(const Matrix4& matrix) { setUniform(transformationMatrixUniform, matrix); + return this; } - /** @brief Projection matrix */ - inline void setProjectionMatrixUniform(const Matrix4& matrix) { + /** + * @brief Set projection matrix + * @return Pointer to self (for method chaining) + */ + inline PhongShader* setProjection(const Matrix4& matrix) { setUniform(projectionMatrixUniform, matrix); + return this; } - /** @brief %Light position */ - inline void setLightUniform(const Vector3& light) { + /** + * @brief Set light position + * @return Pointer to self (for method chaining) + */ + inline PhongShader* setLightPosition(const Vector3& light) { setUniform(lightUniform, light); + return this; } /** - * @brief %Light color + * @brief Set light color + * @return Pointer to self (for method chaining) * * If not set, default value is `(1.0f, 1.0f, 1.0f)`. */ - inline void setLightColorUniform(const Vector3& color) { + inline PhongShader* setLightColor(const Color3& color) { setUniform(lightColorUniform, color); + return this; } private: diff --git a/src/Shaders/PhongShader.vert b/src/Shaders/PhongShader.vert index 19755516a..1c794cbce 100644 --- a/src/Shaders/PhongShader.vert +++ b/src/Shaders/PhongShader.vert @@ -1,11 +1,19 @@ -#version 330 +#ifndef NEW_GLSL +#define in attribute +#define out varying +#endif uniform mat4 transformationMatrix; uniform mat4 projectionMatrix; uniform vec3 light; -layout(location = 0) in vec4 vertex; +#ifdef EXPLICIT_ATTRIB_LOCATION +layout(location = 0) in vec4 position; layout(location = 1) in vec3 normal; +#else +in vec4 position; +in vec3 normal; +#endif out vec3 transformedNormal; out vec3 lightDirection; @@ -13,18 +21,18 @@ out vec3 cameraDirection; void main() { /* Transformed vertex position */ - vec4 transformedVertex4 = transformationMatrix*vertex; - vec3 transformedVertex = transformedVertex4.xyz/transformedVertex4.w; + vec4 transformedPosition4 = transformationMatrix*position; + vec3 transformedPosition = transformedPosition4.xyz/transformedPosition4.w; /* Transformed normal vector */ transformedNormal = normalize(mat3x3(transformationMatrix)*normal); /* Direction to the light */ - lightDirection = normalize(light - transformedVertex); + lightDirection = normalize(light - transformedPosition); /* Direction to the camera */ - cameraDirection = -transformedVertex; + cameraDirection = -transformedPosition; - /* Transform the vertex */ - gl_Position = projectionMatrix*transformedVertex4; + /* Transform the position */ + gl_Position = projectionMatrix*transformedPosition4; } diff --git a/src/Shaders/compatibility.glsl b/src/Shaders/compatibility.glsl new file mode 100644 index 000000000..2ccbfae6b --- /dev/null +++ b/src/Shaders/compatibility.glsl @@ -0,0 +1,14 @@ +#if (!defined(GL_ES) && __VERSION__ >= 130) || (defined(GL_ES) && __VERSION__ >= 300) +#define NEW_GLSL +#endif + +/* On NVidia and GLSL 1.20 layout qualifiers result in parsing error, even if + the extension is defined as supported */ +#if !defined(GL_ES) && __VERSION__ >= 120 && defined(GL_ARB_explicit_attrib_location) +#extension GL_ARB_explicit_attrib_location: enable +#define EXPLICIT_ATTRIB_LOCATION +#endif + +#if defined(GL_ES) && __VERSION__ >= 300 +#define EXPLICIT_ATTRIB_LOCATION +#endif diff --git a/src/SizeTraits.h b/src/SizeTraits.h index 8cf305700..272edbcd7 100644 --- a/src/SizeTraits.h +++ b/src/SizeTraits.h @@ -19,10 +19,15 @@ * @brief Class Magnum::SizeTraits, Magnum::SizeBasedCall, Magnum::Pow, Magnum::Log */ +#include + +#include "Math/Math.h" #include "Magnum.h" namespace Magnum { +/** @todo Remove/internalize things used only in one place (Math::log, Pow, Log)? Simplify SizeTraits? */ + /** @brief Traits class providing suitable types for given data sizes @tparam byte Highest byte needed (counting from zero) @@ -36,7 +41,7 @@ to compute logarithms at compile time, e.g. `SizeTraits::%value>::%SizeType`. */ #ifdef DOXYGEN_GENERATING_OUTPUT -template struct SizeTraits { +template struct SizeTraits { /** * @brief (Unsigned) type able to index the data * @@ -46,7 +51,7 @@ template struct SizeTraits { typedef T SizeType; }; #else -template struct SizeTraits: public SizeTraits {}; +template struct SizeTraits: public SizeTraits {}; #endif #ifndef DOXYGEN_GENERATING_OUTPUT @@ -72,7 +77,7 @@ template<> struct SizeTraits<4> { If you have templated function which you want to call with type suitable for indexing data of some size, you will probably use cascade of IFs, like this: @code -size_t dataSize; +std::size_t dataSize; template Bar foo(Arg1 arg1, Arg2 arg2, ...); Bar bar; @@ -106,7 +111,7 @@ template struct SizeBasedCall: public Base { * @brief Constructor * @param size Data size */ - SizeBasedCall(size_t size): size(size) {} + SizeBasedCall(std::size_t size): size(size) {} /** * @brief Functor @@ -161,7 +166,7 @@ template struct SizeBasedCall: public Base { } private: - size_t size; + std::size_t size; }; /** @@ -172,14 +177,14 @@ template struct SizeBasedCall: public Base { Useful mainly for computing template parameter value, e.g. in conjunction with SizeTraits class. */ -template struct Pow { +template struct Pow { /** @brief Value of the power */ - enum { value = base*Pow::value }; + enum: std::uint32_t { value = base*Pow::value }; }; #ifndef DOXYGEN_GENERATING_OUTPUT -template struct Pow { - enum { value = 1 }; +template struct Pow { + enum: std::uint32_t { value = 1 }; }; #endif @@ -191,15 +196,15 @@ template struct Pow { Useful mainly for computing template parameter value, e.g. in conjunction with SizeTraits class. */ -template struct Log { +template struct Log { /** @brief Value of the logarithm */ - enum { value = 1+Log::value }; + enum: std::uint32_t { value = 1+Log::value }; }; #ifndef DOXYGEN_GENERATING_OUTPUT -template struct Log: public Log {}; -template struct Log { - enum { value = 0 }; +template struct Log: public Log {}; +template struct Log { + enum: std::uint32_t { value = 0 }; }; #endif diff --git a/src/Swizzle.h b/src/Swizzle.h index 8f30f96a5..529d538ec 100644 --- a/src/Swizzle.h +++ b/src/Swizzle.h @@ -28,23 +28,29 @@ namespace Implementation { using Math::Implementation::Sequence; using Math::Implementation::GenerateSequence; - template struct GetPosition { + template struct ComponentAtPosition { static_assert(size > position, "Swizzle parameter out of range of base vector"); - inline constexpr static size_t value() { return position; } + template inline constexpr static T value(const Math::Vector& vector) { return vector[position]; } }; - template struct GetComponent {}; - template struct GetComponent: public GetPosition {}; - template struct GetComponent: public GetPosition {}; - template struct GetComponent: public GetPosition {}; - template struct GetComponent: public GetPosition {}; - template struct GetComponent: public GetPosition {}; - template struct GetComponent: public GetPosition {}; - template struct GetComponent: public GetPosition {}; - template struct GetComponent: public GetPosition {}; - - template struct TypeForSize { + template struct Component {}; + template struct Component: public ComponentAtPosition {}; + template struct Component: public ComponentAtPosition {}; + template struct Component: public ComponentAtPosition {}; + template struct Component: public ComponentAtPosition {}; + template struct Component: public ComponentAtPosition {}; + template struct Component: public ComponentAtPosition {}; + template struct Component: public ComponentAtPosition {}; + template struct Component: public ComponentAtPosition {}; + template struct Component { + template inline constexpr static T value(const Math::Vector&) { return T(0); } + }; + template struct Component { + template inline constexpr static T value(const Math::Vector&) { return T(1); } + }; + + template struct TypeForSize { typedef Math::Vector Type; }; template struct TypeForSize<2, T> { typedef Math::Vector2 Type; }; @@ -55,24 +61,26 @@ namespace Implementation { template struct TypeForSize<4, Color3> { typedef Color4 Type; }; template struct TypeForSize<4, Color4> { typedef Color4 Type; }; - inline constexpr size_t getPosition(size_t size, size_t position) { - return size > position ? position : throw; + template inline constexpr T componentAtPosition(const Math::Vector& vector, std::size_t position) { + return size > position ? vector[position] : throw; } - template inline constexpr size_t getComponent(char component) { - return component == 'x' ? getPosition(size, 0) : - component == 'y' ? getPosition(size, 1) : - component == 'z' ? getPosition(size, 2) : - component == 'w' ? getPosition(size, 3) : - component == 'r' ? getPosition(size, 0) : - component == 'g' ? getPosition(size, 1) : - component == 'b' ? getPosition(size, 2) : - component == 'a' ? getPosition(size, 3) : + template inline constexpr T component(const Math::Vector& vector, char component) { + return component == 'x' ? componentAtPosition(vector, 0) : + component == 'y' ? componentAtPosition(vector, 1) : + component == 'z' ? componentAtPosition(vector, 2) : + component == 'w' ? componentAtPosition(vector, 3) : + component == 'r' ? componentAtPosition(vector, 0) : + component == 'g' ? componentAtPosition(vector, 1) : + component == 'b' ? componentAtPosition(vector, 2) : + component == 'a' ? componentAtPosition(vector, 3) : + component == '0' ? T(0) : + component == '1' ? T(1) : throw; } - template inline constexpr Math::Vector swizzleFrom(Sequence, const Math::Vector& vector, const char(&components)[sizeof...(sequence)+1]) { - return {vector[getComponent(components[sequence])]...}; + template inline constexpr Math::Vector swizzleFrom(Sequence, const Math::Vector& vector, const char(&components)[sizeof...(sequence)+1]) { + return {component(vector, components[sequence])...}; } } #endif @@ -82,14 +90,15 @@ namespace Implementation { Creates new vector from given components. Example: @code -Vector4 original(1, 2, 3, 4); +Vector4 original(-1, 2, 3, 4); -auto vec = swizzle<'a', 'b', 'b', 'g', 'r', 'r'>(original); -// vec == { 4, 3, 3, 2, 1, 1 } +auto vec = swizzle<'a', '1', '0', 'r', 'g', 'b'>(original); +// vec == { 4, 1, 0, -1, 2, 3 } @endcode -You can use letters `x`, `y`, `z`, `w` and `r`, `g`, `b`, `a`. Count of -elements is unlimited, but must be at least one. If the resulting vector is -two, three or four-component, corresponding Vector2, Vector3 or Vector4 +You can use letters `x`, `y`, `z`, `w` and `r`, `g`, `b`, `a` for addressing +components or letters `0` and `1` for zero and one. Count of elements is +unlimited, but must be at least one. If the resulting vector is two, three or +four-component, corresponding Vector2, Vector3, Vector4, Color3 or Color4 specialization is returned. @attention This function is less convenient to write than @@ -97,10 +106,11 @@ swizzle(const T&, const char(&)[newSize]), but the evaluation of the swizzling operation is guaranteed to be always done at compile time instead of at runtime. -@see Vector4::xyz(), Vector4::rgb(), Vector4::xy(), Vector3::xy() +@see @ref matrix-vector-component-access, Vector4::xyz(), Color4::rgb(), + Vector4::xy(), Vector3::xy() */ template inline constexpr typename Implementation::TypeForSize::Type swizzle(const T& vector) { - return {vector[Implementation::GetComponent::value()]...}; + return {Implementation::Component::value(vector)...}; } /** @@ -108,24 +118,26 @@ template inline constexpr typename Implementation:: Creates new vector from given components. Example: @code -Vector4 original(1, 2, 3, 4); +Vector4 original(-1, 2, 3, 4); -auto vec = swizzle(original, "abbgrr"); -// vec == { 4, 3, 3, 2, 1, 1 } +auto vec = swizzle(original, "a10rgb"); +// vec == { 4, 1, 0, -1, 2, 3 } @endcode -You can use letters `x`, `y`, `z`, `w` and `r`, `g`, `b`, `a`. Count of -elements is unlimited, but must be at least one. If the resulting vector is -two, three or four-component, corresponding Vector2, Vector3 or Vector4 -specialization is returned. +You can use letters `x`, `y`, `z`, `w` and `r`, `g`, `b`, `a` for addressing +components or letters `0` and `1` for zero and one. Count of elements is +unlimited, but must be at least one. If the resulting vector is two, three or +four-component, corresponding Vector2, Vector3 or Vector4 specialization is +returned. @attention This function is more convenient to write than swizzle(const T&), but unless the result is marked with `constexpr`, the evaluation of the swizzling operation probably won't be evaluated at compile time, but at runtime. -@see Vector4::xyz(), Vector4::rgb(), Vector4::xy(), Vector3::xy() +@see @ref matrix-vector-component-access, Vector4::xyz(), Color4::rgb(), + Vector4::xy(), Vector3::xy() */ -template inline constexpr typename Implementation::TypeForSize::Type swizzle(const T& vector, const char(&components)[newSize]) { +template inline constexpr typename Implementation::TypeForSize::Type swizzle(const T& vector, const char(&components)[newSize]) { return Implementation::swizzleFrom(typename Implementation::GenerateSequence::Type(), vector, components); } diff --git a/src/Test/CMakeLists.txt b/src/Test/CMakeLists.txt index f86d239e8..87e9f71e2 100644 --- a/src/Test/CMakeLists.txt +++ b/src/Test/CMakeLists.txt @@ -1,2 +1,5 @@ corrade_add_test2(ColorTest ColorTest.cpp) +corrade_add_test2(ResourceManagerTest ResourceManagerTest.cpp) corrade_add_test2(SwizzleTest SwizzleTest.cpp) + +set_target_properties(ResourceManagerTest PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT) diff --git a/src/Test/ColorTest.cpp b/src/Test/ColorTest.cpp index 7813b5f06..7625131af 100644 --- a/src/Test/ColorTest.cpp +++ b/src/Test/ColorTest.cpp @@ -25,8 +25,8 @@ using namespace Corrade::Utility; namespace Magnum { namespace Test { -typedef Magnum::Color3 Color3; -typedef Magnum::Color4 Color4; +typedef Magnum::Color3 Color3; +typedef Magnum::Color4 Color4; typedef Magnum::Color3 Color3f; typedef Magnum::Color4 Color4f; diff --git a/src/Test/ResourceManagerTest.cpp b/src/Test/ResourceManagerTest.cpp new file mode 100644 index 000000000..bf99d364f --- /dev/null +++ b/src/Test/ResourceManagerTest.cpp @@ -0,0 +1,119 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "ResourceManagerTest.h" + +#include + +#include "ResourceManager.h" + +using namespace std; +using namespace Corrade::Utility; + +CORRADE_TEST_MAIN(Magnum::Test::ResourceManagerTest) + +namespace Magnum { namespace Test { + +size_t Data::count = 0; + +ResourceManagerTest::ResourceManagerTest() { + rm = new ResourceManager; + + addTests(&ResourceManagerTest::state, + &ResourceManagerTest::referenceCountedPolicy, + &ResourceManagerTest::manualPolicy, + &ResourceManagerTest::destroy); +} + +void ResourceManagerTest::state() { + ResourceKey questionKey("the-question"); + rm->set(questionKey, new int32_t(10), ResourceDataState::Mutable, ResourcePolicy::Resident); + Resource theQuestion = rm->get(questionKey); + CORRADE_VERIFY(theQuestion.state() == ResourceState::Mutable); + CORRADE_COMPARE(*theQuestion, 10); + + /* Check that hash function is working properly */ + ResourceKey answerKey("the-answer"); + rm->set(answerKey, new int32_t(42), ResourceDataState::Final, ResourcePolicy::Resident); + Resource theAnswer = rm->get(answerKey); + CORRADE_VERIFY(theAnswer.state() == ResourceState::Final); + CORRADE_COMPARE(*theAnswer, 42); + + CORRADE_COMPARE(rm->count(), 2); + + /* Cannot change already final resource */ + stringstream out; + Error::setOutput(&out); + rm->set(answerKey, new int32_t(43), ResourceDataState::Mutable, ResourcePolicy::Resident); + CORRADE_COMPARE(*theAnswer, 42); + CORRADE_COMPARE(out.str(), "ResourceManager: cannot change already final resource\n"); + + /* Check non-final resource changes */ + rm->set(questionKey, new int32_t(20), ResourceDataState::Final, ResourcePolicy::Resident); + CORRADE_VERIFY(theQuestion.state() == ResourceState::Final); + CORRADE_COMPARE(*theQuestion, 20); +} + +void ResourceManagerTest::referenceCountedPolicy() { + ResourceKey dataRefCountKey("dataRefCount"); + + /* Reference counted resources must be requested first */ + { + rm->set(dataRefCountKey, new Data(), ResourceDataState::Final, ResourcePolicy::ReferenceCounted); + CORRADE_COMPARE(rm->count(), 0); + Resource data = rm->get(dataRefCountKey); + CORRADE_VERIFY(data.state() == ResourceState::NotLoaded); + CORRADE_COMPARE(Data::count, 0); + } { + Resource data = rm->get(dataRefCountKey); + CORRADE_COMPARE(rm->count(), 1); + CORRADE_VERIFY(data.state() == ResourceState::NotLoaded); + rm->set(dataRefCountKey, new Data(), ResourceDataState::Final, ResourcePolicy::ReferenceCounted); + CORRADE_VERIFY(data.state() == ResourceState::Final); + CORRADE_COMPARE(Data::count, 1); + } + + CORRADE_COMPARE(rm->count(), 0); + CORRADE_COMPARE(Data::count, 0); +} + +void ResourceManagerTest::manualPolicy() { + ResourceKey dataKey("data"); + + /* Manual free */ + { + rm->set(dataKey, new Data(), ResourceDataState::Mutable, ResourcePolicy::Manual); + Resource data = rm->get(dataKey); + rm->free(); + } + + CORRADE_COMPARE(rm->count(), 1); + CORRADE_COMPARE(Data::count, 1); + rm->free(); + CORRADE_COMPARE(rm->count(), 0); + CORRADE_COMPARE(Data::count, 0); + + rm->set(dataKey, new Data(), ResourceDataState::Mutable, ResourcePolicy::Manual); + CORRADE_COMPARE(rm->count(), 1); + CORRADE_COMPARE(Data::count, 1); +} + +void ResourceManagerTest::destroy() { + delete rm; + rm = nullptr; + CORRADE_COMPARE(Data::count, 0); +} + +}} diff --git a/src/Test/ResourceManagerTest.h b/src/Test/ResourceManagerTest.h new file mode 100644 index 000000000..ef7c1826a --- /dev/null +++ b/src/Test/ResourceManagerTest.h @@ -0,0 +1,51 @@ +#ifndef Magnum_Test_ResourceManagerTest_h +#define Magnum_Test_ResourceManagerTest_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 + +namespace Magnum { + +template class ResourceManager; + +namespace Test { + +class Data { + public: + static std::size_t count; + + inline Data() { ++count; } + inline ~Data() { --count; } +}; + +typedef Magnum::ResourceManager ResourceManager; + +class ResourceManagerTest: public Corrade::TestSuite::Tester { + public: + ResourceManagerTest(); + + void state(); + void referenceCountedPolicy(); + void manualPolicy(); + void destroy(); + + private: + ResourceManager* rm; +}; + +}} + +#endif diff --git a/src/Test/SwizzleTest.cpp b/src/Test/SwizzleTest.cpp index fe9562135..3e821c749 100644 --- a/src/Test/SwizzleTest.cpp +++ b/src/Test/SwizzleTest.cpp @@ -23,13 +23,14 @@ CORRADE_TEST_MAIN(Magnum::Test::SwizzleTest) namespace Magnum { namespace Test { -typedef Math::Vector2 Vector2; -typedef Math::Vector3 Vector3; -typedef Math::Vector4 Vector4; +typedef Math::Vector2 Vector2; +typedef Math::Vector3 Vector3; +typedef Math::Vector4 Vector4; SwizzleTest::SwizzleTest() { addTests(&SwizzleTest::xyzw, &SwizzleTest::rgba, + &SwizzleTest::constants, &SwizzleTest::fromSmall, &SwizzleTest::type, &SwizzleTest::defaultType); @@ -49,12 +50,24 @@ void SwizzleTest::rgba() { CORRADE_COMPARE((swizzle<'b', 'r', 'a', 'g'>(orig)), swizzled); } +void SwizzleTest::constants() { + Vector4 orig(2, 4, 5, 7); + Vector4 swizzled(1, 7, 0, 4); + CORRADE_COMPARE(swizzle(orig, "1w0g"), swizzled); + CORRADE_COMPARE((swizzle<'1', 'w', '0', 'g'>(orig)), swizzled); +} + void SwizzleTest::fromSmall() { + #ifndef CORRADE_GCC45_COMPATIBILITY /* Force compile-time evaluation for both */ constexpr Vector2 orig(1, 2); - #ifndef CORRADE_GCC45_COMPATIBILITY - CORRADE_VERIFY((integral_constant::value)); + constexpr Vector3 swizzled(swizzle(orig, "gxr")); + CORRADE_VERIFY((integral_constant::value)); + #else + Vector2 orig(1, 2); #endif + + CORRADE_COMPARE(swizzle(orig, "gxr"), Vector3(2, 1, 1)); CORRADE_COMPARE((swizzle<'g', 'x', 'r'>(orig)), Vector3(2, 1, 1)); } @@ -81,14 +94,10 @@ void SwizzleTest::type() { void SwizzleTest::defaultType() { Vector4 orig(1, 2, 3, 4); - - Math::Vector<1, int> b(3); - CORRADE_COMPARE(swizzle<'b'>(orig), b); - CORRADE_COMPARE(swizzle(orig, "b"), b); - - Math::Vector<7, int> bragzyx(3, 1, 4, 2, 3, 2, 1); - CORRADE_COMPARE((swizzle<'b', 'r', 'a', 'g', 'z', 'y', 'x'>(orig)), bragzyx); - CORRADE_COMPARE(swizzle(orig, "bragzyx"), bragzyx); + CORRADE_COMPARE(swizzle<'b'>(orig), (Math::Vector<1, int32_t>(3))); + CORRADE_COMPARE(swizzle(orig, "b"), (Math::Vector<1, int32_t>(3))); + CORRADE_COMPARE((swizzle<'b', 'r', 'a', 'g', 'z', 'y', 'x'>(orig)), (Math::Vector<7, int32_t>(3, 1, 4, 2, 3, 2, 1))); + CORRADE_COMPARE(swizzle(orig, "bragzyx"), (Math::Vector<7, int32_t>(3, 1, 4, 2, 3, 2, 1))); } }} diff --git a/src/Test/SwizzleTest.h b/src/Test/SwizzleTest.h index b43180be0..56a705f5d 100644 --- a/src/Test/SwizzleTest.h +++ b/src/Test/SwizzleTest.h @@ -25,6 +25,7 @@ class SwizzleTest: public Corrade::TestSuite::Tester { void xyzw(); void rgba(); + void constants(); void fromSmall(); void type(); void defaultType(); diff --git a/src/Texture.h b/src/Texture.h index d31d2039b..c73550993 100644 --- a/src/Texture.h +++ b/src/Texture.h @@ -20,6 +20,7 @@ */ #include "AbstractTexture.h" +#include "DimensionTraits.h" namespace Magnum { @@ -27,7 +28,7 @@ namespace Magnum { @brief %Texture Template class for one- to three-dimensional textures. See AbstractTexture -documentation for more information about usage. +documentation for more information. In shader, the texture is used via `sampler1D`, `sampler2D` or `sampler3D` depending on dimension count. Note that you can have more than one texture bound @@ -43,14 +44,15 @@ don't support mipmapping and repeating wrapping modes, see @ref Texture::Filter "Filter", @ref Texture::Mipmap "Mipmap" and generateMipmap() documentation for more information. -@requires_gl (rectangle textures) +@requires_gl Rectangle textures are not available in OpenGL ES. @requires_gl31 Extension @extension{ARB,texture_rectangle} (rectangle textures) -@see CubeMapTexture, CubeMapTextureArray +@see Texture1D, Texture2D, Texture3D, CubeMapTexture, CubeMapTextureArray +@todo @extension{AMD,sparse_texture} */ -template class Texture: public AbstractTexture { +template class Texture: public AbstractTexture { public: - static const size_t Dimensions = textureDimensions; /**< @brief %Texture dimension count */ + static const std::uint8_t Dimensions = dimensions; /**< @brief %Texture dimension count */ #ifdef DOXYGEN_GENERATING_OUTPUT /** @@ -61,7 +63,8 @@ template class Texture: public AbstractTexture { enum class Target: GLenum { /** * One-dimensional texture - * @requires_gl + * @requires_gl Only 2D and 3D textures are available in OpenGL + * ES. */ Texture1D = GL_TEXTURE_1D, @@ -69,28 +72,30 @@ template class Texture: public AbstractTexture { /** * Three-dimensional texture - * @requires_gl + * @requires_gles30 %Extension @es_extension{OES,texture_3D} */ Texture3D = GL_TEXTURE_3D, /** * One-dimensional texture array (i.e. two dimensions in total) - * @requires_gl * @requires_gl30 Extension @extension{EXT,texture_array} + * @requires_gl Only 2D and 3D textures are available in OpenGL + * ES. */ Texture1DArray = GL_TEXTURE_1D_ARRAY, /** * Two-dimensional texture array (i.e. three dimensions in total) - * @requires_gl * @requires_gl30 Extension @extension{EXT,texture_array} + * @requires_gles30 Array textures are not available in OpenGL ES + * 2.0. */ Texture2DArray = GL_TEXTURE_2D_ARRAY, /** * Rectangle texture (i.e. two dimensions) - * @requires_gl * @requires_gl31 Extension @extension{ARB,texture_rectangle} + * @requires_gl Rectangle textures are not available in OpenGL ES. */ Rectangle = GL_TEXTURE_RECTANGLE }; @@ -114,17 +119,25 @@ template class Texture: public AbstractTexture { /** * @brief Set wrapping * @param wrapping Wrapping type for all texture dimensions + * @return Pointer to self (for method chaining) * * Sets wrapping type for coordinates out of range (0, 1) for normal * textures and (0, textureSizeInGivenDirection-1) for rectangle - * textures. + * textures. If @extension{EXT,direct_state_access} is not available, + * the texture is bound to some layer before the operation. * @attention For rectangle textures only some modes are supported, - * see @ref AbstractTexture::Wrapping "Wrapping" documentation for - * more information. + * see @ref AbstractTexture::Wrapping "Wrapping" documentation + * for more information. + * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexParameter} + * or @fn_gl_extension{TextureParameter,EXT,direct_state_access} + * with @def_gl{TEXTURE_WRAP_S}, @def_gl{TEXTURE_WRAP_T}, + * @def_gl{TEXTURE_WRAP_R} + * @todo Use something better for this than Vector (mainly something + * that can easily create all values the same) */ - inline void setWrapping(const Math::Vector& wrapping) { - bind(); - DataHelper::setWrapping(_target, wrapping); + inline Texture* setWrapping(const Math::Vector& wrapping) { + DataHelper::setWrapping(this, wrapping); + return this; } /** @@ -133,13 +146,20 @@ template class Texture: public AbstractTexture { * @param internalFormat Internal texture format * @param image Image, BufferedImage or for example * Trade::ImageData of the same dimension count + * @return Pointer to self (for method chaining) * * Sets texture data from given image. The image is not deleted - * afterwards. + * afterwards. If @extension{EXT,direct_state_access} is not available, + * the texture is bound to some layer before the operation. + * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexImage1D}/ + * @fn_gl{TexImage2D}/@fn_gl{TexImage3D} or + * @fn_gl_extension{TextureImage1D,EXT,direct_state_access}/ + * @fn_gl_extension{TextureImage2D,EXT,direct_state_access}/ + * @fn_gl_extension{TextureImage3D,EXT,direct_state_access} */ - template inline void setData(GLint mipLevel, InternalFormat internalFormat, Image* image) { - bind(); - DataHelper::set(_target, mipLevel, internalFormat, image); + template inline Texture* setData(GLint mipLevel, InternalFormat internalFormat, Image* image) { + DataHelper::set(this, _target, mipLevel, internalFormat, image); + return this; } /** @@ -148,6 +168,7 @@ template class Texture: public AbstractTexture { * @param offset Offset where to put data in the texture * @param image Image, BufferedImage or for example * Trade::ImageData + * @return Pointer to self (for method chaining) * * Sets texture subdata from given image. The image is not deleted * afterwards. The image can have either the same dimension count or @@ -157,18 +178,52 @@ template class Texture: public AbstractTexture { * taken as if it had the last dimension equal to 1. It can be used * for e.g. updating 3D texture with multiple 2D images or for filling * 1D texture array (which is two-dimensional) with 1D images. + * + * If @extension{EXT,direct_state_access} is not available, the + * texture is bound to some layer before the operation. + * @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} and @fn_gl{TexSubImage1D}/ + * @fn_gl{TexSubImage2D}/@fn_gl{TexSubImage3D} or + * @fn_gl_extension{TextureSubImage1D,EXT,direct_state_access}/ + * @fn_gl_extension{TextureSubImage2D,EXT,direct_state_access}/ + * @fn_gl_extension{TextureSubImage3D,EXT,direct_state_access} */ - template inline void setSubData(GLint mipLevel, const Math::Vector& offset, Image* image) { - bind(); - DataHelper::setSub(_target, mipLevel, offset, image); + template inline Texture* setSubData(GLint mipLevel, const typename DimensionTraits::VectorType& offset, Image* image) { + DataHelper::setSub(this, _target, mipLevel, offset, image); + return this; + } + + /* Overloads to remove WTF-factor from method chaining order */ + #ifndef DOXYGEN_GENERATING_OUTPUT + inline Texture* setMinificationFilter(Filter filter, Mipmap mipmap = Mipmap::BaseLevel) { + AbstractTexture::setMinificationFilter(filter, mipmap); + return this; + } + inline Texture* setMagnificationFilter(Filter filter) { + AbstractTexture::setMagnificationFilter(filter); + return this; + } + #ifndef MAGNUM_TARGET_GLES + inline Texture* setBorderColor(const Color4& color) { + AbstractTexture::setBorderColor(color); + return this; + } + inline Texture* setMaxAnisotropy(GLfloat anisotropy) { + AbstractTexture::setMaxAnisotropy(anisotropy); + return this; } + #endif + inline Texture* generateMipmap() { + AbstractTexture::generateMipmap(); + return this; + } + #endif }; #ifndef MAGNUM_TARGET_GLES /** @brief One-dimensional texture -@requires_gl +@requires_gl Only 2D and 3D textures are available in OpenGL ES. */ typedef Texture<1> Texture1D; #endif @@ -176,14 +231,12 @@ typedef Texture<1> Texture1D; /** @brief Two-dimensional texture */ typedef Texture<2> Texture2D; -#ifndef MAGNUM_TARGET_GLES /** @brief Three-dimensional texture -@requires_gl +@requires_gles30 %Extension @es_extension{OES,texture_3D} */ typedef Texture<3> Texture3D; -#endif } diff --git a/src/Timeline.cpp b/src/Timeline.cpp new file mode 100644 index 000000000..7183c899d --- /dev/null +++ b/src/Timeline.cpp @@ -0,0 +1,52 @@ +#include "Timeline.h" +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 +#include + +using namespace std::chrono; + +namespace Magnum { + +void Timeline::start() { + running = true; + previousFrameTime = high_resolution_clock::now(); + _previousFrameDuration = 0; +} + +void Timeline::stop() { + running = false; + previousFrameTime = high_resolution_clock::time_point(); + _previousFrameDuration = 0; +} + +void Timeline::nextFrame() { + if(!running) return; + + auto now = high_resolution_clock::now(); + std::uint32_t duration = duration_cast(now-previousFrameTime).count(); + _previousFrameDuration = duration/1e6f; + + if(_previousFrameDuration < _minimalFrameTime) { + Corrade::Utility::sleep(_minimalFrameTime*1000 - duration/1000); + now = high_resolution_clock::now(); + _previousFrameDuration = duration_cast(now-previousFrameTime).count()/1e6f; + } + + previousFrameTime = now; +} + +} diff --git a/src/Timeline.h b/src/Timeline.h new file mode 100644 index 000000000..093191677 --- /dev/null +++ b/src/Timeline.h @@ -0,0 +1,91 @@ +#ifndef Magnum_Timeline_h +#define Magnum_Timeline_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 + +#include "Magnum.h" + +#include "magnumVisibility.h" + +/** @file + * @brief Class Magnum::Timeline + */ + +namespace Magnum { + +/** @brief %Timeline */ +class MAGNUM_EXPORT Timeline { + public: + /** + * @brief Constructor + * + * Constructs stopped timeline. + * @see start() + */ + inline constexpr Timeline(): _minimalFrameTime(0), _previousFrameDuration(0), running(false) {} + + /** @brief Minimal frame time (in seconds) */ + GLfloat minimalFrameTime() const { return _minimalFrameTime; } + + /** + * @brief Set minimal frame time + * + * @see nextFrame() + */ + void setMinimalFrameTime(GLfloat seconds) { + _minimalFrameTime = seconds; + } + + /** + * @brief Start timeline + * + * Sets previous frame duration to `0`. + * @see stop(), previousFrameDuration() + */ + void start(); + + /** + * @brief Stop timeline + */ + void stop(); + + /** + * @brief Advance to next frame + * + * If current frame time is smaller than minimal frame time, pauses + * the execution for remaining time. + * @note This function does nothing if the timeline is stopped. + * @see setMinimalFrameTime() + */ + void nextFrame(); + + /** @brief Duration of previous frame */ + inline constexpr GLfloat previousFrameDuration() const { + return _previousFrameDuration; + } + + private: + std::chrono::high_resolution_clock::time_point previousFrameTime; + GLfloat _minimalFrameTime; + GLfloat _previousFrameDuration; + + bool running; +}; + +} + +#endif diff --git a/src/Trade/AbstractImporter.cpp b/src/Trade/AbstractImporter.cpp index cfd07c7a3..ec68d9c21 100644 --- a/src/Trade/AbstractImporter.cpp +++ b/src/Trade/AbstractImporter.cpp @@ -15,7 +15,10 @@ #include "AbstractImporter.h" +#include + using namespace std; +using namespace Corrade::Utility; namespace Magnum { namespace Trade { diff --git a/src/Trade/AbstractImporter.h b/src/Trade/AbstractImporter.h index 2b7ed2528..23cef208c 100644 --- a/src/Trade/AbstractImporter.h +++ b/src/Trade/AbstractImporter.h @@ -22,25 +22,32 @@ #include #include -#include "ImageData.h" +#include "magnumVisibility.h" namespace Magnum { namespace Trade { class AbstractMaterialData; class CameraData; +template class ImageData; class LightData; -class MeshData; -class ObjectData; +class MeshData2D; +class MeshData3D; +class ObjectData2D; +class ObjectData3D; class SceneData; class TextureData; +typedef ImageData<1> ImageData1D; +typedef ImageData<2> ImageData2D; +typedef ImageData<3> ImageData3D; + /** -@brief Base class for importer plugins +@brief Base for importer plugins Importer is used for importing data like scenes, lights, objects, images, textures etc. -@section AbstractImporterSubclassing Subclassing +@section AbstractImporter-subclassing Subclassing Plugin implements function features(), one or more open() functions, function close() and one or more pairs of data access functions, based on which features are supported in given format. @@ -111,10 +118,10 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::Plugin { * @note The function is not const, because the value will probably * be lazy-populated. */ - virtual inline int defaultScene() { return -1; } + virtual inline std::int32_t defaultScene() { return -1; } /** @brief %Scene count */ - virtual inline unsigned int sceneCount() const { return 0; } + virtual inline std::uint32_t sceneCount() const { return 0; } /** * @brief %Scene ID for given name @@ -122,7 +129,7 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::Plugin { * If no scene for given name exists, returns -1. * @see SceneData::name() */ - virtual int sceneForName(const std::string& name); + virtual std::int32_t sceneForName(const std::string& name); /** * @brief %Scene @@ -130,10 +137,10 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::Plugin { * * Returns pointer to given scene or nullptr, if no such scene exists. */ - virtual SceneData* scene(unsigned int id); + virtual SceneData* scene(std::uint32_t id); /** @brief %Light count */ - virtual inline unsigned int lightCount() const { return 0; } + virtual inline std::uint32_t lightCount() const { return 0; } /** * @brief %Light ID for given name @@ -141,7 +148,7 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::Plugin { * If no light for given name exists, returns -1. * @see LightData::name() */ - virtual int lightForName(const std::string& name); + virtual std::int32_t lightForName(const std::string& name); /** * @brief %Light @@ -149,10 +156,10 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::Plugin { * * Returns pointer to given light or nullptr, if no such light exists. */ - virtual LightData* light(unsigned int id); + virtual LightData* light(std::uint32_t id); /** @brief %Camera count */ - virtual inline unsigned int cameraCount() const { return 0; } + virtual inline std::uint32_t cameraCount() const { return 0; } /** * @brief %Camera ID for given name @@ -160,7 +167,7 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::Plugin { * If no camera for given name exists, returns -1. * @see CameraData::name() */ - virtual int cameraForName(const std::string& name); + virtual std::int32_t cameraForName(const std::string& name); /** * @brief %Camera @@ -169,49 +176,88 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::Plugin { * Returns pointer to given camera or nullptr, if no such camera * exists. */ - virtual CameraData* camera(unsigned int id); + virtual CameraData* camera(std::uint32_t id); + + /** @brief Two-dimensional object count */ + virtual inline std::uint32_t object2DCount() const { return 0; } + + /** + * @brief Two-dimensional object ID for given name + * + * If no scene for given name exists, returns -1. + * @see ObjectData2D::name() + */ + virtual std::int32_t object2DForName(const std::string& name); + + /** + * @brief Two-dimensional object + * @param id %Object ID, from range [0, object2DCount()). + * + * Returns pointer to given object or nullptr, if no such object + * exists. + */ + virtual ObjectData2D* object2D(std::uint32_t id); - /** @brief %Object count */ - virtual inline unsigned int objectCount() const { return 0; } + /** @brief Three-dimensional object count */ + virtual inline std::uint32_t object3DCount() const { return 0; } /** - * @brief %Object ID for given name + * @brief Three-dimensional object ID for given name * * If no scene for given name exists, returns -1. - * @see ObjectData::name() + * @see ObjectData3D::name() */ - virtual int objectForName(const std::string& name); + virtual std::int32_t object3DForName(const std::string& name); /** - * @brief %Object - * @param id %Object ID, from range [0, objectCount()). + * @brief Three-dimensional object + * @param id %Object ID, from range [0, object3DCount()). * * Returns pointer to given object or nullptr, if no such object * exists. */ - virtual ObjectData* object(unsigned int id); + virtual ObjectData3D* object3D(std::uint32_t id); + + /** @brief Two-dimensional mesh count */ + virtual inline std::uint32_t mesh2DCount() const { return 0; } + + /** + * @brief Two-dimensional mesh ID for given name + * + * If no mesh for given name exists, returns -1. + * @see MeshData2D::name() + */ + virtual std::int32_t mesh2DForName(const std::string& name); + + /** + * @brief Two-dimensional mesh + * @param id %Mesh ID, from range [0, meshCount()). + * + * Returns pointer to given mesh or nullptr, if no such mesh exists. + */ + virtual MeshData2D* mesh2D(std::uint32_t id); - /** @brief %Mesh count */ - virtual inline unsigned int meshCount() const { return 0; } + /** @brief Three-dimensional mesh count */ + virtual inline std::uint32_t mesh3DCount() const { return 0; } /** - * @brief %Mesh ID for given name + * @brief Three-dimensional mesh ID for given name * * If no mesh for given name exists, returns -1. - * @see MeshData::name() + * @see MeshData3D::name() */ - virtual int meshForName(const std::string& name); + virtual std::int32_t mesh3DForName(const std::string& name); /** - * @brief %Mesh + * @brief Three-dimensional mesh * @param id %Mesh ID, from range [0, meshCount()). * * Returns pointer to given mesh or nullptr, if no such mesh exists. */ - virtual MeshData* mesh(unsigned int id); + virtual MeshData3D* mesh3D(std::uint32_t id); /** @brief Material count */ - virtual inline unsigned int materialCount() const { return 0; } + virtual inline std::uint32_t materialCount() const { return 0; } /** * @brief Material ID for given name @@ -219,7 +265,7 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::Plugin { * If no material for given name exists, returns -1. * @see AbstractMaterialData::name() */ - virtual int materialForName(const std::string& name); + virtual std::int32_t materialForName(const std::string& name); /** * @brief Material @@ -228,10 +274,10 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::Plugin { * Returns pointer to given material or nullptr, if no such material * exists. */ - virtual AbstractMaterialData* material(unsigned int id); + virtual AbstractMaterialData* material(std::uint32_t id); /** @brief %Texture count */ - virtual inline unsigned int textureCount() const { return 0; } + virtual inline std::uint32_t textureCount() const { return 0; } /** * @brief %Texture ID for given name @@ -239,7 +285,7 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::Plugin { * If no texture for given name exists, returns -1. * @see TextureData::name() */ - virtual int textureForName(const std::string& name); + virtual std::int32_t textureForName(const std::string& name); /** * @brief %Texture @@ -248,10 +294,10 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::Plugin { * Returns pointer to given texture or nullptr, if no such texture * exists. */ - virtual TextureData* texture(unsigned int id); + virtual TextureData* texture(std::uint32_t id); /** @brief One-dimensional image count */ - virtual inline unsigned int image1DCount() const { return 0; } + virtual inline std::uint32_t image1DCount() const { return 0; } /** * @brief One-dimensional image ID for given name @@ -259,7 +305,7 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::Plugin { * If no image for given name exists, returns -1. * @see ImageData1D::name() */ - virtual int image1DForName(const std::string& name); + virtual std::int32_t image1DForName(const std::string& name); /** * @brief One-dimensional image @@ -267,10 +313,10 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::Plugin { * * Returns pointer to given image or nullptr, if no such image exists. */ - virtual ImageData1D* image1D(unsigned int id); + virtual ImageData1D* image1D(std::uint32_t id); /** @brief Two-dimensional image count */ - virtual inline unsigned int image2DCount() const { return 0; } + virtual inline std::uint32_t image2DCount() const { return 0; } /** * @brief Two-dimensional image ID for given name @@ -278,7 +324,7 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::Plugin { * If no image for given name exists, returns -1. * @see ImageData2D::name() */ - virtual int image2DForName(const std::string& name); + virtual std::int32_t image2DForName(const std::string& name); /** * @brief Two-dimensional image @@ -286,10 +332,10 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::Plugin { * * Returns pointer to given image or nullptr, if no such image exists. */ - virtual ImageData2D* image2D(unsigned int id); + virtual ImageData2D* image2D(std::uint32_t id); /** @brief Three-dimensional image count */ - virtual inline unsigned int image3DCount() const { return 0; } + virtual inline std::uint32_t image3DCount() const { return 0; } /** * @brief Three-dimensional image ID for given name @@ -297,7 +343,7 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::Plugin { * If no image for given name exists, returns -1. * @see ImageData3D::name() */ - virtual int image3DForName(const std::string& name); + virtual std::int32_t image3DForName(const std::string& name); /** * @brief Three-dimensional image @@ -305,7 +351,7 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::Plugin { * * Returns pointer to given image or nullptr, if no such image exists. */ - virtual ImageData3D* image3D(unsigned int id); + virtual ImageData3D* image3D(std::uint32_t id); /*@}*/ }; @@ -313,26 +359,30 @@ class MAGNUM_EXPORT AbstractImporter: public Corrade::PluginManager::Plugin { CORRADE_ENUMSET_OPERATORS(AbstractImporter::Features) /* Implementations for inline functions with unused parameters */ -inline int AbstractImporter::sceneForName(const std::string&) { return -1; } -inline SceneData* AbstractImporter::scene(unsigned int) { return nullptr; } -inline int AbstractImporter::lightForName(const std::string&) { return -1; } -inline LightData* AbstractImporter::light(unsigned int) { return nullptr; } -inline int AbstractImporter::cameraForName(const std::string&) { return -1; } -inline CameraData* AbstractImporter::camera(unsigned int) { return nullptr; } -inline int AbstractImporter::objectForName(const std::string&) { return -1; } -inline ObjectData* AbstractImporter::object(unsigned int) { return nullptr; } -inline int AbstractImporter::meshForName(const std::string&) { return -1; } -inline MeshData* AbstractImporter::mesh(unsigned int) { return nullptr; } -inline int AbstractImporter::materialForName(const std::string&) { return -1; } -inline AbstractMaterialData* AbstractImporter::material(unsigned int) { return nullptr; } -inline int AbstractImporter::textureForName(const std::string&) { return -1; } -inline TextureData* AbstractImporter::texture(unsigned int) { return nullptr; } -inline int AbstractImporter::image1DForName(const std::string&) { return -1; } -inline ImageData1D* AbstractImporter::image1D(unsigned int) { return nullptr; } -inline int AbstractImporter::image2DForName(const std::string&) { return -1; } -inline ImageData2D* AbstractImporter::image2D(unsigned int) { return nullptr; } -inline int AbstractImporter::image3DForName(const std::string&) { return -1; } -inline ImageData3D* AbstractImporter::image3D(unsigned int) { return nullptr; } +inline std::int32_t AbstractImporter::sceneForName(const std::string&) { return -1; } +inline SceneData* AbstractImporter::scene(std::uint32_t) { return nullptr; } +inline std::int32_t AbstractImporter::lightForName(const std::string&) { return -1; } +inline LightData* AbstractImporter::light(std::uint32_t) { return nullptr; } +inline std::int32_t AbstractImporter::cameraForName(const std::string&) { return -1; } +inline CameraData* AbstractImporter::camera(std::uint32_t) { return nullptr; } +inline std::int32_t AbstractImporter::object2DForName(const std::string&) { return -1; } +inline ObjectData2D* AbstractImporter::object2D(std::uint32_t) { return nullptr; } +inline std::int32_t AbstractImporter::object3DForName(const std::string&) { return -1; } +inline ObjectData3D* AbstractImporter::object3D(std::uint32_t) { return nullptr; } +inline std::int32_t AbstractImporter::mesh2DForName(const std::string&) { return -1; } +inline MeshData2D* AbstractImporter::mesh2D(std::uint32_t) { return nullptr; } +inline std::int32_t AbstractImporter::mesh3DForName(const std::string&) { return -1; } +inline MeshData3D* AbstractImporter::mesh3D(std::uint32_t) { return nullptr; } +inline std::int32_t AbstractImporter::materialForName(const std::string&) { return -1; } +inline AbstractMaterialData* AbstractImporter::material(std::uint32_t) { return nullptr; } +inline std::int32_t AbstractImporter::textureForName(const std::string&) { return -1; } +inline TextureData* AbstractImporter::texture(std::uint32_t) { return nullptr; } +inline std::int32_t AbstractImporter::image1DForName(const std::string&) { return -1; } +inline ImageData1D* AbstractImporter::image1D(std::uint32_t) { return nullptr; } +inline std::int32_t AbstractImporter::image2DForName(const std::string&) { return -1; } +inline ImageData2D* AbstractImporter::image2D(std::uint32_t) { return nullptr; } +inline std::int32_t AbstractImporter::image3DForName(const std::string&) { return -1; } +inline ImageData3D* AbstractImporter::image3D(std::uint32_t) { return nullptr; } }} diff --git a/src/Trade/AbstractMaterialData.h b/src/Trade/AbstractMaterialData.h index 477146bea..0e0b17c69 100644 --- a/src/Trade/AbstractMaterialData.h +++ b/src/Trade/AbstractMaterialData.h @@ -24,7 +24,7 @@ namespace Magnum { namespace Trade { /** -@brief Base class for material data +@brief Base for material data Subclasses provide access to parameters for given material type. */ diff --git a/src/Trade/CMakeLists.txt b/src/Trade/CMakeLists.txt index 9ef1442be..12b1fd60d 100644 --- a/src/Trade/CMakeLists.txt +++ b/src/Trade/CMakeLists.txt @@ -4,9 +4,12 @@ set(MagnumTrade_HEADERS CameraData.h ImageData.h LightData.h - MeshData.h - MeshObjectData.h - ObjectData.h + MeshData2D.h + MeshData3D.h + MeshObjectData2D.h + MeshObjectData3D.h + ObjectData2D.h + ObjectData3D.h PhongMaterialData.h SceneData.h TextureData.h) diff --git a/src/Trade/ImageData.h b/src/Trade/ImageData.h index f054f6464..cb6ca2690 100644 --- a/src/Trade/ImageData.h +++ b/src/Trade/ImageData.h @@ -19,7 +19,9 @@ * @brief Class Magnum::Trade::ImageData */ +#include "Math/Vector3.h" #include "AbstractImage.h" +#include "DimensionTraits.h" #include "TypeTraits.h" namespace Magnum { namespace Trade { @@ -30,14 +32,14 @@ namespace Magnum { namespace Trade { Provides access to image data and additional information about data type and dimensions. Can be used in the same situations as Image and BufferedImage. */ -template class ImageData: public AbstractImage { +template class ImageData: public AbstractImage { public: - const static size_t Dimensions = imageDimensions; /**< @brief %Image dimension count */ + const static std::uint8_t Dimensions = dimensions; /**< @brief %Image dimension count */ /** * @brief Constructor * @param name %Image name - * @param dimensions %Image dimensions + * @param size %Image size * @param components Color components. Data type is detected * from passed data array. * @param data %Image data @@ -45,12 +47,12 @@ template class ImageData: public AbstractImage { * Note that the image data are not copied on construction, but they * are deleted on class destruction. */ - template inline ImageData(const std::string& name, const Math::Vector& dimensions, Components components, T* data): AbstractImage(components, TypeTraits::imageType()), _name(name), _dimensions(dimensions), _data(reinterpret_cast(data)) {} + template inline ImageData(const std::string& name, const typename DimensionTraits::VectorType& size, Components components, T* data): AbstractImage(components, TypeTraits::imageType()), _name(name), _size(size), _data(reinterpret_cast(data)) {} /** * @brief Constructor * @param name %Image name - * @param dimensions %Image dimensions + * @param size %Image size * @param components Color components * @param type Data type * @param data %Image data @@ -58,7 +60,7 @@ template class ImageData: public AbstractImage { * Note that the image data are not copied on construction, but they * are deleted on class destruction. */ - inline ImageData(const std::string& name, const Math::Vector& dimensions, Components components, ComponentType type, GLvoid* data): AbstractImage(components, type), _name(name), _dimensions(dimensions), _data(reinterpret_cast(data)) {} + inline ImageData(const std::string& name, const typename DimensionTraits::VectorType& size, Components components, ComponentType type, GLvoid* data): AbstractImage(components, type), _name(name), _size(size), _data(reinterpret_cast(data)) {} /** @brief Destructor */ inline ~ImageData() { delete[] _data; } @@ -66,16 +68,16 @@ template class ImageData: public AbstractImage { /** @brief %Image name */ inline std::string name() const { return _name; } - /** @brief %Image dimensions */ - inline constexpr const Math::Vector& dimensions() const { return _dimensions; } + /** @brief %Image size */ + inline typename DimensionTraits::VectorType size() const { return _size; } /** @brief Pointer to raw data */ inline void* data() { return _data; } - inline constexpr const void* data() const { return _data; } /**< @overload */ + inline const void* data() const { return _data; } /**< @overload */ private: std::string _name; - Math::Vector _dimensions; + Math::Vector _size; char* _data; }; diff --git a/src/Trade/MeshData.h b/src/Trade/MeshData.h deleted file mode 100644 index 7617f56c3..000000000 --- a/src/Trade/MeshData.h +++ /dev/null @@ -1,116 +0,0 @@ -#ifndef Magnum_Trade_MeshData_h -#define Magnum_Trade_MeshData_h -/* - Copyright © 2010, 2011, 2012 Vladimír Vondruš - - 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. -*/ - -/** @file - * @brief Class Magnum::Trade::MeshData - */ - -#include "Mesh.h" - -namespace Magnum { namespace Trade { - -/** -@brief %Mesh data - -Provides access to mesh data and additional information, such as primitive -type. -*/ -class MAGNUM_EXPORT MeshData { - MeshData(const MeshData& other) = delete; - MeshData(MeshData&& other) = delete; - MeshData& operator=(const MeshData& other) = delete; - MeshData& operator=(MeshData&& other) = delete; - - public: - /** - * @brief Constructor - * @param name %Mesh name - * @param primitive Primitive - * @param indices Array with indices or 0, if this is not - * indexed mesh - * @param vertices Array with vertex arrays. At least one - * vertex array should be present. - * @param normals Array with normal arrays or empty array - * @param textureCoords2D Array with two-dimensional texture - * coordinate arrays or empty array - */ - inline MeshData(const std::string& name, Mesh::Primitive primitive, std::vector* indices, std::vector*> vertices, std::vector*> normals, std::vector*> textureCoords2D): _name(name), _primitive(primitive), _indices(indices), _vertices(vertices), _normals(normals), _textureCoords2D(textureCoords2D) {} - - /** @brief Destructor */ - ~MeshData(); - - /** @brief %Mesh name */ - inline std::string name() const { return _name; } - - /** @brief Primitive */ - inline Mesh::Primitive primitive() const { return _primitive; } - - /** - * @brief Indices - * @return Indices or nullptr if the mesh is not indexed. - */ - inline std::vector* indices() { return _indices; } - inline const std::vector* indices() const { return _indices; } /**< @overload */ - - /** @brief Count of vertex arrays */ - inline unsigned int vertexArrayCount() const { return _vertices.size(); } - - /** - * @brief Vertices - * @param id ID of vertex data array - * @return Vertices or nullptr if there is no vertex array with given - * ID. - */ - inline std::vector* vertices(unsigned int id) { return _vertices[id]; } - inline const std::vector* vertices(unsigned int id) const { return _vertices[id]; } /**< @overload */ - - /** @brief Count of normal arrays */ - inline unsigned int normalArrayCount() const { return _normals.size(); } - - /** - * @brief Normals - * @param id ID of normal data array - * @return Vertices or nullptr if there is no normal array with given - * ID. - */ - inline std::vector* normals(unsigned int id) { return _normals[id]; } - inline const std::vector* normals(unsigned int id) const { return _normals[id]; } /**< @overload */ - - /** @brief Count of 2D texture coordinate arrays */ - inline unsigned int textureCoords2DArrayCount() const { return _textureCoords2D.size(); } - - /** - * @brief 2D texture coordinates - * @param id ID of texture coordinates array - * @return %Texture coordinates or nullptr if there is no texture - * coordinates array with given ID. - */ - inline std::vector* textureCoords2D(unsigned int id) { return _textureCoords2D[id]; } - inline const std::vector* textureCoords2D(unsigned int id) const { return _textureCoords2D[id]; } /**< @overload */ - - private: - std::string _name; - Mesh::Primitive _primitive; - std::vector* _indices; - std::vector*> _vertices; - std::vector*> _normals; - std::vector*> _textureCoords2D; -}; - -}} - -#endif diff --git a/src/Trade/MeshData2D.cpp b/src/Trade/MeshData2D.cpp new file mode 100644 index 000000000..8fee8177d --- /dev/null +++ b/src/Trade/MeshData2D.cpp @@ -0,0 +1,26 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "MeshData2D.h" + +namespace Magnum { namespace Trade { + +MeshData2D::~MeshData2D() { + delete _indices; + for(auto i: _positions) delete i; + for(auto i: _textureCoords2D) delete i; +} + +}} diff --git a/src/Trade/MeshData2D.h b/src/Trade/MeshData2D.h new file mode 100644 index 000000000..4e812f136 --- /dev/null +++ b/src/Trade/MeshData2D.h @@ -0,0 +1,106 @@ +#ifndef Magnum_Trade_MeshData2D_h +#define Magnum_Trade_MeshData2D_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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. +*/ + +/** @file + * @brief Class Magnum::Trade::MeshData2D + */ + +#include + +#include "Math/Point2D.h" +#include "Mesh.h" + +namespace Magnum { namespace Trade { + +/** +@brief Two-dimensional mesh data + +Provides access to mesh data and additional information, such as primitive +type. +@see MeshData3D +*/ +class MAGNUM_EXPORT MeshData2D { + MeshData2D(const MeshData2D& other) = delete; + MeshData2D(MeshData2D&& other) = delete; + MeshData2D& operator=(const MeshData2D& other) = delete; + MeshData2D& operator=(MeshData2D&& other) = delete; + + public: + /** + * @brief Constructor + * @param name %Mesh name + * @param primitive Primitive + * @param indices Array with indices or 0, if this is not + * indexed mesh + * @param positions Array with vertex positions. At least one + * position array should be present. + * @param textureCoords2D Array with two-dimensional texture + * coordinate arrays or empty array + */ + inline MeshData2D(const std::string& name, Mesh::Primitive primitive, std::vector* indices, std::vector*> positions, std::vector*> textureCoords2D): _name(name), _primitive(primitive), _indices(indices), _positions(positions), _textureCoords2D(textureCoords2D) {} + + /** @brief Destructor */ + ~MeshData2D(); + + /** @brief %Mesh name */ + inline std::string name() const { return _name; } + + /** @brief Primitive */ + inline Mesh::Primitive primitive() const { return _primitive; } + + /** + * @brief Indices + * @return Indices or nullptr if the mesh is not indexed. + */ + inline std::vector* indices() { return _indices; } + inline const std::vector* indices() const { return _indices; } /**< @overload */ + + /** @brief Count of vertex position arrays */ + inline std::uint32_t positionArrayCount() const { return _positions.size(); } + + /** + * @brief Positions + * @param id ID of position data array + * @return Positions or nullptr if there is no vertex array with given + * ID. + */ + inline std::vector* positions(std::uint32_t id) { return _positions[id]; } + inline const std::vector* positions(std::uint32_t id) const { return _positions[id]; } /**< @overload */ + + /** @brief Count of 2D texture coordinate arrays */ + inline std::uint32_t textureCoords2DArrayCount() const { return _textureCoords2D.size(); } + + /** + * @brief 2D texture coordinates + * @param id ID of texture coordinates array + * @return %Texture coordinates or nullptr if there is no texture + * coordinates array with given ID. + */ + inline std::vector* textureCoords2D(std::uint32_t id) { return _textureCoords2D[id]; } + inline const std::vector* textureCoords2D(std::uint32_t id) const { return _textureCoords2D[id]; } /**< @overload */ + + private: + std::string _name; + Mesh::Primitive _primitive; + std::vector* _indices; + std::vector*> _positions; + std::vector*> _textureCoords2D; +}; + +}} + +#endif diff --git a/src/Trade/MeshData.cpp b/src/Trade/MeshData3D.cpp similarity index 85% rename from src/Trade/MeshData.cpp rename to src/Trade/MeshData3D.cpp index 94308d843..8dd8ab10c 100644 --- a/src/Trade/MeshData.cpp +++ b/src/Trade/MeshData3D.cpp @@ -13,13 +13,13 @@ GNU Lesser General Public License version 3 for more details. */ -#include "MeshData.h" +#include "MeshData3D.h" namespace Magnum { namespace Trade { -MeshData::~MeshData() { +MeshData3D::~MeshData3D() { delete _indices; - for(auto it = _vertices.begin(); it != _vertices.end(); ++it) delete *it; + for(auto it = _positions.begin(); it != _positions.end(); ++it) delete *it; for(auto it = _normals.begin(); it != _normals.end(); ++it) delete *it; for(auto it = _textureCoords2D.begin(); it != _textureCoords2D.end(); ++it) delete *it; } diff --git a/src/Trade/MeshData3D.h b/src/Trade/MeshData3D.h new file mode 100644 index 000000000..1de247976 --- /dev/null +++ b/src/Trade/MeshData3D.h @@ -0,0 +1,120 @@ +#ifndef Magnum_Trade_MeshData3D_h +#define Magnum_Trade_MeshData3D_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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. +*/ + +/** @file + * @brief Class Magnum::Trade::MeshData3D + */ + +#include + +#include "Math/Point3D.h" +#include "Mesh.h" + +namespace Magnum { namespace Trade { + +/** +@brief Three-dimensional mesh data + +Provides access to mesh data and additional information, such as primitive +type. +@see MeshData2D +*/ +class MAGNUM_EXPORT MeshData3D { + MeshData3D(const MeshData3D& other) = delete; + MeshData3D(MeshData3D&& other) = delete; + MeshData3D& operator=(const MeshData3D& other) = delete; + MeshData3D& operator=(MeshData3D&& other) = delete; + + public: + /** + * @brief Constructor + * @param name %Mesh name + * @param primitive Primitive + * @param indices Array with indices or 0, if this is not + * indexed mesh + * @param positions Array with vertex positions. At least one + * position array should be present. + * @param normals Array with normal arrays or empty array + * @param textureCoords2D Array with two-dimensional texture + * coordinate arrays or empty array + */ + inline MeshData3D(const std::string& name, Mesh::Primitive primitive, std::vector* indices, std::vector*> positions, std::vector*> normals, std::vector*> textureCoords2D): _name(name), _primitive(primitive), _indices(indices), _positions(positions), _normals(normals), _textureCoords2D(textureCoords2D) {} + + /** @brief Destructor */ + ~MeshData3D(); + + /** @brief %Mesh name */ + inline std::string name() const { return _name; } + + /** @brief Primitive */ + inline Mesh::Primitive primitive() const { return _primitive; } + + /** + * @brief Indices + * @return Indices or nullptr if the mesh is not indexed. + */ + inline std::vector* indices() { return _indices; } + inline const std::vector* indices() const { return _indices; } /**< @overload */ + + /** @brief Count of vertex position arrays */ + inline std::uint32_t positionArrayCount() const { return _positions.size(); } + + /** + * @brief Positions + * @param id ID of position data array + * @return Positions or nullptr if there is no vertex array with given + * ID. + */ + inline std::vector* positions(std::uint32_t id) { return _positions[id]; } + inline const std::vector* positions(std::uint32_t id) const { return _positions[id]; } /**< @overload */ + + /** @brief Count of normal arrays */ + inline std::uint32_t normalArrayCount() const { return _normals.size(); } + + /** + * @brief Normals + * @param id ID of normal data array + * @return Normals or nullptr if there is no normal array with given + * ID. + */ + inline std::vector* normals(std::uint32_t id) { return _normals[id]; } + inline const std::vector* normals(std::uint32_t id) const { return _normals[id]; } /**< @overload */ + + /** @brief Count of 2D texture coordinate arrays */ + inline std::uint32_t textureCoords2DArrayCount() const { return _textureCoords2D.size(); } + + /** + * @brief 2D texture coordinates + * @param id ID of texture coordinates array + * @return %Texture coordinates or nullptr if there is no texture + * coordinates array with given ID. + */ + inline std::vector* textureCoords2D(std::uint32_t id) { return _textureCoords2D[id]; } + inline const std::vector* textureCoords2D(std::uint32_t id) const { return _textureCoords2D[id]; } /**< @overload */ + + private: + std::string _name; + Mesh::Primitive _primitive; + std::vector* _indices; + std::vector*> _positions; + std::vector*> _normals; + std::vector*> _textureCoords2D; +}; + +}} + +#endif diff --git a/src/Trade/MeshObjectData.h b/src/Trade/MeshObjectData2D.h similarity index 56% rename from src/Trade/MeshObjectData.h rename to src/Trade/MeshObjectData2D.h index e8b9568e3..dff0770b0 100644 --- a/src/Trade/MeshObjectData.h +++ b/src/Trade/MeshObjectData2D.h @@ -1,5 +1,5 @@ -#ifndef Magnum_Trade_MeshObjectData_h -#define Magnum_Trade_MeshObjectData_h +#ifndef Magnum_Trade_MeshObjectData2D_h +#define Magnum_Trade_MeshObjectData2D_h /* Copyright © 2010, 2011, 2012 Vladimír Vondruš @@ -16,23 +16,24 @@ */ /** @file - * @brief Class Magnum::Trade::MeshObjectData + * @brief Class Magnum::Trade::MeshObjectData2D */ -#include "ObjectData.h" +#include "ObjectData2D.h" namespace Magnum { namespace Trade { /** -@brief %Mesh object data +@brief Two-dimensional mesh object data Provides access to material information for given mesh instance. +@see MeshObjectData3D */ -class MeshObjectData: public ObjectData { - MeshObjectData(const MeshObjectData& other) = delete; - MeshObjectData(MeshObjectData&& other) = delete; - MeshObjectData& operator=(const MeshObjectData& other) = delete; - MeshObjectData& operator=(MeshObjectData&& other) = delete; +class MeshObjectData2D: public ObjectData2D { + MeshObjectData2D(const MeshObjectData2D& other) = delete; + MeshObjectData2D(MeshObjectData2D&& other) = delete; + MeshObjectData2D& operator=(const MeshObjectData2D& other) = delete; + MeshObjectData2D& operator=(MeshObjectData2D&& other) = delete; public: /** @@ -45,13 +46,13 @@ class MeshObjectData: public ObjectData { * * Creates object with mesh instance type. */ - inline MeshObjectData(const std::string& name, const std::vector& children, const Matrix4& transformation, unsigned int instance, unsigned int material): ObjectData(name, children, transformation, InstanceType::Mesh, instance), _material(material) {} + inline MeshObjectData2D(const std::string& name, const std::vector& children, const Matrix4& transformation, std::uint32_t instance, std::uint32_t material): ObjectData2D(name, children, transformation, InstanceType::Mesh, instance), _material(material) {} /** @brief Material ID */ - inline unsigned int material() const { return _material; } + inline std::uint32_t material() const { return _material; } private: - unsigned int _material; + std::uint32_t _material; }; }} diff --git a/src/Trade/MeshObjectData3D.h b/src/Trade/MeshObjectData3D.h new file mode 100644 index 000000000..acec3ed31 --- /dev/null +++ b/src/Trade/MeshObjectData3D.h @@ -0,0 +1,60 @@ +#ifndef Magnum_Trade_MeshObjectData3D_h +#define Magnum_Trade_MeshObjectData3D_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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. +*/ + +/** @file + * @brief Class Magnum::Trade::MeshObjectData3D + */ + +#include "ObjectData3D.h" + +namespace Magnum { namespace Trade { + +/** +@brief Three-dimensional mesh object data + +Provides access to material information for given mesh instance. +@see MeshObjectData2D +*/ +class MeshObjectData3D: public ObjectData3D { + MeshObjectData3D(const MeshObjectData3D& other) = delete; + MeshObjectData3D(MeshObjectData3D&& other) = delete; + MeshObjectData3D& operator=(const MeshObjectData3D& other) = delete; + MeshObjectData3D& operator=(MeshObjectData3D&& other) = delete; + + public: + /** + * @brief Constructor + * @param name %Mesh object name + * @param children Child objects + * @param transformation Transformation (relative to parent) + * @param instance Instance ID + * @param material Material ID + * + * Creates object with mesh instance type. + */ + inline MeshObjectData3D(const std::string& name, const std::vector& children, const Matrix4& transformation, std::uint32_t instance, std::uint32_t material): ObjectData3D(name, children, transformation, InstanceType::Mesh, instance), _material(material) {} + + /** @brief Material ID */ + inline std::uint32_t material() const { return _material; } + + private: + std::uint32_t _material; +}; + +}} + +#endif diff --git a/src/Trade/ObjectData2D.h b/src/Trade/ObjectData2D.h new file mode 100644 index 000000000..8cc1b9226 --- /dev/null +++ b/src/Trade/ObjectData2D.h @@ -0,0 +1,104 @@ +#ifndef Magnum_Trade_ObjectData2D_h +#define Magnum_Trade_ObjectData2D_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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. +*/ + +/** @file + * @brief Class Magnum::Trade::ObjectData2D + */ + +#include "Math/Matrix4.h" +#include "Magnum.h" + +namespace Magnum { namespace Trade { + +/** +@brief Two-dimensional object data + +Provides access to object transformation and hierarchy. See also +MeshObjectData2D, which is specialized for objects with mesh instance type. +@see ObjectData3D +*/ +class ObjectData2D { + ObjectData2D(const ObjectData2D& other) = delete; + ObjectData2D(ObjectData2D&& other) = delete; + ObjectData2D& operator=(const ObjectData2D& other) = delete; + ObjectData2D& operator=(ObjectData2D&& other) = delete; + + public: + /** @brief Instance type */ + enum class InstanceType { + Camera, /**< Camera instance (see CameraData) */ + Mesh, /**< Three-dimensional mesh instance (see MeshData2D) */ + Empty /**< Empty */ + }; + + /** + * @brief Constructor + * @param name Object name + * @param children Child objects + * @param transformation Transformation (relative to parent) + * @param instanceType Instance type + * @param instanceId Instance ID + */ + inline ObjectData2D(const std::string& name, const std::vector& children, const Matrix3& transformation, InstanceType instanceType, std::uint32_t instanceId): _name(name), _children(children), _transformation(transformation), _instanceType(instanceType), _instanceId(instanceId) {} + + /** + * @brief Constructor for empty instance + * @param name Object name + * @param children Child objects + * @param transformation Transformation (relative to parent) + */ + inline ObjectData2D(const std::string& name, const std::vector& children, const Matrix3& transformation): _name(name), _children(children), _transformation(transformation), _instanceType(InstanceType::Empty), _instanceId(-1) {} + + /** @brief Destructor */ + inline virtual ~ObjectData2D() {} + + /** @brief %Object name */ + inline std::string name() const { return _name; } + + /** @brief Child objects */ + inline std::vector& children() { return _children; } + + /** @brief Transformation (relative to parent) */ + inline Matrix3 transformation() const { return _transformation; } + + /** + * @brief Instance type + * @return Type of instance held by this object + * + * If the instance is of type InstanceType::Mesh, the instance can be + * casted to MeshObjectData2D and provide more information. + */ + inline InstanceType instanceType() const { return _instanceType; } + + /** + * @brief Instance ID + * @return ID of given camera / light / mesh etc., specified by + * instanceType() + */ + inline std::int32_t instanceId() const { return _instanceId; } + + private: + std::string _name; + std::vector _children; + Matrix3 _transformation; + InstanceType _instanceType; + std::int32_t _instanceId; +}; + +}} + +#endif diff --git a/src/Trade/ObjectData.h b/src/Trade/ObjectData3D.h similarity index 61% rename from src/Trade/ObjectData.h rename to src/Trade/ObjectData3D.h index 3da9cd9ad..0f125b672 100644 --- a/src/Trade/ObjectData.h +++ b/src/Trade/ObjectData3D.h @@ -1,5 +1,5 @@ -#ifndef Magnum_Trade_ObjectData_h -#define Magnum_Trade_ObjectData_h +#ifndef Magnum_Trade_ObjectData3D_h +#define Magnum_Trade_ObjectData3D_h /* Copyright © 2010, 2011, 2012 Vladimír Vondruš @@ -16,31 +16,33 @@ */ /** @file - * @brief Class Magnum::Trade::ObjectData + * @brief Class Magnum::Trade::ObjectData3D */ +#include "Math/Matrix4.h" #include "Magnum.h" namespace Magnum { namespace Trade { /** -@brief %Object data +@brief Three-dimensional object data Provides access to object transformation and hierarchy. See also -MeshObjectData, which is specialized for objects with mesh instance type. +MeshObjectData3D, which is specialized for objects with mesh instance type. +@see ObjectData2D */ -class ObjectData { - ObjectData(const ObjectData& other) = delete; - ObjectData(ObjectData&& other) = delete; - ObjectData& operator=(const ObjectData& other) = delete; - ObjectData& operator=(ObjectData&& other) = delete; +class ObjectData3D { + ObjectData3D(const ObjectData3D& other) = delete; + ObjectData3D(ObjectData3D&& other) = delete; + ObjectData3D& operator=(const ObjectData3D& other) = delete; + ObjectData3D& operator=(ObjectData3D&& other) = delete; public: /** @brief Instance type */ enum class InstanceType { Camera, /**< Camera instance (see CameraData) */ Light, /**< Light instance (see LightData) */ - Mesh, /**< Mesh instance (see MeshData) */ + Mesh, /**< Three-dimensional mesh instance (see MeshData3D) */ Empty /**< Empty */ }; @@ -52,7 +54,7 @@ class ObjectData { * @param instanceType Instance type * @param instanceId Instance ID */ - inline ObjectData(const std::string& name, const std::vector& children, const Matrix4& transformation, InstanceType instanceType, unsigned int instanceId): _name(name), _children(children), _transformation(transformation), _instanceType(instanceType), _instanceId(instanceId) {} + inline ObjectData3D(const std::string& name, const std::vector& children, const Matrix4& transformation, InstanceType instanceType, std::uint32_t instanceId): _name(name), _children(children), _transformation(transformation), _instanceType(instanceType), _instanceId(instanceId) {} /** * @brief Constructor for empty instance @@ -60,16 +62,16 @@ class ObjectData { * @param children Child objects * @param transformation Transformation (relative to parent) */ - inline ObjectData(const std::string& name, const std::vector& children, const Matrix4& transformation): _name(name), _children(children), _transformation(transformation), _instanceType(InstanceType::Empty), _instanceId(-1) {} + inline ObjectData3D(const std::string& name, const std::vector& children, const Matrix4& transformation): _name(name), _children(children), _transformation(transformation), _instanceType(InstanceType::Empty), _instanceId(-1) {} /** @brief Destructor */ - inline virtual ~ObjectData() {} + inline virtual ~ObjectData3D() {} /** @brief %Object name */ inline std::string name() const { return _name; } /** @brief Child objects */ - inline std::vector& children() { return _children; } + inline std::vector& children() { return _children; } /** @brief Transformation (relative to parent) */ inline Matrix4 transformation() const { return _transformation; } @@ -79,7 +81,7 @@ class ObjectData { * @return Type of instance held by this object * * If the instance is of type InstanceType::Mesh, the instance can be - * casted to MeshObjectData and provide more information. + * casted to MeshObjectData3D and provide more information. */ inline InstanceType instanceType() const { return _instanceType; } @@ -88,14 +90,14 @@ class ObjectData { * @return ID of given camera / light / mesh etc., specified by * instanceType() */ - inline int instanceId() const { return _instanceId; } + inline std::int32_t instanceId() const { return _instanceId; } private: std::string _name; - std::vector _children; + std::vector _children; Matrix4 _transformation; InstanceType _instanceType; - int _instanceId; + std::int32_t _instanceId; }; }} diff --git a/src/Trade/PhongMaterialData.h b/src/Trade/PhongMaterialData.h index 7aa7cf453..21896cba3 100644 --- a/src/Trade/PhongMaterialData.h +++ b/src/Trade/PhongMaterialData.h @@ -19,6 +19,7 @@ * @brief Class Magnum::Trade::PhongMaterialData */ +#include "Math/Vector3.h" #include "Magnum.h" #include "AbstractMaterialData.h" diff --git a/src/Trade/SceneData.h b/src/Trade/SceneData.h index 678243208..226fa327a 100644 --- a/src/Trade/SceneData.h +++ b/src/Trade/SceneData.h @@ -36,20 +36,25 @@ class MAGNUM_EXPORT SceneData { public: /** * @brief Constructor - * @param name %Scene name - * @param children Child objects + * @param name Scene name + * @param children2D Two-dimensional child objects + * @param children3D Three-dimensional child objects */ - inline SceneData(const std::string& name, const std::vector& children): _name(name), _children(children) {} + inline SceneData(const std::string& name, const std::vector& children2D, const std::vector& children3D): _name(name), _children2D(children2D), _children3D(children3D) {} - /** @brief %Scene name */ + /** @brief Scene name */ inline std::string name() const { return _name; } - /** @brief Child objects */ - inline const std::vector& children() const { return _children; } + /** @brief Two-dimensional child objects */ + inline const std::vector& children2D() const { return _children2D; } + + /** @brief Three-dimensional child objects */ + inline const std::vector& children3D() const { return _children3D; } private: std::string _name; - std::vector _children; + std::vector _children2D, + _children3D; }; }} diff --git a/src/TypeTraits.cpp b/src/TypeTraits.cpp index f9936e742..4dad71afe 100644 --- a/src/TypeTraits.cpp +++ b/src/TypeTraits.cpp @@ -15,18 +15,22 @@ #include "TypeTraits.h" +#include + +using namespace std; + namespace Magnum { #ifndef DOXYGEN_GENERATING_OUTPUT -static_assert(sizeof(GLubyte) == sizeof(unsigned char), "GLubyte is not the same as unsigned char"); -static_assert(sizeof(GLbyte) == sizeof(char), "GLbyte is not the same as char"); -static_assert(sizeof(GLushort) == sizeof(unsigned short), "GLushort is not the same as unsigned short"); -static_assert(sizeof(GLshort) == sizeof(short), "GLshort is not the same as short"); -static_assert(sizeof(GLuint) == sizeof(unsigned int), "GLuint is not the same as unsigned int"); -static_assert(sizeof(GLint) == sizeof(int), "GLint is not the same as int"); -static_assert(sizeof(GLfloat) == sizeof(float), "GLfloat is not the same as float"); +static_assert(is_same::value, "GLubyte is not the same as uint8_t"); +static_assert(is_same::value, "GLbyte is not the same as int8_t"); +static_assert(is_same::value, "GLushort is not the same as uint16_t"); +static_assert(is_same::value, "GLshort is not the same as int16_t"); +static_assert(is_same::value, "GLuint is not the same as uint32_t"); +static_assert(is_same::value, "GLint is not the same as int32_t"); +static_assert(is_same::value, "GLfloat is not the same as float"); #ifndef MAGNUM_TARGET_GLES -static_assert(sizeof(GLdouble) == sizeof(double), "GLdouble is not the same as double"); +static_assert(is_same::value, "GLdouble is not the same as double"); #endif #endif diff --git a/src/TypeTraits.h b/src/TypeTraits.h index 3e95eec12..23f882df5 100644 --- a/src/TypeTraits.h +++ b/src/TypeTraits.h @@ -19,10 +19,20 @@ * @brief Enum Magnum::Type, class Magnum::TypeOf, Magnum::TypeInfo, Magnum::TypeTraits */ +#include "Math/MathTypeTraits.h" #include "AbstractImage.h" namespace Magnum { +namespace Math { + template class RectangularMatrix; + template class Matrix; + template class Vector; +} + +template class Color3; +template class Color4; + /** @brief Traits class for plain OpenGL types @@ -32,7 +42,17 @@ Where it makes sense, this class extends Math::MathTypeTraits with OpenGL-specific traits. */ #ifdef DOXYGEN_GENERATING_OUTPUT -template struct TypeTraits: public Math::MathTypeTraits { +template struct TypeTraits: Math::MathTypeTraits { + /** + * @brief Corresponding type for vertex attributes + * + * Implemented only in types which can be used for vertex attributes. This + * function is not present for types unusable for vertex attributes, like + * five-component vectors or GLdouble in OpenGL ES. See also + * @ref AbstractShaderProgram-types. + */ + typedef U AttributeType; + /** * @brief OpenGL plain type ID * @@ -64,14 +84,14 @@ template struct TypeTraits: public Math::MathTypeTraits { * Returns sizeof(GLfloat) for GLfloat, but also sizeof(GLfloat) for * Vector3. See count(). */ - inline constexpr static size_t size(); + inline constexpr static std::size_t size(); /** * @brief Count of plain elements in this type * * Returns 1 for plain OpenGL types like GLint, but e.g. 3 for Vector3. */ - inline constexpr static size_t count(); + inline constexpr static std::size_t count(); }; #else template struct TypeTraits {}; @@ -91,7 +111,7 @@ enum class Type: GLenum { , /** * Double - * @requires_gl + * @requires_gl Only floats are available in OpenGL ES. */ Double = GL_DOUBLE #endif @@ -128,11 +148,11 @@ struct MAGNUM_EXPORT TypeInfo { * These two lines provide the same information, one at compile time, * one at runtime: * @code - * size_t size = TypeTraits::size(); - * size_t size = TypeInfo::sizeOf(Type::UnsignedByte); + * std::size_t size = TypeTraits::size(); + * std::size_t size = TypeInfo::sizeOf(Type::UnsignedByte); * @endcode */ - static size_t sizeOf(Type type); + static std::size_t sizeOf(Type type); /** * @brief Whether the type is integral @@ -156,94 +176,169 @@ template<> struct TypeOf { typedef GLfloat Type; }; template<> struct TypeOf { typedef GLdouble Type; }; #endif -template<> struct TypeTraits: public Math::MathTypeTraits { +template<> struct TypeTraits: Math::MathTypeTraits { + /* Can not be used for attributes */ inline constexpr static Type type() { return Type::UnsignedByte; } inline constexpr static Type indexType() { return Type::UnsignedByte; } inline constexpr static AbstractImage::ComponentType imageType() { return AbstractImage::ComponentType::UnsignedByte; } - inline constexpr static size_t size() { return sizeof(GLubyte); } - inline constexpr static size_t count() { return 1; } + inline constexpr static std::size_t size() { return sizeof(GLubyte); } + inline constexpr static std::size_t count() { return 1; } }; -template<> struct TypeTraits: public Math::MathTypeTraits { +template<> struct TypeTraits: Math::MathTypeTraits { + /* Can not be used for attributes */ inline constexpr static Type type() { return Type::Byte; } /* Can not be used for indices */ inline constexpr static AbstractImage::ComponentType imageType() { return AbstractImage::ComponentType::Byte; } - inline constexpr static size_t size() { return sizeof(GLbyte); } - inline constexpr static size_t count() { return 1; } + inline constexpr static std::size_t size() { return sizeof(GLbyte); } + inline constexpr static std::size_t count() { return 1; } }; -template<> struct TypeTraits: public Math::MathTypeTraits { +template<> struct TypeTraits: Math::MathTypeTraits { + /* Can not be used for attributes */ inline constexpr static Type type() { return Type::UnsignedShort; } inline constexpr static Type indexType() { return Type::UnsignedShort; } inline constexpr static AbstractImage::ComponentType imageType() { return AbstractImage::ComponentType::UnsignedShort; } - inline constexpr static size_t size() { return sizeof(GLushort); } - inline constexpr static size_t count() { return 1; } + inline constexpr static std::size_t size() { return sizeof(GLushort); } + inline constexpr static std::size_t count() { return 1; } }; -template<> struct TypeTraits: public Math::MathTypeTraits { +template<> struct TypeTraits: Math::MathTypeTraits { + /* Can not be used for attributes */ inline constexpr static Type type() { return Type::Short; } /* Can not be used for indices */ inline constexpr static AbstractImage::ComponentType imageType() { return AbstractImage::ComponentType::Short; } - inline constexpr static size_t size() { return sizeof(GLshort); } - inline constexpr static size_t count() { return 1; } + inline constexpr static std::size_t size() { return sizeof(GLshort); } + inline constexpr static std::size_t count() { return 1; } }; -template<> struct TypeTraits: public Math::MathTypeTraits { +template<> struct TypeTraits: Math::MathTypeTraits { + typedef GLuint AttributeType; inline constexpr static Type type() { return Type::UnsignedInt; } inline constexpr static Type indexType() { return Type::UnsignedInt; } inline constexpr static AbstractImage::ComponentType imageType() { return AbstractImage::ComponentType::UnsignedInt; } - inline constexpr static size_t size() { return sizeof(GLuint); } - inline constexpr static size_t count() { return 1; } + inline constexpr static std::size_t size() { return sizeof(GLuint); } + inline constexpr static std::size_t count() { return 1; } }; -template<> struct TypeTraits: public Math::MathTypeTraits { +template<> struct TypeTraits: Math::MathTypeTraits { + typedef GLint AttributeType; inline constexpr static Type type() { return Type::Int; } /* Can not be used for indices */ inline constexpr static AbstractImage::ComponentType imageType() { return AbstractImage::ComponentType::Int; } - inline constexpr static size_t size() { return sizeof(GLint); } - inline constexpr static size_t count() { return 1; } + inline constexpr static std::size_t size() { return sizeof(GLint); } + inline constexpr static std::size_t count() { return 1; } }; -template<> struct TypeTraits: public Math::MathTypeTraits { +template<> struct TypeTraits: Math::MathTypeTraits { + typedef GLfloat AttributeType; inline constexpr static Type type() { return Type::Float; } /* Can not be used for indices */ inline constexpr static AbstractImage::ComponentType imageType() { return AbstractImage::ComponentType::Float; } - inline constexpr static size_t size() { return sizeof(GLfloat); } - inline constexpr static size_t count() { return 1; } + inline constexpr static std::size_t size() { return sizeof(GLfloat); } + inline constexpr static std::size_t count() { return 1; } }; #ifndef MAGNUM_TARGET_GLES -template<> struct TypeTraits: public Math::MathTypeTraits { +template<> struct TypeTraits: Math::MathTypeTraits { + typedef GLdouble AttributeType; inline constexpr static Type type() { return Type::Double; } /* Can not be used for indices */ /* Can not be used for images */ - inline constexpr static size_t size() { return sizeof(GLdouble); } - inline constexpr static size_t count() { return 1; } + inline constexpr static std::size_t size() { return sizeof(GLdouble); } + inline constexpr static std::size_t count() { return 1; } }; #endif -template struct TypeTraits> { - inline constexpr static Type type() { return TypeTraits::type(); } - /* Can not be used for indices */ - /* Can not be used for images */ - inline constexpr static size_t size() { return sizeof(T); } - inline constexpr static size_t count() { return vectorSize; } -}; +namespace Implementation { + template struct VectorTypeTraits { + /* Might be used for attributes, see below */ + inline constexpr static Type type() { return TypeTraits::type(); } + /* Might be used for attributes, see below */ + /* Can not be used for indices */ + /* Can not be used for images */ + inline constexpr static std::size_t size() { return sizeof(T); } + inline constexpr static std::size_t count() { return vectorSize; } + }; -template struct TypeTraits>: public TypeTraits> {}; -template struct TypeTraits>: public TypeTraits> {}; -template struct TypeTraits>: public TypeTraits> {}; + template struct VectorAttributeType {}; -template struct TypeTraits> { - inline constexpr static Type type() { return TypeTraits::type(); } - /* Can not be used for indices */ - /* Can not be used for images */ - inline constexpr static size_t size() { return sizeof(T); } - inline constexpr static size_t count() { return matrixSize*matrixSize; } -}; + template<> struct VectorAttributeType { + typedef GLuint AttributeType; + }; + + template<> struct VectorAttributeType { + typedef GLint AttributeType; + }; + + template<> struct VectorAttributeType { + typedef GLfloat AttributeType; + }; + + #ifndef MAGNUM_TARGET_GLES + template<> struct VectorAttributeType { + typedef GLdouble AttributeType; + }; + #endif +} + +template struct TypeTraits>: Implementation::VectorTypeTraits {}; + +/* Only some vectors can be used as attributes */ +template struct TypeTraits>: Implementation::VectorTypeTraits<1, T>, Implementation::VectorAttributeType {}; +template struct TypeTraits>: Implementation::VectorTypeTraits<2, T>, Implementation::VectorAttributeType {}; +template struct TypeTraits>: Implementation::VectorTypeTraits<3, T>, Implementation::VectorAttributeType {}; +template struct TypeTraits>: Implementation::VectorTypeTraits<4, T>, Implementation::VectorAttributeType {}; + +template struct TypeTraits>: TypeTraits> {}; +template struct TypeTraits>: TypeTraits> {}; +template struct TypeTraits>: TypeTraits> {}; +template struct TypeTraits>: TypeTraits> {}; +template struct TypeTraits>: TypeTraits> {}; +template struct TypeTraits>: TypeTraits> {}; +template struct TypeTraits>: TypeTraits> {}; + +namespace Implementation { + template struct MatrixTypeTraits { + inline constexpr static Type type() { return TypeTraits::type(); } + /* Might be used for attributes, see below */ + /* Can not be used for indices */ + /* Can not be used for images */ + inline constexpr static std::size_t size() { return sizeof(T); } + inline constexpr static std::size_t count() { return rows; } + inline constexpr static std::size_t vectors() { return cols; } + }; + + template struct MatrixAttributeType {}; + + template<> struct MatrixAttributeType { + typedef GLfloat AttributeType; + }; + + #ifndef MAGNUM_TARGET_GLES + template<> struct MatrixAttributeType { + typedef GLdouble AttributeType; + }; + #endif +} + +template struct TypeTraits>: Implementation::MatrixTypeTraits {}; + +/* Only some floating-point matrices can be used as attributes */ +template struct TypeTraits>: Implementation::MatrixTypeTraits<2, 2, T>, Implementation::MatrixAttributeType {}; +template struct TypeTraits>: Implementation::MatrixTypeTraits<3, 3, T>, Implementation::MatrixAttributeType {}; +template struct TypeTraits>: Implementation::MatrixTypeTraits<4, 4, T>, Implementation::MatrixAttributeType {}; +template struct TypeTraits>: Implementation::MatrixTypeTraits<2, 3, T>, Implementation::MatrixAttributeType {}; +template struct TypeTraits>: Implementation::MatrixTypeTraits<3, 2, T>, Implementation::MatrixAttributeType {}; +template struct TypeTraits>: Implementation::MatrixTypeTraits<2, 4, T>, Implementation::MatrixAttributeType {}; +template struct TypeTraits>: Implementation::MatrixTypeTraits<4, 2, T>, Implementation::MatrixAttributeType {}; +template struct TypeTraits>: Implementation::MatrixTypeTraits<3, 4, T>, Implementation::MatrixAttributeType {}; +template struct TypeTraits>: Implementation::MatrixTypeTraits<4, 3, T>, Implementation::MatrixAttributeType {}; + +template struct TypeTraits>: TypeTraits> {}; -template struct TypeTraits>: public TypeTraits> {}; -template struct TypeTraits>: public TypeTraits> {}; +template struct TypeTraits>: TypeTraits> {}; +template struct TypeTraits>: TypeTraits> {}; #endif } diff --git a/src/magnumCompatibility.h b/src/magnumCompatibility.h index 70a8de0ed..bd81d0bb4 100644 --- a/src/magnumCompatibility.h +++ b/src/magnumCompatibility.h @@ -15,11 +15,11 @@ GNU Lesser General Public License version 3 for more details. */ +#include "corradeCompatibility.h" #include "magnumConfigure.h" -#ifdef CORRADE_GCC45_COMPATIBILITY -#define constexpr -#define nullptr 0 +#ifdef MAGNUM_GCC46_COMPATIBILITY +#define override #endif #endif diff --git a/src/magnumConfigure.h.cmake b/src/magnumConfigure.h.cmake index 9e8a3c7e8..a2d1d818f 100644 --- a/src/magnumConfigure.h.cmake +++ b/src/magnumConfigure.h.cmake @@ -1 +1,3 @@ #cmakedefine MAGNUM_TARGET_GLES +#cmakedefine MAGNUM_TARGET_GLES2 +#cmakedefine MAGNUM_GCC46_COMPATIBILITY