๐Ÿ“ฝ Highly Optimized Graphics Math (glm) for C


๐ŸŽฅ OpenGL Mathematics (glm) for C

Build Status Build status Documentation Status Coverage Status codecov Codacy Badge Backers on Open Collective Sponsors on Open Collective


Almost all functions (inline versions) and parameters are documented inside the corresponding headers.
Complete documentation: http://cglm.readthedocs.io

Note for previous versions:

  • _dup (duplicate) is changed to _copy. For instance glm_vec_dup -> glm_vec3_copy
  • OpenGL related functions are dropped to make this lib platform/third-party independent
  • make sure you have latest version and feel free to report bugs, troubles
  • [bugfix] euler angles was implemented in reverse order (extrinsic) it was fixed, now they are intrinsic. Make sure that you have the latest version
  • [major change] by starting v0.4.0, quaternions are stored as [x, y, z, w], it was [w, x, y, z] in v0.3.5 and earlier versions
  • [api rename] by starting v0.4.5, glm_simd functions are renamed to glmm_
  • [new option] by starting v0.4.5, you can disable alignment requirement, check options in docs.
  • [major change] by starting v0.5.0, vec3 functions use glm_vec3_ namespace, it was glm_vec_ until v0.5.0
  • [major change] by starting v0.5.1, built-in alignment is removed from vec3 and mat3 types
  • [major change] by starting v0.7.3, inline print functions are disabled in release/production mode to eliminate print costs (see options in documentation). Print output also improved. You can disable colors if you need (see documentation)

Note for C++ developers:

If you are not aware of the original GLM library yet, you may also want to look at: https://github.com/g-truc/glm

Note for new comers (Important):

  • vec4 and mat4 variables must be aligned. (There will be unaligned versions later)
  • in and [in, out] parameters must be initialized (please). But [out] parameters not, initializing out param is also redundant
  • All functions are inline if you don't want to use pre-compiled versions with glmc_ prefix, you can ignore build process. Just include headers.
  • if your debugger takes you to cglm headers then make sure you are not trying to copy vec4 to vec3 or alig issues...
  • Welcome!

Note for experienced developers:

  • Since I'm testing this library in my projects, sometimes bugs occurs; finding that bug[s] and making improvements would be more easy with multiple developer/contributor and their projects or knowledge. Consider to make some tests if you suspect something is wrong and any feedbacks, contributions and bug reports are always welcome.


cglm doesn't alloc any memory on heap. So it doesn't provide any allocator. You should alloc memory for out parameters too if you pass pointer of memory location. Don't forget that vec4 (also quat/versor) and mat4 must be aligned (16-bytes), because cglm uses SIMD instructions to optimize most operations if available.

Returning vector or matrix... ?

cglm supports both ARRAY API and STRUCT API, so you can return structs if you utilize struct api (glms_).

Other APIs like Vulkan, Metal, Dx?

Currently cglm uses default clip space configuration (-1, 1) for camera functions (perspective, extract corners...), in the future other clip space configurations will be supported

Like some other graphics libraries (especially OpenGL) this library use Column-Major layout to keep matrices in the memory.
In the future the library may support an option to use row-major layout, CURRENTLY if you need to row-major layout you will need to transpose it.


  • array api and struct api, you can use arrays or structs.
  • general purpose matrix operations (mat4, mat3)
  • chain matrix multiplication (square only)
  • general purpose vector operations (cross, dot, rotate, proj, angle...)
  • affine transformations
  • matrix decomposition (extract rotation, scaling factor)
  • optimized affine transform matrices (mul, rigid-body inverse)
  • camera (lookat)
  • projections (ortho, perspective)
  • quaternions
  • euler angles / yaw-pitch-roll to matrix
  • extract euler angles
  • inline or pre-compiled function call
  • frustum (extract view frustum planes, corners...)
  • bounding box (AABB in Frustum (culling), crop, merge...)
  • bounding sphere
  • project, unproject
  • easing functions
  • curves
  • curve interpolation helpers (SMC, deCasteljau...)
  • helpers to convert cglm types to Apple's simd library to pass cglm types to Metal GL without packing them on both sides
  • ray intersection helpers
  • and others...

You have two option to call a function/operation: inline or library call (link) Almost all functions are marked inline (always_inline) so compiler will probably inline. To call pre-compiled version, just use glmc_ (c stands for 'call') instead of glm_.

  #include <cglm/cglm.h>   /* for inline */
  #include <cglm/call.h>   /* for library call (this also includes cglm.h) */

  mat4 rot, trans, rt;
  /* ... */
  glm_mul(trans, rot, rt);  /* inline */
  glmc_mul(trans, rot, rt); /* call from library */

Most of math functions are optimized manualy with SSE2 if available, if not? Dont worry there are non-sse versions of all operations

You can pass matrices and vectors as array to functions rather than get address.

  mat4 m = {
    1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1

  glm_translate(m, (vec3){1.0f, 0.0f, 0.0f});

Library contains general purpose mat4 mul and inverse functions, and also contains some special forms (optimized) of these functions for affine transformations' matrices. If you want to multiply two affine transformation matrices you can use glm_mul instead of glm_mat4_mul and glm_inv_tr (ROT + TR) instead glm_mat4_inv

/* multiplication */
mat4 modelMat;
glm_mul(T, R, modelMat);

/* othonormal rot + tr matrix inverse (rigid-body) */

Struct API

The struct API works as follows, note the s suffix on types, the glms_ prefix on functions and the GLMS_ prefix on constants:

#include <cglm/struct.h>

mat4s inv = glms_mat4_inv(mat);

Struct functions generally take their parameters as values and return their results, rather than taking pointers and writing to out parameters. That means your parameters can usually be const, if you're into that.

The types used are actually unions that allow access to the same data multiple ways. One of those ways involves anonymous structures, available since C11. MSVC also supports it for earlier C versions out of the box and GCC/Clang do if you enable -fms-extensions. To explicitly enable these anonymous structures, #define CGLM_USE_ANONYMOUS_STRUCT to 1, to disable them, to 0. For backward compatibility, you can also #define CGLM_NO_ANONYMOUS_STRUCT (value is irrelevant) to disable them. If you don't specify explicitly, cglm will do a best guess based on your compiler and the C version you're using.


CMake (All platforms)

$ mkdir build
$ cd build
$ cmake .. # [Optional] -DCGLM_SHARED=ON
$ make
$ sudo make install # [Optional]
Cmake options with Defaults:
option(CGLM_SHARED "Shared build" ON)
option(CGLM_STATIC "Static build" OFF)
option(CGLM_USE_C99 "" OFF) # C11 
option(CGLM_USE_TEST "Enable Tests" OFF) # for make check - make test

Use with your CMake project

  • Example:
cmake_minimum_required(VERSION 3.8.2)

project(<Your Project Name>)

add_executable(${PROJECT_NAME} src/main.c)
target_link_libraries(${LIBRARY_NAME} PRIVATE


# or you can use find_package to configure cglm

Meson (All platforms)

$ meson build # [Optional] --default-library=static
$ cd build
$ ninja
$ sudo ninja install # [Optional]
Meson options with Defaults:
enable_tests=false # to run tests: ninja test

Use with your Meson project

  • Example:
# Clone cglm or create a cglm.wrap under <source_root>/subprojects
project('name', 'c')

cglm_dep = dependency('cglm', fallback : 'cglm', 'cglm_dep')

executable('exe', 'src/main.c', dependencies : cglm_dep)

Swift (Swift Package Manager)

Currently only default build options are supported. Add cglm dependency to your project:

  dependencies: [
    .package(url: "https://github.com/recp/cglm", .branch("master")),

Now add cgml as a dependency to your target. Product choices are:

  • cglm for inlined version of the library which can be linked only statically
  • cglmc for a compiled version of the library with no linking limitation
  dependencies: [
    .product(name: "cglm", package: "cglm"),

Unix (Autotools)

$ sh autogen.sh
$ ./configure
$ make
$ make check # [Optional]
$ [sudo] make install # [Optional]

This will also install pkg-config files so you can use pkg-config --cflags cglm and pkg-config --libs cglm to retrieve compiler and linker flags.

The files will be installed into the given prefix (usually /usr/local by default on Linux), but your pkg-config may not be configured to actually check there. You can figure out where it's looking by running pkg-config --variable pc_path pkg-config and change the path the files are installed to via ./configure --with-pkgconfigdir=/your/path. Alternatively, you can add the prefix path to your PKG_CONFIG_PATH environment variable.

Windows (MSBuild)

Windows related build file and project files are located in win folder, make sure you are inside cglm/win folder. Code Analysis is enabled, so it may take awhile to build.

$ cd win
$ .\build.bat

if msbuild won't work (because of multi version VS) then try to build with devenv:

$ devenv cglm.sln /Build Release

Running Tests on Windows

You can see test project in same visual studio solution file. It is enough to run that project to run tests.

Building Docs

First you need install Sphinx: http://www.sphinx-doc.org/en/master/usage/installation.html then:

$ cd docs
$ sphinx-build source build

it will compile docs into build folder, you can run index.html inside that function.

How to use

If you want to use the inline versions of functions, then include the main header

#include <cglm/cglm.h>

the header will include all headers. Then call the func you want e.g. rotate vector by axis:

glm_vec3_rotate(v1, glm_rad(45), (vec3){1.0f, 0.0f, 0.0f});

some functions are overloaded :) e.g you can normalize vector:


this will normalize vec and store normalized vector into vec but if you will store normalized vector into another vector do this:

glm_vec3_normalize_to(vec, result);

like this function you may see _to postfix, this functions store results to another variables and save temp memory

to call pre-compiled versions include header with c postfix, c means call. Pre-compiled versions are just wrappers.

#include <cglm/call.h>

this header will include all headers with c postfix. You need to call functions with c posfix:


Function usage and parameters are documented inside related headers. You may see same parameter passed twice in some examples like this:

glm_mat4_mul(m1, m2, m1);

/* or */
glm_mat4_mul(m1, m1, m1);

the first two parameter are [in] and the last one is [out] parameter. After multiplying m1 and m2, the result is stored in m1. This is why we send m1 twice. You may store the result in a different matrix, this is just an example.

Example: Computing MVP matrix

Option 1

mat4 proj, view, model, mvp;

/* init proj, view and model ... */

glm_mat4_mul(proj, view, viewProj);
glm_mat4_mul(viewProj, model, mvp);

Option 2

mat4 proj, view, model, mvp;

/* init proj, view and model ... */

glm_mat4_mulN((mat4 *[]){&proj, &view, &model}, 3, mvp);

How to send matrix to OpenGL

mat4 is array of vec4 and vec4 is array of floats. glUniformMatrix4fv functions accecpts float* as value (last param), so you can cast mat4 to float* or you can pass first column of matrix as beginning of memory of matrix:

Option 1: Send first column

glUniformMatrix4fv(location, 1, GL_FALSE, matrix[0]);

/* array of matrices */
glUniformMatrix4fv(location, 1, GL_FALSE, matrix[0][0]);

Option 2: Cast matrix to pointer type (also valid for multiple dimensional arrays)

glUniformMatrix4fv(location, 1, GL_FALSE, (float *)matrix);

You can pass matrices the same way to other APIs e.g. Vulkan, DX...


  • This library uses float types only, does not support Integers, Double... yet
  • If headers are not working properly with your compiler, IDE please open an issue, because I'm using GCC and clang to test it maybe sometimes MSVC


  • Unit tests (In Progress)
  • Unit tests for comparing cglm with glm results
  • Add version info
  • Unaligned operations (e.g. glm_umat4_mul)
  • Extra documentation
  • ARM Neon Arch (In Progress)


This project exists thanks to all the people who contribute. [Contribute].


Thank you to all our backers! ๐Ÿ™ [Become a backer]


Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]


MIT. check the LICENSE file

  • TODO: Make cglm work with Metal, Vulkan and DirectX

    TODO: Make cglm work with Metal, Vulkan and DirectX

    cglm must support Metal and Vulkan (and maybe DirectX). To do this cglm may provide alternative functions for alternative NDC coordinates. Or we could do that with preprocessor macros. But providing extra functions will provide ability to switch between graphics APIs without rebuilding the code.


    1. https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf
    2. https://metashapes.com/blog/opengl-metal-projection-matrix-problem/
    help wanted feedback wanted portability feature request important major-update clip-space 
    opened by recp 49
  • cglm structs

    cglm structs

    Hi there,

    I wanted to upload these changes with a minimal and initial implementation for the vec4s type. There are several things missing, like function docs and other struct types. My intention here is to start reviewing it (not to merge this branch yet, it isn't finished by any means), take your feedback as you envision this feature and make the necessary changes.

    So far I was able to add a test, and make check pass all of them. I'll make more tests as the feature is developed.

    I also did some changes when I start testing to be able to compile on the Raspberry PI, since it doesn't suppor SSE{2} instructions. Specifically the change in the test_quat.c file: #if defined( __SSE__ ) || defined( __SSE2__ )

    So, let me know what you think, and start shaping the feature from there.

    feature feedback wanted in progress 
    opened by acoto87 33
  • Type Safe Implementation

    Type Safe Implementation

    What is the stance on a type-safe wrapper that utilizes structs or unions instead of arrays?

    Is there any interest in a wrapper (kind of like the call "wrapper") that adds type safety?

    enhancement feature feedback wanted in progress 
    opened by jonathanplatzer 22
  • Building with emscripten.

    Building with emscripten.

    Looks like there is an issue with the order and spaghetti of the headers.

    This fixed the issue for me.

    diff --git a/include/cglm/cglm.h b/include/cglm/cglm.h
    index 52c7e97..d3fdce6 100644
    --- a/include/cglm/cglm.h
    +++ b/include/cglm/cglm.h
    @@ -11,12 +11,12 @@
     #include "common.h"
     #include "vec3.h"
     #include "vec4.h"
    +#include "quat.h"
     #include "mat4.h"
     #include "mat3.h"
     #include "affine.h"
     #include "cam.h"
     #include "frustum.h"
    -#include "quat.h"
     #include "euler.h"
     #include "plane.h"
     #include "box.h"
    [email protected]:~/src/github/cglm$ sh autogen.sh 
    libtoolize: putting auxiliary files in '.'.
    libtoolize: linking file './ltmain.sh'
    libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'.
    libtoolize: linking file 'm4/libtool.m4'
    libtoolize: linking file 'm4/ltoptions.m4'
    libtoolize: linking file 'm4/ltsugar.m4'
    libtoolize: linking file 'm4/ltversion.m4'
    libtoolize: linking file 'm4/lt~obsolete.m4'
    libtoolize: Consider adding '-I m4' to ACLOCAL_AMFLAGS in Makefile.am.
    configure.ac:22: installing './ar-lib'
    configure.ac:18: installing './compile'
    configure.ac:27: installing './config.guess'
    configure.ac:27: installing './config.sub'
    configure.ac:11: installing './install-sh'
    configure.ac:11: installing './missing'
    makefile.am: installing './depcomp'
    parallel-tests: installing './test-driver'
    [email protected]:~/src/github/cglm$ CC=emcc ./configure
    checking for a BSD-compatible install... /usr/bin/install -c
    checking whether build environment is sane... yes
    checking for a thread-safe mkdir -p... /bin/mkdir -p
    checking for gawk... gawk
    checking whether make sets $(MAKE)... yes
    checking whether make supports nested variables... yes
    checking for gcc... emcc
    checking whether the C compiler works... yes
    checking for C compiler default output file name... a.out
    checking for suffix of executables... 
    checking whether we are cross compiling... no
    checking for suffix of object files... o
    checking whether we are using the GNU C compiler... yes
    checking whether emcc accepts -g... yes
    checking for emcc option to accept ISO C89... none needed
    checking whether emcc understands -c and -o together... yes
    checking for style of include used by make... GNU
    checking dependency style of emcc... gcc3
    checking for ar... ar
    checking the archiver (ar) interface... ar
    checking build system type... x86_64-pc-linux-gnu
    checking host system type... x86_64-pc-linux-gnu
    checking how to print strings... printf
    checking for a sed that does not truncate output... /bin/sed
    checking for grep that handles long lines and -e... /bin/grep
    checking for egrep... /bin/grep -E
    checking for fgrep... /bin/grep -F
    checking for ld used by emcc... /usr/bin/ld
    checking if the linker (/usr/bin/ld) is GNU ld... yes
    checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
    checking the name lister (/usr/bin/nm -B) interface... BSD nm
    checking whether ln -s works... yes
    checking the maximum length of command line arguments... 1572864
    checking how to convert x86_64-pc-linux-gnu file names to x86_64-pc-linux-gnu format... func_convert_file_noop
    checking how to convert x86_64-pc-linux-gnu file names to toolchain format... func_convert_file_noop
    checking for /usr/bin/ld option to reload object files... -r
    checking for objdump... objdump
    checking how to recognize dependent libraries... pass_all
    checking for dlltool... no
    checking how to associate runtime and link libraries... printf %s\n
    checking for archiver @FILE support... @
    checking for strip... strip
    checking for ranlib... ranlib
    checking command to parse /usr/bin/nm -B output from emcc object... failed
    checking for sysroot... no
    checking for a working dd... /bin/dd
    checking how to truncate binary pipes... /bin/dd bs=4096 count=1
    checking for mt... mt
    checking if mt is a manifest tool... no
    checking how to run the C preprocessor... emcc -E
    checking for ANSI C header files... yes
    checking for sys/types.h... yes
    checking for sys/stat.h... yes
    checking for stdlib.h... yes
    checking for string.h... yes
    checking for memory.h... yes
    checking for strings.h... yes
    checking for inttypes.h... yes
    checking for stdint.h... yes
    checking for unistd.h... yes
    checking for dlfcn.h... yes
    checking for objdir... .libs
    checking if emcc supports -fno-rtti -fno-exceptions... yes
    checking for emcc option to produce PIC... -fPIC -DPIC
    checking if emcc PIC flag -fPIC -DPIC works... yes
    checking if emcc static flag -static works... yes
    checking if emcc supports -c -o file.o... yes
    checking if emcc supports -c -o file.o... (cached) yes
    checking whether the emcc linker (/usr/bin/ld) supports shared libraries... yes
    checking whether -lc should be explicitly linked in... yes
    checking dynamic linker characteristics... ERROR:root:no input files
    note that input files without a known suffix are ignored, make sure your input files end with one of: ('.c', '.C', '.i', '.cpp', '.cxx', '.cc', '.c++', '.CPP', '.CXX', '.CC', '.C++', '.ii', '.m', '.mi', '.mm', '.mii', '/dev/null', '.bc', '.o', '.obj', '.lo', '.dylib', '.so', '.a', '.ll', '.h', '.hxx', '.hpp', '.hh', '.H', '.HXX', '.HPP', '.HH')
    GNU/Linux ld.so
    checking how to hardcode library paths into programs... immediate
    checking whether stripping libraries is possible... yes
    checking if libtool supports shared libraries... yes
    checking whether to build shared libraries... yes
    checking whether to build static libraries... yes
    checking for floor in -lm... yes
    checking for special C compiler options needed for large files... no
    checking for _FILE_OFFSET_BITS value needed for large files... unknown
    checking for _LARGE_FILES value needed for large files... unknown
    checking limits.h usability... yes
    checking limits.h presence... yes
    checking for limits.h... yes
    checking stddef.h usability... yes
    checking stddef.h presence... yes
    checking for stddef.h... yes
    checking for stdint.h... (cached) yes
    checking for stdlib.h... (cached) yes
    checking for string.h... (cached) yes
    checking for stdbool.h that conforms to C99... yes
    checking for _Bool... yes
    checking for inline... inline
    checking for int32_t... yes
    checking for int64_t... yes
    checking for size_t... yes
    checking for uint16_t... yes
    checking for uint32_t... yes
    checking for uint64_t... yes
    checking for uint8_t... yes
    checking for error_at_line... no
    checking that generated files are newer than configure... done
    configure: creating ./config.status
    config.status: creating makefile
    config.status: creating config.h
    config.status: executing depfiles commands
    config.status: executing libtool commands
    [email protected]:~/src/github/cglm$ make
    (CDPATH="${ZSH_VERSION+.}:" && cd . && /bin/bash /home/cheako/src/github/cglm/missing autoheader)
    rm -f stamp-h1
    touch config.h.in
    cd . && /bin/bash ./config.status config.h
    config.status: creating config.h
    make  all-am
    make[1]: Entering directory '/home/cheako/src/github/cglm'
    depbase=`echo src/euler.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
    /bin/bash ./libtool  --tag=CC   --mode=compile emcc -DHAVE_CONFIG_H -I.    -Wall -std=gnu99 -O3 -Wstrict-aliasing=2 -fstrict-aliasing -pedantic -g -O2 -MT src/euler.lo -MD -MP -MF $depbase.Tpo -c -o src/euler.lo src/euler.c &&\
    mv -f $depbase.Tpo $depbase.Plo
    libtool: compile:  emcc -DHAVE_CONFIG_H -I. -Wall -std=gnu99 -O3 -Wstrict-aliasing=2 -fstrict-aliasing -pedantic -g -O2 -MT src/euler.lo -MD -MP -MF src/.deps/euler.Tpo -c src/euler.c  -fPIC -DPIC -o src/.libs/euler.o
    In file included from src/euler.c:8:
    In file included from src/../include/cglm/cglm.h:14:
    In file included from src/../include/cglm/mat4.h:48:
    In file included from src/../include/cglm/quat.h:59:
    src/../include/cglm/affine-mat.h:157:3: error: implicit declaration of function
          'glm_mat4_pick3t' is invalid in C99
      glm_mat4_pick3t(mat, r);
    src/../include/cglm/affine-mat.h:158:3: error: implicit declaration of function
          'glm_mat4_ins3' is invalid in C99
      glm_mat4_ins3(r, mat);
    src/../include/cglm/affine-mat.h:158:3: note: did you mean 'glm_mat3_inv'?
    src/../include/cglm/mat3.h:281:1: note: 'glm_mat3_inv' declared here
    glm_mat3_inv(mat3 mat, mat3 dest) {
    In file included from src/euler.c:8:
    In file included from src/../include/cglm/cglm.h:14:
    src/../include/cglm/mat4.h:179:1: error: static declaration of 'glm_mat4_pick3t'
          follows non-static declaration
    glm_mat4_pick3t(mat4 mat, mat3 dest) {
    src/../include/cglm/affine-mat.h:157:3: note: previous implicit declaration is
      glm_mat4_pick3t(mat, r);
    In file included from src/euler.c:8:
    In file included from src/../include/cglm/cglm.h:14:
    src/../include/cglm/mat4.h:201:1: error: static declaration of 'glm_mat4_ins3'
          follows non-static declaration
    glm_mat4_ins3(mat3 mat, mat4 dest) {
    src/../include/cglm/affine-mat.h:158:3: note: previous implicit declaration is
      glm_mat4_ins3(r, mat);
    4 errors generated.
    ERROR:root:compiler frontend failed to generate LLVM bitcode, halting
    makefile:876: recipe for target 'src/euler.lo' failed
    make[1]: *** [src/euler.lo] Error 1
    make[1]: Leaving directory '/home/cheako/src/github/cglm'
    makefile:668: recipe for target 'all' failed
    make: *** [all] Error 2
    [email protected]:~/src/github/cglm$ 
    opened by cheako 12
  • Can't install on my system.

    Can't install on my system.


    I have a Mac. I'm having trouble installing this on my system, although I have run sh build-deps.sh multiple times (although I removed the directory and re-cloned from git each time I tried).

    I know I haven't provided much information, but I really don't know what info to provide.

    One thing I thought was rather strange is that build-deps.sh was outputting this:

    -- Looking for io.h -- Looking for io.h - not found -- Looking for malloc.h -- Looking for malloc.h - not found

    Sorry for minimal info provided, but if anyone can tell me what info I should provide, to troubleshoot this, that would be fantastic. Thanks for reading.

    opened by Thak676 11
  • swizzle support

    swizzle support

    now as C math library cglm supports swizzling: https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)#Swizzling

    glm_vec_swizzle(vec4 v, int mask, vec4 dest) glm_vec4_swizzle(vec4 v, int mask, vec4 dest)

    Predefined masks:

    /* vec3 */
    /* vec4 */

    Example usage (flip vec4 components):

    vec4 vector = {12, 73.7, 0.936, 1.05};
    glm_vec4_print(vector, stderr);
    glm_vec4_swizzle(vector, GLM_WZYX, vector);
    glm_vec4_print(vector, stderr);
    Vector (float4):
    	|12.0000   73.7000.  0.9360   1.0500|
    Vector (float4):
    	|1.0500.  0.9360.  73.7000   12.0000|

    This functions may be improved my SIMD instructions

    opened by recp 10
  • Why are matrices 2-d arrays instead of 1-d?

    Why are matrices 2-d arrays instead of 1-d?

    Hi, this is not an issue so much as just a question I have. Why are matrices represented as an array[m][n] instead of a flat array[m*n]? It seems like doing it the second way would be better for performance since it takes up less memory and doesn't require as many dereferences to access, and you can still trivially get individual vectors out of flat-array-represented matrices.

    feedback wanted 
    opened by moon-chilled 9
  • Replace non-standard M_PI* constants

    Replace non-standard M_PI* constants

    The constants M_PI, M_PI_2 and M_PI_4 are not in the C standard. If you, for example, run GCC in strict C99 mode, including CGLM headers will fail to compile.

    A minimal example to demonstrate, let's call it mpi.c:

    #include <cglm/cglm.h>
    int main(void) {       
        return 0;

    Trying to compile this with gcc -std=c99 mpi.c will barf saying that M_PI isn't defined.

    $ gcc -std=c99 mpi.c
    In file included from /usr/local/include/cglm/common.h:57:0,
                     from /usr/local/include/cglm/cglm.h:11,
                     from mpi.c:1:
    /usr/local/include/cglm/util.h: In function โ€˜glm_radโ€™:
    /usr/local/include/cglm/util.h:61:16: error: โ€˜M_PIโ€™ undeclared (first use in this function); did you mean โ€˜__Pโ€™?
       return deg * CGLM_PI / 180.0f;
    (And like a dozen more errors like this.)

    This pull request simply replaces those constants with their literal numeric values. I retained the cast from double to float to make sure there's really no change in behavior.

    For comparison, the definitions in musl libc and glibc are identical.

    opened by hartenfels 9
  • quaternion improvements and new features

    quaternion improvements and new features

    New functions:

    • [x] glm_quat_mat4t(versor q, mat4 dest) - convert quat to mat4 (transposed)
    • [x] glm_quat_mat3(versor q, mat3 dest) - convert quat to mat3
    • [x] glm_quat_mat3t(versor q, mat3 dest) - convert quat to mat3 (transposed)
    • [x] glm_mat4_quat(mat4 m, versor dest) - convert mat4 to quat
    • [x] glm_mat3_quat(mat3 m, versor dest) - convert mat3 to quat
    • [x] glm_quat_conjugate(versor q, versor dest)
    • [x] glm_quat_inv(versor q, versor dest) - inverse of quaternion
    • [x] change WXYZ order to XYZW. (In Progress)
    • [x] change quat_mulvto quat_mul(because we multiply quat with quat, not vector), we may use mulv for multiply quat with vector (In Progress)
    • [x] SSE/SSE2 version for quat_mul (maybe)
    • [x] glm_quat_axis(versor q, vec3 dest) - get axis from quat
    • [x] float glm_quat_real(versor q) - returns w
    • [x] float glm_quat_angle(versor q) - get angle from quat
    • [x] glm_quat_imag(versor q, vec3 dest)
    • [x] glm_quat_imagn(versor q, vec3 dest) - normalized version of `_imag
    • [x] float glm_quat_imaglen(versor q)
    • [x] glm_quat_add(versor p, versor q, versor dest)
    • [x] glm_quat_sub(versor p, versor q, versor dest)
    • [x] rotate vector with quat (glm_quat_roatev(versor q, vec3 v, vec3 dest) maybe)
    • [x] rotate matrix with quat (glm_quat_roate(versor q, mat4 transform, mat4 dest) maybe)
    • [x] update docs (In Progress)
    • [x] tests (In Progress)
    • [x] glm_quat_look(vec3 eye, versor ori, mat4 dest) - create view matrix using quaternion
    • [x] glm_quat_for(vec3 dir, vec3 fwd, vec3 up, versor dest) - creates quaternion for look rotation (source to dest point)

    New Helpers:

    • [x] glm_vec4_sqrt(vec4 v, vec4 dest)
    • [x] glm_vec_sqrt(vec3 v, vec3 dest)
    • [x] glm_vec4_sign(vec4 v, vec4 dest)
    • [x] glm_vec_sign(vec3 v, vec3 dest)
    • [x] SSE2 implementation for vec4_dot and vec4_norm2
    • [x] glm_vec_lerp(vec3 from, vec3 to, float t, vec3 dest)
    • [x] glm_vec4_lerp(vec4 from, vec4 to, float t, vec4 dest)
    • [x] float glm_lerp(float from, float to, float t) [DROPPED] - [x] glm_mat4_mulq(mat4 m, versor q, mat4 dest) - multiply mat4 with quat; now we have glm_quat_roate for this purpose [DROPPED] - [x] glm_mat4_quat_sse2(mat4 m, versor dest) - convert mat4 to quat (SSE2 version) [DROPPED] - [x] glm_quat_slerp_sse2(versor from, versor to, float t, versor dest) - it seems it is not produce correct results, also glm_quat_slerp version is improved and using vec4s no need to write manual SSE codes because vec4 functions are optimized with SIMD functions [POSTPONED] - [ ] float glm_quat_euler(versor q, vec3 eulXYZ) - convert quat to euler angles [POSTPONED] - [ ] float glm_euler_quat(vec3 eulXYZ, versor dest) - convert euler angles to quat


    • normalize quaternion (not input itself) in glm_quat_mat4 and glm_quat_mat3 before convert to matrix (if this is not good idea, please let me know)
    • change WXYZ order to XYZW
    • change glm_quat_mulv to glm_quat_mul and use glm_quat_mulvfor multiply quat with vector
    enhancement feature feedback wanted 
    opened by recp 9
  • Test failures on Raspberry Pi

    Test failures on Raspberry Pi

    Fresh clone from the repo, up to date Pi4:

    make check

    assert fail in test/src/test_affine.h on line 536 : ASSERT((glm_uniscaled)(m1)) ๐„‚ glm_uniscaled assert fail in test/src/test_affine.h on line 536 : ASSERT((glmc_uniscaled)(m1)) ๐„‚ glmc_uniscaled assert fail in test/src/test_vec3.h on line 875 : ASSERT(test_eq(v1[0], 0.0f)) ๐„‚ glm_vec3_rotate_m4 assert fail in test/src/test_vec3.h on line 947 : ASSERT(test_eq(v1[0], 0.0f)) ๐„‚ glm_vec3_rotate_m3 assert fail in test/src/test_vec3.h on line 875 : ASSERT(test_eq(v1[0], 0.0f)) ๐„‚ glmc_vec3_rotate_m4 assert fail in test/src/test_vec3.h on line 947 : ASSERT(test_eq(v1[0], 0.0f)) ๐„‚ glmc_vec3_rotate_m3 assert fail in test/src/test_vec4.h on line 517 : ASSERT(test_eq(v2[0] + v1[0] * s, v3[0])) ๐„‚ glm_vec4_muladds assert fail in test/src/test_vec4.h on line 517 : ASSERT(test_eq(v2[0] + v1[0] * s, v3[0])) ๐„‚ glmc_vec4_muladds

    cglm test results (0.59s):

    635 tests are runned, 627 are passed, 8 are failed


    opened by PeterOGB 8
  • vec2 and mat2 support

    vec2 and mat2 support

    This PR provides new vector and matrix size. Some mat2 operations supports SIMD (because it may not worth to implement SIMD for all operations, currently cglm supports SIMD if it makes that operation faster than plain/raw implementation)

    There are a few TODOs before merge this PR:

    • [x] rotate vec2 by angle and axis
    • [x] struct support for vec2 and mat2
    • [x] some tests
    • [ ] documentation
    • [ ] more to come
    opened by recp 8
  • glm::adjugate ?

    glm::adjugate ?

    Hello there,

    I am currently using cglm in my game engine and was wondering if there is an implementation of adjugate in cglm? here how the function looks like from glm C++ library


    Thank you.

    feature feedback wanted proposal 
    opened by ghost 4
  • Error in glm_sign()

    Error in glm_sign()

    glm_sign(), as ((val >> 31) - (-val >> 31)) fails if val is INT_MIN. In fact, it has undefinded behaviour (shifting signed 32-bit value by 31 bits).

    Using shifts, or bitwise operations in general, on signed values is a bit iffy. It would be surprising if this function was so performance-critical that this kind of branchless hack is worth it. It would be more sensible to implement it the same way as glm_signf() later inthe same source file.

    feedback wanted in progress 
    opened by pm4gh 1
  • Possible problem in glm_inv_tr SIMD implementations

    Possible problem in glm_inv_tr SIMD implementations

    A static analyzer used on code indirectly including affine.h (but not using glm_inv_tr) gives me this warning:

    cglm/simd/neon/affine.h:95:8: style: Variable 'r3' is assigned a value that is never used. [unreadVariable] r3 = vmat.val[3];

    I'm not familiar with SSE or NEON intrinsics and can't affirm that something is wrong, but it seems strange that the SSE version uses the r3 input argument while the NEON one doesn't.

    in progress todo check:implementation 
    opened by pm4gh 2
  • use fixed size integers (`int32`) for ivec instead of `int`

    use fixed size integers (`int32`) for ivec instead of `int`

    I think we should replace int with int32 in ivec[ 2 | 3 | 4 ] typedefs in order to make the vector size clear. Because in C int must be least 32-bit but it may be 64 on some platforms, AFAIK, there is no restrictions

    feedback wanted 
    opened by recp 1
  • Clang vector/matrix intrin support

    Clang vector/matrix intrin support

    Clang has a WIP matrix implementation: https://clang.llvm.org/docs/LanguageExtensions.html#matrix-types

    And several functional vector implementations: https://clang.llvm.org/docs/LanguageExtensions.html#vectors-and-extended-vectors (The vector extension I personally have had the best experience with being ext_vector_type, which also seems to be the most commonly used in the llvm repo)

    Which support/will-support nice C++-reminiscent features like using normal binary operators and some degree of auto-SIMD, at least planned support.

    Given the incompleteness of these features I understand this is a bit of an empty request - but could there possibly be a mechanism provided for overriding the types used for matrices and vectors? Like -DOVERRIDE_VECTOR_TYPENAME or something of the sort? Since it seems like CGLM has features not planned to be implemented for the intrinsic matrices and vectors.

    Thanks either way!

    feedback wanted 
    opened by Th3T3chn0G1t 1
  • Make rotation functions take unit axes

    Make rotation functions take unit axes

    Excerpt from #206 discussion:

    Having APIs not perform normalization means the application code can perform it if needed; if application already has a unit quaternion, it can simply feed them to the API. However, if the API always normalizes, and the application already has unit quaternions, the normalization step by API is needless and wastes CPU cycles by normalizing an already unit vector.

    Just expecting unit quaternions and leaving option of normalizing to the application seems like the optimal choice

    Following functions normalize incoming vector/quaternion/matrix:

    | No. | Function | File | |-----|----------------------|------------| | 1 | glm_vec3_rotate | vec3.h | | 2 | glm_vec3_rotate_m3 | vec3.h | | 3 | glm_vec3_rotate_m4 | vec3.h | | 4 | glm_rotate_make | affine.h | | 5 | glm_quatv | quat.h | | 6 | glm_quat_rotatev | quat.h | | 7 | glm_quat_for | quat.h | | 8 | glm_quat_forp | quat.h |

    These should be changed to take unit vectors i.e. avoid normalizing input vector/axis and document that the input is expected to be normalized. This gives the application programmer choice to avoid the normalization step if s/he already has a normalized vector in app side.

    help wanted feedback wanted in progress 
    opened by legends2k 6
  • v0.8.5(Mar 20, 2022)

    Bugfixes and Improvements:

    • https://github.com/recp/cglm/commit/82d1050c63a7c9f35fc1f02f28419ef61d488cad: update GLM_FLT_EPSILON to use 1e-5 instead of 1e-
    • https://github.com/recp/cglm/commit/8e784e762f7dd38994c2dbb47c84b8a69ee3d8db: win: fix shared library name and destination ( thanks to @podsvirov )
    • https://github.com/recp/cglm/commit/9f5cc3a7453db281fed2ace7577b849493bfb146: implement a few complex routines ( thanks to @mxi )
    • https://github.com/recp/cglm/commit/2d5506d15d6ca90cc99809483c1d03396de67345: set PACKAGE_VERSION so it gets substituted in cglm.pc.in by cmake ( thanks to @omar-polo )
    • https://github.com/recp/cglm/commit/68e3a072e845dfd5d380ddc07fe7df7f700c04c6: header containing sse3 intrinsics is pmmintrin.h ( thanks to @madebr )
    • https://github.com/recp/cglm/commit/5cd1a4ab44b9608ce0790359b860da007e17dae7: add missing ivec types
    • https://github.com/recp/cglm/commit/3a141b7cc8ec714ce8f4a42f40169c7eb2ac44ff: extend unions for struct api
    • https://github.com/recp/cglm/commit/2a4748d45265434b095714f185b40b22d76fc7f1: fix glm_pickmatrix()'s param type
    • https://github.com/recp/cglm/commit/7d47b7f1fd16df6516c407eff8c2a7633c93849f: fix a bug in glm_lookat_lh ( thanks to @Sand3r-)
    • https://github.com/recp/cglm/commit/7e211e1f49c4d915074a149017ae5b7efb91fded: fix bug in view_lh.h ( thanks to @Sand3r-)
    • https://github.com/recp/cglm/commit/851a58cedbfc42d06a64724869000880d37aba96: remove unused variable ( thanks to @geckor14)
    • some improvements including build files

    Sponsorship: Consider become a sponsor for cglm

    Supporting cross platform, multiple OS-es and multiple CPUs requires multiple hardwares to test on it which requires extra financial cost. Also sparing time is another big issue while working at somewhere fulltime... Your company can become a sponsor to help:


    Source code(tar.gz)
    Source code(zip)
  • v0.8.4(Aug 18, 2021)

    Now there are _no and _zo vesions of project / unproject functions. They are placed in include/cglm/clipspace/ and include/cglm/call/clipspace/ folders.

    if CGLM_CLIPSPACE_INCLUDE_ALL is defined then all clipspace headers are icluded in project.h or related main headers, otherwise only related clipspace headers will be included to avoid including unused headers...

    New Features

    • https://github.com/recp/cglm/pull/218: add ZERO_TO_ONE support to glm_unprojecti ( thanks to @Nairou )
    • https://github.com/recp/cglm/pull/219: add ZERO_TO_ONE support to glm_project
    • https://github.com/recp/cglm/pull/219: new function: glm_pickmatrix() aka gluPickMatrix()

    Bugfix and Improvements

    • https://github.com/recp/cglm/pull/205: include affine.h in quat.h; remove needless decls ( thanks to @legends2k )
    • https://github.com/recp/cglm/pull/207: fix vec3_ortho ( thanks to @legends2k )
    • https://github.com/recp/cglm/pull/209: fix cross product when an operand is also dest ( thanks to @legends2k )
    • https://github.com/recp/cglm/pull/210: compute quaternion rotating a vector into another ( thanks to @legends2k )
    • fix including headers
    • fix some documentations ( thanks to @bubba2k and others )

    Sponsorship: Consider become a sponsor for cglm

    Supporting cross platform, multiple OS-es and multiple CPUs requires multiple hardwares to test on it which requires extra financial cost. Also sparing time is another big issue while working at somewhere fulltime... Your company can become a sponsor to help:


    Source code(tar.gz)
    Source code(zip)
  • v0.8.3(May 30, 2021)

    Major New Feature: Clipspace Control (https://github.com/recp/cglm/pull/198) ๐ŸŽ‰

    cglm now supports different clipspace configurations.

    Many many thanks to @raedwulf and @michael-g to provide this feature to cglm which was in TODOs long time. There are missing tests for now but tests will or should be added as soon as possible. Also thanks to @hartenfels and @bwhmather fixing build files...


    /* auto created in cglm */

    New functions

    Now there are _no, _zo, _lh, _rh... vesions of projection and view functions. No need to paste all of them here, they are placed in include/cglm/clipspace/, include/cglm/struct/clipspace/ and include/cglm/call/clipspace/ folders.

    if CGLM_CLIPSPACE_INCLUDE_ALL is defined then all clipspace headers are icluded in cam.h or related main headers, otherwise only related clipspace headers will be included to avoid including unused headers...

    New Features

    • https://github.com/recp/cglm/pull/195 nlerp for quaternions ( thanks to @legends2k )

    Bugfix and Improvements

    • simd: optimize glm_mat4_zero() with simd
    • simd, sse: optimize mat4 inv with sse
      • reduce a few shufflees
      • re-oder instructions for ILP
    • simd, sse: optimize mat4 mul with sse
    • simd, sse: optimize mat4 mul-v with sse
    • arm neon: optimize mat4 mul with neon
    • arm neon: optimize affine with neon
    • sse: optimize affine with sse
    • sse: optimize glm_quat_mul with sse
    • sse: optimize glm_mat2_mul_sse2 with sse
    • sse2: optimize glm_mat3_mul_sse2() with sse2
    • simd, sse: reduce some computation at glm_mul_rot_sse2()
    • arm, neon: impove hadd performance
    • arm, neon: use negate instruction instead of xor in glm_inv_tr_neon()
    • style: rename nearVal, farVal to nearZ and farZ
    • https://github.com/recp/cglm/pull/192 fix function param type ( thanks to @Winter091 )
    • other improvements may not be mentioned here....

    Sponsorship: Consider become a sponsor for cglm

    Supporting cross platform, multiple OS-es and multiple CPUs requires multiple hardwares to test on it which requires extra financial cost. Also sparing time is another big issue while working at somewhere fulltime... Your company can become a sponsor to help:


    Source code(tar.gz)
    Source code(zip)
  • v0.8.2(Apr 29, 2021)

    New Features and Improvements

    • #188 configure and install cglm.pc with cmake ( thanks to @wdouglass )
    • minor doc impovements ( thanks to @ylecuyer )
    • [x] rename glmm_shuff1x() to glmm_splat(), mark glmm_shuff1x() as DEPRECATED
    • [x] optimize translate functions with FMA and NEON
    • [x] use unified glmm api for vec4
    • [x] arm: define CGLM_ARM64 for identify arm64
    • [x] arm: optimize vec4 div with NEON
    • [x] arm, neon: implement mat4 determinant with NEON
    • [x] arm, neon: implement mat4 inv with NEON
    • [x] arm, neon: update mat4_mul to use FMA
    • [x] arm, neon: neon/fma support for glm_mul()
    • [x] arm, neon: neon/fma support for glm_mul_rot()
    • [x] arm, neon: neon/fma support for glm_inv_tr()
    • [x] arm, neon: neon/fma support for glm_mat2_mul()
    • [x] arm, neon: neon/fma support for glm_quat_mul()

    New glmm functions:

    • glmm_set1(x)
    • glmm_splat_x(x)
    • glmm_splat_y(x)
    • glmm_splat_z(x)
    • glmm_splat_w(x)
    • glmm_xor(a, b) for neon
    • glmm_vhadd(a) for neon
    Source code(tar.gz)
    Source code(zip)
  • v0.8.1(Apr 19, 2021)

    New Features:

    Implement FMA

    SIMD operations are optimized with FMA instructions to reduce operations and increasee accuracy. The gennerated CPU instructions are reduced. All matrix and related-vector operations are optimized.

    FMA must be enable for these optimizations (with -mfma flag on GCC and Clang, /arch:AVX2 /O1-2 on MSVC)

    • [x] optimize mat4 SSE operations with FMA
    • [x] optimize mat3 SSE operations with FMA
    • [x] optimize mat2 SSE operations with FMA
    • [x] optimize affine mat SSE operations with FMA
    • [x] optimize vec4 muladd and muladds operations with FMA

    New glmm functions (SSE + NEON):

    • glmm_vhadd() - broadcast-ed hadd
    • glmm_fmadd(a, b, c) - fused multiply add
    • glmm_fnmadd(a, b, c) - fused negative multiply add
    • glmm_fmsub(a, b, c) - fused multiply sub
    • glmm_fnmsub(a, b, c) - fused negative multiply sub

    New glmm functions (AVX):

    • glmm256_fmadd(a, b, c) - fused multiply add AVX
    • glmm256_fnmadd(a, b, c) - fused negative multiply add AVX
    • glmm256_fmsub(a, b, c) - fused multiply sub AVX
    • glmm256_fnmsub(a, b, c) - fused negative multiply sub AVX
    • glm_mat4_scale_avx(mat4 m, float s) - scale matrix with scalar (if AVX enabled)


    • #183: add CMake interface library target ( thanks to @legends2k )

    Use as header-only library with your CMake project

    This requires no building or installation of cglm.

    • Example:
    cmake_minimum_required(VERSION 3.8.2)
    project(<Your Project Name>)
    add_executable(${PROJECT_NAME} src/main.c)
    target_link_libraries(${LIBRARY_NAME} PRIVATE
    add_subdirectory(external/cglm/ EXCLUDE_FROM_ALL)
    Source code(tar.gz)
    Source code(zip)
  • v0.8.0(Mar 2, 2021)

    Bugfixes and Improvements:

    • #180: aabb v sphere intesect fix (glm_aabb_sphere()) ( thanks to @ILeonor to report this ) - todo: more aabb v sphere intersect options
    • #178: fix cmake config install path ( thanks to @gaurapanasenko )
    • #177: remove wrong c standard bug ( thanks to @Winter091 )
    • #172: replace hex floating point literals ( thanks to @SanderMertens ) - todo: https://github.com/recp/cglm/pull/172#issuecomment-737080592
    • #169: fix Documentions WARNING for __restrict attribute ( thanks to @podsvirov )
    • update cglm.podspec
    • improve documentation
    Source code(tar.gz)
    Source code(zip)
  • v0.7.9(Nov 18, 2020)

    New Features:

    • arm neon: support transpose mat4 with neon
    • arm neon: multiply mat4 with vec4
    • Swift Package Manager support, swiftpm package file with module map ( thanks to @smumryakW )
    • meson: add 'install' option ( thanks to @Akaricchi ) ย 

      This is useful for people who want to use cglm as a meson subproject without polluting the main project's install target.

    Bugfixes and Improvements:

    • arm neon: move neon-scale to simd header
    • fix docs for glm_vec2() ( thanks to @emersion )
    • simd/x86: fix -Wcast-align warnings (gcc/clang) ( thanks to @Akaricchi ) ย 

      This modifies glmm_{load,store}3 functions to make the compiler assume the v pointer is appropriately aligned for the type it is being cast to. Not tested with CGLM_ALL_UNALIGNED, but it probably doesn't matter.

    Source code(tar.gz)
    Source code(zip)
  • v0.7.8(Aug 9, 2020)

    New Features:

    • build: meson build support ( thanks to @randy408 ) https://github.com/recp/cglm/pull/154

    Bugfixes and Improvements:

    • win32: fix symbol exports, drop CGLM_DLL, add CGLM_STATIC... ( thanks to @randy408 )
      • CGLM_EXPORTS - building a shared library (dllexport)
      • CGLM_STATIC - required for cglm\call headers with statically built library (no attributes)
      • No defines - assume dynamic (dllimport)
    • win32, test: don't link 'm' with msvc ( thanks to @randy408 )
    • gcc: fix some warnings ( thanks to @randy408 )
    • io: make options changeable by user, define colors as empty macro to remove colors from prints
    • io: add documentation to io.h header
    • io: deprecate CGLM_NO_PRINTS_NOOP
    • documentation improvements and fixes
    Source code(tar.gz)
    Source code(zip)
  • v0.7.7(Jul 31, 2020)

    New Features:

    2D Affine Transforms

    Now we have 2D Affine Transform functions. 2D Transform functions are suffixed with 2d, functions that don't have any suffixes are 3D. For instance glm_translate2d() is 2D and glm_translate() is 3D.

    New Functions:


    • glm_translate2d()
    • glm_translate2d_to()
    • glm_translate2d_x()
    • glm_translate2d_y()
    • glm_translate2d_make()


    • glm_scale2d_to()
    • glm_scale2d_make()
    • glm_scale2d()
    • glm_scale2d_uni()


    • glm_rotate2d_make()
    • glm_rotate2d()
    • glm_rotate2d_to()

    All these functions are documented at https://cglm.readthedocs.io/en/latest/affine2d.html . Rotate functions are rotating around Z axes. SIMD optimizations will be applied in the future releases.

    Bugfixes and Improvements:

    • mat3_mulv: function behaviour to match with mat4 ( thanks to @Terri00 )
    • mat2: don't use vec4 directly on mat2 because of alignment requirements may be different
    • define CGLM_DEFINE_PRINTS macro for test targets to see printed results
    • documentation fixes


    • build: update CFLAGS (-O3 -std=gnu11) for check/test target to match the main target
    • build: remove RTC1 from CMake build for Windows/MSVC
    Source code(tar.gz)
    Source code(zip)
  • v0.7.6(Jun 12, 2020)

    Critical Bugfix:

    • neon: fix vec4_muladds (critical): https://github.com/recp/cglm/commit/f49e8f99914e9739fef1daf47f58748cb749877d

    Bugfixes and Improvements:

    • Use epsilon to compare vec2/vec3/vec4_eq_all
    • mat2: suppress warnings for initializing mat2 sruct
    • Build: Improve CMake build integration
    • Build: Update CMake to export Config to use find_package()
    • Build: Drop pedantic from C Flags and allow extensions
    • tests: add option to disable colors in test output
    • tests: add test for frustum

    New Features:

    • Option to override FLT_EPSILON with GLM_FLT_EPSILON
    Source code(tar.gz)
    Source code(zip)
  • v0.7.4(May 16, 2020)

    Critical Bugfix:

    • fix arm neon build; to negating vectors, NEON gives single intrinsic: https://github.com/recp/cglm/commit/269bdb3dbd07001b4345d8b9c88f235b27d4804a


    • io: in release mode, make print functions macro to suppress unused parameter warnings
    • build, cmake: use PROJECT_VERSION_** to set so version instead of custom variables
    Source code(tar.gz)
    Source code(zip)
  • v0.7.3(Apr 30, 2020)

    Bugfixes and Improvements:

    • suppress documentation warnings
    • remove redundant typedef
    • fix print functions to align column correctly

    New Features:

    Print Functions Improvements

    • While printing, mis-alignment of columns are fixed: larger numbers are printed via %g and others are printed via %f Column withs are calculated before print.

    • Now values are colorful ;)

      Screen Shot 2020-05-01 at 1 17 48 AM
    • New options with default values:

        #define CGLM_PRINT_PRECISION    5
        #define CGLM_PRINT_MAX_TO_SHORT 1e5
        #define CGLM_PRINT_COLOR        "\033[36m"
        #define CGLM_PRINT_COLOR_RESET  "\033[0m"
    • Inline prints are only enabled in DEBUG mode and if CGLM_DEFINE_PRINTS is defined.
    • You can still call library-print functions e.g. glmc_print...

    To make codes unbroken, cglm makes inline print functions to be empty-body (if DEBUG and CGLM_DEFINE_PRINTS are not defined):

    CGLM_INLINE void glm_mat4_print(mat4 matrix, FILE *o) { }

    compiler must eliminate this empty inline function calls. This also can be disabled by defining CGLM_NO_PRINTS_NOOP macro. ๐ŸŽ‰

    Define CGLM_PRINT_PRECISION to change print precision, default is increased to 5 from 4 ...

    Source code(tar.gz)
    Source code(zip)
  • v0.7.2(Apr 27, 2020)

    Bugfixes and Improvements:

    • fix glms_sphere_transform by using mat4s instead of mat4 (#121) ( thanks to @Zollerboy1 )
    • fix glms_vec2_rotate() by using a dest vec2s instead of taking an axis ( thanks to @Zollerboy1 )
    • fix some documentation mistakes ( thanks to @Uwila )
    • remove redundant forward decelerations
    • use glm_clamp_zo in some places to clamp between 0 and 1
    • make Github recognize header language as C (#127) ( thanks to @Uwila )
    • [README] link contributors' avatars to the correct page ( thanks to @Uwila )
    • and some forgotten big or small fixes maybe :) ( thanks to all )

    New Features:

    • ray-triangle intersection ( many thanks to @Uwila )

    • CMake build support ( many thanks to @FMMazur and @realaltffour ) Now we can build cglm with CMake and can integrate with other CMake projects.

      CMake options:

      option(CGLM_SHARED "Shared build" ON)
      option(CGLM_STATIC "Static build" OFF)
      option(CGLM_USE_C99 "" OFF) # C11 
      option(CGLM_USE_TEST "Enable Tests" OFF) # for make check - make test

    there may be some bugs in CMake configurations, it will be improved by time.

    feel free to suggest new features, improvements and fix things by creating issues or pull requests.

    Source code(tar.gz)
    Source code(zip)
  • v0.7.1(Mar 2, 2020)

  • v0.7.0(Feb 25, 2020)

    New Features:

    • Now vec2 and mat2 are officially supported (including struct api) ๐ŸŽ‰ ( https://github.com/recp/cglm/pull/97 )
    • add forward vector as macro (vec3, RH)

    Bugfixes and Improvements:

    • quat: fix quat_for and quat_forp implementations; These are identical to QuaternionLook / LookRotation in other frameworks/engines...
    • add notes for versor/quaternion type to describe memory layout
    • merge test sources into one C source
    • make plane zero if norm is zero after normalization
    • Add more tests

    Since vec2 and mat2 are new features, bugs may occurs. Any feedback or help would be appreciated.

    Source code(tar.gz)
    Source code(zip)
  • v0.6.2(Jan 17, 2020)

    • Now tests can be run on Windows too. Just run cglm-test project.
    • Anonymous structs are enabled for MSC >=1900 (Visual Studio 2015+)
    • win: fix glms_quat_imagn if use_struct option is disabled
    Source code(tar.gz)
    Source code(zip)
  • v0.6.1(Jan 17, 2020)

    New Features:

    • Custom Built-in Unit Test Suite: Now we have custom test suite which don't require external dependencies. It is very cool and simple to implement
    • Helpers for apple's simd library (#107)
    • mat4: add zero for call

    Bugfixes and Improvements:

    • Add more tests
    • Remove build-deps.sh
    • Remove cmocka from submodules and update docs
    • quat: fix glmc_quat_normalize()
    • vec: fix min/max for compiled vec3
    • arm: fix type castings for ARM Neon
    • vec4: fix parameter name for NEON
    • build: remove duplicate entry in makefile
    • Change empty prototypes to (void) ( @hartenfels )
    • Add a vec2s struct type for consistency ( @hartenfels )
    • Don't add default autoconf flags to build ( @hartenfels )
    • [major change] Use gnu11 instead of gnu99 ( @hartenfels )
    • and some other bugfixes and improvements made by @hartenfels
    • Fix spelling error in name of glms_rotate_x ( @jdolan )

    Now cglm don't require external dependencies and it has very cool test suite ๐ŸŽ‰

    Source code(tar.gz)
    Source code(zip)
  • v0.6.0(Sep 1, 2019)

    New API: Structs ( thanks to @acoto87 ) (https://github.com/recp/cglm/pull/80)

    cglm now supports structs. To use struct api, just include cglm/struct.h header. You can also use struct api with array api. Struct api provides type-safety. Currently struct parameters are pass-by-value but in the future it may be pass-by-reference by using pointers (feedbacks are welcome by creating issues).

    New Features and Improvements:

    • swizzling api: now cglm supports swizzling
    • Find post-build.sh even when not building in. ( @hartenfels )
    • quat: fix glm_quat_axis axis parameter type
    • win: remove optional DLLMain entry point
    • new name for euler sequence (#94) ( @superbigio )
    • squared distance with SIMD support (#96) ( @superbigio )
    • glm_lerpc(), glm_step(), glm_smoothstep(), glm_smoothinterp() (#98) ( @superbigio )
    • added glm_vec_fill() (#100) ( @superbigio )
    • swapped argument order in glmm_store3() (#102) ( @superbigio )
    • vec: some useful functions (#103) ( @superbigio )
    • quat: fix identity quat in glm_quat_normalize_to (#88) ( @yushli )
    • and some minor changes...

    New glmm (SIMD) functions: (thanks to @superbigio )

    • glmm_norm2(v) squared l2 norm
    • glmm_vhmin(v) horizontal min
    • glmm_vhmax(v) horizontal max
    • glmm_norm_one(v) l1 norm
    • glmm_norm_inf(v) infinity norm
    Source code(tar.gz)
    Source code(zip)
  • v0.5.4(Apr 30, 2019)

    Bug fixes and Improvements:

    • improve vec3 alignment ( @haxpor )
    • Add missing header for size_t ( @acoto87 )
    • move common headers to common.h
    • Fix glm_vec4_distance for armv7 and improve for SSE2 ( @haxpor )
    • ci: print test logs after failure
    • fix glm_quat_normalize_to ( @yushli )
    • improve docs
    • fix build scripts
      • fix linking cmocka
      • fix build script if folder names contain spaces
    Source code(tar.gz)
    Source code(zip)
  • v0.5.3(Mar 3, 2019)


    • drop glm__memcpy, glm__memset and glm__memzero
      • copy matrix items manually in _ucopy functions
    • update docs

    New Functions:

    • float glm_mat3_rmc(vec3 r, mat3 m, vec3 c) multiplies row vector, matrix and column vector and returns scalar.
    • glm_mat3_zero(mat3 mat), glm_mat4_zero(mat4 mat) make given matrix zero.
    Source code(tar.gz)
    Source code(zip)
  • v0.5.2(Feb 3, 2019)

    New Options:

    • CGLM_SSE4_DOT : Enable SSE4 dot product
    • CGLM_SSE3_DOT : Enable SSE3 dot product

    New Functions:

    • glm_persp_move_far() extend frustum's far distance
    • void glm_vec4_cubic(float s, vec4 dest) fills vec4 as [s^3, s^2, s, 1.0]
    • float glm_mat4_rmc(vec4 r, mat4 m, vec4 c) multiplies row vector, matrix and column vector and returns scalar. This is good helper to get SMC result easily for curves.
    • float glm_smc(float s, mat4 m, vec4 c) calculates SMC multiplication by using glm_mat4_rmc()and glm_vec4_cubic()
    • float glm_bezier() cubic bezier equation
    • float glm_hermite() cubic hermite equation
    • float glm_decasteljau() solve cubic bezier equation using decasteljau

    New glmm (SIMD) functions:

    • glmm_vhadds(v) horizontal add, returns register
    • glmm_hadd(v) horizontal add, returns scalar
    • glmm_vdots(a, b) dot product, single lane contain dot product to convert result to scalar
    • glmm_vdot(a, b) dot product, all lanes contain dot product to use result with other vector operations


    • glmm_ functions are moved to platform specific headers.
    • Now some glmm_ functions supports NEON
    • CGLM_SIMD_x86, CGLM_SIMD_ARM and CGLM_SIMD are defined if it is supported.
    Source code(tar.gz)
    Source code(zip)
  • v0.5.1(Jan 2, 2019)

    New Features or Improvements:

    • [major change] builtin alignment (8-byte) is removed from vec3 and mat3 types
    • a helper to get normalized cross product (glm_vec3_crossn())
    • helpers to get trace of matrix


    • fix comparing two float values in tests
    Source code(tar.gz)
    Source code(zip)
  • v0.5.0(Dec 2, 2018)

    New Features or Improvements:

    • [major change]: rename glm_vec_ namespace to glm_vec3_
    • new minadd, and maxadd functions for vectors
    • new negate functions e.g. glm_vec3_negate() , glm_vec4_negate()


    • fix versor alignment ( thanks to @sinisterchipmunk )
    • fix glm_vec3_angle() if cosine is out of range, now it does not return NaN and more stable.


    • _flipsign and _inv functions for vectors are deprecated in favor of _negate function.
    Source code(tar.gz)
    Source code(zip)
  • v0.4.9(Oct 19, 2018)

    New Features or Improvements:

    • identiy helper for arrays (matrix/quaternion). This helpers will make each item of array identity matrix/quaternion.
    • define math constants in cglm header ( @hartenfels ). Now cglm does not depends on platform specific math constants


    • avx: replace binary constants with hex. Binary constants are GCC extensions ( thanks to @jonathanplatzer )
    • avx: fix glm_mul_avx().
    Source code(tar.gz)
    Source code(zip)
  • v0.4.8(Jul 23, 2018)

    New Features or Improvements:

    • easing functions (experimental)
    • additional utils (see util.h)
      • add MIN and MAX macros
      • new version for clamp: clamp to zero and one
      • percentage
      • glm_eq to compare floats
    • unalignned version for vec4_copy: vec4_ucopy. Use this if you want to copy vector from external source
    • Add macro for automatic alignment of matrices (@jonathanplatzer)


    • Fix alignment issue when using AVX (@jonathanplatzer)
    Source code(tar.gz)
    Source code(zip)
  • v0.4.7(Jun 9, 2018)

    New Features or Improvements:

    • add support for spheres
    • aabb and sphere intersect functions
    • add squared distance for vec3; this will improve performance by avoiding calling sqrt function in some places
    Source code(tar.gz)
    Source code(zip)
  • v0.4.6(May 27, 2018)

    New Features or Improvements:

    • optimize glm_scale_make and glm_translate_make
    • align local variables on stack (because since v0.4.5, alignment is optional)
    • add missing call versions
    • helper for getting center of aabb (wrapper for vec_center)

    Bug fixes:

    • fix glm_translate_to

    API changes:

    • improve glm_mat4_mulv3 to apply translation too
    Source code(tar.gz)
    Source code(zip)
  • v0.4.5(May 10, 2018)

    • _MSC_VER is used instead of _WIN32 (Yatima1460)
    • header dependencies are fixed
    • New option for alignment; Alignment requirement is now OPTIONAL, check the docs to see options
    • New option for SSE/SSE2 shuffle operations
    • New namespace definition; now glmm_ is used for SIMD api
    • Alignment is disabled for older Visual Studio versions, this will fix alignment error for function params. Alignment is still required for Visual Studio 2017 15.6+ if it is not disabled.
    Source code(tar.gz)
    Source code(zip)
  • v0.4.4(Apr 21, 2018)

  • v0.4.3(Apr 18, 2018)

Recep Aslantas
alone with numbers
Recep Aslantas
A terminal-based graphics library for both 2D and 3D graphics.

TermGL A terminal-based graphics library for both 2D and 3D graphics. Written in C, created for terminals supporting ANSI escape codes. Table of Conte

null 201 Jun 26, 2022
kaun is a replacement for lรถve's built-in love.graphics module intended for 3D graphics

kaun kaun is a replacement for lรถve's built-in love.graphics module intended for 3D graphics. It is a Lua module you can require from a shared library

Joel Schumacher 4 Apr 5, 2021
This repo contains the DirectX Graphics samples that demonstrate how to build graphics intensive applications on Windows.

DirectX-Graphics-Samples This repo contains the DirectX 12 Graphics samples that demonstrate how to build graphics intensive applications for Windows

Microsoft 4.6k Jun 27, 2022
A C math library targeted at games

Kazmath Kazmath is a simple 3D maths library written in C. It was initially coded for use in my book, Beginning OpenGL Game Programming - Second editi

Luke Benstead 502 May 25, 2022
Pure C math library for 2D and 3D programming

MATHC MATHC is a simple math library for 2D and 3D programming. Features Vectors (2D, 3D and 4D) (integer type and floating-point type) Quaternions Ma

Felipe da Silva 594 Jun 24, 2022
Bash math utilities

Bashmash Bash math utilities What is Bashmash? Bashmash is a set of math utilities for the Bash language. It simplifies common mathematical operations

Hubert Pastyrzak 11 Mar 11, 2021
Phyxed is a 2D physics engine with support for fixed point math.

Phyxed is a 2D physics engine with support for fixed point math.

Anders Elfgren 23 Jan 18, 2022
Optimized GPU noise functions and utilities

Optimized GPU noise functions and utilities

Brian Sharpe 328 Jul 1, 2022
DirectX 11 and 12 library that provides a scalable and GCN-optimized solution for deferred shadow filtering

AMD ShadowFX The ShadowFX library provides a scalable and GCN-optimized solution for deferred shadow filtering. Currently the library supports uniform

GPUOpen Effects 163 Jun 23, 2022
Cross-platform, graphics API agnostic, "Bring Your Own Engine/Framework" style rendering library.

bgfx - Cross-platform rendering library GitHub Discussions Discord Chat What is it? Cross-platform, graphics API agnostic, "Bring Your Own Engine/Fram

ะ‘ั€ะฐะฝะธะผะธั€ ะšะฐั€ะฐัŸะธั› 11.8k Jul 2, 2022
2D Vector Graphics Engine Powered by a JIT Compiler

Blend2D 2D Vector Graphics Powered by a JIT Compiler. Official Home Page (blend2d.com) Official Repository (blend2d/blend2d) Public Chat Channel Zlib

Blend2D 1.1k Jun 25, 2022
A modern cross-platform low-level graphics library and rendering framework

Diligent Engine A Modern Cross-Platform Low-Level 3D Graphics Library Diligent Engine is a lightweight cross-platform graphics API abstraction library

Diligent Graphics 2.4k Jun 29, 2022
Lightweight and modular C++11 graphics middleware for games and data visualization

Magnum โ€” Lightweight and modular C++11/C++14 graphics middleware for games and data visualization Looking for an open-source library that gives you gr

Vladimรญr Vondruลก 4.1k Jun 22, 2022
Yocto/GL: Tiny C++ Libraries for Data-Driven Physically-based Graphics

Yocto/GL: Tiny C++ Libraries for Data-Oriented Physically-based Graphics Yocto/GL is a collection of small C++17 libraries for building physically-bas

Fabio Pellacini 2.3k Jun 26, 2022
A library for high-performance, modern 2D graphics with SDL written in C.

SDL_gpu, a library for making hardware-accelerated 2D graphics easy. by Jonathan Dearborn SDL_gpu is licensed under the terms of the MIT License. See

Jonathan Dearborn 1k Jun 20, 2022
3D engine from scratch (without OpenGL or any other 3D graphics library)

Simple 3d engine based on SFML library. I tried to make this engine powerful and easy to understand.

Vectozavr 21 Jun 4, 2022
Dear PyGui 3D Engine (early development) and Graphics API demos.

Marvel This repo is the working location of the eventual Dear PyGui 3D Engine. It also contains several single file examples of creating a triangle wi

Jonathan Hoffstadt 78 Jun 21, 2022
4K Executable Graphics framework

Blossom ?? Blossom is a small framework for creating 4K Executable Graphics artworks for the demoscene. You are free to use this as the basis for your

Luna 159 Jun 22, 2022
This repository is used for storing sourcecode related to final project of Computer Graphics and Computer Vision

Computer Graphics and Computer Vision Description: This repository is used for storing sourcecode related to final project of Computer Graphics and Co

null 12 Jun 16, 2022