C
Biblioteca matemática 2D | 3D altamente otimizada, também conhecida como OpenGL Mathematics (glm) para `C` . cglm fornece muitos utilitários para ajudar as operações matemáticas a serem rápidas e rápidas de escrever. É amigável à comunidade, fique à vontade para trazer quaisquer problemas ou bugs que você enfrentou.
Quase todas as funções (versões inline) e parâmetros estão documentados dentro dos cabeçalhos correspondentes.
Documentação completa: http://cglm.readthedocs.io
glm_vec_dup -> glm_vec3_copy
CGLM_FORCE_DEPTH_ZERO_TO_ONE
e CGLM_FORCE_LEFT_HANDED
são fornecidos para controlar o clipspace. Você deve ser capaz de usar cglm com Vulkan, DirectX e Metal agora... veja https://cglm.readthedocs.io/en/latest/opt.html#clipspace-option-s Se você ainda não conhece a biblioteca GLM original, você também pode dar uma olhada em: https://github.com/g-truc/glm
vec4
e mat4
devem estar alinhadas. (Haverá versões desalinhadas posteriormente) cglm
não aloca nenhuma memória no heap. Portanto, não fornece nenhum alocador. Você também deve alocar memória para parâmetros externos se passar o ponteiro do local da memória. Não esqueça que vec4 (também quat/ versor ) e mat4 devem estar alinhados (16 bytes), porque cglm usa instruções SIMD para otimizar a maioria das operações, se disponíveis.
cglm suporta ARRAY API e STRUCT API , então você pode retornar structs se utilizar struct api ( glms_
).
Como algumas outras bibliotecas gráficas (especialmente OpenGL), esta biblioteca usa o layout Column-Major para manter matrizes na memória. No futuro, a biblioteca poderá suportar uma opção para usar o layout de linha principal. ATUALMENTE, se você precisar do layout de linha principal, precisará transpô-lo. |
Você tem duas opções para chamar uma função/operação: inline ou chamada de biblioteca (link) Quase todas as funções são marcadas inline (always_inline), então o compilador provavelmente estará inline. Para chamar versões pré-compiladas, basta usar glmc_
(c significa 'call') em vez de 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 */
A maioria das funções matemáticas são otimizadas manualmente com SSE2, se disponível, caso contrário? Não se preocupe, existem versões não-sse de todas as operações
Você pode passar matrizes e vetores como array para funções em vez de obter endereços.
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 });
A biblioteca contém funções mat4 mul e inversas de uso geral e também contém algumas formas especiais (otimizadas) dessas funções para matrizes de transformações afins. Se você deseja multiplicar duas matrizes de transformação afins, você pode usar glm_mul em vez de glm_mat4_mul e glm_inv_tr (ROT + TR) em vez de glm_mat4_inv
/* multiplication */
mat4 modelMat ;
glm_mul ( T , R , modelMat );
/* othonormal rot + tr matrix inverse (rigid-body) */
glm_inv_tr ( modelMat );
A API struct funciona da seguinte maneira, observe o sufixo s
nos tipos, o prefixo glms_
nas funções e o prefixo GLMS_
nas constantes:
#include
mat4s mat = GLMS_MAT4_IDENTITY_INIT ;
mat4s inv = glms_mat4_inv ( mat );
Funções estruturais geralmente tomam seus parâmetros como valores e retornam seus resultados, em vez de pegar ponteiros e escrever parâmetros. Isso significa que seus parâmetros geralmente podem ser const
, se você gostar disso.
Os tipos usados são, na verdade, uniões que permitem acesso aos mesmos dados de várias maneiras. Uma dessas formas envolve estruturas anônimas, disponíveis desde C11. MSVC também oferece suporte para versões C anteriores prontas para uso e GCC/Clang o faz se você habilitar -fms-extensions
. Para ativar explicitamente essas estruturas anônimas, #define CGLM_USE_ANONYMOUS_STRUCT
para 1
, para desativá-las, para 0
. Para compatibilidade com versões anteriores, você também pode #define CGLM_NO_ANONYMOUS_STRUCT
(o valor é irrelevante) para desativá-los. Se você não especificar explicitamente, o cglm fará uma estimativa melhor com base no seu compilador e na versão C que você está usando.
$ 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
Isso não requer construção ou instalação de 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
Como funções matemáticas como sinf
são usadas, isso não pode ser direcionado a wasm32-unknown-unknown
, um wasi-sdk ou emscripten deve ser usado.
Deve-se observar que a construção compartilhada ainda não é compatível com WebAssembly.
Para suporte simd128, adicione -msimd128
a CMAKE_C_FLAGS
, na linha de comando -DCMAKE_C_FLAGS="-msimd128"
.
Para testes, a opção cmake CGLM_USE_TEST
ainda funcionaria, você precisará de um tempo de execução wasi para executar testes, consulte nosso arquivo de configuração ci para obter um exemplo detalhado.
$ cmake ..
-DCMAKE_TOOLCHAIN_FILE=/path/to/wasi-sdk-19.0/share/cmake/wasi-sdk.cmake
-DWASI_SDK_PREFIX=/path/to/wasi-sdk-19.0
Onde /path/to/wasi-sdk-19.0/
é o caminho para extrair o wasi sdk.
Neste caso, por padrão, seria feita uma construção estática.
$ emcmake cmake ..
-DCMAKE_EXE_LINKER_FLAGS= " -s STANDALONE_WASM "
-DCGLM_STATIC=ON
O emcmake
aqui é o wrapper cmake para Emscripten do emsdk instalado.
$ 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)
Atualmente, apenas as opções de compilação padrão são suportadas. Adicione a dependência cglm ao seu projeto:
...
Package (
...
dependencies : [
...
. package ( url : " https://github.com/recp/cglm " , . branch ( " master " ) ) ,
]
...
)
Agora adicione cgml como uma dependência ao seu destino. As opções de produtos são:
...
. target (
...
dependencies : [
...
. product ( name : " cglm " , package : " cglm " ) ,
]
...
)
...
$ sh autogen.sh
$ ./configure
$ make
$ make check # [Optional]
$ [sudo] make install # [Optional]
Isso também instalará arquivos pkg-config para que você possa usar pkg-config --cflags cglm
e pkg-config --libs cglm
para recuperar sinalizadores do compilador e do vinculador.
Os arquivos serão instalados no prefixo fornecido (geralmente /usr/local
por padrão no Linux), mas seu pkg-config pode não estar configurado para realmente verificar lá. Você pode descobrir para onde ele está executando pkg-config --variable pc_path pkg-config
e alterar o caminho para o qual os arquivos são instalados via ./configure --with-pkgconfigdir=/your/path
. Alternativamente, você pode adicionar o caminho do prefixo à sua variável de ambiente PKG_CONFIG_PATH
.
O arquivo de compilação e os arquivos de projeto relacionados ao Windows estão localizados na pasta win
, certifique-se de estar dentro da pasta cglm/win
. A análise de código está habilitada, portanto pode demorar um pouco para ser construída.
$ cd win
$ . build.bat
se msbuild
não funcionar (por causa do VS multiversão), tente construir com devenv
:
$ devenv cglm.sln / Build Release
Você pode ver o projeto de teste no mesmo arquivo de solução do Visual Studio. Basta rodar aquele projeto para rodar os testes.
Primeiro você precisa instalar o Sphinx: http://www.sphinx-doc.org/en/master/usage/installation.html e depois:
$ cd docs
$ sphinx-build source build
ele irá compilar documentos na pasta build, você pode executar index.html dentro dessa função.
Se você quiser usar as versões embutidas das funções, inclua o cabeçalho principal
#include
o cabeçalho incluirá todos os cabeçalhos. Em seguida, chame a função desejada, por exemplo, girar o vetor por eixo:
glm_vec3_rotate ( v1 , glm_rad ( 45 ), ( vec3 ){ 1.0f , 0.0f , 0.0f });
algumas funções estão sobrecarregadas :) por exemplo, você pode normalizar o vetor:
glm_vec3_normalize ( vec );
isso normalizará vec e armazenará o vetor normalizado em vec
mas se você for armazenar o vetor normalizado em outro vetor, faça o seguinte:
glm_vec3_normalize_to ( vec , result );
como esta função você pode ver _to
postfix, esta função armazena resultados em outras variáveis e economiza memória temporária
para chamar versões pré-compiladas incluem cabeçalho com postfix c
, c significa chamada. Versões pré-compiladas são apenas wrappers.
#include
este cabeçalho incluirá todos os cabeçalhos com postfix c. Você precisa chamar funções com c posfix:
glmc_vec3_normalize ( vec );
O uso e os parâmetros da função são documentados dentro dos cabeçalhos relacionados. Você pode ver o mesmo parâmetro passado duas vezes em alguns exemplos como este:
glm_mat4_mul ( m1 , m2 , m1 );
/* or */
glm_mat4_mul ( m1 , m1 , m1 );
os dois primeiros parâmetros são [in] e o último é o parâmetro [out] . Após multiplicar m1 e m2 , o resultado é armazenado em m1 . É por isso que enviamos m1 duas vezes. Você pode armazenar o resultado em uma matriz diferente, este é apenas um exemplo.
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 é um array de vec4 e vec4 é um array de carros alegóricos. As funções glUniformMatrix4fv
aceitam float*
como value
(último parâmetro), então você pode converter mat4 para float* ou pode passar a primeira coluna da matriz como início da memória da matriz:
Opção 1: enviar a primeira coluna
glUniformMatrix4fv ( location , 1 , GL_FALSE , matrix [ 0 ]);
/* array of matrices */
glUniformMatrix4fv ( location , 1 , GL_FALSE , matrix [ 0 ][ 0 ]);
Opção 2: Converter matriz em tipo de ponteiro (também válido para matrizes multidimensionais)
glUniformMatrix4fv ( location , 1 , GL_FALSE , ( float * ) matrix );
Você pode passar matrizes da mesma maneira para outras APIs, por exemplo, Vulkan, DX...
PENDÊNCIA:
glm_umat4_mul
) Este projeto existe graças a todas as pessoas que contribuem. [Contribuir].
Obrigado a todos os nossos apoiadores! [Torne-se um apoiador]
Apoie este projeto tornando-se um patrocinador. Seu logotipo aparecerá aqui com um link para seu site. [Torne-se um patrocinador]
MIT. verifique o arquivo LICENSE