C
Hochoptimierte 2D|3D-Mathematikbibliothek, auch bekannt als OpenGL Mathematics (glm) für „C“ . cglm bietet zahlreiche Hilfsprogramme, mit denen mathematische Operationen schnell und schnell geschrieben werden können. Es ist gemeinschaftsfreundlich. Sie können gerne alle Probleme und Fehler mitbringen, auf die Sie gestoßen sind.
Fast alle Funktionen (Inline-Versionen) und Parameter sind in den entsprechenden Headern dokumentiert.
Vollständige Dokumentation: http://cglm.readthedocs.io
glm_vec_dup -> glm_vec3_copy
CGLM_FORCE_DEPTH_ZERO_TO_ONE
und CGLM_FORCE_LEFT_HANDED
werden zur Steuerung des Clipspace bereitgestellt. Sie sollten cglm jetzt mit Vulkan, DirectX und Metal verwenden können ... siehe https://cglm.readthedocs.io/en/latest/opt.html#clipspace-option-s Wenn Sie die ursprüngliche GLM-Bibliothek noch nicht kennen, können Sie sich auch Folgendes ansehen: https://github.com/g-truc/glm
vec4
und mat4
-Variablen müssen ausgerichtet sein. (Es wird später nicht ausgerichtete Versionen geben) cglm
reserviert keinen Speicher auf dem Heap. Es bietet also keinen Allokator. Sie sollten auch Speicher für Out -Parameter zuweisen, wenn Sie einen Zeiger auf den Speicherort übergeben. Vergessen Sie nicht, dass vec4 (auch quat/ versor ) und mat4 ausgerichtet sein müssen (16 Byte), da cglm SIMD-Anweisungen verwendet, um die meisten Operationen zu optimieren, sofern verfügbar.
cglm unterstützt sowohl die ARRAY-API als auch die STRUCT-API , sodass Sie Strukturen zurückgeben können, wenn Sie struct api ( glms_
) verwenden.
Wie einige andere Grafikbibliotheken (insbesondere OpenGL) verwendet diese Bibliothek das Column-Major-Layout, um Matrizen im Speicher zu halten. In Zukunft unterstützt die Bibliothek möglicherweise eine Option zur Verwendung eines zeilenorientierten Layouts. Wenn Sie derzeit ein zeilenorientiertes Layout benötigen, müssen Sie es transponieren. |
Sie haben zwei Möglichkeiten, eine Funktion/Operation aufzurufen: Inline oder Bibliotheksaufruf (Link). Fast alle Funktionen sind als Inline (always_inline) gekennzeichnet, daher wird der Compiler wahrscheinlich Inline aufrufen. Um vorkompilierte Versionen aufzurufen, verwenden Sie einfach glmc_
(c steht für „call“) anstelle von 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 */
Die meisten mathematischen Funktionen werden manuell mit SSE2 optimiert, falls verfügbar, wenn nicht? Machen Sie sich keine Sorgen, es gibt Nicht-SSE-Versionen aller Vorgänge
Sie können Matrizen und Vektoren als Array an Funktionen übergeben, anstatt die Adresse abzurufen.
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 });
Die Bibliothek enthält allgemeine Mat4-MUL- und Umkehrfunktionen sowie einige spezielle (optimierte) Formen dieser Funktionen für Matrizen affiner Transformationen. Wenn Sie zwei affine Transformationsmatrizen multiplizieren möchten, können Sie glm_mul anstelle von glm_mat4_mul und glm_inv_tr (ROT + TR) anstelle von glm_mat4_inv verwenden
/* multiplication */
mat4 modelMat ;
glm_mul ( T , R , modelMat );
/* othonormal rot + tr matrix inverse (rigid-body) */
glm_inv_tr ( modelMat );
Die Struktur-API funktioniert wie folgt. Beachten Sie das Suffix s
bei Typen, das Präfix glms_
bei Funktionen und das Präfix GLMS_
bei Konstanten:
#include
mat4s mat = GLMS_MAT4_IDENTITY_INIT ;
mat4s inv = glms_mat4_inv ( mat );
Strukturfunktionen nehmen ihre Parameter im Allgemeinen als Werte an und geben ihre Ergebnisse zurück , anstatt Zeiger zu nehmen und in Out-Parameter zu schreiben. Das bedeutet, dass Ihre Parameter normalerweise const
sein können, wenn Sie sich dafür interessieren.
Bei den verwendeten Typen handelt es sich tatsächlich um Unions, die den Zugriff auf dieselben Daten auf mehrere Arten ermöglichen. Eine dieser Möglichkeiten umfasst anonyme Strukturen, die seit C11 verfügbar sind. MSVC unterstützt es auch für frühere C-Versionen standardmäßig und GCC/Clang tun dies, wenn Sie -fms-extensions
aktivieren. Um diese anonymen Strukturen explizit zu aktivieren, #define CGLM_USE_ANONYMOUS_STRUCT
auf 1
, um sie zu deaktivieren, auf 0
. Aus Gründen der Abwärtskompatibilität können Sie sie auch #define CGLM_NO_ANONYMOUS_STRUCT
(Wert ist irrelevant) deaktivieren. Wenn Sie dies nicht explizit angeben, ermittelt cglm die beste Schätzung basierend auf Ihrem Compiler und der von Ihnen verwendeten C-Version.
$ 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
Dies erfordert keine Erstellung oder Installation von 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
Da mathematische Funktionen wie sinf
verwendet werden, kann dies nicht auf wasm32-unknown-unknown
abzielen, es sollte entweder wasi-sdk oder emscripten verwendet werden.
Beachten Sie, dass Shared Builds für WebAssembly noch nicht unterstützt werden.
Für die Unterstützung von simd128 fügen Sie -msimd128
zu CMAKE_C_FLAGS
in der Befehlszeile -DCMAKE_C_FLAGS="-msimd128"
hinzu.
Für Tests würde die cmake-Option CGLM_USE_TEST
weiterhin funktionieren. Sie benötigen eine Wasi-Laufzeitumgebung zum Ausführen von Tests. Ein detailliertes Beispiel finden Sie in unserer CI-Konfigurationsdatei.
$ cmake ..
-DCMAKE_TOOLCHAIN_FILE=/path/to/wasi-sdk-19.0/share/cmake/wasi-sdk.cmake
-DWASI_SDK_PREFIX=/path/to/wasi-sdk-19.0
Dabei ist /path/to/wasi-sdk-19.0/
der Pfad zum extrahierten Wasi-SDK.
In diesem Fall würde standardmäßig ein statischer Build erstellt.
$ emcmake cmake ..
-DCMAKE_EXE_LINKER_FLAGS= " -s STANDALONE_WASM "
-DCGLM_STATIC=ON
Das emcmake
hier ist der cmake-Wrapper für Emscripten aus dem installierten 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)
Derzeit werden nur Standard-Build-Optionen unterstützt. Fügen Sie Ihrem Projekt eine cglm- Abhängigkeit hinzu:
...
Package (
...
dependencies : [
...
. package ( url : " https://github.com/recp/cglm " , . branch ( " master " ) ) ,
]
...
)
Fügen Sie nun cgml als Abhängigkeit zu Ihrem Ziel hinzu. Produktauswahl ist:
...
. target (
...
dependencies : [
...
. product ( name : " cglm " , package : " cglm " ) ,
]
...
)
...
$ sh autogen.sh
$ ./configure
$ make
$ make check # [Optional]
$ [sudo] make install # [Optional]
Dadurch werden auch pkg-config-Dateien installiert, sodass Sie pkg-config --cflags cglm
und pkg-config --libs cglm
verwenden können, um Compiler- und Linker-Flags abzurufen.
Die Dateien werden im angegebenen Präfix installiert (normalerweise standardmäßig /usr/local
unter Linux), aber Ihre pkg-config ist möglicherweise nicht so konfiguriert, dass sie dort tatsächlich prüft. Sie können herausfinden, wo es sucht, indem Sie pkg-config --variable pc_path pkg-config
ausführen und den Pfad, in dem die Dateien installiert werden, über ./configure --with-pkgconfigdir=/your/path
ändern. Alternativ können Sie den Präfixpfad zu Ihrer Umgebungsvariablen PKG_CONFIG_PATH
hinzufügen.
Windows-bezogene Build-Dateien und Projektdateien befinden sich im win
-Ordner. Stellen Sie sicher, dass Sie sich im Ordner cglm/win
befinden. Die Codeanalyse ist aktiviert, daher kann die Erstellung eine Weile dauern.
$ cd win
$ . build.bat
Wenn msbuild
nicht funktioniert (wegen Multi-Version-VS), versuchen Sie, mit devenv
zu erstellen:
$ devenv cglm.sln / Build Release
Sie können das Testprojekt in derselben Visual Studio-Lösungsdatei sehen. Es reicht aus, dieses Projekt auszuführen, um Tests durchzuführen.
Zuerst müssen Sie Sphinx installieren: http://www.sphinx-doc.org/en/master/usage/installation.html, dann:
$ cd docs
$ sphinx-build source build
Es werden Dokumente in den Build-Ordner kompiliert. Sie können index.html innerhalb dieser Funktion ausführen.
Wenn Sie die Inline-Versionen von Funktionen verwenden möchten, schließen Sie den Hauptheader ein
#include
Der Header enthält alle Header. Rufen Sie dann die gewünschte Funktion auf, z. B. den Vektor um die Achse drehen:
glm_vec3_rotate ( v1 , glm_rad ( 45 ), ( vec3 ){ 1.0f , 0.0f , 0.0f });
Einige Funktionen sind überlastet :) Beispielsweise können Sie den Vektor normalisieren:
glm_vec3_normalize ( vec );
Dadurch wird vec normalisiert und der normalisierte Vektor in vec
gespeichert. Wenn Sie den normalisierten Vektor jedoch in einem anderen Vektor speichern möchten, gehen Sie wie folgt vor:
glm_vec3_normalize_to ( vec , result );
Wie bei dieser Funktion sehen Sie möglicherweise _to
postfix. Diese Funktion speichert Ergebnisse in anderen Variablen und spart temporären Speicher
Um vorkompilierte Versionen aufzurufen, enthalten Sie den Header mit dem Postfix c
, c bedeutet Aufruf. Vorkompilierte Versionen sind lediglich Wrapper.
#include
Dieser Header enthält alle Header mit dem Postfix c. Sie müssen Funktionen mit c posfix aufrufen:
glmc_vec3_normalize ( vec );
Funktionsverwendung und Parameter werden in zugehörigen Headern dokumentiert. In einigen Beispielen wie diesem kann es sein, dass derselbe Parameter zweimal übergeben wird:
glm_mat4_mul ( m1 , m2 , m1 );
/* or */
glm_mat4_mul ( m1 , m1 , m1 );
Die ersten beiden Parameter sind [in] und der letzte ist der [out] -Parameter. Nach der Multiplikation von m1 und m2 wird das Ergebnis in m1 gespeichert. Deshalb senden wir m1 zweimal. Sie können das Ergebnis in einer anderen Matrix speichern, dies ist nur ein Beispiel.
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 ist ein Array von vec4 und vec4 ist ein Array von Floats. glUniformMatrix4fv
-Funktionen akzeptieren float*
als value
(letzter Parameter), sodass Sie mat4 in float* umwandeln können oder die erste Spalte der Matrix als Anfang des Speichers der Matrix übergeben können:
Option 1: Erste Spalte senden
glUniformMatrix4fv ( location , 1 , GL_FALSE , matrix [ 0 ]);
/* array of matrices */
glUniformMatrix4fv ( location , 1 , GL_FALSE , matrix [ 0 ][ 0 ]);
Option 2: Matrix in Zeigertyp umwandeln (gilt auch für mehrdimensionale Arrays)
glUniformMatrix4fv ( location , 1 , GL_FALSE , ( float * ) matrix );
Sie können Matrizen auf die gleiche Weise an andere APIs übergeben, z. B. Vulkan, DX ...
TODO:
glm_umat4_mul
) Dieses Projekt existiert dank aller Menschen, die dazu beitragen. [Beitragen].
Vielen Dank an alle unsere Unterstützer! [Unterstützer werden]
Unterstützen Sie dieses Projekt, indem Sie Sponsor werden. Hier erscheint Ihr Logo mit einem Link zu Ihrer Website. [Sponsor werden]
MIT. Überprüfen Sie die LICENSE-Datei