Reorganized section 2

This commit is contained in:
Christophe Riccio 2018-08-22 01:51:12 +02:00
parent 80f4ea1a85
commit 02a794a621

434
manual.md
View File

@ -8,27 +8,26 @@
## Table of Contents ## Table of Contents
+ [0. Licenses](#section0) + [0. Licenses](#section0)
+ [1. Getting started](#section1) + [1. Getting started](#section1)
+ [1.1. Setup](#section1_1) + [1.1. Using global headers](#section1_1)
+ [1.2. Faster compilation](#section1_2) + [1.2. Using separated headers](#section1_2)
+ [1.3. Example usage](#section1_3) + [1.3. Using extension headers](#section1_3)
+ [1.4. Dependencies](#section1_4) + [1.4. Dependencies](#section1_4)
+ [2. Preprocessor configurations](#section2) + [2. Preprocessor configurations](#section2)
+ [2.1. GLM\_FORCE\_SWIZZLE: Enable swizzle operators](#section2_1) + [2.1. GLM\_FORCE\_MESSAGES: Platform auto detection and default configuration](#section2_1)
+ [2.2. GLM\_FORCE\_SWIZZLE: Enable swizzle functions](#section2_2) + [2.2. GLM_\FORCE\_PLATFORM\_UNKNOWN: Force GLM to no detect the build platform](#section2_2)
+ [2.3. GLM\_FORCE\_XYZW\_ONLY: Only exposes x, y, z and w components](#section2_3) + [2.3. GLM\_FORCE\_CXX**: C++ language detection](#section2_3)
+ [2.4. GLM\_FORCE\_MESSAGES: Compile-time message system](#section2_4) + [2.4. GLM\_FORCE\_EXPLICIT\_CTOR: Requiring explicit conversions](#section2_4)
+ [2.5. GLM\_FORCE\_CXX**: C++ language detection](#section2_5) + [2.5. GLM\_FORCE\_INLINE: Force inline](#section2_5)
+ [2.6. SIMD support](#section2_6) + [2.6. GLM\_FORCE\_DEFAULT\_ALIGNED_GENTYPES: Force GLM to use aligned types by default](#section2_6)
+ [2.7. GLM\_FORCE\_LEFT\_HANDED: Force left handed coordinate system](#section2_7) + [2.7. GLM\_FORCE\_SIMD\_**: Using SIMD optimizations](#section2_7)
+ [2.8. GLM\_FORCE\_DEPTH\_ZERO\_TO\_ONE: Force the use of a clip space between 0 to 1](#section2_8) + [2.8. GLM\_PRECISION\_**: Default precision](#section2_8)
+ [2.9. GLM\_PRECISION\_**: genType default precision](#section2_9) + [2.9. GLM\_FORCE\_SINGLE\_ONLY: Removed explicit 64-bits floating point types](#section2_9)
+ [2.10. GLM\_FORCE\_INLINE: Force inline](#section2_10) + [2.10. GLM\_FORCE\_SWIZZLE: Enable swizzle operators](#section2_10)
+ [2.11. GLM\_FORCE\_SIZE\_T\_LENGTH: Vector and matrix static size type](#section2_11) + [2.11. GLM\_FORCE\_XYZW\_ONLY: Only exposes x, y, z and w components](#section2_11)
+ [2.12. GLM\_FORCE\_EXPLICIT\_CTOR: Requiring explicit conversions](#section2_12) + [2.12. GLM\_FORCE\_LEFT\_HANDED: Force left handed coordinate system](#section2_12)
+ [2.13. GLM\_FORCE\_UNRESTRICTED\_GENTYPE: Removing genType restriction](#section2_13) + [2.13. GLM\_FORCE\_DEPTH\_ZERO\_TO\_ONE: Force the use of a clip space between 0 to 1](#section2_13)
+ [2.14. GLM\_FORCE\_SINGLE\_ONLY: Removed explicit 64-bits floating point types](#section2_14) + [2.14. GLM\_FORCE\_SIZE\_T\_LENGTH: Vector and matrix static size type](#section2_14)
+ [2.15. GLM\_FORCE\_DEFAULT\_ALIGNED_GENTYPES: Force GLM to use aligned types by default](#section2_15) + [2.15. GLM\_FORCE\_UNRESTRICTED\_GENTYPE: Removing genType restriction](#section2_15)
+ [2.16. GLM\_FORCE\_PLATFORM\_UNKNOWN: Force GLM to no detect the build platform](#section2_16)
+ [3. Stable extensions](#section3) + [3. Stable extensions](#section3)
+ [3.1. Scalar types](#section3_1) + [3.1. Scalar types](#section3_1)
+ [3.2. Scalar functions](#section3_2) + [3.2. Scalar functions](#section3_2)
@ -155,12 +154,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
### <a name="section1_1"></a> 1.1. Using global headers ### <a name="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: 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 ```cpp
#include <glm/glm.hpp> #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:
```cpp ```cpp
// Include all GLM core / GLSL features // Include all GLM core / GLSL features
#include <glm/glm.hpp> // vec2, vec3, mat4, radians #include <glm/glm.hpp> // vec2, vec3, mat4, radians
@ -179,10 +177,11 @@ glm::mat4 transform(glm::vec2 const& Orientation, glm::vec3 const& Translate, gl
} }
``` ```
*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.*
### <a name="section1_2"></a> 1.2. Using separated headers ### <a name="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: 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 ```cpp
#include <glm/vec2.hpp> // vec2, bvec2, dvec2, ivec2 and uvec2 #include <glm/vec2.hpp> // vec2, bvec2, dvec2, ivec2 and uvec2
#include <glm/vec3.hpp> // vec3, bvec3, dvec3, ivec3 and uvec3 #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. #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 ```cpp
// Include GLM core features // Include GLM core features
#include <glm/vec2.hpp> // vec2 #include <glm/vec2.hpp> // vec2
@ -214,7 +213,7 @@ Using GLM through headers including features separated following the structure o
#include <glm/mat4x4.hpp> // mat4 #include <glm/mat4x4.hpp> // mat4
#include <glm/trigonometric.hpp> //radians #include <glm/trigonometric.hpp> //radians
// Include GLM extensions // Include GLM extension
#include <glm/ext/matrix_transform.hpp> // perspective, translate, rotate #include <glm/ext/matrix_transform.hpp> // perspective, translate, rotate
glm::mat4 transform(glm::vec2 const& Orientation, glm::vec3 const& Translate, glm::vec3 const& Up) glm::mat4 transform(glm::vec2 const& Orientation, glm::vec3 const& Translate, glm::vec3 const& Up)
@ -232,12 +231,14 @@ glm::mat4 transform(glm::vec2 const& Orientation, glm::vec3 const& Translate, gl
Using GLM through split headers to minimize the project build time: Using GLM through split headers to minimize the project build time:
```cpp ```cpp
// Include GLM extensions // Include GLM vector extensions:
#include <glm/ext/vector_float2.hpp> // vec2 #include <glm/ext/vector_float2.hpp> // vec2
#include <glm/ext/vector_float3.hpp> // vec3 #include <glm/ext/vector_float3.hpp> // vec3
#include <glm/ext/vector_trigonometric.hpp> // radians
// Include GLM matrix extensions:
#include <glm/ext/matrix_float4x4.hpp> // mat4 #include <glm/ext/matrix_float4x4.hpp> // mat4
#include <glm/ext/matrix_transform.hpp> // perspective, translate, rotate #include <glm/ext/matrix_transform.hpp> // perspective, translate, rotate
#include <glm/trigonometric.hpp> // radians
glm::mat4 transform(glm::vec2 const& Orientation, glm::vec3 const& Translate, glm::vec3 const& Up) glm::mat4 transform(glm::vec2 const& Orientation, glm::vec3 const& Translate, glm::vec3 const& Up)
{ {
@ -255,137 +256,44 @@ glm::mat4 transform(glm::vec2 const& Orientation, glm::vec3 const& Translate, gl
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>`. 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>`.
--- ---
## <a name="section2"></a> 2. Preprocessor options ## <a name="section2"></a> 2. Preprocessor configurations
### <a name="section2_1"></a> 2.1. GLM\_FORCE\_SWIZZLE: Enable swizzle operators ### <a name="section2_1"></a> 2.1. GLM\_FORCE\_MESSAGES: Platform auto detection and default configuration
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). 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.
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.
Using `GLM_FORCE_MESSAGES`, GLM will report the configuration as part of the build log.
```cpp ```cpp
vec4 A; #define GLM_FORCE_MESSAGES // Or defined when building (e.g. -DGLM_FORCE_SWIZZLE)
vec2 B;
B.yx = A.wy;
B = A.xx;
vec3 C = A.bgr;
vec3 D = B.rsz; // Invalid, won't compile
```
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.
*Note that enabling swizzle expressions will massively increase the size of your binaries and the time it takes to compile them!*
### <a name="section2_2"></a> GLM\_FORCE\_SWIZZLE: Enable swizzle functions
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)
#include <glm/glm.hpp> #include <glm/glm.hpp>
void foo()
{
glm::vec4 ColorRGBA(1.0f, 0.5f, 0.0f, 1.0f);
glm::vec3 ColorBGR = ColorRGBA.bgr();
glm::vec3 PositionA(1.0f, 0.5f, 0.0f, 1.0f);
glm::vec3 PositionB = PositionXYZ.xyz() * 2.0f;
glm::vec2 TexcoordST(1.0f, 0.5f);
glm::vec4 TexcoordSTPQ = TexcoordST.stst();
}
``` ```
Swizzle operators return a **copy** of the component values, and thus *can't* be used as L-values to change a vector's values. Example of configuration log generated by `GLM_FORCE_MESSAGES`:
```cpp ```cpp
#define GLM_FORCE_SWIZZLE GLM: version 0.9.9.1
#include <glm/glm.hpp> GLM: C++ 17 with extensions
GLM: Clang compiler detected
void foo() GLM: x86 64 bits with AVX instruction set build target
{ GLM: Linux platform detected
glm::vec3 A(1.0f, 0.5f, 0.0f); 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.
// No compiler error, but A is not modified. GLM: GLM_FORCE_UNRESTRICTED_GENTYPE is undefined. Follows strictly GLSL on valid function genTypes.
// An anonymous copy is being modified (and then discarded). GLM: GLM_FORCE_DEPTH_ZERO_TO_ONE is undefined. Using negative one to one depth clip space.
A.bgr() = glm::vec3(2.0f, 1.5f, 1.0f); // A is not modified! GLM: GLM_FORCE_LEFT_HANDED is undefined. Using right handed coordinate system.
}
``` ```
### <a name="section2_2"></a> 2.2. Anonymous union member implementation The following subsections describe each configurations and defines.
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. ### <a name="section2_2"></a> 2.2. GLM_\FORCE\_PLATFORM\_UNKNOWN: Force GLM to no detect the build platform
```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.
void foo()
{
glm::vec4 ColorRGBA(1.0f, 0.5f, 0.0f, 1.0f);
// l-value:
glm::vec4 ColorBGRA = ColorRGBA.bgra;
// r-value:
ColorRGBA.bgra = ColorRGBA;
// Both l-value and r-value
ColorRGBA.bgra = ColorRGBA.rgba;
}
```
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()`.
```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 ClampedA = glm::clamp(Color.rgba, 0.f, 1.f); // ERROR
// Explicit conversion through a constructor
vec4 ClampedB = glm::clamp(vec4(Color.rgba), 0.f, 1.f); // OK
// Explicit conversion through operator()
vec4 ClampedC = glm::clamp(Color.rgba(), 0.f, 1.f); // OK
}
```
### <a name="section2_3"></a> 2.3. GLM\_FORCE\_XYZW\_ONLY: Only exposes x, y, z and w components
TODO TODO
### <a name="section2_4"></a> 2.4. GLM\_FORCE\_MESSAGES: Compile-time message system ### <a name="section2_3"></a> 2.3. GLM\_FORCE\_CXX**: C++ language detection
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 &lt;glm/glm.hpp&gt;. The messages are generated only by compiler supporting \#program message and
only once per project build.
```cpp
#define GLM_FORCE_MESSAGES
#include <glm/glm.hpp>
```
### <a name="section2_5"></a> 2.5. 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 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 &lt;glm/glm.hpp&gt; to restrict the language feature set C++98: any inclusion of &lt;glm/glm.hpp&gt; to restrict the language feature set C++98:
@ -408,7 +316,56 @@ GLM\_FORCE\_CXX11, GLM\_FORCE\_CXX14.
GLM\_FORCE\_CXX14 overrides GLM\_FORCE\_CXX11 and GLM\_FORCE\_CXX11 GLM\_FORCE\_CXX14 overrides GLM\_FORCE\_CXX11 and GLM\_FORCE\_CXX11
overrides GLM\_FORCE\_CXX98 defines. overrides GLM\_FORCE\_CXX98 defines.
### <a name="section2_6"></a> 2.6. SIMD support ### <a name="section2_4"></a> 2.4. GLM\_FORCE\_EXPLICIT\_CTOR: Requiring explicit conversions
GLSL supports implicit conversions of vector and matrix types. For example, an ivec4 can be implicitly converted into vec4.
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
#include <glm/glm.hpp>
void foo()
{
glm::ivec4 a;
...
glm::vec4 b(a); // Explicit conversion, OK
glm::vec4 c = a; // Implicit conversion, OK
...
}
```
With GLM\_FORCE\_EXPLICIT\_CTOR define, implicit conversions are not allowed:
```cpp
#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
...
}
```
### <a name="section2_5"></a> 2.5. GLM\_FORCE\_INLINE: Force inline
To push further the software performance, a programmer can define GLM\_FORCE\_INLINE before any inclusion of &lt;glm/glm.hpp&gt; to force the compiler to inline GLM code.
```cpp
#define GLM_FORCE_INLINE
#include <glm/glm.hpp>
```
### <a name="section2_6"></a> 2.6. GLM\_FORCE\_DEFAULT\_ALIGNED_GENTYPES: Force GLM to use aligned types by default
TODO
### <a name="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). 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. 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 ```cpp
#define GLM_FORCE_AVX2 #define GLM_FORCE_SIMD_AVX2
#include <glm/glm.hpp> #include <glm/glm.hpp>
// If the compiler doesnt support AVX2 instrinsics, compiler errors will happen. // If the compiler doesnt 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. Additionally, GLM provides a low level SIMD API in glm/simd directory for users who are really interested in writing fast algorithms.
### <a name="section2_7"></a> 2.7. GLM\_FORCE\_LEFT\_HANDED: Force left handed coordinate system ### <a name="section2_8"></a> 2.8. GLM\_PRECISION\_**: Default precision
TODO
### <a name="section2_8"></a> 2.8. GLM\_FORCE\_DEPTH\_ZERO\_TO\_ONE: Force the use of a clip space between 0 to 1
TODO
### <a name="section2_9"></a> 2.9. GLM\_PRECISION\_**: Default precision
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. 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,16 +433,130 @@ Available defines for unsigned integer types (glm::uvec\*):
* GLM\_PRECISION\_MEDIUMP\_UINT: Medium precision * GLM\_PRECISION\_MEDIUMP\_UINT: Medium precision
* GLM\_PRECISION\_HIGHP\_UINT: High precision (default) * GLM\_PRECISION\_HIGHP\_UINT: High precision (default)
### <a name="section2_10"></a> 2.10. GLM\_FORCE\_INLINE: Force inline ### <a name="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 &lt;glm/glm.hpp&gt; 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.
### <a name="section2_10"></a> 2.10. GLM\_FORCE\_SWIZZLE: Enable swizzle operators
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 ```cpp
#define GLM_FORCE_INLINE vec4 A;
#include <glm/glm.hpp> vec2 B;
B.yx = A.wy;
B = A.xx;
vec3 C = A.bgr;
vec3 D = B.rsz; // Invalid, won't compile
``` ```
### <a name="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`.
*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)
#include <glm/glm.hpp>
void foo()
{
glm::vec4 ColorRGBA = glm::vec4(1.0f, 0.5f, 0.0f, 1.0f);
glm::vec3 ColorBGR = ColorRGBA.bgr();
glm::vec3 PositionA = glm::vec3(1.0f, 0.5f, 0.0f);
glm::vec3 PositionB = PositionXYZ.xyz() * 2.0f;
glm::vec2 TexcoordST = glm::vec2(1.0f, 0.5f);
glm::vec4 TexcoordSTPQ = TexcoordST.stst();
}
```
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_SWIZZLE
#include <glm/glm.hpp>
void foo()
{
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
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.
void foo()
{
glm::vec4 ColorRGBA = glm::vec4(1.0f, 0.5f, 0.0f, 1.0f);
// l-value:
glm::vec4 ColorBGRA = ColorRGBA.bgra;
// r-value:
ColorRGBA.bgra = ColorRGBA;
// Both l-value and r-value
ColorRGBA.bgra = ColorRGBA.rgba;
}
```
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()
{
vec4 Color = vec4(1.0f, 0.5f, 0.0f, 1.0f);
// Generates compiler errors. Color.rgba is not a vector type.
vec4 ClampedA = clamp(Color.rgba, 0.f, 1.f); // ERROR
// Explicit conversion through a constructor
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*
### <a name="section2_11"></a> 2.11. GLM\_FORCE\_XYZW\_ONLY: Only exposes x, y, z and w components
TODO
### <a name="section2_12"></a> 2.12. GLM\_FORCE\_LEFT\_HANDED: Force left handed coordinate system
TODO
### <a name="section2_13"></a> 2.13. GLM\_FORCE\_DEPTH\_ZERO\_TO\_ONE: Force the use of a clip space between 0 to 1
TODO
### <a name="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. GLSL supports the member function .length() for all vector and matrix types.
@ -522,44 +585,7 @@ void foo(vec4 const& v)
} }
``` ```
### <a name="section2_12"></a> 2.12. GLM\_FORCE\_EXPLICIT\_CTOR: Requiring explicit conversions ### <a name="section2_15"></a> 2.15. GLM\_FORCE\_UNRESTRICTED\_GENTYPE: Removing genType restriction
GLSL supports implicit conversions of vector and matrix types. For example, an ivec4 can be implicitly converted into vec4.
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.
```cpp
#include <glm/glm.hpp>
void foo()
{
glm::ivec4 a;
...
glm::vec4 b(a); // Explicit conversion, OK
glm::vec4 c = a; // Implicit conversion, OK
...
}
```
With GLM\_FORCE\_EXPLICIT\_CTOR define, implicit conversions are not allowed:
```cpp
#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
...
}
```
### <a name="section2_13"></a> 2.13. GLM\_FORCE\_UNRESTRICTED\_GENTYPE: Removing genType restriction
By default GLM only supports basic types as genType for vector, matrix and quaternion types: By default GLM only supports basic types as genType for vector, matrix and quaternion types:
@ -582,18 +608,6 @@ typedef glm::vec<4, half> my_hvec4;
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. 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.
### <a name="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.
### <a name="section2_15"></a> 2.15. GLM\_FORCE\_DEFAULT\_ALIGNED_GENTYPES: Force GLM to use aligned types by default
TODO
### <a name="section2_16"></a> 2.16. GLM_\FORCE\_PLATFORM\_UNKNOWN: Force GLM to no detect the build platform
TODO
--- ---
## <a name="section3"></a> 3. Stable extensions ## <a name="section3"></a> 3. Stable extensions