C
语言的 OpenGL 数学 (glm) 高度优化的 2D|3D 数学库,也称为“C”的 OpenGL 数学 (glm) 。 cglm提供了很多 utils 来帮助数学运算快速且快速地编写。它是社区友好的,请随意提出您遇到的任何问题、错误。
几乎所有函数(内联版本)和参数都记录在相应的标头中。
完整文档:http://cglm.readthedocs.io
glm_vec_dup -> glm_vec3_copy
CGLM_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 /* for inline */
#include /* 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
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 (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 (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 /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
标头将包含所有标头。然后调用您想要的函数,例如按轴旋转向量:
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
该标头将包含所有带有 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
) 这个项目的存在要感谢所有做出贡献的人。 [贡献]。
感谢我们所有的支持者! [成为支持者]
成为赞助商来支持该项目。您的徽标将显示在此处,并带有指向您网站的链接。 [成为赞助商]
麻省理工学院。检查许可证文件