Almost all functions (inline versions) and parameters are documented inside the corresponding headers.
Complete documentation: https://cglm.readthedocs.io
- _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)
If you are not aware of the original GLM library yet, you may also want to look at: https://github.com/g-truc/glm
vec4
andmat4
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!
- 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.
cglm supports both ARRAY API and STRUCT API, so you can return structs if you utilize struct api (glms_
).
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
- 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 options 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 versions, 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) */
glm_inv_tr(modelMat);
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 mat = GLMS_MAT4_IDENTITY_INIT;
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.
$ mkdir build
$ cd build
$ cmake .. # [Optional] -DCGLM_SHARED=ON
$ make
$ sudo make install # [Optional]
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
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
cglm_headers)
add_subdirectory(external/cglm/ EXCLUDE_FROM_ALL)
- 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
cglm)
add_subdirectory(external/cglm/)
# or you can use find_package to configure cglm
$ meson build # [Optional] --default-library=static
$ cd build
$ ninja
$ sudo ninja install # [Optional]