summaryrefslogtreecommitdiff
path: root/libs/cglm/README.md
blob: 5f8968e3b865edef7c44b698cfd927ec39804b7c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
# πŸŽ₯ OpenGL Mathematics (glm) for `C`

<p align="center">
   <img alt="" src="cglm.png" width="550" />
</p>
<br>
<p align="center">
    <a href="https://travis-ci.com/recp/cglm">
        <img src="https://travis-ci.com/recp/cglm.svg?branch=master"
             alt="Build Status">
    </a>
    <a href="https://ci.appveyor.com/project/recp/cglm/branch/master">
        <img src="https://ci.appveyor.com/api/projects/status/av7l3gc0yhfex8y4/branch/master?svg=true"
             alt="Windows Build Status">
    </a>
    <a href="http://cglm.readthedocs.io/en/latest/?badge=latest">
        <img src="https://readthedocs.org/projects/cglm/badge/?version=latest"
             alt="Documentation Status">
    </a>
    <a href="https://www.codacy.com/app/recp/cglm?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=recp/cglm&amp;utm_campaign=Badge_Grade">
        <img src="https://api.codacy.com/project/badge/Grade/6a62b37d5f214f178ebef269dc4a6bf1"
             alt="Codacy Badge"/>
    </a>
    <a href="https://coveralls.io/github/recp/cglm?branch=master">
        <img src="https://coveralls.io/repos/github/recp/cglm/badge.svg?branch=master"
             alt="Coverage Status"/>
    </a>
    <a href="https://codecov.io/gh/recp/cglm">
        <img src="https://codecov.io/gh/recp/cglm/branch/master/graph/badge.svg"
             alt="Coverage Status"/>
    </a>
    <br /><br />
    <a href="#sponsors">
        <img src="https://opencollective.com/cglm/sponsors/badge.svg"
             alt="Sponsors on Open Collective"/>
    </a>
    <a href="#backers">
        <img src="https://opencollective.com/cglm/backers/badge.svg"
             alt="Backers on Open Collective"/>
    </a>
</p>

<br>

<p align="center">
Highly optimized 2D|3D math library, also known as <b>OpenGL Mathematics (glm) for `C`</b>. <b>cglm</b> provides lot of utils to help math operations to be fast and quick to write. It is community friendly, feel free to bring any issues, bugs you faced. 
</p>

---

#### πŸ“š Documentation

Almost all functions (inline versions) and parameters are documented inside the corresponding headers. <br />
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)
- **[major change]** by starting v0.8.3, **cglm** supports alternative clipspace configuations e.g. Left Handed, Zero-to-One (_zo)... `CGLM_FORCE_DEPTH_ZERO_TO_ONE` and `CGLM_FORCE_LEFT_HANDED` is provided to control clipspace. You should be able to use **cglm** with Vulkan, DirectX and Metal now... see https://cglm.readthedocs.io/en/latest/opt.html#clipspace-option-s

#### πŸ“Œ 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.

#### πŸ“Œ Allocations?
`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_`).

<hr/>

<table>
  <tbody>
    <tr>
      <td>
        <div>Like some other graphics libraries (especially OpenGL) this library use Column-Major layout to keep matrices in the memory. </div>
        <div>&nbsp;</div>
        <div>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. </div>
      </td>
      <td>
        <img src="https://upload.wikimedia.org/wikipedia/commons/3/3f/Matrix_Columns.svg" width="300px" />
      </td>
    </tr>
  </tbody>
</table>

## πŸš€ Features
- **scalar** and **simd** (sse, avx, neon...) optimizations
- option to use different clipspaces e.g. Left Handed, Zero-to-One... (currrently right handed negative-one is default)
- 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 (S*M*C, 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...

<hr />

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_`.

```C
  #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.

```C
  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
```C
/* multiplication */
mat4 modelMat;
glm_mul(T, R, modelMat);

/* othonormal rot + tr matrix inverse (rigid-body) */
glm_inv_tr(modelMat);
```

### 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:

```C
#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.

## πŸ”¨ Build

### CMake (All platforms)
```bash
$ mkdir build
$ cd build
$ cmake .. # [Optional] -DCGLM_SHARED=ON
$ make
$ sudo make install # [Optional]
```

##### Cmake options with Defaults:

```CMake
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 as header-only library with your CMake project

This requires no building or installation of cglm.

* Example:

``` cmake
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)
```

#### Use with your CMake project
* Example:
```cmake
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 (All platforms)

```bash
$ meson build # [Optional] --default-library=static
$ cd build
$ ninja
$ sudo ninja install # [Optional]
```

##### Meson options with Defaults:

```meson
c_std=c11
buildtype=release
default_library=shared
enable_tests=false #Β to run tests: ninja test
```
#### Use with your Meson project
* Example:
```meson
# 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:

```swift
...
Package( 
  ...
  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

```swift
...
.target(
  ...
  dependencies: [
    ...
    .product(name: "cglm", package: "cglm"),
  ]
  ...
)
...
```

### Unix (Autotools)

```bash
$ 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.

```Powershell
$ cd win
$ .\build.bat
```
if `msbuild` won't work (because of multi version VS) then try to build with `devenv`:
```Powershell
$ 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:
```bash
$ 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
```C
#include <cglm/cglm.h>
```
the header will include all headers. Then call the func you want e.g. rotate vector by axis:
```C
glm_vec3_rotate(v1, glm_rad(45), (vec3){1.0f, 0.0f, 0.0f});
```
some functions are overloaded :) e.g you can normalize vector:
```C
glm_vec3_normalize(vec);
```
this will normalize vec and store normalized vector into `vec` but if you will store normalized vector into another vector do this:
```C
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.
```C
#include <cglm/call.h>
```
this header will include all headers with c postfix. You need to call functions with c posfix:
```C
glmc_vec3_normalize(vec);
```

Function usage and parameters are documented inside related headers. You may see same parameter passed twice in some examples like this:
```C
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
```C
mat4 proj, view, model, mvp;

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

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

#### Option 2
```C
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
```C
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)
```C
glUniformMatrix4fv(location, 1, GL_FALSE, (float *)matrix);
```

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

## Notes

- 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

**TODO:**
- [ ] Unit tests (In Progress)
- [ ] Unit tests for comparing cglm with glm results
- [x] Add version info
- [ ] Unaligned operations (e.g. `glm_umat4_mul`)
- [x] Extra documentation
- [x] ARM Neon Arch


## Contributors

This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
<a href="https://github.com/recp/cglm/graphs/contributors"><img src="https://opencollective.com/cglm/contributors.svg?width=890&button=false" /></a>


## Backers

Thank you to all our backers! πŸ™ [[Become a backer](https://opencollective.com/cglm#backer)]

<a href="https://opencollective.com/cglm#backers" target="_blank"><img src="https://opencollective.com/cglm/backers.svg?width=890"></a>


## Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/cglm#sponsor)]

<a href="https://opencollective.com/cglm/sponsor/0/website" target="_blank"><img src="https://opencollective.com/cglm/sponsor/0/avatar.svg"></a>
<a href="https://opencollective.com/cglm/sponsor/1/website" target="_blank"><img src="https://opencollective.com/cglm/sponsor/1/avatar.svg"></a>
<a href="https://opencollective.com/cglm/sponsor/2/website" target="_blank"><img src="https://opencollective.com/cglm/sponsor/2/avatar.svg"></a>
<a href="https://opencollective.com/cglm/sponsor/3/website" target="_blank"><img src="https://opencollective.com/cglm/sponsor/3/avatar.svg"></a>
<a href="https://opencollective.com/cglm/sponsor/4/website" target="_blank"><img src="https://opencollective.com/cglm/sponsor/4/avatar.svg"></a>
<a href="https://opencollective.com/cglm/sponsor/5/website" target="_blank"><img src="https://opencollective.com/cglm/sponsor/5/avatar.svg"></a>
<a href="https://opencollective.com/cglm/sponsor/6/website" target="_blank"><img src="https://opencollective.com/cglm/sponsor/6/avatar.svg"></a>
<a href="https://opencollective.com/cglm/sponsor/7/website" target="_blank"><img src="https://opencollective.com/cglm/sponsor/7/avatar.svg"></a>
<a href="https://opencollective.com/cglm/sponsor/8/website" target="_blank"><img src="https://opencollective.com/cglm/sponsor/8/avatar.svg"></a>
<a href="https://opencollective.com/cglm/sponsor/9/website" target="_blank"><img src="https://opencollective.com/cglm/sponsor/9/avatar.svg"></a>

## License
MIT. check the LICENSE file