@ -155,12 +154,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
### <aname="section1_1"></a> 1.1. Using global headers
GLM is a header-only library, and thus does not need to be compiled. We can use GLM's implementation of GLSL's mathematics functionality by including the `<glm/glm.hpp>` header:
```cpp
#include<glm/glm.hpp>
```
Using GLM through headers including everything:
To extend the feature set supported by GLM and keeping the library as close to GLSL as possible, new features are implemented as extensions that can be included thought a separated header:
### <aname="section1_2"></a> 1.2. Using separated headers
*Note: Including `glm/glm.hpp` and `glm/ext.hpp` is convenient but pull a lot of code which will significantly increase build time, particularly if these files are included in all source files. We may prefer to use the approaches describe in the two following sections to keep the project build fast.*
GLM relies on C++ templates heavily, and may significantly increase compilation times for projects that use it. Hence, user projects could only include the features they actually use:
### <aname="section1_2"></a> 1.2. Using separated headers
GLM relies on C++ templates heavily, and may significantly increase compilation times for projects that use it. Hence, user projects could only include the features they actually use. Following is the list of all the core features, based on GLSL specification, headers:
```cpp
#include<glm/vec2.hpp> // vec2, bvec2, dvec2, ivec2 and uvec2
#include<glm/vec3.hpp> // vec3, bvec3, dvec3, ivec3 and uvec3
@ -206,7 +205,7 @@ GLM relies on C++ templates heavily, and may significantly increase compilation
#include<glm/vector_relational.hpp> // all the GLSL vector relational functions: equal, less, etc.
```
Using GLM through headers including features separated following the structure of GLSL specifications:
The following is a code sample using separated core headers and an extension:
```cpp
// Include GLM core features
#include<glm/vec2.hpp> // vec2
@ -214,7 +213,7 @@ Using GLM through headers including features separated following the structure o
GLM does not depend on external libraries or headers such as `<GL/gl.h>`, [`<GL/glcorearb.h>`](http://www.opengl.org/registry/api/GL/glcorearb.h), `<GLES3/gl3.h>`, `<GL/glu.h>`, or `<windows.h>`.
Shader languages like GLSL often feature so-called swizzle expressions, which may be used to freely select and arrange a vector's components. For example, `variable.x`, `variable.xzy` and `variable.zxyy` respectively form a scalar, a 3D vector and a 4D vector. The result of a swizzle expression in GLSL can be either an R-value or an L-value. Swizzle expressions can be written with characters from exactly one of `xyzw` (usually for positions), `rgba` (usually for colors), and `stpq` (usually for texture coordinates).
```cpp
vec4 A;
vec2 B;
B.yx = A.wy;
B = A.xx;
vec3 C = A.bgr;
vec3 D = B.rsz; // Invalid, won't compile
```
### <aname="section2_1"></a> 2.1. GLM\_FORCE\_MESSAGES: Platform auto detection and default configuration
GLM optionally supports some of this functionality via the methods described in the following sections. Swizzling can be enabled by defining `GLM_FORCE_SWIZZLE` before including any GLM header files, or as part of a project's build process.
When included, GLM will first automatically detect the compiler used, the C++ standard supported, the compiler arguments used to configure itself matching the build environment.
*Note that enabling swizzle expressions will massively increase the size of your binaries and the time it takes to compile them!*
For example, if the compiler arguments request AVX code generation, GLM will rely on its code path providing AVX optimizations when available.
We can change GLM configuration using specific C++ preprocessor defines that must be declared before including any GLM headers.
When compiling GLM as C++98, R-value swizzle expressions are simulated through member functions of each vector type.
Using `GLM_FORCE_MESSAGES`, GLM will report the configuration as part of the build log.
```cpp
#define GLM_FORCE_SWIZZLE // Or defined when building (e.g. -DGLM_FORCE_SWIZZLE)
#define GLM_FORCE_MESSAGES // Or defined when building (e.g. -DGLM_FORCE_SWIZZLE)
#include<glm/glm.hpp>
```
void foo()
{
glm::vec4 ColorRGBA(1.0f, 0.5f, 0.0f, 1.0f);
glm::vec3 ColorBGR = ColorRGBA.bgr();
Example of configuration log generated by `GLM_FORCE_MESSAGES`:
```cpp
GLM: version 0.9.9.1
GLM: C++ 17 with extensions
GLM: Clang compiler detected
GLM: x86 64 bits with AVX instruction set build target
GLM: Linux platform detected
GLM: GLM_FORCE_SWIZZLE is undefined. swizzling functions or operators are disabled.
GLM: GLM_FORCE_SIZE_T_LENGTH is undefined. .length() returns a glm::length_t, a typedef of int following GLSL.
GLM: GLM_FORCE_UNRESTRICTED_GENTYPE is undefined. Follows strictly GLSL on valid function genTypes.
GLM: GLM_FORCE_DEPTH_ZERO_TO_ONE is undefined. Using negative one to one depth clip space.
GLM: GLM_FORCE_LEFT_HANDED is undefined. Using right handed coordinate system.
```
glm::vec3 PositionA(1.0f, 0.5f, 0.0f, 1.0f);
glm::vec3 PositionB = PositionXYZ.xyz() * 2.0f;
The following subsections describe each configurations and defines.
glm::vec2 TexcoordST(1.0f, 0.5f);
glm::vec4 TexcoordSTPQ = TexcoordST.stst();
}
```
### <aname="section2_2"></a> 2.2. GLM_\FORCE\_PLATFORM\_UNKNOWN: Force GLM to no detect the build platform
Swizzle operators return a **copy** of the component values, and thus *can't* be used as L-values to change a vector's values.
TODO
### <aname="section2_3"></a> 2.3. GLM\_FORCE\_CXX**: C++ language detection
GLM will automatically take advantage of compilers’ language extensions when enabled. To increase cross platform compatibility and to avoid compiler extensions, a programmer can define GLM\_FORCE\_CXX98 before
any inclusion of <glm/glm.hpp> to restrict the language feature set C++98:
```cpp
#define GLM_FORCE_SWIZZLE
#define GLM_FORCE_CXX98
#include<glm/glm.hpp>
void foo()
{
glm::vec3 A(1.0f, 0.5f, 0.0f);
// No compiler error, but A is not modified.
// An anonymous copy is being modified (and then discarded).
A.bgr() = glm::vec3(2.0f, 1.5f, 1.0f); // A is not modified!
}
```
### <aname="section2_2"></a> 2.2. Anonymous union member implementation
Visual C++ supports, as a _non-standard language extension_, anonymous `struct`s as `union` members. This permits a powerful swizzling implementation that both allows L-value swizzle expressions and GLSL-like syntax. To use this feature, the language extension must be enabled by a supporting compiler and `GLM_FORCE_SWIZZLE` must be `#define`d.
For C++11 and C++14, equivalent defines are available:
GLM\_FORCE\_CXX11, GLM\_FORCE\_CXX14.
```cpp
#define GLM_FORCE_SWIZZLE
#define GLM_FORCE_CXX11
#include<glm/glm.hpp>
// Only guaranteed to work with Visual C++!
// Some compilers that support Microsoft extensions may compile this.
void foo()
{
glm::vec4 ColorRGBA(1.0f, 0.5f, 0.0f, 1.0f);
// If the compiler doesn’t support C++11, compiler errors will happen.
```
// l-value:
glm::vec4 ColorBGRA = ColorRGBA.bgra;
GLM\_FORCE\_CXX14 overrides GLM\_FORCE\_CXX11 and GLM\_FORCE\_CXX11
GLSL supports implicit conversions of vector and matrix types. For example, an ivec4 can be implicitly converted into vec4.
This version returns implementation-specific objects that _implicitly convert_ to their respective vector types. As a consequence of this design, these extra types **can't be directly used** by GLM functions; they must be converted through constructors or `operator()`.
Often, this behaviour is not desirable but following the spirit of the library, this is the default behavior in GLM. However, GLM 0.9.6 introduced the define GLM\_FORCE\_EXPLICIT\_CTOR to require explicit conversion for GLM types.
```cpp
#define GLM_FORCE_SWIZZLE
#include<glm/glm.hpp>
using glm::vec4;
void foo()
{
vec4 Color(1.0f, 0.5f, 0.0f, 1.0f);
// Generates compiler errors. Color.rgba is not a vector type.
vec4 ClampedB = glm::clamp(vec4(Color.rgba), 0.f, 1.f); // OK
glm::ivec4 a;
...
// Explicit conversion through operator()
vec4 ClampedC = glm::clamp(Color.rgba(), 0.f, 1.f); // OK
glm::vec4 b(a); // Explicit conversion, OK
glm::vec4 c = a; // Implicit conversion, OK
...
}
```
### <aname="section2_3"></a> 2.3. GLM\_FORCE\_XYZW\_ONLY: Only exposes x, y, z and w components
TODO
### <aname="section2_4"></a> 2.4. GLM\_FORCE\_MESSAGES: Compile-time message system
GLM includes a notification system which can display some information at build time:
* Platform: Windows, Linux, Native Client, QNX, etc.
* Compiler: Visual C++, Clang, GCC, ICC, etc.
* Build model: 32bits or 64 bits
* C++ version: C++98, C++11, MS extensions, etc.
* Architecture: x86, SSE, AVX, etc.
* Included extensions
* etc.
This system is disabled by default. To enable this system, define GLM\_FORCE\_MESSAGES before any inclusion of <glm/glm.hpp>. The messages are generated only by compiler supporting \#program message and
only once per project build.
With GLM\_FORCE\_EXPLICIT\_CTOR define, implicit conversions are not allowed:
```cpp
#define GLM_FORCE_MESSAGES
#define GLM_FORCE_EXPLICIT_CTOR
#include<glm/glm.hpp>
void foo()
{
glm::ivec4 a;
{
glm::vec4 b(a); // Explicit conversion, OK
glm::vec4 c = a; // Implicit conversion, ERROR
...
}
```
### <aname="section2_5"></a> 2.5. GLM\_FORCE\_CXX**: C++ language detection
### <aname="section2_5"></a> 2.5. GLM\_FORCE\_INLINE: Force inline
GLM will automatically take advantage of compilers’ language extensions when enabled. To increase cross platform compatibility and to avoid compiler extensions, a programmer can define GLM\_FORCE\_CXX98 before
any inclusion of <glm/glm.hpp> to restrict the language feature set C++98:
To push further the software performance, a programmer can define GLM\_FORCE\_INLINE before any inclusion of <glm/glm.hpp> to force the compiler to inline GLM code.
```cpp
#define GLM_FORCE_CXX98
#define GLM_FORCE_INLINE
#include<glm/glm.hpp>
```
For C++11 and C++14, equivalent defines are available:
GLM\_FORCE\_CXX11, GLM\_FORCE\_CXX14.
### <aname="section2_6"></a> 2.6. GLM\_FORCE\_DEFAULT\_ALIGNED_GENTYPES: Force GLM to use aligned types by default
```cpp
#define GLM_FORCE_CXX11
#include<glm/glm.hpp>
// If the compiler doesn’t support C++11, compiler errors will happen.
```
GLM\_FORCE\_CXX14 overrides GLM\_FORCE\_CXX11 and GLM\_FORCE\_CXX11
overrides GLM\_FORCE\_CXX98 defines.
TODO
### <aname="section2_6"></a> 2.6. SIMD support
### <aname="section2_7"></a> 2.7. GLM\_FORCE\_SIMD\_**: Using SIMD optimizations
GLM provides some SIMD optimizations based on [compiler intrinsics](https://msdn.microsoft.com/en-us/library/26td21ds.aspx).
These optimizations will be automatically thanks to compiler arguments.
@ -427,7 +384,7 @@ The use of intrinsic functions by GLM implementation can be avoided using the de
```
```cpp
#define GLM_FORCE_AVX2
#define GLM_FORCE_SIMD_AVX2
#include<glm/glm.hpp>
// If the compiler doesn’t support AVX2 instrinsics, compiler errors will happen.
@ -435,15 +392,7 @@ The use of intrinsic functions by GLM implementation can be avoided using the de
Additionally, GLM provides a low level SIMD API in glm/simd directory for users who are really interested in writing fast algorithms.
### <aname="section2_7"></a> 2.7. GLM\_FORCE\_LEFT\_HANDED: Force left handed coordinate system
TODO
### <aname="section2_8"></a> 2.8. GLM\_FORCE\_DEPTH\_ZERO\_TO\_ONE: Force the use of a clip space between 0 to 1
C++ does not provide a way to implement GLSL default precision selection (as defined in GLSL 4.10 specification section 4.5.3) with GLSL-like syntax.
@ -484,82 +433,159 @@ Available defines for unsigned integer types (glm::uvec\*):
* GLM\_PRECISION\_MEDIUMP\_UINT: Medium precision
* GLM\_PRECISION\_HIGHP\_UINT: High precision (default)
### <aname="section2_10"></a> 2.10. GLM\_FORCE\_INLINE: Force inline
### <aname="section2_9"></a> 2.9. GLM\_FORCE\_SINGLE\_ONLY: Removed explicit 64-bits floating point types
To push further the software performance, a programmer can define GLM\_FORCE\_INLINE before any inclusion of <glm/glm.hpp> to force the compiler to inline GLM code.
Some platforms (Dreamcast) doesn't support double precision floating point values. To compile on such platforms, GCC has the --m4-single-only build argument. When defining GLM\_FORCE\_SINGLE\_ONLY before including GLM headers, GLM releases the requirement of double precision floating point values support. Effectivement, all the float64 types are no longer defined and double behaves like float.
Shader languages like GLSL often feature so-called swizzle expressions, which may be used to freely select and arrange a vector's components. For example, `variable.x`, `variable.xzy` and `variable.zxyy` respectively form a scalar, a 3D vector and a 4D vector. The result of a swizzle expression in GLSL can be either an R-value or an L-value. Swizzle expressions can be written with characters from exactly one of `xyzw` (usually for positions), `rgba` (usually for colors), and `stpq` (usually for texture coordinates).
```cpp
#define GLM_FORCE_INLINE
#include<glm/glm.hpp>
vec4 A;
vec2 B;
B.yx = A.wy;
B = A.xx;
vec3 C = A.bgr;
vec3 D = B.rsz; // Invalid, won't compile
```
### <aname="section2_11"></a> 3.6. GLM\_FORCE\_SIZE\_T\_LENGTH: Vector and matrix static size
GLM supports some of this functionality. Swizzling can be enabled by defining `GLM_FORCE_SWIZZLE`.
GLSL supports the member function .length() for all vector and matrix types.
*Note: Enabling swizzle expressions will massively increase the size of your binaries and the time it takes to compile them!*
GLM has two levels of swizzling support described in the following subsections.
#### 2.10.1. Swizzle functions for standard C++ 98
When compiling GLM as C++98, R-value swizzle expressions are simulated through member functions of each vector type.
```cpp
#define GLM_FORCE_SWIZZLE // Or defined when building (e.g. -DGLM_FORCE_SWIZZLE)
This function returns a int however this function typically interacts with STL size\_t based code. GLM provides GLM\_FORCE\_SIZE\_T\_LENGTH pre-processor option so that member functions length() return a size\_t.
Additionally, GLM defines the type glm::length\_t to identify length() returned type, independently from GLM\_FORCE\_SIZE\_T\_LENGTH.
Swizzle operators return a **copy** of the component values, and thus *can't* be used as L-values to change a vector's values.
```cpp
#define GLM_FORCE_SIZE_T_LENGTH
#define GLM_FORCE_SWIZZLE
#include<glm/glm.hpp>
void foo(vec4 const& v)
void foo()
{
glm::length_t Length = v.length();
...
glm::vec3 A = glm::vec3(1.0f, 0.5f, 0.0f);
// No compiler error, but A is not modified.
// An anonymous copy is being modified (and then discarded).
A.bgr() = glm::vec3(2.0f, 1.5f, 1.0f); // A is not modified!
#### 2.10.2. Swizzle operations for C++ 98 with language extensions
GLSL supports implicit conversions of vector and matrix types. For example, an ivec4 can be implicitly converted into vec4.
Visual C++, GCC and Clang support, as a _non-standard language extension_, anonymous `struct`s as `union` members. This permits a powerful swizzling implementation that both allows L-value swizzle expressions and GLSL-like syntax. To use this feature, the language extension must be enabled by a supporting compiler and `GLM_FORCE_SWIZZLE` must be `#define`d.
```cpp
#define GLM_FORCE_SWIZZLE
#include<glm/glm.hpp>
// Only guaranteed to work with Visual C++!
// Some compilers that support Microsoft extensions may compile this.
Often, this behaviour is not desirable but following the spirit of the library, this behavior is supported in GLM. However, GLM 0.9.6 introduced the define GLM\_FORCE\_EXPLICIT\_CTOR to require explicit
conversion for GLM types.
This version returns implementation-specific objects that _implicitly convert_ to their respective vector types. As a consequence of this design, these extra types **can't be directly used** as C++ function arguments; they must be converted through constructors or `operator()`.
```cpp
#define GLM_FORCE_SWIZZLE
#include<glm/glm.hpp>
using namespace glm;
void foo()
{
glm::ivec4 a;
...
vec4 Color = vec4(1.0f, 0.5f, 0.0f, 1.0f);
glm::vec4 b(a); // Explicit conversion, OK
glm::vec4 c = a; // Implicit conversion, OK
// Generates compiler errors. Color.rgba is not a vector type.
vec4 ClampedB = clamp(vec4(Color.rgba), 0.f, 1.f); // OK
// Explicit conversion through operator()
vec4 ClampedC = clamp(Color.rgba(), 0.f, 1.f); // OK
}
```
*Note: The implementation has a caveat: Swizzle operator types must be different on both size of the equal operator or the operation will fail. There is no known fix for this issue to date*
### <aname="section2_11"></a> 2.11. GLM\_FORCE\_XYZW\_ONLY: Only exposes x, y, z and w components
TODO
### <aname="section2_12"></a> 2.12. GLM\_FORCE\_LEFT\_HANDED: Force left handed coordinate system
TODO
### <aname="section2_13"></a> 2.13. GLM\_FORCE\_DEPTH\_ZERO\_TO\_ONE: Force the use of a clip space between 0 to 1
TODO
### <aname="section2_14"></a> 2.14. GLM\_FORCE\_SIZE\_T\_LENGTH: Vector and matrix static size
GLSL supports the member function .length() for all vector and matrix types.
```cpp
#include<glm/glm.hpp>
void foo(vec4 const& v)
{
int Length = v.length();
...
}
```
With GLM\_FORCE\_EXPLICIT\_CTOR define, implicit conversions are not allowed:
This function returns a int however this function typically interacts with STL size\_t based code. GLM provides GLM\_FORCE\_SIZE\_T\_LENGTH pre-processor option so that member functions length() return a size\_t.
Additionally, GLM defines the type glm::length\_t to identify length() returned type, independently from GLM\_FORCE\_SIZE\_T\_LENGTH.
However, defining GLM\_FORCE\_UNRESTRICTED\_GENTYPE is not compatible with GLM\_FORCE\_SWIZZLE and will generate a compilation error if both are defined at the same time.
### <aname="section2_14"></a> 2.14. GLM\_FORCE\_SINGLE\_ONLY: Removed explicit 64-bits floating point types
Some platforms (Dreamcast) doesn't support double precision floating point values. To compile on such platforms, GCC has the --m4-single-only build argument. When defining GLM\_FORCE\_SINGLE\_ONLY before including GLM headers, GLM releases the requirement of double precision floating point values support. Effectivement, all the float64 types are no longer defined and double behaves like float.
### <aname="section2_15"></a> 2.15. GLM\_FORCE\_DEFAULT\_ALIGNED_GENTYPES: Force GLM to use aligned types by default
TODO
### <aname="section2_16"></a> 2.16. GLM_\FORCE\_PLATFORM\_UNKNOWN: Force GLM to no detect the build platform