GLM (OpenGL Mathematics)

repository·master·Indexed 11 days ago

https://github.com/g-truc/glm

A header-only C++ mathematics library that implements GLSL specifications. It provides vector, matrix, and transformation functions for graphics programming, software rendering, image processing, and physics simulations. Requires a C++17 compiler (or GLM 1.0 branch for older standards). Features include GLSL compatibility, a comprehensive extension system, and zero external dependencies.

Tokens
12.9K
Snippets
40
Records
74
Agent score
45%

What's inside GLM

  1. Overview of OpenGL Mathematics (GLM)

    master

    GLM is a header-only C++ mathematics library designed for graphics software. It is based on the OpenGL Shading Language (GLSL) specifications, meaning it uses the same naming conventions and functionality as GLSL. This makes it highly intuitive for developers familiar with GLSL to use in C++ environments.

    Key features include:

    • GLSL Compatibility: Classes and functions mirror GLSL.
    • Extension System: Provides extended capabilities like matrix transformations, quaternions, data packing, random numbers, and noise using GLSL-style extension conventions.
    • Versatility: While optimized for OpenGL, it is suitable for software rendering (raytracing/rasterisation), image processing, and physics simulations.
    • Zero Dependencies: A platform-independent library with no external dependencies.
  2. Enable GLSL-style swizzling with GLM_FORCE_SWIZZLE

    master

    To enable swizzle expressions (e.g., v.xyz(), v.rgba), define GLM_FORCE_SWIZZLE.

    Warning: Enabling swizzling significantly increases binary size and compilation time.

    C++98 Support (R-value only)

    In C++98, swizzling is implemented via member functions. These return a copy and cannot be used as L-values (you cannot assign to them).

    #define GLM_FORCE_SWIZZLE
    #include <glm/glm.hpp>
    
    glm::vec3 A = glm::vec3(1.0f, 0.5f, 0.0f);
    A.bgr() = glm::vec3(2.0f, 1.5f, 1.0f); // ERROR: A is NOT modified; only a temporary copy is changed.

    C++ with Language Extensions (L-value support)

    On compilers supporting anonymous struct/union extensions (like MSVC, GCC, Clang), GLM_FORCE_SWIZZLE allows GLSL-like syntax and L-value swizzling:

    #define GLM_FORCE_SWIZZLE
    #include <glm/glm.hpp>
    
    glm::vec4 ColorRGBA = glm::vec4(1.0f, 0.5f, 0.0f, 1.0f);
    ColorRGBA.bgra = glm::vec4(1.0f); // Works: L-value swizzle

    Note: Swizzle operator types are not standard vector types and may require explicit conversion via vec4(Color.rgba) when passed to functions.

    #define GLM_FORCE_SWIZZLE
    #include <glm/glm.hpp>
    
    using namespace glm;
    vec4 Color = vec4(1.0f, 0.5f, 0.0f, 1.0f);
    
    // Explicit conversion required for function arguments
    vec4 ClampedB = clamp(vec4(Color.rgba), 0.f, 1.f); 
  3. Enable experimental features with GLM_ENABLE_EXPERIMENTAL

    master
    To use experimental features in GLM, you must define the GLM_ENABLE_EXPERIMENTAL macro in your project. This allows access to various GTX extensions that are not yet considered part of the stable core API.
  4. Use GLM precision qualifiers

    master

    GLM supports GLSL-style precision qualifiers through type prefixes. This allows you to trade precision for performance. By default, all types use high precision.

    Available prefixes include:

    • highp_ (e.g., highp_vec4)
    • mediump_ (e.g., mediump_vec4)
    • lowp_ (e.g., lowp_vec4)

    Example usage:

    #include <glm/glm.hpp>
    
    void example(const glm::vec4 & v) {
        highp_vec4 a = v;
        mediump_vec4 b = a;
        lowp_vec3 c = glm::ivec3(b);
    }
  5. How to use GLM extensions

    master

    GLM extends its core GLSL feature set through dedicated extension headers. To use an extension, include its specific header file. Once included, the extension's features are added directly to the glm namespace. Including an extension also automatically includes all its dependent core functionalities and other required extensions.

    #include <glm/glm.hpp>
    #include <glm/gtc/matrix_transform.hpp>
    
    int foo()
    {
        glm::vec4 Position = glm::vec4(glm::vec3(0.0f), 1.0f);
        glm::mat4 Model = glm::translate(glm::mat4(1.0f), glm::vec3(1.0f));
    
        glm::vec4 Transformed = Model * Position;
        return 0;
    }
  6. Avoid using 'namespace glm;'

    master
    It is strongly recommended NOT to use using namespace glm;. Because GLM follows GLSL conventions, it uses many common tokens for types and functions. Using the namespace globally can lead to name collisions with other third-party libraries or the standard library.
  7. Include GLM using global headers

    master

    GLM is a header-only library. For convenience, you can include all core GLSL mathematics functionality and all extensions using two main headers.

    Warning: Including <glm/glm.hpp> and <glm/ext.hpp> pulls in a large amount of code, which can significantly increase compilation times if included in many source files.

    // Include all GLM core / GLSL features
    #include <glm/glm.hpp> // vec2, vec3, mat4, radians
    
    // Include all GLM extensions
    #include <glm/ext.hpp> // perspective, translate, rotate
  8. Build and Install GLM from Source

    master

    You can build GLM using CMake. By default, it is a header-only library, but you can build it as a shared library by passing -DBUILD_SHARED_LIBS=ON.

    cd /path/to/glm
    cmake \
        -DGLM_BUILD_TESTS=OFF \
        -DBUILD_SHARED_LIBS=OFF \
        -B build .
    cmake --build build -- all
    cmake --build build -- install
  9. Use experimental GTX extensions

    master

    GLM categorizes extensions into two types:

    1. GTC: Stable, tested, and reliable.
    2. GTX: Experimental. These may change between versions without restriction.

    To use experimental GTX extensions, you must define the GLM_ENABLE_EXPERIMENTAL macro before including any GLM headers.

    #define GLM_ENABLE_EXPERIMENTAL
    #include <glm/gtx/some_experimental_extension.hpp>
  10. Configure GLM via CMake FetchContent

    master

    You can integrate GLM into your CMake project using the FetchContent module. This allows CMake to automatically download and configure GLM during the build process without requiring a pre-installed version on your system.

    include(FetchContent)
    
    FetchContent_declare(
      glm
      GIT_REPOSITORY https://github.com/g-truc/glm.git
      GIT_TAG 1.0.3 # Or a specific version/commit
    )
    FetchContent_MakeAvailable(glm)
  11. Find GLM with CMake

    master

    GLM provides CMake package configuration files (glmConfig.cmake and glmConfigVersion.cmake).

    Using an installed version

    If GLM is installed on your system, you may need to set glm_DIR to the directory containing the configuration files (typically <installation prefix>/lib/cmake/glm/). Use find_package to load it and link against the glm::glm target.

    Using GLM as a submodule

    If you have added GLM as a submodule in your project, use add_subdirectory(glm) to expose the glm::glm target.

    # Using installed GLM
    set(glm_DIR <installation prefix>/lib/cmake/glm) # if necessary
    find_package(glm REQUIRED)
    target_link_libraries(<your executable> glm::glm)
    # Using GLM as a submodule
    add_subdirectory(glm)
    target_link_libraries(<your executable> glm::glm)
    # or
    target_include_directories(<your executable> glm)
  12. System Requirements and Compiler Support for GLM

    master

    GLM requires a C++17 compiler. If you are working with older C++ standards, you should use the GLM 1.0 branch.

    Supported compilers include:

    • GCC: 8 and higher
    • Clang: 6 and higher
    • Apple Clang: 6.0 and higher
    • Visual C++: 2019 and higher
    • CUDA: 9.0 and higher (experimental)
    • Any C++17 compliant compiler