C
Высокооптимизированная математическая библиотека 2D|3D, также известная как OpenGL Mathematics (glm) для `C` . cglm предоставляет множество утилит, помогающих выполнять математические операции быстро и быстро. Это дружелюбное сообщество, не стесняйтесь сообщать о любых проблемах и ошибках, с которыми вы столкнулись.
Почти все функции (встроенные версии) и параметры документированы внутри соответствующих заголовков.
Полная документация: 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), эта библиотека использует макет Column-Major для хранения матриц в памяти. В будущем библиотека может поддерживать возможность использования разбивки по строкам. В НАСТОЯЩЕЕ время, если вам нужна разметка по строкам, вам придется ее транспонировать. |
У вас есть два варианта вызова функции/операции: встроенный или вызов библиотеки (ссылка). Почти все функции помечены как встроенные (always_inline), поэтому компилятор, вероятно, будет встроенным. Чтобы вызвать предварительно скомпилированные версии, просто используйте glmc_
(c означает «вызов») вместо 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 );
Структурный API работает следующим образом. Обратите внимание на суффикс s
для типов, префикс glms_
для функций и префикс GLMS_
для констант:
#include
mat4s mat = GLMS_MAT4_IDENTITY_INIT ;
mat4s inv = glms_mat4_inv ( mat );
Структурные функции обычно принимают свои параметры как значения и возвращают результаты, а не принимают указатели и записывают выходные параметры. Это означает, что ваши параметры обычно могут быть const
, если вам это нравится.
Используемые типы на самом деле представляют собой объединения, которые позволяют получить доступ к одним и тем же данным несколькими способами. Один из таких способов предполагает использование анонимных структур, доступных начиная с C11. MSVC также поддерживает его для более ранних версий C, а GCC/Clang поддерживает его, если вы включите -fms-extensions
. Чтобы явно включить эти анонимные структуры, #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 добавьте -msimd128
к CMAKE_C_FLAGS
в командной строке -DCMAKE_C_FLAGS="-msimd128"
.
Для тестов опция 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
— это оболочка cmake для Emscripten из установленного emsdk.
$ 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
для получения флагов компилятора и компоновщика.
Файлы будут установлены в указанный префикс (обычно /usr/local
по умолчанию в Linux), но ваш 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
, эти функции сохраняют результаты в другие переменные и сохраняют временную память
для вызова предварительно скомпилированных версий включите заголовок с постфиксом 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
) Этот проект существует благодаря всем людям, которые вносят свой вклад. [Способствовать].
Спасибо всем нашим сторонникам! [Стать спонсором]
Поддержите этот проект, став спонсором. Здесь появится ваш логотип со ссылкой на ваш сайт. [Стать спонсором]
Массачусетский технологический институт. проверьте файл ЛИЦЕНЗИИ