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
มีไว้เพื่อควบคุม clipspace คุณควรจะสามารถใช้ 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 ได้หากคุณใช้ 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 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 config ของเรา
$ 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
ที่นี่คือ wrapper 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
มันจะรวบรวมเอกสารลงในโฟลเดอร์ build คุณสามารถเรียกใช้ index.html ภายในฟังก์ชันนั้นได้
หากคุณต้องการใช้ฟังก์ชันเวอร์ชันอินไลน์ ให้รวมส่วนหัวหลักด้วย
#include
ส่วนหัวจะรวมส่วนหัวทั้งหมด จากนั้นเรียก func ที่คุณต้องการ เช่น หมุนเวกเตอร์ตามแกน:
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
postfix, c หมายถึงการโทร เวอร์ชันที่คอมไพล์ไว้ล่วงหน้าเป็นเพียงตัวห่อหุ้ม
#include
ส่วนหัวนี้จะรวมส่วนหัวทั้งหมดที่มี c postfix คุณต้องเรียกใช้ฟังก์ชันด้วย c posfix:
glmc_vec3_normalize ( vec );
การใช้ฟังก์ชันและพารามิเตอร์ได้รับการบันทึกไว้ในส่วนหัวที่เกี่ยวข้อง คุณอาจเห็นพารามิเตอร์เดียวกันถูกส่งสองครั้งในบางตัวอย่างเช่นนี้:
glm_mat4_mul ( m1 , m2 , m1 );
/* or */
glm_mat4_mul ( m1 , m1 , m1 );
พารามิเตอร์สองตัวแรกคือ [ใน] และพารามิเตอร์สุดท้ายคือพารามิเตอร์ [ออก] หลังจากคูณ 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 ให้ลอย* หรือคุณสามารถส่งคอลัมน์แรกของเมทริกซ์เป็นจุดเริ่มต้นของหน่วยความจำของเมทริกซ์:
ตัวเลือกที่ 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
) โครงการนี้เกิดขึ้นได้ต้องขอบคุณทุกคนที่มีส่วนร่วม [มีส่วนช่วย].
ขอขอบคุณผู้สนับสนุนของเราทุกคน! [มาเป็นผู้สนับสนุน]
สนับสนุนโครงการนี้ด้วยการเป็นผู้สนับสนุน โลโก้ของคุณจะแสดงที่นี่พร้อมลิงก์ไปยังเว็บไซต์ของคุณ [มาเป็นสปอนเซอร์]
เอ็มไอที. ตรวจสอบไฟล์ใบอนุญาต