C语言的 OpenGL 数学 (glm) 
高度优化的 2D|3D 数学库,也称为“C”的 OpenGL 数学 (glm) 。 cglm提供了很多 utils 来帮助数学运算快速且快速地编写。它是社区友好的,请随意提出您遇到的任何问题、错误。
几乎所有函数(内联版本)和参数都记录在相应的标头中。
完整文档:http://cglm.readthedocs.io
glm_vec_dup -> glm_vec3_copyCGLM_FORCE_DEPTH_ZERO_TO_ONE和CGLM_FORCE_LEFT_HANDED来控制剪辑空间。您现在应该能够将cglm与 Vulkan、DirectX 和 Metal 一起使用...请参阅 https://cglm.readthedocs.io/en/latest/opt.html#clipspace-option-s 如果您还不知道原始的 GLM 库,您可能还想看看:https://github.com/g-truc/glm
vec4和mat4变量必须对齐。 (后续会有未对齐的版本) cglm不在堆上分配任何内存。所以它不提供任何分配器。如果您传递内存位置的指针,您也应该为输出参数分配内存。不要忘记vec4 (也称为 quat/ versor )和mat4必须对齐(16 字节),因为cglm使用 SIMD 指令来优化大多数操作(如果可用)。
cglm支持ARRAY API和STRUCT API ,因此如果您使用 struct api ( glms_ ),则可以返回结构。
与其他一些图形库(尤其是 OpenGL)一样,该库使用列主布局将矩阵保留在内存中。 将来,该库可能支持使用行优先布局的选项,当前如果您需要行优先布局,则需要转置它。 |
您有两个选项来调用函数/操作:内联或库调用(链接) 几乎所有函数都标记为内联(always_inline),因此编译器可能会内联。要调用预编译版本,只需使用glmc_ (c 代表“call”)而不是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 */大多数数学函数都是使用 SSE2 手动优化的(如果可用的话),如果没有?不用担心所有操作都有非 sse 版本
您可以将矩阵和向量作为数组传递给函数,而不是获取地址。
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 });库包含通用 mat4 mul 和逆函数,还包含这些函数的一些特殊形式(优化),用于仿射变换矩阵。如果你想将两个仿射变换矩阵相乘,你可以使用 glm_mul 代替 glm_mat4_mul 和 glm_inv_tr (ROT + TR) 代替 glm_mat4_inv
/* multiplication */
mat4 modelMat ;
glm_mul ( T , R , modelMat );
/* othonormal rot + tr matrix inverse (rigid-body) */
glm_inv_tr ( modelMat ); struct API 的工作方式如下,请注意类型上的s后缀、函数上的glms_前缀和常量上的GLMS_前缀:
#include <cglm/struct.h>
mat4s mat = GLMS_MAT4_IDENTITY_INIT ;
mat4s inv = glms_mat4_inv ( mat );结构函数通常将其参数作为值并返回其结果,而不是采用指针并写入输出参数。这意味着如果您愿意的话,您的参数通常可以是const 。
使用的类型实际上是允许以多种方式访问相同数据的联合。其中一种方法涉及匿名结构,自 C11 起可用。如果您启用-fms-extensions MSVC 还支持开箱即用的早期 C 版本,并且 GCC/Clang 也支持它。要显式启用这些匿名结构, #define CGLM_USE_ANONYMOUS_STRUCT为1 ,若要禁用它们,则将其设置为0 。为了向后兼容,您还可以#define CGLM_NO_ANONYMOUS_STRUCT (值不相关)来禁用它们。如果您没有明确指定,cglm 将根据您的编译器和您使用的 C 版本进行最佳猜测。
$ 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 这不需要构建或安装 cglm。
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 ) 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 由于使用了像sinf这样的数学函数,因此不能针对wasm32-unknown-unknown ,应该使用 wasi-sdk 或 emscripten 之一。
应该注意的是,WebAssembly 尚不支持共享构建。
对于 simd128 支持,请在命令行-DCMAKE_C_FLAGS="-msimd128" -msimd128添加到CMAKE_C_FLAGS 。
对于测试,cmake 选项CGLM_USE_TEST仍然有效,您需要一个 wasi 运行时来运行测试,请参阅我们的 ci 配置文件以获取详细示例。
$ cmake ..
-DCMAKE_TOOLCHAIN_FILE=/path/to/wasi-sdk-19.0/share/cmake/wasi-sdk.cmake
-DWASI_SDK_PREFIX=/path/to/wasi-sdk-19.0其中/path/to/wasi-sdk-19.0/是提取的 wasi sdk 的路径。
在这种情况下,它会默认进行静态构建。
$ emcmake cmake ..
-DCMAKE_EXE_LINKER_FLAGS= " -s STANDALONE_WASM "
-DCGLM_STATIC=ON这里的emcmake是来自已安装的 emsdk 的 Emscripten 的 cmake 包装器。
$ meson build # [Optional] --default-library=static
$ cd build
$ ninja
$ sudo ninja install # [Optional] c_std = c11
buildtype = release
default_library = shared
build_tests = true # to run tests: ninja test # 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)目前仅支持默认构建选项。将cglm依赖项添加到您的项目中:
...
Package (
...
dependencies : [
...
. package ( url : " https://github.com/recp/cglm " , . branch ( " master " ) ) ,
]
...
)现在将cgml添加为目标的依赖项。产品选择有:
...
. target (
...
dependencies : [
...
. product ( name : " cglm " , package : " cglm " ) ,
]
...
)
...$ sh autogen.sh
$ ./configure
$ make
$ make check # [Optional]
$ [sudo] make install # [Optional]这还将安装 pkg-config 文件,以便您可以使用pkg-config --cflags cglm和pkg-config --libs cglm来检索编译器和链接器标志。
这些文件将安装到给定的前缀(通常在 Linux 上默认为/usr/local ),但您的 pkg-config 可能未配置为实际检查那里。您可以通过运行pkg-config --variable pc_path pkg-config找出它的位置,并通过./configure --with-pkgconfigdir=/your/path更改文件安装的路径。或者,您可以将前缀路径添加到PKG_CONFIG_PATH环境变量中。
Windows 相关的构建文件和项目文件位于win文件夹中,请确保您位于cglm/win文件夹中。代码分析已启用,因此可能需要一段时间才能构建。
$ cd win
$ . build.bat如果msbuild不起作用(因为多版本 VS),则尝试使用devenv进行构建:
$ devenv cglm.sln / Build Release您可以在同一个 Visual Studio 解决方案文件中看到测试项目。运行该项目来运行测试就足够了。
首先你需要安装Sphinx:http://www.sphinx-doc.org/en/master/usage/installation.html 然后:
$ cd docs
$ sphinx-build source build它将把文档编译到构建文件夹中,您可以在该函数内运行index.html。
如果您想使用函数的内联版本,请包含主标头
#include <cglm/cglm.h>标头将包含所有标头。然后调用您想要的函数,例如按轴旋转向量:
glm_vec3_rotate ( v1 , glm_rad ( 45 ), ( vec3 ){ 1.0f , 0.0f , 0.0f });有些函数被重载了:)例如你可以标准化向量:
glm_vec3_normalize ( vec );这将对 vec 进行归一化并将归一化向量存储到vec中,但如果要将归一化向量存储到另一个向量中,请执行以下操作:
glm_vec3_normalize_to ( vec , result );像这个函数一样,你可能会看到_to postfix,这个函数将结果存储到另一个变量并保存临时内存
调用预编译版本包含带有c后缀的头文件,c表示调用。预编译版本只是包装。
#include <cglm/call.h>该标头将包含所有带有 c 后缀的标头。您需要使用 c posfix 调用函数:
glmc_vec3_normalize ( vec );函数用法和参数记录在相关标题中。在某些示例中,您可能会看到相同的参数传递两次,如下所示:
glm_mat4_mul ( m1 , m2 , m1 );
/* or */
glm_mat4_mul ( m1 , m1 , m1 );前两个参数是[in] ,最后一个是[out]参数。 m1和m2相乘后,结果存储在m1中。这就是我们发送m1两次的原因。您可以将结果存储在不同的矩阵中,这只是一个示例。
mat4 proj , view , model , mvp ;
/* init proj, view and model ... */
glm_mat4_mul ( proj , view , viewProj );
glm_mat4_mul ( viewProj , model , mvp ); mat4 proj , view , model , mvp ;
/* init proj, view and model ... */
glm_mat4_mulN (( mat4 * []){ & proj , & view , & model }, 3 , mvp ); mat4 是 vec4 数组,vec4 是浮点数数组。 glUniformMatrix4fv函数接受float*作为value (最后一个参数),因此您可以将 mat4 转换为 float* 或者可以将矩阵的第一列作为矩阵内存的开头传递:
选项 1:发送第一列
glUniformMatrix4fv ( location , 1 , GL_FALSE , matrix [ 0 ]);
/* array of matrices */
glUniformMatrix4fv ( location , 1 , GL_FALSE , matrix [ 0 ][ 0 ]);选项 2:将矩阵转换为指针类型(对于多维数组也有效)
glUniformMatrix4fv ( location , 1 , GL_FALSE , ( float * ) matrix );您可以以相同的方式将矩阵传递给其他 API,例如 Vulkan、DX...
待办事项:
glm_umat4_mul ) 这个项目的存在要感谢所有做出贡献的人。 [贡献]。
感谢我们所有的支持者! [成为支持者]
成为赞助商来支持该项目。您的徽标将显示在此处,并带有指向您网站的链接。 [成为赞助商]
麻省理工学院。检查许可证文件