From d9bc0e36f58e5c947c2f87ca805938d1a9ceb68e Mon Sep 17 00:00:00 2001 From: Rasmus Rosengren Date: Sun, 5 Sep 2021 23:26:06 +0200 Subject: [PATCH] Initial commit, quad render with proj camera --- .gitignore | 1 + Cargo.lock | 1432 +++++++++++++++++++++++++++++++++ Cargo.toml | 12 + assets/shaders/chunk.frag | 8 + assets/shaders/chunk.vert | 10 + src/camera.rs | 99 +++ src/input.rs | 138 ++++ src/main.rs | 159 ++++ src/renderer/debug.rs | 134 +++ src/renderer/mod.rs | 51 ++ src/renderer/shader.rs | 141 ++++ src/renderer/texture.rs | 59 ++ src/renderer/vertex_array.rs | 48 ++ src/renderer/vertex_buffer.rs | 34 + 14 files changed, 2326 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 assets/shaders/chunk.frag create mode 100644 assets/shaders/chunk.vert create mode 100644 src/camera.rs create mode 100644 src/input.rs create mode 100644 src/main.rs create mode 100644 src/renderer/debug.rs create mode 100644 src/renderer/mod.rs create mode 100644 src/renderer/shader.rs create mode 100644 src/renderer/texture.rs create mode 100644 src/renderer/vertex_array.rs create mode 100644 src/renderer/vertex_buffer.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..e535493 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1432 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9fe5e32de01730eb1f6b7f5b51c17e03e2325bf40a74f754f04f130043affff" + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + +[[package]] +name = "andrew" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c4afb09dd642feec8408e33f92f3ffc4052946f6b20f32fb99c1f58cd4fa7cf" +dependencies = [ + "bitflags", + "rusttype", + "walkdir", + "xdg", + "xml-rs", +] + +[[package]] +name = "android_glue" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "000444226fcff248f2bc4c7625be32c63caccfecc2723a2b9f78a7487a49c407" + +[[package]] +name = "approx" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278" +dependencies = [ + "num-traits", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "blocks" +version = "0.1.0" +dependencies = [ + "cgmath", + "gl", + "glutin", + "image", +] + +[[package]] +name = "bytemuck" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72957246c41db82b8ef88a5486143830adeb8227ef9837740bdec67724cf2c5b" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "calloop" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b036167e76041694579972c28cf4877b4f92da222560ddb49008937b6a6727c" +dependencies = [ + "log", + "nix 0.18.0", +] + +[[package]] +name = "cc" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cgl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" +dependencies = [ + "libc", +] + +[[package]] +name = "cgmath" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a98d30140e3296250832bbaaff83b27dcd6fa3cc70fb6f1f3e5c9c0023b5317" +dependencies = [ + "approx", + "num-traits", +] + +[[package]] +name = "cocoa" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63902e9223530efb4e26ccd0cf55ec30d592d3b42e21a28defc42a9586e832" +dependencies = [ + "bitflags", + "block", + "cocoa-foundation", + "core-foundation 0.9.1", + "core-graphics 0.22.2", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" +dependencies = [ + "bitflags", + "block", + "core-foundation 0.9.1", + "core-graphics-types", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "core-foundation" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" +dependencies = [ + "core-foundation-sys 0.7.0", + "libc", +] + +[[package]] +name = "core-foundation" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" +dependencies = [ + "core-foundation-sys 0.8.2", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" + +[[package]] +name = "core-foundation-sys" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" + +[[package]] +name = "core-graphics" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923" +dependencies = [ + "bitflags", + "core-foundation 0.7.0", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "269f35f69b542b80e736a20a89a05215c0ce80c2c03c514abb2e318b78379d86" +dependencies = [ + "bitflags", + "core-foundation 0.9.1", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" +dependencies = [ + "bitflags", + "core-foundation 0.9.1", + "foreign-types", + "libc", +] + +[[package]] +name = "core-video-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34ecad23610ad9757664d644e369246edde1803fcb43ed72876565098a5d3828" +dependencies = [ + "cfg-if 0.1.10", + "core-foundation-sys 0.7.0", + "core-graphics 0.19.2", + "libc", + "objc", +] + +[[package]] +name = "crc32fast" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "crossbeam" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae5588f6b3c3cb05239e90bd110f257254aecd01e4635400391aeae07497845" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b10ddc024425c88c2ad148c1b0fd53f4c6d38db9697c9f1588381212fa657c9" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +dependencies = [ + "cfg-if 1.0.0", + "lazy_static", +] + +[[package]] +name = "darling" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "deflate" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" +dependencies = [ + "adler32", + "byteorder", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dlib" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b11f15d1e3268f140f68d390637d5e76d849782d971ae7063e0da69fe9709a76" +dependencies = [ + "libloading 0.6.7", +] + +[[package]] +name = "dlib" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794" +dependencies = [ + "libloading 0.7.0", +] + +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "gif" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a668f699973d0f573d15749b7002a9ac9e1f9c6b220e7b165601334c173d8de" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "gl" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a94edab108827d67608095e269cf862e60d920f144a5026d3dbcfd8b877fb404" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + +[[package]] +name = "glutin" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "762d6cd2e1b855d99668ebe591cc9058659d85ac39a9a2078000eb122ddba8f0" +dependencies = [ + "android_glue", + "cgl", + "cocoa", + "core-foundation 0.9.1", + "glutin_egl_sys", + "glutin_emscripten_sys", + "glutin_gles2_sys", + "glutin_glx_sys", + "glutin_wgl_sys", + "lazy_static", + "libloading 0.7.0", + "log", + "objc", + "osmesa-sys", + "parking_lot", + "wayland-client", + "wayland-egl", + "winapi", + "winit", +] + +[[package]] +name = "glutin_egl_sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2abb6aa55523480c4adc5a56bbaa249992e2dddb2fc63dc96e04a3355364c211" +dependencies = [ + "gl_generator", + "winapi", +] + +[[package]] +name = "glutin_emscripten_sys" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80de4146df76e8a6c32b03007bc764ff3249dcaeb4f675d68a06caf1bac363f1" + +[[package]] +name = "glutin_gles2_sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094e708b730a7c8a1954f4f8a31880af00eb8a1c5b5bf85d28a0a3c6d69103" +dependencies = [ + "gl_generator", + "objc", +] + +[[package]] +name = "glutin_glx_sys" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e393c8fc02b807459410429150e9c4faffdb312d59b8c038566173c81991351" +dependencies = [ + "gl_generator", + "x11-dl", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3da5951a1569dbab865c6f2a863efafff193a93caf05538d193e9e3816d21696" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "image" +version = "0.23.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "gif", + "jpeg-decoder", + "num-iter", + "num-rational", + "num-traits", + "png", + "scoped_threadpool", + "tiff", +] + +[[package]] +name = "instant" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jpeg-decoder" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2" +dependencies = [ + "rayon", +] + +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21" + +[[package]] +name = "libloading" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "351a32417a12d5f7e82c368a66781e307834dae04c6ce0cd4456d52989229883" +dependencies = [ + "cfg-if 1.0.0", + "winapi", +] + +[[package]] +name = "libloading" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a" +dependencies = [ + "cfg-if 1.0.0", + "winapi", +] + +[[package]] +name = "lock_api" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "memmap2" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b70ca2a6103ac8b665dc150b142ef0e4e89df640c9e6cf295d189c3caebe5a" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +dependencies = [ + "autocfg", +] + +[[package]] +name = "minimal-lexical" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c835948974f68e0bd58636fc6c5b1fbff7b297e3046f11b3b3c18bbac012c6d" + +[[package]] +name = "miniz_oxide" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +dependencies = [ + "adler32", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "mio" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16" +dependencies = [ + "libc", + "log", + "miow", + "ntapi", + "winapi", +] + +[[package]] +name = "mio-misc" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ddf05411bb159cdb5801bb10002afb66cb4572be656044315e363460ce69dc2" +dependencies = [ + "crossbeam", + "crossbeam-queue", + "log", + "mio", +] + +[[package]] +name = "miow" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" +dependencies = [ + "winapi", +] + +[[package]] +name = "ndk" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8794322172319b972f528bf90c6b467be0079f1fa82780ffb431088e741a73ab" +dependencies = [ + "jni-sys", + "ndk-sys", + "num_enum", + "thiserror", +] + +[[package]] +name = "ndk-glue" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5caf0c24d51ac1c905c27d4eda4fa0635bbe0de596b8f79235e0b17a4d29385" +dependencies = [ + "lazy_static", + "libc", + "log", + "ndk", + "ndk-macro", + "ndk-sys", +] + +[[package]] +name = "ndk-macro" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d1c6307dc424d0f65b9b06e94f88248e6305726b14729fd67a5e47b2dc481d" +dependencies = [ + "darling", + "proc-macro-crate 0.1.5", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ndk-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c44922cb3dbb1c70b5e5f443d63b64363a898564d739ba5198e3a9138442868d" + +[[package]] +name = "nix" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83450fe6a6142ddd95fb064b746083fc4ef1705fe81f64a64e1d4b39f54a1055" +dependencies = [ + "bitflags", + "cc", + "cfg-if 0.1.10", + "libc", +] + +[[package]] +name = "nix" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" +dependencies = [ + "bitflags", + "cc", + "cfg-if 1.0.0", + "libc", +] + +[[package]] +name = "nom" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffd9d26838a953b4af82cbeb9f1592c6798916983959be223a7124e992742c1" +dependencies = [ + "memchr", + "minimal-lexical", + "version_check", +] + +[[package]] +name = "ntapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +dependencies = [ + "winapi", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9bd055fb730c4f8f4f57d45d35cd6b3f0980535b056dc7ff119cee6a66ed6f" +dependencies = [ + "derivative", + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "486ea01961c4a818096de679a8b740b26d9033146ac5291b1c98557658f8cdd9" +dependencies = [ + "proc-macro-crate 1.0.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "once_cell" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" + +[[package]] +name = "osmesa-sys" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b" +dependencies = [ + "shared_library", +] + +[[package]] +name = "owned_ttf_parser" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f923fb806c46266c02ab4a5b239735c144bdeda724a50ed058e5226f594cde3" +dependencies = [ + "ttf-parser", +] + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", +] + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "pkg-config" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" + +[[package]] +name = "png" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" +dependencies = [ + "bitflags", + "crc32fast", + "deflate", + "miniz_oxide 0.3.7", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-crate" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fdbd1df62156fbc5945f4762632564d7d038153091c3fcf1067f6aef7cff92" +dependencies = [ + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro2" +version = "1.0.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "raw-window-handle" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a441a7a6c80ad6473bd4b74ec1c9a4c951794285bf941c2126f607c72e48211" +dependencies = [ + "libc", +] + +[[package]] +name = "rayon" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rusttype" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc7c727aded0be18c5b80c1640eae0ac8e396abf6fa8477d96cb37d18ee5ec59" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped-tls" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" + +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "serde" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" + +[[package]] +name = "shared_library" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11" +dependencies = [ + "lazy_static", + "libc", +] + +[[package]] +name = "smallvec" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" + +[[package]] +name = "smithay-client-toolkit" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4750c76fd5d3ac95fa3ed80fe667d6a3d8590a960e5b575b98eea93339a80b80" +dependencies = [ + "andrew", + "bitflags", + "calloop", + "dlib 0.4.2", + "lazy_static", + "log", + "memmap2", + "nix 0.18.0", + "wayland-client", + "wayland-cursor", + "wayland-protocols", +] + +[[package]] +name = "strsim" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" + +[[package]] +name = "syn" +version = "1.0.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "thiserror" +version = "1.0.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tiff" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a53f4706d65497df0c4349241deddf35f84cee19c87ed86ea8ca590f4464437" +dependencies = [ + "jpeg-decoder", + "miniz_oxide 0.4.4", + "weezl", +] + +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + +[[package]] +name = "ttf-parser" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e5d7cd7ab3e47dda6e56542f4bbf3824c15234958c6e1bd6aaa347e93499fdc" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + +[[package]] +name = "wayland-client" +version = "0.28.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ab332350e502f159382201394a78e3cc12d0f04db863429260164ea40e0355" +dependencies = [ + "bitflags", + "downcast-rs", + "libc", + "nix 0.20.0", + "scoped-tls", + "wayland-commons", + "wayland-scanner", + "wayland-sys", +] + +[[package]] +name = "wayland-commons" +version = "0.28.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21817947c7011bbd0a27e11b17b337bfd022e8544b071a2641232047966fbda" +dependencies = [ + "nix 0.20.0", + "once_cell", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-cursor" +version = "0.28.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be610084edd1586d45e7bdd275fe345c7c1873598caa464c4fb835dee70fa65a" +dependencies = [ + "nix 0.20.0", + "wayland-client", + "xcursor", +] + +[[package]] +name = "wayland-egl" +version = "0.28.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99ba1ab1e18756b23982d36f08856d521d7df45015f404a2d7c4f0b2d2f66956" +dependencies = [ + "wayland-client", + "wayland-sys", +] + +[[package]] +name = "wayland-protocols" +version = "0.28.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "286620ea4d803bacf61fa087a4242ee316693099ee5a140796aaba02b29f861f" +dependencies = [ + "bitflags", + "wayland-client", + "wayland-commons", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.28.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce923eb2deb61de332d1f356ec7b6bf37094dc5573952e1c8936db03b54c03f1" +dependencies = [ + "proc-macro2", + "quote", + "xml-rs", +] + +[[package]] +name = "wayland-sys" +version = "0.28.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d841fca9aed7febf9bed2e9796c49bf58d4152ceda8ac949ebe00868d8f0feb8" +dependencies = [ + "dlib 0.5.0", + "lazy_static", + "pkg-config", +] + +[[package]] +name = "weezl" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b77fdfd5a253be4ab714e4ffa3c49caf146b4de743e97510c0656cf90f1e8e" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "winit" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79610794594d5e86be473ef7763f604f2159cbac8c94debd00df8fb41e86c2f8" +dependencies = [ + "bitflags", + "cocoa", + "core-foundation 0.9.1", + "core-graphics 0.22.2", + "core-video-sys", + "dispatch", + "instant", + "lazy_static", + "libc", + "log", + "mio", + "mio-misc", + "ndk", + "ndk-glue", + "ndk-sys", + "objc", + "parking_lot", + "percent-encoding", + "raw-window-handle", + "scopeguard", + "smithay-client-toolkit", + "wayland-client", + "winapi", + "x11-dl", +] + +[[package]] +name = "x11-dl" +version = "2.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf981e3a5b3301209754218f962052d4d9ee97e478f4d26d4a6eced34c1fef8" +dependencies = [ + "lazy_static", + "libc", + "maybe-uninit", + "pkg-config", +] + +[[package]] +name = "xcursor" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7" +dependencies = [ + "nom", +] + +[[package]] +name = "xdg" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" + +[[package]] +name = "xml-rs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..94efe08 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "blocks" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +cgmath = "0.18" +gl = "0.14" +glutin = "0.27" +image = "0.23" \ No newline at end of file diff --git a/assets/shaders/chunk.frag b/assets/shaders/chunk.frag new file mode 100644 index 0000000..c602257 --- /dev/null +++ b/assets/shaders/chunk.frag @@ -0,0 +1,8 @@ +#version 430 +layout(location = 0) out vec4 out_color; + +// uniform vec3 color; + +void main() { + out_color = vec4(1.0, 0.0, 0.5, 1.0); +} \ No newline at end of file diff --git a/assets/shaders/chunk.vert b/assets/shaders/chunk.vert new file mode 100644 index 0000000..066af76 --- /dev/null +++ b/assets/shaders/chunk.vert @@ -0,0 +1,10 @@ +#version 430 +layout(location = 0) in vec2 position; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main() { + gl_Position = projection * view * model * vec4(position, 0.0, 1.0); +} diff --git a/src/camera.rs b/src/camera.rs new file mode 100644 index 0000000..57358c0 --- /dev/null +++ b/src/camera.rs @@ -0,0 +1,99 @@ +use std::ops::Rem; + +use cgmath::{perspective, point3, vec3, Angle, Deg, InnerSpace, Matrix4, Point3, Vector3}; + +#[derive(Clone, Copy, Debug)] +pub struct Camera { + pub position: Point3, + pub yaw: Deg, + pub pitch: Deg, +} + +static WORLD_UP: Vector3 = vec3(0.0, 1.0, 0.0); + +impl Camera { + pub fn new() -> Self { + Self { + position: point3(0.0, 0.0, 0.0), + yaw: Deg(0.0), + pitch: Deg(0.0), + } + } + + pub fn move_right(&mut self, amount: f32) { + let right_dir = self.right_dir(); + self.position += amount * right_dir; + } + + pub fn move_left(&mut self, amount: f32) { + self.move_right(-amount); + } + + pub fn move_forward(&mut self, amount: f32) { + let forward_dir = self.horizontal_front_dir(); + self.position += amount * forward_dir; + } + + pub fn move_backward(&mut self, amount: f32) { + self.move_forward(-amount); + } + + pub fn move_up(&mut self, amount: f32) { + self.position += amount * WORLD_UP; + } + + pub fn move_down(&mut self, amount: f32) { + self.move_up(-amount); + } + + pub fn rotate_yaw>>(&mut self, amount: D) { + self.yaw -= amount.into(); + self.yaw = Deg(self.yaw.0.rem(360.0)); + } + + pub fn rotate_pitch>>(&mut self, amount: D) { + self.pitch += amount.into(); + self.pitch = Deg(self.pitch.0.clamp(-89.9, 89.9)); + } + + pub fn view_matrix(&self) -> Matrix4 { + let front_dir = self.front_dir(); + let right_dir = self.right_dir(); + let up_dir = front_dir.cross(right_dir); + Matrix4::look_to_rh(self.position, front_dir, WORLD_UP) + } + + pub fn projection_matrix(&self) -> Matrix4 { + perspective(Deg(45.0), 16.0 / 9.0, 0.0001, 1000.0) + } + + fn horizontal_front_dir(&self) -> Vector3 { + vec3(self.yaw.cos(), 0.0, -self.yaw.sin()).normalize() + } + + fn front_dir(&self) -> Vector3 { + println!( + "{:?}", + vec3( + self.yaw.cos() * self.pitch.cos(), + self.pitch.sin(), + -self.yaw.sin() * self.pitch.cos(), + ) + ); + vec3( + self.yaw.cos() * self.pitch.cos(), + self.pitch.sin(), + -self.yaw.sin() * self.pitch.cos(), + ) + .normalize() + } + + fn right_dir(&self) -> Vector3 { + vec3( + (self.yaw - Deg(90.0)).cos(), + 0.0, + -(self.yaw - Deg(90.0)).sin(), + ) + .normalize() + } +} diff --git a/src/input.rs b/src/input.rs new file mode 100644 index 0000000..7053597 --- /dev/null +++ b/src/input.rs @@ -0,0 +1,138 @@ +use std::collections::{HashMap, HashSet}; + +use glutin::event::{ + ElementState, KeyboardInput, MouseButton, MouseScrollDelta, VirtualKeyCode, WindowEvent, +}; + +pub struct KeyboardState { + state: HashSet, + momentary_state: HashMap, +} + +impl KeyboardState { + pub fn new() -> Self { + Self { + state: HashSet::new(), + momentary_state: HashMap::new(), + } + } + + pub fn is_pressed(&self, key: VirtualKeyCode) -> bool { + self.state.get(&key).is_some() + } + + pub fn was_pressed(&self, key: VirtualKeyCode) -> bool { + self.momentary_state.get(&key) == Some(&ElementState::Pressed) + } + + pub fn was_released(&self, key: VirtualKeyCode) -> bool { + self.momentary_state.get(&key) == Some(&ElementState::Released) + } + + pub fn process_event(&mut self, event: &WindowEvent) { + match *event { + WindowEvent::KeyboardInput { + input: + KeyboardInput { + state, + virtual_keycode: Some(virtual_keycode), + .. + }, + .. + } => { + self.momentary_state.insert(virtual_keycode, state); + match state { + ElementState::Pressed => { + self.state.insert(virtual_keycode); + } + ElementState::Released => { + self.state.remove(&virtual_keycode); + } + } + } + _ => (), + } + } + + pub fn clear_momentary_state(&mut self) { + self.momentary_state.clear(); + } +} + +#[derive(Clone, Copy, Debug, Default)] +pub struct Point { + pub x: f64, + pub y: f64, +} + +impl Point { + pub fn new(x: f64, y: f64) -> Self { + Self { x, y } + } +} + +pub struct MouseState { + button_state: HashSet, + momentary_button_state: HashMap, + pub position: Point, + pub mouse_delta: Point, + pub scroll_delta: f32, +} + +impl MouseState { + pub fn new() -> Self { + Self { + button_state: HashSet::new(), + momentary_button_state: HashMap::new(), + position: Default::default(), + mouse_delta: Default::default(), + scroll_delta: 0.0, + } + } + + pub fn is_pressed(&self, button: MouseButton) -> bool { + self.button_state.get(&button).is_some() + } + + pub fn was_pressed(&self, button: MouseButton) -> bool { + self.momentary_button_state.get(&button) == Some(&ElementState::Pressed) + } + + pub fn was_released(&self, button: MouseButton) -> bool { + self.momentary_button_state.get(&button) == Some(&ElementState::Released) + } + + pub fn process_event(&mut self, event: &WindowEvent) { + match *event { + WindowEvent::CursorMoved { position, .. } => { + self.mouse_delta.x += position.x - self.position.x; + self.mouse_delta.y += position.y - self.position.y; + self.position = Point::new(position.x, position.y); + } + WindowEvent::MouseInput { button, state, .. } => { + self.momentary_button_state.insert(button, state); + match state { + ElementState::Pressed => { + self.button_state.insert(button); + } + ElementState::Released => { + self.button_state.remove(&button); + } + } + } + WindowEvent::MouseWheel { delta, .. } => match delta { + MouseScrollDelta::LineDelta(_, y) => { + self.scroll_delta += y; + } + _ => (), + }, + _ => (), + } + } + + pub fn clear_momentary_state(&mut self) { + self.momentary_button_state.clear(); + self.mouse_delta = Default::default(); + self.scroll_delta = 0.0; + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..6c78e49 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,159 @@ +mod camera; +mod input; +mod renderer; + +use std::{ffi::CString, time::Instant}; + +use cgmath::{Deg, Matrix4}; +use gl::types::*; +use glutin::dpi::PhysicalSize; +use input::{KeyboardState, MouseState}; +use renderer::{shader::Shader, vertex_buffer::VertexBuffer}; + +use crate::{ + camera::Camera, + renderer::{debug::DebugCallback, vertex_array::VertexArray, VertexBufferElement}, +}; + +// Vertex data +static QUAD_DATA: [GLfloat; 24] = [ + 0.5, 0.5, 1.0, 1.0, // top right + -0.5, 0.5, 0.0, 1.0, // top left + -0.5, -0.5, 0.0, 0.0, // bottom left + -0.5, -0.5, 0.0, 0.0, // bottom left + 0.5, -0.5, 1.0, 0.0, // bottom right + 0.5, 0.5, 1.0, 1.0, // top right +]; + +fn main() { + let event_loop = glutin::event_loop::EventLoop::new(); + let window = + glutin::window::WindowBuilder::new().with_inner_size(PhysicalSize::new(1920.0, 1080.0)); + let gl_window = glutin::ContextBuilder::new() + .build_windowed(window, &event_loop) + .unwrap(); + + // It is essential to make the context current before calling `gl::load_with`. + let gl_window = unsafe { gl_window.make_current() }.unwrap(); + + // Load the OpenGL function pointers + gl::load_with(|symbol| gl_window.get_proc_address(symbol)); + + let chunk_shader = Shader::from_file("chunk.vert", "chunk.frag"); + + unsafe { + gl::Enable(gl::BLEND); + gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA); + } + + let _debug_callback = unsafe { + DebugCallback::new(|message| { + println!("{:?}", message); + }) + }; + + let quad_va = unsafe { + let vb = VertexBuffer::new( + &QUAD_DATA, + vec![ + VertexBufferElement::floats(2), + VertexBufferElement::floats(2), + ], + ); + VertexArray::new(&[vb]) + }; + + let mut camera = Camera::new(); + camera.position.x = 10.0; + camera.position.y = 10.0; + + let mut keyboard_state = KeyboardState::new(); + let mut mouse_state = MouseState::new(); + + let mut show_fps = false; + + let mut last_update_time = Instant::now(); + event_loop.run(move |event, _, control_flow| { + use glutin::event::{Event, VirtualKeyCode, WindowEvent}; + use glutin::event_loop::ControlFlow; + *control_flow = ControlFlow::Poll; + + match event { + Event::LoopDestroyed => return, + Event::WindowEvent { event, .. } => { + keyboard_state.process_event(&event); + mouse_state.process_event(&event); + match event { + WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, + WindowEvent::Resized(size) => unsafe { + gl::Viewport(0, 0, size.width as i32, size.height as i32); + }, + _ => (), + } + } + _ => (), + } + + let now = Instant::now(); + let ms_since_last_update = (now - last_update_time).as_nanos() as f64 / 1_000_000.0; + if ms_since_last_update > 16.666 { + last_update_time = now; + println!("{:?}", camera); + + if keyboard_state.was_pressed(VirtualKeyCode::F) { + show_fps = !show_fps; + } + + let move_speed = 0.1; + + if keyboard_state.is_pressed(VirtualKeyCode::W) { + camera.move_forward(move_speed); + } else if keyboard_state.is_pressed(VirtualKeyCode::S) { + camera.move_backward(move_speed); + } + + if keyboard_state.is_pressed(VirtualKeyCode::D) { + camera.move_right(move_speed); + } else if keyboard_state.is_pressed(VirtualKeyCode::A) { + camera.move_left(move_speed); + } + + if keyboard_state.is_pressed(VirtualKeyCode::Space) { + camera.move_up(move_speed); + } else if keyboard_state.is_pressed(VirtualKeyCode::LShift) { + camera.move_down(move_speed); + } + + let mouse_sens = 0.4; + camera.rotate_yaw(Deg(mouse_sens * mouse_state.mouse_delta.x as f32)); + camera.rotate_pitch(-Deg(mouse_sens * mouse_state.mouse_delta.y as f32)); + + let start = Instant::now(); + unsafe { + gl::ClearColor(0.3, 0.3, 0.6, 1.0); + gl::Clear(gl::COLOR_BUFFER_BIT); + + let model_matrix = Matrix4::from_scale(10.0); + + chunk_shader.enable(); + chunk_shader.set_mat4(&CString::new("model").unwrap(), model_matrix); + chunk_shader.set_mat4(&CString::new("view").unwrap(), camera.view_matrix()); + chunk_shader.set_mat4( + &CString::new("projection").unwrap(), + camera.projection_matrix(), + ); + quad_va.bind(); + gl::DrawArrays(gl::TRIANGLES, 0, 6); + } + + let dur = Instant::now() - start; + let ms = dur.as_nanos() as f64 / 1_000_000.0; + if show_fps { + println!("Render time: {}ms", ms); + } + gl_window.swap_buffers().unwrap(); + keyboard_state.clear_momentary_state(); + mouse_state.clear_momentary_state(); + } + }); +} diff --git a/src/renderer/debug.rs b/src/renderer/debug.rs new file mode 100644 index 0000000..9f29c98 --- /dev/null +++ b/src/renderer/debug.rs @@ -0,0 +1,134 @@ +use std::{ + ffi::{c_void, CStr}, + panic, ptr, +}; + +use gl::types::{GLchar, GLenum, GLsizei}; + +#[derive(Clone, Debug)] +pub struct DebugMessage { + id: GLenum, + source: DebugSource, + type_: DebugType, + severity: DebugSeverity, + message: String, +} + +#[derive(Clone, Copy, Debug)] +pub enum DebugSource { + Api, + WindowSystem, + ShaderCompiler, + ThirdParty, + Application, + Other, +} + +#[derive(Clone, Copy, Debug)] +pub enum DebugType { + Error, + DeprecatedBehavior, + UndefinedBehavior, + Portability, + Performance, + Marker, + Other, + PopGroup, + PushGroup, +} + +#[derive(Clone, Copy, Debug)] +pub enum DebugSeverity { + Notification, + Low, + Medium, + High, +} + +pub struct DebugCallback { + _user_callback: Box>, +} + +impl DebugCallback { + pub unsafe fn new(user_callback: F) -> Self + where + F: Fn(DebugMessage) + 'static + Send + panic::RefUnwindSafe, + { + let user_callback = Box::new(Box::new(user_callback) as Box<_>); + + gl::Enable(gl::DEBUG_OUTPUT); + gl::DebugMessageCallback( + Some(debug_callback), + &*user_callback as &Box<_> as *const Box<_> as *const c_void, + ); + + Self { + _user_callback: user_callback, + } + } +} + +impl Drop for DebugCallback { + fn drop(&mut self) { + unsafe { + gl::DebugMessageCallback(None, ptr::null()); + gl::Disable(gl::DEBUG_OUTPUT); + } + } +} + +extern "system" fn debug_callback( + source: GLenum, + type_: GLenum, + id: GLenum, + severity: GLenum, + _length: GLsizei, + message: *const GLchar, + user_param: *mut c_void, +) { + let user_callback = user_param as *mut Box as *const _; + let user_callback: &Box = unsafe { &*user_callback }; + + let msg_src = match source { + gl::DEBUG_SOURCE_API => DebugSource::Api, + gl::DEBUG_SOURCE_WINDOW_SYSTEM => DebugSource::WindowSystem, + gl::DEBUG_SOURCE_SHADER_COMPILER => DebugSource::ShaderCompiler, + gl::DEBUG_SOURCE_THIRD_PARTY => DebugSource::ThirdParty, + gl::DEBUG_SOURCE_APPLICATION => DebugSource::Application, + gl::DEBUG_SOURCE_OTHER => DebugSource::Other, + _ => unreachable!(), + }; + + let msg_type = match type_ { + gl::DEBUG_TYPE_ERROR => DebugType::Error, + gl::DEBUG_TYPE_DEPRECATED_BEHAVIOR => DebugType::DeprecatedBehavior, + gl::DEBUG_TYPE_UNDEFINED_BEHAVIOR => DebugType::UndefinedBehavior, + gl::DEBUG_TYPE_PORTABILITY => DebugType::Portability, + gl::DEBUG_TYPE_PERFORMANCE => DebugType::Performance, + gl::DEBUG_TYPE_MARKER => DebugType::Marker, + gl::DEBUG_TYPE_OTHER => DebugType::Other, + gl::DEBUG_TYPE_POP_GROUP => DebugType::PopGroup, + gl::DEBUG_TYPE_PUSH_GROUP => DebugType::PushGroup, + _ => unreachable!(), + }; + + let msg_severity = match severity { + gl::DEBUG_SEVERITY_NOTIFICATION => DebugSeverity::Notification, + gl::DEBUG_SEVERITY_LOW => DebugSeverity::Low, + gl::DEBUG_SEVERITY_MEDIUM => DebugSeverity::Medium, + gl::DEBUG_SEVERITY_HIGH => DebugSeverity::High, + _ => unreachable!(), + }; + + let msg = unsafe { String::from_utf8(CStr::from_ptr(message).to_bytes().to_vec()).unwrap() }; + + let message = DebugMessage { + id, + source: msg_src, + type_: msg_type, + severity: msg_severity, + message: msg, + }; + + user_callback(message); +} diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs new file mode 100644 index 0000000..1447e04 --- /dev/null +++ b/src/renderer/mod.rs @@ -0,0 +1,51 @@ +pub mod debug; +pub mod shader; +pub mod texture; +pub mod vertex_array; +pub mod vertex_buffer; + +use std::mem; + +use gl::types::GLfloat; + +#[derive(Debug)] +pub enum GlType { + Float, +} + +impl GlType { + pub fn to_raw_enum(&self) -> u32 { + match *self { + GlType::Float => gl::FLOAT, + } + } + + pub fn mem_size(&self) -> u32 { + match *self { + GlType::Float => mem::size_of::() as u32, + } + } +} + +#[derive(Debug)] +pub struct VertexBufferElement { + size: u32, + type_: GlType, +} + +impl VertexBufferElement { + pub fn floats(size: u32) -> Self { + Self { + size, + type_: GlType::Float, + } + } + + pub fn to_raw_enum(&self) -> u32 { + self.type_.to_raw_enum() + } + + pub fn mem_size(&self) -> u32 { + self.size * self.type_.mem_size() + } +} diff --git a/src/renderer/shader.rs b/src/renderer/shader.rs new file mode 100644 index 0000000..628577c --- /dev/null +++ b/src/renderer/shader.rs @@ -0,0 +1,141 @@ +use cgmath::{Matrix, Matrix2, Matrix4, Vector3, Vector4}; +use gl::types::*; +use std::{ + ffi::{CStr, CString}, + fs, ptr, str, +}; + +pub struct Shader { + id: GLuint, +} + +impl Shader { + pub fn from_file(vs_path: &str, fs_path: &str) -> Self { + let vs_source = fs::read_to_string(format!("assets/shaders/{}", vs_path)) + .expect(&format!("Could not read vertex shader {}", vs_path)); + let fs_source = fs::read_to_string(format!("assets/shaders/{}", fs_path)) + .expect(&format!("Could not read fragment shader {}", fs_path)); + + Self::from_source(&vs_source, &fs_source) + } + + pub fn from_source(vs_source: &str, fs_source: &str) -> Self { + let vs_id = Self::compile_shader(vs_source, gl::VERTEX_SHADER); + let fs_id = Self::compile_shader(fs_source, gl::FRAGMENT_SHADER); + let program_id = Self::link_program(vs_id, fs_id); + unsafe { + gl::DeleteShader(vs_id); + gl::DeleteShader(fs_id); + } + + Self { id: program_id } + } + + pub fn enable(&self) { + unsafe { + gl::UseProgram(self.id); + } + } + + pub fn set_mat2(&self, name: &CStr, matrix: Matrix2) { + unsafe { + let location = gl::GetUniformLocation(self.id, name.as_ptr()); + gl::UniformMatrix2fv(location, 1, gl::FALSE, matrix.as_ptr()); + } + } + + pub fn set_mat4(&self, name: &CStr, matrix: Matrix4) { + unsafe { + let location = gl::GetUniformLocation(self.id, name.as_ptr()); + gl::UniformMatrix4fv(location, 1, gl::FALSE, matrix.as_ptr()); + } + } + + pub fn set_vec3(&self, name: &CStr, vec: Vector3) { + unsafe { + let location = gl::GetUniformLocation(self.id, name.as_ptr()); + gl::Uniform3f(location, vec.x, vec.y, vec.z); + } + } + + pub fn set_vec4(&self, name: &CStr, vec: Vector4) { + unsafe { + let location = gl::GetUniformLocation(self.id, name.as_ptr()); + gl::Uniform4f(location, vec.x, vec.y, vec.z, vec.w); + } + } + + pub fn set_int(&self, name: &CStr, int: i32) { + unsafe { + let location = gl::GetUniformLocation(self.id, name.as_ptr()); + gl::Uniform1i(location, int); + } + } + + fn compile_shader(src: &str, ty: GLenum) -> GLuint { + let shader; + unsafe { + shader = gl::CreateShader(ty); + + let c_str = CString::new(src.as_bytes()).unwrap(); + gl::ShaderSource(shader, 1, &c_str.as_ptr(), ptr::null()); + gl::CompileShader(shader); + + let mut status = gl::FALSE as GLint; + gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut status); + + if status != (gl::TRUE as GLint) { + let mut len = 0; + gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut len); + let mut buf = Vec::with_capacity(len as usize); + buf.set_len((len as usize) - 1); // subtract 1 to skip the trailing null character + gl::GetShaderInfoLog( + shader, + len, + ptr::null_mut(), + buf.as_mut_ptr() as *mut GLchar, + ); + panic!( + "{}", + str::from_utf8(&buf) + .ok() + .expect("ShaderInfoLog not valid utf8") + ); + } + } + shader + } + + fn link_program(vs: GLuint, fs: GLuint) -> GLuint { + unsafe { + let program = gl::CreateProgram(); + gl::AttachShader(program, vs); + gl::AttachShader(program, fs); + gl::LinkProgram(program); + // Get the link status + let mut status = gl::FALSE as GLint; + gl::GetProgramiv(program, gl::LINK_STATUS, &mut status); + + // Fail on error + if status != (gl::TRUE as GLint) { + let mut len: GLint = 0; + gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &mut len); + let mut buf = Vec::with_capacity(len as usize); + buf.set_len((len as usize) - 1); // subtract 1 to skip the trailing null character + gl::GetProgramInfoLog( + program, + len, + ptr::null_mut(), + buf.as_mut_ptr() as *mut GLchar, + ); + panic!( + "{}", + str::from_utf8(&buf) + .ok() + .expect("ProgramInfoLog not valid utf8") + ); + } + program + } + } +} diff --git a/src/renderer/texture.rs b/src/renderer/texture.rs new file mode 100644 index 0000000..74e2741 --- /dev/null +++ b/src/renderer/texture.rs @@ -0,0 +1,59 @@ +use std::{ffi::c_void, path::Path}; + +use image::{DynamicImage, GenericImageView}; + +#[derive(Debug)] +pub struct Texture { + pub id: u32, + pub width: u32, + pub height: u32, +} + +impl Texture { + pub unsafe fn new(image: DynamicImage, flip_vertical: bool) -> Self { + let image = if flip_vertical { image.flipv() } else { image }; + + let width = image.width(); + let height = image.width(); + + let (data, gl_format) = match image { + DynamicImage::ImageRgb8(image) => (image.into_raw(), gl::RGB), + DynamicImage::ImageRgba8(image) => (image.into_raw(), gl::RGBA), + _ => unimplemented!(), + }; + + let mut id = 0; + gl::CreateTextures(gl::TEXTURE_2D, 1, &mut id); + gl::TextureParameteri(id, gl::TEXTURE_MIN_FILTER, gl::NEAREST as i32); + gl::TextureParameteri(id, gl::TEXTURE_MAG_FILTER, gl::NEAREST as i32); + gl::TextureParameteri(id, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as i32); + gl::TextureParameteri(id, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as i32); + + gl::TextureStorage2D(id, 1, gl::RGBA8, width as i32, height as i32); + gl::TextureSubImage2D( + id, + 0, + 0, + 0, + width as i32, + height as i32, + gl_format, + gl::UNSIGNED_BYTE, + data.as_ptr() as *const c_void, + ); + + Self { id, width, height } + } + + pub unsafe fn from_path

(path: P, flip_vertical: bool) -> Self + where + P: AsRef, + { + let image = image::open(path).expect("Couldn't open image"); + Self::new(image, flip_vertical) + } + + pub unsafe fn bind_to_unit(&self, unit: u32) { + gl::BindTextureUnit(unit, self.id); + } +} diff --git a/src/renderer/vertex_array.rs b/src/renderer/vertex_array.rs new file mode 100644 index 0000000..22ca27f --- /dev/null +++ b/src/renderer/vertex_array.rs @@ -0,0 +1,48 @@ +use super::vertex_buffer::VertexBuffer; + +#[derive(Debug)] +pub struct VertexArray { + pub id: u32, + pub elements: u32, +} + +impl VertexArray { + pub unsafe fn new(buffers: &[VertexBuffer]) -> Self { + let mut id = 0; + gl::CreateVertexArrays(1, &mut id); + + let mut attrib_index = 0; + for (binding_index, buffer) in buffers.iter().enumerate() { + let stride = buffer + .layout + .iter() + .fold(0, |prev, element| prev + element.mem_size()); + gl::VertexArrayVertexBuffer(id, binding_index as u32, buffer.id, 0, stride as i32); + + let mut offset = 0; + for element in buffer.layout.iter() { + gl::EnableVertexArrayAttrib(id, attrib_index as u32); + gl::VertexArrayAttribFormat( + id, + attrib_index as u32, + element.size as i32, + element.to_raw_enum(), + gl::FALSE, + offset, + ); + gl::VertexArrayAttribBinding(id, attrib_index as u32, binding_index as u32); + + offset += element.mem_size(); + attrib_index += 1; + } + } + + let elements = buffers.iter().min_by_key(|b| b.elements).unwrap().elements; + + Self { id, elements } + } + + pub unsafe fn bind(&self) { + gl::BindVertexArray(self.id); + } +} diff --git a/src/renderer/vertex_buffer.rs b/src/renderer/vertex_buffer.rs new file mode 100644 index 0000000..8a26aa7 --- /dev/null +++ b/src/renderer/vertex_buffer.rs @@ -0,0 +1,34 @@ +use std::mem; + +use gl::types::{GLfloat, GLsizeiptr, GLuint}; + +use super::VertexBufferElement; + +#[derive(Debug)] +pub struct VertexBuffer { + pub id: GLuint, + pub elements: u32, + pub layout: Vec, +} + +impl VertexBuffer { + pub unsafe fn new(data: &[GLfloat], layout: Vec) -> Self { + let mut id = 0; + gl::CreateBuffers(1, &mut id); + + gl::NamedBufferStorage( + id, + (data.len() * mem::size_of::()) as GLsizeiptr, + mem::transmute(&data[0]), + gl::DYNAMIC_STORAGE_BIT, + ); + + let elements = + data.len() as u32 / layout.iter().fold(0, |prev, element| prev + element.size); + Self { + id, + elements, + layout, + } + } +}