Initial commit

master
eater 4 years ago
commit adafd5a370
Signed by: eater
GPG Key ID: AD2560A0F84F0759

1
.gitignore vendored

@ -0,0 +1 @@
target

741
Cargo.lock generated

@ -0,0 +1,741 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "adler32"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2"
[[package]]
name = "alga"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f823d037a7ec6ea2197046bafd4ae150e6bc36f9ca347404f46a46823fa84f2"
dependencies = [
"approx",
"num-complex",
"num-traits",
]
[[package]]
name = "approx"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3"
dependencies = [
"num-traits",
]
[[package]]
name = "autocfg"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "bytemuck"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37fa13df2292ecb479ec23aa06f4507928bef07839be9ef15281411076629431"
[[package]]
name = "byteorder"
version = "1.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
[[package]]
name = "c2-chacha"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb"
dependencies = [
"ppv-lite86",
]
[[package]]
name = "cc"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cmake"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62"
dependencies = [
"cc",
]
[[package]]
name = "color_quant"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd"
[[package]]
name = "crc32fast"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
dependencies = [
"cfg-if",
]
[[package]]
name = "crossbeam-deque"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
dependencies = [
"crossbeam-epoch",
"crossbeam-utils",
"maybe-uninit",
]
[[package]]
name = "crossbeam-epoch"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
"lazy_static",
"maybe-uninit",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-queue"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
dependencies = [
"autocfg",
"cfg-if",
"lazy_static",
]
[[package]]
name = "deflate"
version = "0.7.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4"
dependencies = [
"adler32",
"byteorder",
]
[[package]]
name = "eatgel"
version = "0.1.0"
dependencies = [
"eatgel-proc-macro",
"gl",
"image",
"nalgebra",
"nalgebra-glm",
]
[[package]]
name = "eatgel-graph"
version = "0.1.0"
dependencies = [
"nalgebra-glm",
]
[[package]]
name = "eatgel-proc-macro"
version = "0.1.0"
dependencies = [
"proc-macro2",
"proc_macro_roids",
"quote",
"syn",
]
[[package]]
name = "either"
version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
[[package]]
name = "generic-array"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd"
dependencies = [
"typenum",
]
[[package]]
name = "getrandom"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "gif"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "471d90201b3b223f3451cd4ad53e34295f16a1df17b1edf3736d47761c3981af"
dependencies = [
"color_quant",
"lzw",
]
[[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 = "glfw"
version = "0.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b4c1f2e99ce4181c37d9582986ed32a8f55235bdc9427258d96d09cc9666a29"
dependencies = [
"bitflags",
"glfw-sys",
"libc",
"log",
"objc",
"raw-window-handle",
"semver",
"winapi",
]
[[package]]
name = "glfw-sys"
version = "3.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b567b13b593ec58ea912b2658ee6230ffe20a069fa5b771800acc69bb3a157e"
dependencies = [
"cmake",
]
[[package]]
name = "hermit-abi"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1010591b26bbfe835e9faeabeb11866061cc7dcebffd56ad7d0942d0e61aefd8"
dependencies = [
"libc",
]
[[package]]
name = "image"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef4e336ec01a678e7ab692914c641181528e8656451e6252f8f9e33728882eaf"
dependencies = [
"bytemuck",
"byteorder",
"gif",
"jpeg-decoder",
"num-iter",
"num-rational",
"num-traits",
"png",
"scoped_threadpool",
"tiff",
]
[[package]]
name = "inflate"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff"
dependencies = [
"adler32",
]
[[package]]
name = "jpeg-decoder"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0256f0aec7352539102a9efbcb75543227b7ab1117e0f95450023af730128451"
dependencies = [
"byteorder",
"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.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018"
[[package]]
name = "libm"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
[[package]]
name = "log"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
dependencies = [
"cfg-if",
]
[[package]]
name = "lzw"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084"
[[package]]
name = "malloc_buf"
version = "0.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
dependencies = [
"libc",
]
[[package]]
name = "matrixmultiply"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4f7ec66360130972f34830bfad9ef05c6610a43938a467bcc9ab9369ab3478f"
dependencies = [
"rawpointer",
]
[[package]]
name = "maybe-uninit"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
[[package]]
name = "memoffset"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9"
dependencies = [
"rustc_version",
]
[[package]]
name = "miniz_oxide"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5"
dependencies = [
"adler32",
]
[[package]]
name = "nalgebra"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6511777ed3da44b6a11e732a66a7d6274dfbbcd68ad968e64b778dcb829d94a"
dependencies = [
"alga",
"approx",
"generic-array",
"matrixmultiply",
"num-complex",
"num-rational",
"num-traits",
"rand",
"rand_distr",
"typenum",
]
[[package]]
name = "nalgebra-glm"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ae78da13d67be0d2e4ab567490477e4c9f314fc151ddfff6713b15bdbb2aa72"
dependencies = [
"alga",
"approx",
"nalgebra",
"num-traits",
]
[[package]]
name = "num-complex"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-integer"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-iter"
version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfb0800a0291891dd9f4fe7bd9c19384f98f7fbe0cd0f39a2c6b88b9868bbc00"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da4dc79f9e6c81bef96148c8f6b8e72ad4541caa4a24373e900a36da07de03a3"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
dependencies = [
"autocfg",
"libm",
]
[[package]]
name = "num_cpus"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "objc"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
dependencies = [
"malloc_buf",
]
[[package]]
name = "png"
version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef859a23054bbfee7811284275ae522f0434a3c8e7f4b74bd4a35ae7e1c4a283"
dependencies = [
"bitflags",
"crc32fast",
"deflate",
"inflate",
]
[[package]]
name = "ppv-lite86"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
[[package]]
name = "proc-macro2"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435"
dependencies = [
"unicode-xid",
]
[[package]]
name = "proc_macro_roids"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06675fa2c577f52bcf77fbb511123927547d154faa08097cc012c66ec3c9611a"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "quote"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom",
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853"
dependencies = [
"c2-chacha",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_distr"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2"
dependencies = [
"rand",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core",
]
[[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 = "rawpointer"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
[[package]]
name = "rayon"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098"
dependencies = [
"crossbeam-deque",
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9"
dependencies = [
"crossbeam-deque",
"crossbeam-queue",
"crossbeam-utils",
"lazy_static",
"num_cpus",
]
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
"semver",
]
[[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 = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "syn"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "tiff"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "002351e428db1eb1d8656d4ca61947c3519ac3191e1c804d4600cd32093b77ad"
dependencies = [
"byteorder",
"lzw",
"miniz_oxide",
]
[[package]]
name = "triangle-time"
version = "0.1.0"
dependencies = [
"eatgel",
"gl",
"glfw",
"image",
"nalgebra-glm",
]
[[package]]
name = "typenum"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
[[package]]
name = "unicode-xid"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "winapi"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
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-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "xml-rs"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "541b12c998c5b56aa2b4e6f18f03664eef9a4fd0a246a55594efae6cc2d964b5"

@ -0,0 +1,2 @@
[workspace]
members = ["triangle-time", "eatgel", "eatgel-proc-macro", "eatgel-graph"]

@ -0,0 +1,8 @@
[package]
name = "eatgel-graph"
version = "0.1.0"
authors = ["eater <=@eater.me>"]
edition = "2018"
[dependencies]
nalgebra-glm = "0.6.0"

@ -0,0 +1,95 @@
use nalgebra_glm::{identity, vec3, Mat4, Vec3, U4};
use std::cell::{Ref, RefCell};
use std::rc::Rc;
struct Graph {
root: NodeRef,
}
impl Graph {
fn new() -> Graph {
let mut node = Node::new();
node.is_root = true;
Graph {
root: node.into_ref(),
}
}
}
type NodeRef = Rc<RefCell<Node>>;
trait NodeExt {
fn append_child(&self, child: &NodeRef);
fn remove_child(&self, child: &NodeRef);
}
struct Node {
rotation: Vec3,
transform: Mat4,
origin: Vec3,
absolute_position: Option<Mat4>,
children: Vec<NodeRef>,
parent: Option<NodeRef>,
is_root: bool,
}
impl Node {
fn new() -> Node {
Node {
rotation: vec3(0.0, 0.0, 0.0),
transform: identity::<_, U4>(),
origin: vec3(0.0, 0.0, 0.0),
absolute_position: None,
children: vec![],
parent: None,
is_root: false,
}
}
fn into_ref(self) -> NodeRef {
Rc::new(RefCell::new(self))
}
}
impl NodeExt for NodeRef {
fn append_child(&self, child: &NodeRef) {
if Rc::ptr_eq(&self, child) {
return;
}
if let Some(parent) = child.borrow().parent.clone() {
parent.remove_child(&self)
}
self.borrow_mut().children.push(child.clone())
}
fn remove_child(&self, child: &NodeRef) {
let children = &mut self.borrow_mut().children;
let mut offset: usize = 0;
for i in 0..childs.len() {
if Rc::ptr_eq(&childs[i - offset], child) {
children.remove(i - offset);
offset += 1;
}
}
}
}
#[cfg(test)]
pub mod test {
use crate::*;
#[test]
pub fn it_works() {
let node = Node::new().into_ref();
node.append_child(&node);
node.remove_child(&node);
let second_node = Node::new().into_ref();
node.append_child(&second_node);
let graph = Graph::new();
graph.root.append_child(&node);
assert_eq!(1, graph.root.borrow().children.len());
}
}

@ -0,0 +1,16 @@
[package]
name = "eatgel-proc-macro"
version = "0.1.0"
authors = ["eater <=@eater.me>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
proc-macro = true
[dependencies]
proc_macro_roids = "0.7.0"
proc-macro2 = "1.0.9"
syn = "1.0.16"
quote = "1.0.3"

@ -0,0 +1,191 @@
extern crate proc_macro;
use proc_macro::{Literal, TokenStream, TokenTree};
use proc_macro_roids::{DeriveInputStructExt, FieldExt};
use quote::quote;
use std::str::FromStr;
use proc_macro2::TokenStream as TokenStream2;
use syn::{parse_macro_input, parse_quote, DeriveInput};
#[proc_macro_derive(ShaderData, attributes(skip))]
pub fn derive_shader_data(token_stream: TokenStream) -> TokenStream {
let mut iter = token_stream.into_iter();
let empty = TokenStream::new();
if let Some(TokenTree::Ident(ident)) = iter.next() {
if ident.to_string() != "struct" {
return empty;
}
} else {
return empty;
}
let struct_name = if let Some(TokenTree::Ident(ident)) = iter.next() {
ident.to_string()
} else {
return empty;
};
let mut group = if let Some(TokenTree::Group(group)) = iter.next() {
group
} else {
return empty;
}
.stream()
.into_iter();
let mut keys = vec![];
loop {
let item = group.next();
if item.is_none() {
break;
}
let item = item.unwrap();
if item.to_string() == "#" {
if let Some(TokenTree::Group(tag)) = group.next() {
if tag.to_string() == "[skip]" {
while let Some(x) = group.next() {
if x.to_string() == "," {
break;
}
}
}
continue;
} else {
break;
}
}
let name = match item {
TokenTree::Ident(ident) => ident.to_string(),
_ => break,
};
// :
group.next();
let mut stream = vec![];
while let Some(x) = group.next() {
if x.to_string() == "," {
break;
}
stream.push(x);
}
keys.push(name);
}
let init = keys
.iter()
.map(|name| Literal::string(&name).to_string())
.collect::<Vec<String>>()
.join(", ");
let mut index = -1;
let apply = keys
.iter()
.map(|name| {
index += 1;
format!(
"(gl as &dyn UpdateUniform<_>).update_uniform_by_index(gl, program_id, {}, &self.{});",
index,
name
)
})
.collect::<Vec<String>>()
.join("\n");
let gen_source = format!(
r#"
impl ::eatgel::ShaderData for {} {{
fn init(&mut self, gl: &mut ::eatgel::GlContext, program_id: u32) {{
gl.register_uniforms(program_id, &[{}]);
}}
fn apply(&self, gl: &::eatgel::GlContext, program_id: u32) {{
{}
}}
}}
"#,
struct_name, init, apply,
);
TokenStream::from_str(&gen_source).unwrap()
}
#[proc_macro_derive(VertexData, attributes(skip))]
pub fn derive_vertex_data(token_stream: TokenStream) -> TokenStream {
let ast = parse_macro_input!(token_stream as DeriveInput);
let name = &ast.ident;
let mut index = -1;
let fields = ast
.fields()
.iter()
.map(move |field| {
index += 1;
let name = index;
(name, field)
})
.filter(|(_, field)| !field.is_phantom_data())
.filter(|(_, field)| !field.contains_tag(&parse_quote!(vertex_data), &parse_quote!(skip)));
let sizes = fields
.clone()
.map(|(_, field)| {
let type_name = field.type_name();
quote!(
::std::mem::size_of::<#type_name>()
)
})
.collect::<Vec<_>>();
let types = fields
.clone()
.map(|(_, field)| {
let type_name = field.type_name();
quote!(
::eatgel::type_descriptor_of::<#type_name>()
)
})
.collect::<Vec<_>>();
let pointers = fields
.map(|(index, field)| {
if let Some(name) = field.ident.as_ref() {
quote!(
self.#name.as_ptr() as *const ::std::ffi::c_void
)
} else {
quote!(
self.#index.as_ptr() as *const ::std::ffi::c_void
)
}
})
.collect::<Vec<_>>();
let token_stream2: TokenStream2 = quote!(
impl ::eatgel::VertexData for #name {
fn get_sizes() -> Box<[usize]> {
return vec![#(#sizes,)*].into_boxed_slice()
}
fn get_types() -> Box<[::eatgel::TypeDescriptor]> {
return vec![#(#types,)*].into_boxed_slice()
}
fn get_pointers(&self) -> Box<[*const ::std::ffi::c_void]> {
return vec![#(#pointers,)*].into_boxed_slice()
}
}
);
token_stream2.into()
}

2
eatgel/.gitignore vendored

@ -0,0 +1,2 @@
/target
Cargo.lock

@ -0,0 +1,18 @@
[package]
name = "eatgel"
version = "0.1.0"
authors = ["eater <=@eater.me>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
gl = "0.14.0"
nalgebra-glm = "0.6.0"
nalgebra = "0.20.0"
image = "0.23.0"
eatgel-proc-macro = { path = "../eatgel-proc-macro", optional = true }
[features]
derive = ["eatgel-proc-macro"]
default = ["derive"]

@ -0,0 +1,185 @@
use crate::types::TypeDescriptor;
use std::ffi::c_void;
use std::ops::Range;
pub struct StaticBufferNonIndexed {
pub vao: u32,
pub attributes: Vec<Attribute>,
pub elements: usize,
}
impl StaticBufferNonIndexed {
pub fn bind(&self) {
unsafe {
gl::BindVertexArray(self.vao);
}
}
pub fn draw(&self) {
self.bind();
unsafe { gl::DrawArrays(gl::TRIANGLES, 0, self.elements as i32) }
}
}
pub struct StaticBuffer {
pub vao: u32,
pub attributes: Vec<Attribute>,
pub ebo: u32,
pub indices: usize,
}
impl StaticBuffer {
pub fn bind(&self) {
unsafe {
gl::BindVertexArray(self.vao);
gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, self.ebo);
}
}
pub fn draw(&self) {
self.bind();
unsafe {
gl::DrawElements(
gl::TRIANGLES,
self.indices as i32,
gl::UNSIGNED_INT,
0 as *const c_void,
)
}
}
}
impl Drop for StaticBuffer {
fn drop(&mut self) {
unsafe { gl::DeleteVertexArrays(1, [self.vao].as_ptr()) }
}
}
pub struct Attributes {
mem: Box<[u8]>,
pub attributes: Vec<Attribute>,
pub size: usize,
pub elements: usize,
}
impl Attributes {
pub fn as_ptr(&self) -> *const c_void {
self.mem.as_ptr() as *const c_void
}
}
pub struct Attribute {
pub amount: usize,
pub stride: usize,
pub offset: usize,
pub gl_type: u32,
}
pub trait VertexData {
fn get_sizes() -> Box<[usize]>;
fn get_types() -> Box<[TypeDescriptor]>;
fn get_pointers(&self) -> Box<[*const c_void]>;
}
pub trait VertexDataCollection<D>
where
D: VertexData,
{
fn get_amount(&self) -> usize;
fn get_list(&self) -> &[D];
fn create_ptr(&self, interleaved: bool, range: Option<Range<usize>>) -> Attributes {
let sizes = D::get_sizes();
let struct_size = sizes.clone().iter().sum();
let range = range.unwrap_or(0..self.get_amount());
let amount = range.end - range.start;
let mut list = vec![0u8; struct_size * amount];
let items = self.get_list();
for i in range.clone() {
let item = &items[i];
let pointers = item.get_pointers();
let sizes_and_pointers = sizes
.iter()
.zip(pointers.iter())
.collect::<Vec<(&usize, &*const c_void)>>();
let mut offset = 0;
for (size, ptr) in sizes_and_pointers {
let index = if interleaved {
offset + (struct_size * (i - range.start))
} else {
(offset * amount) + size * i
};
unsafe {
std::ptr::copy(ptr.cast(), list.as_mut_ptr().add(index), *size);
}
offset += size;
}
}
let mut attributes = vec![];
let mut offset = 0;
for (size, type_desc) in sizes.iter().zip(D::get_types().iter()) {
attributes.push(Attribute {
amount: type_desc.amount as usize,
gl_type: type_desc.gl_type,
stride: if interleaved { struct_size } else { *size },
offset: if interleaved { offset } else { offset * amount },
});
offset += *size;
}
Attributes {
mem: list.into_boxed_slice(),
attributes,
size: struct_size * amount,
elements: items.len(),
}
}
}
impl<D: VertexData> VertexDataCollection<D> for Vec<D> {
fn get_amount(&self) -> usize {
self.len()
}
fn get_list(&self) -> &[D] {
&self
}
}
impl<D: VertexData> VertexDataCollection<D> for &[D] {
fn get_amount(&self) -> usize {
self.len()
}
fn get_list(&self) -> &[D] {
self
}
}
impl<D: VertexData> VertexDataCollection<D> for Box<[D]> {
fn get_amount(&self) -> usize {
self.len()
}
fn get_list(&self) -> &[D] {
&self
}
}
impl<D: VertexData> VertexDataCollection<D> for [D] {
fn get_amount(&self) -> usize {
self.len()
}
fn get_list(&self) -> &[D] {
&self
}
}

@ -0,0 +1,31 @@
use image::ImageError;
use std::ffi::NulError;
use std::str::Utf8Error;
#[derive(Debug)]
pub enum Error {
ShaderContainsNul(NulError),
ShaderCompilationFailure(String),
ShaderProgramLinkFailure(String),
InfoLogEncodingError(Utf8Error),
TextureLoadError(ImageError),
TextureParseError,
}
impl From<Utf8Error> for Error {
fn from(utf8err: Utf8Error) -> Self {
Error::InfoLogEncodingError(utf8err)
}
}
impl From<NulError> for Error {
fn from(nul_err: NulError) -> Self {
Error::ShaderContainsNul(nul_err)
}
}
impl From<ImageError> for Error {
fn from(image_err: ImageError) -> Self {
Error::TextureLoadError(image_err)
}
}

@ -0,0 +1,217 @@
use std::ffi::{c_void, CStr, CString};
pub mod buffer;
mod err;
pub mod shader;
pub mod texture;
mod types;
mod update_uniform;
use crate::buffer::{Attributes, StaticBufferNonIndexed};
use buffer::StaticBuffer;
pub use buffer::{VertexData, VertexDataCollection};
#[cfg(feature = "derive")]
pub use eatgel_proc_macro::{ShaderData, VertexData};
pub use shader::ShaderData;
use std::collections::HashMap;
use std::mem::size_of;
use std::ptr::null;
pub use types::{amount_of, type_descriptor_of, type_of, TypeDescriptor, TypeResolver};
pub use update_uniform::*;
pub struct GlContext {
cache: HashMap<u32, Box<[i32]>>,
clear_color: [f32; 4],
}
#[repr(u32)]
#[derive(Debug, Copy, Clone)]
enum Severity {
Low = gl::DEBUG_SEVERITY_LOW,
Medium = gl::DEBUG_SEVERITY_MEDIUM,
High = gl::DEBUG_SEVERITY_HIGH,
Notification = gl::DEBUG_SEVERITY_NOTIFICATION,
}
impl From<u32> for Severity {
fn from(x: u32) -> Self {
match x {
gl::DEBUG_SEVERITY_LOW => Severity::Low,
gl::DEBUG_SEVERITY_MEDIUM => Severity::Medium,
gl::DEBUG_SEVERITY_HIGH => Severity::High,
_ => Severity::Notification,
}
}
}
extern "system" fn gl_message_callback(
_source: u32,
_error_type: u32,
_id: u32,
severity: u32,
_length: i32,
message: *const i8,
_user_data: *mut c_void,
) {
unsafe {
println!(
"Message ({:?}): {:?}",
Severity::from(severity),
CStr::from_ptr(message)
);
}
}
impl GlContext {
pub fn new<F>(f: F) -> Self
where
F: FnMut(&'static str) -> *const c_void,
{
gl::load_with(f);
unsafe {
gl::Enable(gl::DEBUG_OUTPUT);
gl::DebugMessageCallback(Some(gl_message_callback), null())
}
GlContext {
cache: HashMap::new(),
clear_color: [0., 0., 0., 0.],
}
}
pub fn set_clear_color(&mut self, red: f32, green: f32, blue: f32, alpha: f32) {
self.clear_color = [red, green, blue, alpha];
}
pub fn clear(&self) {
unsafe {
gl::ClearColor(
self.clear_color[0],
self.clear_color[1],
self.clear_color[2],
self.clear_color[3],
);
gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
}
}
pub fn get_uniform_location(&self, program_id: u32, name: &str) -> i32 {
let name = CString::new(name).expect("Failed creating CString from &str");
unsafe { gl::GetUniformLocation(program_id, name.as_ptr()) }
}
pub fn register_uniforms(&mut self, program_id: u32, uniforms: &[&str]) {
let mut ids = vec![];
for name in uniforms {
unsafe {
ids.push(gl::GetUniformLocation(
program_id,
CString::new(name.to_string())
.expect("Nul character in uniform name")
.as_ptr(),
))
}
}
self.cache.insert(program_id, ids.into_boxed_slice());
}
pub fn get_uniform_location_by_index(&self, program_id: u32, index: usize) -> i32 {
self.cache.get(&program_id).map(|x| x[index]).unwrap_or(-1)
}
unsafe fn create_attribs(&self, attributes: &Attributes) {
let mut index = 0;
for attribute in &attributes.attributes {
gl::VertexAttribPointer(
index,
attribute.amount as i32,
attribute.gl_type,
gl::FALSE,
attribute.stride as i32,
attribute.offset as *const c_void,
);
gl::EnableVertexAttribArray(index);
index += 1;
}
}
pub fn create_static_buffer_non_indexed<C: VertexDataCollection<D>, D: VertexData>(
&self,
buffer: C,
) -> StaticBufferNonIndexed {
let attributes = buffer.create_ptr(false, None);
let mut vbo = 0;
let mut vao = 0;
unsafe {
gl::GenVertexArrays(1, &mut vao);
gl::GenBuffers(1, &mut vbo);
gl::BindVertexArray(vao);
gl::BindBuffer(gl::ARRAY_BUFFER, vbo);
gl::BufferData(
gl::ARRAY_BUFFER,
attributes.size as isize,
attributes.as_ptr(),
gl::STATIC_DRAW,
);
self.create_attribs(&attributes)
}
StaticBufferNonIndexed {
vao,
elements: attributes.elements,
attributes: attributes.attributes,
}
}
pub fn create_static_buffer<C: VertexDataCollection<D>, D: VertexData>(
&self,
buffer: C,
indices: &[u32],
) -> StaticBuffer {
let attributes = buffer.create_ptr(false, None);
let mut vbo = 0;
let mut vao = 0;
let mut ebo = 0;
unsafe {
gl::GenVertexArrays(1, &mut vao);
gl::GenBuffers(1, &mut vbo);
gl::GenBuffers(1, &mut ebo);
gl::BindVertexArray(vao);
gl::BindBuffer(gl::ARRAY_BUFFER, vbo);
gl::BufferData(
gl::ARRAY_BUFFER,
attributes.size as isize,
attributes.as_ptr(),
gl::STATIC_DRAW,
);
self.create_attribs(&attributes);
gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, ebo);
gl::BufferData(
gl::ELEMENT_ARRAY_BUFFER,
(size_of::<u32>() * indices.len()) as isize,
indices.as_ptr() as *const c_void,
gl::STATIC_DRAW,
);
}
StaticBuffer {
vao,
ebo,
indices: indices.len(),
attributes: attributes.attributes,
}
}
}

@ -0,0 +1,144 @@
use crate::err::Error;
use crate::GlContext;
use std::ffi::CString;
use std::ops::{Deref, DerefMut};
use std::os::raw::c_char;
use std::ptr::null;
use std::str::from_utf8;
pub trait ShaderData {
fn init(&mut self, gl: &mut GlContext, program_id: u32);
fn apply(&self, gl: &GlContext, program_id: u32);
}
impl ShaderData for () {
fn init(&mut self, _gl: &mut GlContext, _program_id: u32) {}
fn apply(&self, _gl: &GlContext, _program_id: u32) {}
}
pub struct ShaderProgram<D: ShaderData> {
pub program_id: u32,
data: D,
}
impl<D: ShaderData> ShaderProgram<D> {
pub fn init(&mut self, gl: &mut GlContext) {
self.data.init(gl, self.program_id);
}
pub fn apply(&self, gl: &GlContext) {
self.data.apply(gl, self.program_id);
}
}
impl<D: ShaderData> Deref for ShaderProgram<D> {
type Target = D;
fn deref(&self) -> &Self::Target {
&self.data
}
}
impl<D: ShaderData> DerefMut for ShaderProgram<D> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.data
}
}
pub struct Shader(pub u32);
impl Drop for Shader {
fn drop(&mut self) {
unsafe { gl::DeleteShader(self.0) }
}
}
#[repr(u32)]
pub enum ShaderType {
Vertex = gl::VERTEX_SHADER,
Fragment = gl::FRAGMENT_SHADER,
}
impl Shader {
pub fn compile(shader_type: ShaderType, source: &str) -> Result<Shader, Error> {
let shader_id = unsafe { gl::CreateShader(shader_type as u32) };
let source = CString::new(source.as_bytes())?;
unsafe {
gl::ShaderSource(shader_id, 1, &source.as_ptr(), null());
gl::CompileShader(shader_id);
let mut success = 0;
gl::GetShaderiv(shader_id, gl::COMPILE_STATUS, &mut success);
if success != 1 {
let mut log_length = 0;
gl::GetShaderiv(shader_id, gl::INFO_LOG_LENGTH, &mut log_length);
let mut log = Vec::with_capacity(log_length as usize);
let mut len = 0;
gl::GetShaderInfoLog(
shader_id,
log_length,
&mut len,
log.as_mut_ptr() as *mut c_char,
);
log.set_len(len as usize);
return Err(Error::ShaderCompilationFailure(
from_utf8(&log)?.to_string(),
));
}
}
Ok(Shader(shader_id))
}
}
impl ShaderProgram<()> {
pub fn create(shader0: Shader, shader1: Shader) -> Result<ShaderProgram<()>, Error> {
ShaderProgram::create_with_data((), shader0, shader1)
}
}
impl<D: ShaderData> ShaderProgram<D> {
pub fn enable(&self) {
unsafe { gl::UseProgram(self.program_id) }
}
pub fn create_with_data(
data: D,
shader0: Shader,
shader1: Shader,
) -> Result<ShaderProgram<D>, Error> {
unsafe {
let program_id = gl::CreateProgram();
gl::AttachShader(program_id, shader0.0);
gl::AttachShader(program_id, shader1.0);
gl::LinkProgram(program_id);
let mut status = 0;
gl::GetProgramiv(program_id, gl::LINK_STATUS, &mut status);
if status != 1 {
let mut log_length = 0;
gl::GetProgramiv(program_id, gl::INFO_LOG_LENGTH, &mut log_length);
let mut log = Vec::with_capacity(log_length as usize);
let mut len = 0;
gl::GetProgramInfoLog(
program_id,
log_length,
&mut len,
log.as_mut_ptr() as *mut c_char,
);
log.set_len(len as usize);
return Err(Error::ShaderProgramLinkFailure(
from_utf8(&log)?.to_string(),
));
}
gl::DeleteShader(shader0.0);
gl::DeleteShader(shader1.0);
Ok(ShaderProgram { data, program_id })
}
}
}

@ -0,0 +1,180 @@
use crate::err::Error;
pub use image::{ColorType, ImageFormat};
use image::{DynamicImage, GenericImageView};
use nalgebra_glm::Vec4;
use std::io::{BufRead, Seek};
use std::os::raw::c_void;
#[repr(u32)]
#[derive(Copy, Clone, Debug)]
pub enum WrapStyle {
Repeat = gl::REPEAT,
MirroredRepeat = gl::MIRRORED_REPEAT,
ClampToEdge = gl::CLAMP_TO_EDGE,
ClampToBorder = gl::CLAMP_TO_BORDER,
}
#[repr(u32)]
#[derive(Copy, Clone, Debug)]
pub enum FilterStyle {
Nearest = gl::NEAREST,
Linear = gl::LINEAR,
}
impl FilterStyle {
fn get_gl_enum(filter: FilterStyle, mipmap: Option<FilterStyle>) -> i32 {
let gl_enum = match (filter, mipmap) {
(FilterStyle::Nearest, None) => gl::NEAREST,
(FilterStyle::Linear, None) => gl::LINEAR,
(FilterStyle::Linear, Some(FilterStyle::Linear)) => gl::LINEAR_MIPMAP_LINEAR,
(FilterStyle::Linear, Some(FilterStyle::Nearest)) => gl::LINEAR_MIPMAP_NEAREST,
(FilterStyle::Nearest, Some(FilterStyle::Linear)) => gl::NEAREST_MIPMAP_LINEAR,
(FilterStyle::Nearest, Some(FilterStyle::Nearest)) => gl::NEAREST_MIPMAP_NEAREST,
};
gl_enum as i32
}
}
#[derive(Clone, Debug)]
pub struct Texture {
image_id: u32,
options: TextureOptions,
}
pub struct Image {
pub image: DynamicImage,
}
impl Image {
pub fn load<R: BufRead + Seek>(r: R, format: ImageFormat) -> Result<Image, Error> {
Ok(Image {
image: image::load(r, format)?,
})
}
pub fn into_texture(mut self, options: TextureOptions) -> Result<Texture, Error> {
let mut image_id = 0;
unsafe {
gl::GenTextures(1, &mut image_id);
gl::BindTexture(gl::TEXTURE_2D, image_id);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, options.wrap_s as i32);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, options.wrap_t as i32);
gl::TexParameteri(
gl::TEXTURE_2D,
gl::TEXTURE_MAG_FILTER,
FilterStyle::get_gl_enum(options.mag_filter, options.mag_mipmap_filter),
);
gl::TexParameteri(
gl::TEXTURE_2D,
gl::TEXTURE_MAG_FILTER,
FilterStyle::get_gl_enum(options.min_filter, options.min_mipmap_filter),
);
if let Some((_, ref border)) = options.border {
gl::TexParameterfv(gl::TEXTURE_2D, gl::TEXTURE_BORDER_COLOR, border.as_ptr())
}
if options.flip_vertically {
self.image = self.image.flipv()
}
let pixels = self
.image
.pixels()
.into_iter()
.flat_map(|x| vec![x.2[0], x.2[1], x.2[2], x.2[3]])
.collect::<Vec<u8>>();
let width = self.image.width();
let height = self.image.height();
gl::TexImage2D(
gl::TEXTURE_2D,
0,
gl::RGBA as i32,
width as i32,
height as i32,
0,
gl::RGBA,
gl::UNSIGNED_BYTE,
pixels.as_ptr() as *const c_void,
);
gl::GenerateMipmap(gl::TEXTURE_2D);
}
Ok(Texture { image_id, options })
}
}
#[derive(Clone, Debug)]
pub struct TextureOptions {
wrap_s: WrapStyle,
wrap_t: WrapStyle,
border: Option<(i32, Vec4)>,
mag_filter: FilterStyle,
min_filter: FilterStyle,
min_mipmap_filter: Option<FilterStyle>,
mag_mipmap_filter: Option<FilterStyle>,
flip_vertically: bool,
}
impl Default for TextureOptions {
fn default() -> Self {
TextureOptions {
wrap_s: WrapStyle::Repeat,
wrap_t: WrapStyle::Repeat,
border: None,
mag_filter: FilterStyle::Linear,
min_filter: FilterStyle::Linear,
min_mipmap_filter: None,
mag_mipmap_filter: None,
flip_vertically: true,
}
}
}
#[repr(u32)]
#[derive(Debug, Copy, Clone)]
pub enum TextureSlot {
Slot0 = gl::TEXTURE0,
Slot1 = gl::TEXTURE1,
Slot2 = gl::TEXTURE2,
Slot3 = gl::TEXTURE3,
Slot4 = gl::TEXTURE4,
Slot5 = gl::TEXTURE5,
Slot6 = gl::TEXTURE6,
Slot7 = gl::TEXTURE7,
Slot8 = gl::TEXTURE8,
Slot9 = gl::TEXTURE9,
Slot10 = gl::TEXTURE10,
Slot11 = gl::TEXTURE11,
Slot12 = gl::TEXTURE12,
Slot13 = gl::TEXTURE13,
Slot14 = gl::TEXTURE14,
Slot15 = gl::TEXTURE15,
Slot16 = gl::TEXTURE16,
Slot17 = gl::TEXTURE17,
Slot18 = gl::TEXTURE18,
Slot19 = gl::TEXTURE19,
Slot20 = gl::TEXTURE20,
Slot21 = gl::TEXTURE21,
Slot22 = gl::TEXTURE22,
Slot23 = gl::TEXTURE23,
Slot24 = gl::TEXTURE24,
Slot25 = gl::TEXTURE25,
Slot26 = gl::TEXTURE26,
Slot27 = gl::TEXTURE27,
Slot28 = gl::TEXTURE28,
Slot29 = gl::TEXTURE29,
Slot30 = gl::TEXTURE30,
Slot31 = gl::TEXTURE31,
}
impl Texture {
pub fn enable(&self, slot: TextureSlot) {
unsafe {
gl::ActiveTexture(slot as u32);
gl::BindTexture(gl::TEXTURE_2D, self.image_id);
}
}
}

@ -0,0 +1,120 @@
use nalgebra_glm::{Vec2, Vec3, Vec4};
pub trait TypeResolver {
fn type_of() -> u32;
fn amount_of() -> u32;
fn get_type_descriptor() -> TypeDescriptor {
TypeDescriptor {
gl_type: Self::type_of(),
amount: Self::amount_of(),
}
}
}
#[derive(Debug, Copy, Clone)]
pub struct TypeDescriptor {
pub gl_type: u32,
pub amount: u32,
}
pub fn type_descriptor_of<T: TypeResolver>() -> TypeDescriptor {
T::get_type_descriptor()
}
pub fn type_of<T: TypeResolver>() -> u32 {
T::type_of()
}
pub fn amount_of<T: TypeResolver>() -> u32 {
T::amount_of()
}
impl TypeResolver for bool {
fn type_of() -> u32 {
gl::UNSIGNED_BYTE
}
fn amount_of() -> u32 {
1
}
}
impl TypeResolver for u8 {
fn type_of() -> u32 {
gl::UNSIGNED_BYTE
}
fn amount_of() -> u32 {
1
}
}
impl TypeResolver for i8 {
fn type_of() -> u32 {
gl::BYTE
}
fn amount_of() -> u32 {
1
}
}
impl TypeResolver for u16 {
fn type_of() -> u32 {
gl::UNSIGNED_SHORT
}
fn amount_of() -> u32 {
1
}
}
impl TypeResolver for i16 {
fn type_of() -> u32 {
gl::SHORT
}
fn amount_of() -> u32 {
1
}
}
impl TypeResolver for u32 {
fn type_of() -> u32 {
gl::UNSIGNED_INT
}
fn amount_of() -> u32 {
1
}
}
impl TypeResolver for i32 {
fn type_of() -> u32 {
gl::INT
}
fn amount_of() -> u32 {
1
}
}
impl TypeResolver for Vec2 {
fn type_of() -> u32 {
gl::FLOAT
}
fn amount_of() -> u32 {
2
}
}
impl TypeResolver for Vec3 {
fn type_of() -> u32 {
gl::FLOAT
}
fn amount_of() -> u32 {
3
}
}
impl TypeResolver for Vec4 {
fn type_of() -> u32 {
gl::FLOAT
}
fn amount_of() -> u32 {
4
}
}

@ -0,0 +1,342 @@
use crate::texture::TextureSlot;
use crate::GlContext;
use nalgebra_glm::{Mat3, Mat4};
use std::convert::From;
use std::ptr::null;
pub trait UpdateUniform<T> {
fn update_uniform(&self, location: i32, value: T);
fn update_uniform_by_index(&self, gl: &GlContext, program_id: u32, index: usize, value: T) {
self.update_uniform(gl.get_uniform_location_by_index(program_id, index), value)
}
}
impl UpdateUniform<i32> for GlContext {
fn update_uniform(&self, location: i32, value: i32) {
unsafe { gl::Uniform1i(location, value) }
}
}
impl UpdateUniform<&i32> for GlContext {
fn update_uniform(&self, location: i32, value: &i32) {
unsafe { gl::Uniform1i(location, *value) }
}
}
impl UpdateUniform<&Vec<i32>> for GlContext {
fn update_uniform(&self, location: i32, value: &Vec<i32>) {
unsafe { gl::Uniform1iv(location, value.len() as i32, value.as_ptr()) }
}
}
impl UpdateUniform<&nalgebra_glm::TVec2<i32>> for GlContext {
fn update_uniform(&self, location: i32, value: &nalgebra_glm::TVec2<i32>) {
unsafe { gl::Uniform2i(location, value.x, value.y) }
}
}
impl UpdateUniform<&Vec<nalgebra_glm::TVec2<i32>>> for GlContext {
fn update_uniform(&self, location: i32, value: &Vec<nalgebra_glm::TVec2<i32>>) {
unsafe {
gl::Uniform2iv(
location,
value.len() as i32,
value.first().map(|x| x.as_ptr()).unwrap_or(null()),
)
}
}
}
impl UpdateUniform<&nalgebra_glm::TVec3<i32>> for GlContext {
fn update_uniform(&self, location: i32, value: &nalgebra_glm::TVec3<i32>) {
unsafe { gl::Uniform3i(location, value.x, value.y, value.z) }
}
}
impl UpdateUniform<&Vec<nalgebra_glm::TVec3<i32>>> for GlContext {
fn update_uniform(&self, location: i32, value: &Vec<nalgebra_glm::TVec3<i32>>) {
unsafe {
gl::Uniform3iv(
location,
value.len() as i32,
value.first().map(|x| x.as_ptr()).unwrap_or(null()),
)
}
}
}
impl UpdateUniform<&nalgebra_glm::TVec4<i32>> for GlContext {
fn update_uniform(&self, location: i32, value: &nalgebra_glm::TVec4<i32>) {
unsafe { gl::Uniform4i(location, value.x, value.y, value.z, value.w) }
}
}
impl UpdateUniform<&Vec<nalgebra_glm::TVec4<i32>>> for GlContext {
fn update_uniform(&self, location: i32, value: &Vec<nalgebra_glm::TVec4<i32>>) {
unsafe {
gl::Uniform4iv(
location,
value.len() as i32,
value.first().map(|x| x.as_ptr()).unwrap_or(null()),
)
}
}
}
impl UpdateUniform<u32> for GlContext {
fn update_uniform(&self, location: i32, value: u32) {
unsafe { gl::Uniform1ui(location, value) }
}
}
impl UpdateUniform<&u32> for GlContext {
fn update_uniform(&self, location: i32, value: &u32) {
unsafe { gl::Uniform1ui(location, *value) }
}
}
impl UpdateUniform<&Vec<u32>> for GlContext {
fn update_uniform(&self, location: i32, value: &Vec<u32>) {
unsafe { gl::Uniform1uiv(location, value.len() as i32, value.as_ptr()) }
}
}
impl UpdateUniform<&nalgebra_glm::TVec2<u32>> for GlContext {
fn update_uniform(&self, location: i32, value: &nalgebra_glm::TVec2<u32>) {
unsafe { gl::Uniform2ui(location, value.x, value.y) }
}
}
impl UpdateUniform<&Vec<nalgebra_glm::TVec2<u32>>> for GlContext {
fn update_uniform(&self, location: i32, value: &Vec<nalgebra_glm::TVec2<u32>>) {
unsafe {
gl::Uniform2uiv(
location,
value.len() as i32,
value.first().map(|x| x.as_ptr()).unwrap_or(null()),
)
}
}
}
impl UpdateUniform<&nalgebra_glm::TVec3<u32>> for GlContext {
fn update_uniform(&self, location: i32, value: &nalgebra_glm::TVec3<u32>) {
unsafe { gl::Uniform3ui(location, value.x, value.y, value.z) }
}
}
impl UpdateUniform<&Vec<nalgebra_glm::TVec3<u32>>> for GlContext {
fn update_uniform(&self, location: i32, value: &Vec<nalgebra_glm::TVec3<u32>>) {
unsafe {
gl::Uniform3uiv(
location,
value.len() as i32,
value.first().map(|x| x.as_ptr()).unwrap_or(null()),
)
}
}
}
impl UpdateUniform<&nalgebra_glm::TVec4<u32>> for GlContext {
fn update_uniform(&self, location: i32, value: &nalgebra_glm::TVec4<u32>) {
unsafe { gl::Uniform4ui(location, value.x, value.y, value.z, value.w) }
}
}
impl UpdateUniform<&Vec<nalgebra_glm::TVec4<u32>>> for GlContext {
fn update_uniform(&self, location: i32, value: &Vec<nalgebra_glm::TVec4<u32>>) {
unsafe {
gl::Uniform4uiv(
location,
value.len() as i32,
value.first().map(|x| x.as_ptr()).unwrap_or(null()),
)
}
}
}
impl UpdateUniform<f32> for GlContext {
fn update_uniform(&self, location: i32, value: f32) {
unsafe { gl::Uniform1f(location, value) }
}
}
impl UpdateUniform<&f32> for GlContext {
fn update_uniform(&self, location: i32, value: &f32) {
unsafe { gl::Uniform1f(location, *value) }
}
}
impl UpdateUniform<&Vec<f32>> for GlContext {
fn update_uniform(&self, location: i32, value: &Vec<f32>) {
unsafe { gl::Uniform1fv(location, value.len() as i32, value.as_ptr()) }
}
}
impl UpdateUniform<&nalgebra_glm::TVec1<f32>> for GlContext {
fn update_uniform(&self, location: i32, value: &nalgebra_glm::TVec1<f32>) {
unsafe { gl::Uniform1f(location, value.x) }
}
}
impl UpdateUniform<&Vec<nalgebra_glm::TVec1<f32>>> for GlContext {
fn update_uniform(&self, location: i32, value: &Vec<nalgebra_glm::TVec1<f32>>) {
unsafe {
gl::Uniform1fv(
location,
value.len() as i32,
value.first().map(|x| x.as_ptr()).unwrap_or(null()),
)
}
}
}
impl UpdateUniform<&nalgebra_glm::TVec2<f32>> for GlContext {
fn update_uniform(&self, location: i32, value: &nalgebra_glm::TVec2<f32>) {
unsafe { gl::Uniform2f(location, value.x, value.y) }
}
}
impl UpdateUniform<&Vec<nalgebra_glm::TVec2<f32>>> for GlContext {
fn update_uniform(&self, location: i32, value: &Vec<nalgebra_glm::TVec2<f32>>) {
unsafe {
gl::Uniform2fv(
location,
value.len() as i32,
value.first().map(|x| x.as_ptr()).unwrap_or(null()),
)
}
}
}
impl UpdateUniform<&nalgebra_glm::TVec3<f32>> for GlContext {
fn update_uniform(&self, location: i32, value: &nalgebra_glm::TVec3<f32>) {
unsafe { gl::Uniform3f(location, value.x, value.y, value.z) }
}
}
impl UpdateUniform<&Vec<nalgebra_glm::TVec3<f32>>> for GlContext {
fn update_uniform(&self, location: i32, value: &Vec<nalgebra_glm::TVec3<f32>>) {
unsafe {
gl::Uniform3fv(
location,
value.len() as i32,
value.first().map(|x| x.as_ptr()).unwrap_or(null()),
)
}
}
}
impl UpdateUniform<&nalgebra_glm::TVec4<f32>> for GlContext {
fn update_uniform(&self, location: i32, value: &nalgebra_glm::TVec4<f32>) {
unsafe { gl::Uniform4f(location, value.x, value.y, value.z, value.w) }
}
}
impl UpdateUniform<&Vec<nalgebra_glm::TVec4<f32>>> for GlContext {
fn update_uniform(&self, location: i32, value: &Vec<nalgebra_glm::TVec4<f32>>) {
unsafe {
gl::Uniform4fv(
location,
value.len() as i32,
value.first().map(|x| x.as_ptr()).unwrap_or(null()),
)
}
}
}
impl UpdateUniform<f64> for GlContext {
fn update_uniform(&self, location: i32, value: f64) {
unsafe { gl::Uniform1d(location, value) }
}
}
impl UpdateUniform<&f64> for GlContext {
fn update_uniform(&self, location: i32, value: &f64) {
unsafe { gl::Uniform1d(location, *value) }
}
}
impl UpdateUniform<&Vec<f64>> for GlContext {
fn update_uniform(&self, location: i32, value: &Vec<f64>) {
unsafe { gl::Uniform1dv(location, value.len() as i32, value.as_ptr()) }
}
}
impl UpdateUniform<&nalgebra_glm::TVec1<f64>> for GlContext {
fn update_uniform(&self, location: i32, value: &nalgebra_glm::TVec1<f64>) {
unsafe { gl::Uniform1d(location, value.x) }
}
}
impl UpdateUniform<&nalgebra_glm::TVec2<f64>> for GlContext {
fn update_uniform(&self, location: i32, value: &nalgebra_glm::TVec2<f64>) {
unsafe { gl::Uniform2d(location, value.x, value.y) }
}
}
impl UpdateUniform<&Vec<nalgebra_glm::TVec2<f64>>> for GlContext {
fn update_uniform(&self, location: i32, value: &Vec<nalgebra_glm::TVec2<f64>>) {
unsafe {
gl::Uniform2dv(
location,
value.len() as i32,
value.first().map(|x| x.as_ptr()).unwrap_or(null()),
)
}
}
}
impl UpdateUniform<&nalgebra_glm::TVec3<f64>> for GlContext {
fn update_uniform(&self, location: i32, value: &nalgebra_glm::TVec3<f64>) {
unsafe { gl::Uniform3d(location, value.x, value.y, value.z) }
}
}
impl UpdateUniform<&Vec<nalgebra_glm::TVec3<f64>>> for GlContext {
fn update_uniform(&self, location: i32, value: &Vec<nalgebra_glm::TVec3<f64>>) {
unsafe {
gl::Uniform3dv(
location,
value.len() as i32,
value.first().map(|x| x.as_ptr()).unwrap_or(null()),
)
}
}
}
impl UpdateUniform<&nalgebra_glm::TVec4<f64>> for GlContext {
fn update_uniform(&self, location: i32, value: &nalgebra_glm::TVec4<f64>) {
unsafe { gl::Uniform4d(location, value.x, value.y, value.z, value.w) }
}
}
impl UpdateUniform<&Vec<nalgebra_glm::TVec4<f64>>> for GlContext {
fn update_uniform(&self, location: i32, value: &Vec<nalgebra_glm::TVec4<f64>>) {
unsafe {
gl::Uniform4dv(
location,
value.len() as i32,
value.first().map(|x| x.as_ptr()).unwrap_or(null()),
)
}
}
}
impl UpdateUniform<&Mat3> for GlContext {
fn update_uniform(&self, location: i32, value: &Mat3) {
unsafe { gl::UniformMatrix3fv(location, 1, u8::from(false), value.as_ptr()) }
}
}
impl UpdateUniform<&Mat4> for GlContext {
fn update_uniform(&self, location: i32, value: &Mat4) {
unsafe { gl::UniformMatrix4fv(location, 1, u8::from(false), value.as_ptr()) }
}
}
impl UpdateUniform<&TextureSlot> for GlContext {
fn update_uniform(&self, location: i32, value: &TextureSlot) {
unsafe { gl::Uniform1i(location, (*value as i32) - 0x84C0) }
}
}

@ -0,0 +1 @@
/target

@ -0,0 +1,388 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "alga"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f823d037a7ec6ea2197046bafd4ae150e6bc36f9ca347404f46a46823fa84f2"
dependencies = [
"approx",
"num-complex",
"num-traits",
]
[[package]]
name = "approx"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3"
dependencies = [
"num-traits",
]
[[package]]
name = "autocfg"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "c2-chacha"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb"
dependencies = [
"ppv-lite86",
]
[[package]]
name = "cc"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cmake"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62"
dependencies = [
"cc",
]
[[package]]
name = "generic-array"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd"
dependencies = [
"typenum",
]
[[package]]
name = "getrandom"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[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 = "glfw"
version = "0.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b4c1f2e99ce4181c37d9582986ed32a8f55235bdc9427258d96d09cc9666a29"
dependencies = [
"bitflags",
"glfw-sys",
"libc",
"log",
"objc",
"raw-window-handle",
"semver",
"winapi",
]
[[package]]
name = "glfw-sys"
version = "3.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b567b13b593ec58ea912b2658ee6230ffe20a069fa5b771800acc69bb3a157e"
dependencies = [
"cmake",
]
[[package]]
name = "khronos_api"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
[[package]]
name = "libc"
version = "0.2.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018"
[[package]]
name = "libm"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
[[package]]
name = "log"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
dependencies = [
"cfg-if",
]
[[package]]
name = "malloc_buf"
version = "0.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
dependencies = [
"libc",
]
[[package]]
name = "matrixmultiply"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4f7ec66360130972f34830bfad9ef05c6610a43938a467bcc9ab9369ab3478f"
dependencies = [
"rawpointer",
]
[[package]]
name = "nalgebra"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6511777ed3da44b6a11e732a66a7d6274dfbbcd68ad968e64b778dcb829d94a"
dependencies = [
"alga",
"approx",
"generic-array",
"matrixmultiply",
"num-complex",
"num-rational",
"num-traits",
"rand",
"rand_distr",
"typenum",
]
[[package]]
name = "nalgebra-glm"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ae78da13d67be0d2e4ab567490477e4c9f314fc151ddfff6713b15bdbb2aa72"
dependencies = [
"alga",
"approx",
"nalgebra",
"num-traits",
]
[[package]]
name = "num-complex"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-integer"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da4dc79f9e6c81bef96148c8f6b8e72ad4541caa4a24373e900a36da07de03a3"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
dependencies = [
"autocfg",
"libm",
]
[[package]]
name = "objc"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
dependencies = [
"malloc_buf",
]
[[package]]
name = "ppv-lite86"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom",
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853"
dependencies = [
"c2-chacha",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_distr"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2"
dependencies = [
"rand",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core",
]
[[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 = "rawpointer"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "triangle-time"
version = "0.1.0"
dependencies = [
"gl",
"glfw",
"nalgebra-glm",
]
[[package]]
name = "typenum"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "winapi"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
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-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "xml-rs"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "541b12c998c5b56aa2b4e6f18f03664eef9a4fd0a246a55594efae6cc2d964b5"

@ -0,0 +1,14 @@
[package]
name = "triangle-time"
version = "0.1.0"
authors = ["eater <=@eater.me>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
eatgel = { path = "../eatgel" }
glfw = "0.36.0"
gl = "0.14.0"
nalgebra-glm = "0.6.0"
image = "0.23.0"

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

@ -0,0 +1,11 @@
#version 330 core
out vec4 FragColor;
in vec2 TexCoord;
uniform sampler2D our_texture;
void main()
{
FragColor = texture(our_texture, TexCoord);
}

@ -0,0 +1,17 @@
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
out vec2 TexCoord;
// uniform mat4 transform;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
// note that we read the multiplication from right to left
gl_Position = projection * view * model * vec4(aPos, 1.0);
TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}

@ -0,0 +1,394 @@
use eatgel::buffer::StaticBufferNonIndexed;
use eatgel::shader::{Shader, ShaderProgram, ShaderType};
use eatgel::texture::{Image, ImageFormat, Texture, TextureSlot};
use eatgel::{GlContext, ShaderData, UpdateUniform, VertexData};
use glfw::ffi::glfwGetTime;
use glfw::{
flush_messages, Action, Callback, Context, Glfw, Key, OpenGlProfileHint, SwapInterval, Window,
WindowEvent, WindowHint, WindowMode,
};
use nalgebra_glm as glm;
use nalgebra_glm::{one, vec2, vec3, zero, Mat4, Vec2, Vec3};
use std::io::Cursor;
#[derive(ShaderData)]
struct Simple {
model: Mat4,
view: Mat4,
projection: Mat4,
our_texture: TextureSlot,
}
#[derive(VertexData)]
struct Vertex {
position: Vec3,
uv: Vec2,
}
impl Default for Simple {
fn default() -> Self {
Simple {
model: zero(),
view: zero(),
projection: zero(),
our_texture: TextureSlot::Slot0,
}
}
}
impl Simple {
pub fn new() -> Self {
Self::default()
}
}
struct State {
shader_program: ShaderProgram<Simple>,
texture: Texture,
context: GlContext,
object: StaticBufferNonIndexed,
size: (i32, i32),
}
fn init(mut context: GlContext, window: &Window) -> State {
let vertex_shader = Shader::compile(
ShaderType::Vertex,
include_str!("../shaders/simple_vertex.glsl"),
)
.expect("Failed to compile vertex shader");
let fragment_shader = Shader::compile(
ShaderType::Fragment,
include_str!("../shaders/simple_fragment.glsl"),
)
.expect("Failed to compile fragment shader");
let mut shader_program =
ShaderProgram::create_with_data(Simple::new(), vertex_shader, fragment_shader)
.expect("Failed create shader program");
let vertices = vec![
Vertex {
position: vec3(-0.5, -0.5, -0.5),
uv: vec2(0.0, 0.0),
},
Vertex {
position: vec3(0.5, -0.5, -0.5),
uv: vec2(1.0, 0.0),
},
Vertex {
position: vec3(0.5, 0.5, -0.5),
uv: vec2(1.0, 1.0),
},
Vertex {
position: vec3(0.5, 0.5, -0.5),
uv: vec2(1.0, 1.0),
},
Vertex {
position: vec3(-0.5, 0.5, -0.5),
uv: vec2(0.0, 1.0),
},
Vertex {
position: vec3(-0.5, -0.5, -0.5),
uv: vec2(0.0, 0.0),
},
Vertex {
position: vec3(-0.5, -0.5, 0.5),
uv: vec2(0.0, 0.0),
},
Vertex {
position: vec3(0.5, -0.5, 0.5),
uv: vec2(1.0, 0.0),
},
Vertex {
position: vec3(0.5, 0.5, 0.5),
uv: vec2(1.0, 1.0),
},
Vertex {
position: vec3(0.5, 0.5, 0.5),
uv: vec2(1.0, 1.0),
},
Vertex {
position: vec3(-0.5, 0.5, 0.5),
uv: vec2(0.0, 1.0),
},
Vertex {
position: vec3(-0.5, -0.5, 0.5),
uv: vec2(0.0, 0.0),
},
Vertex {
position: vec3(-0.5, 0.5, 0.5),
uv: vec2(1.0, 0.0),
},
Vertex {
position: vec3(-0.5, 0.5, -0.5),
uv: vec2(1.0, 1.0),
},
Vertex {
position: vec3(-0.5, -0.5, -0.5),
uv: vec2(0.0, 1.0),
},
Vertex {
position: vec3(-0.5, -0.5, -0.5),
uv: vec2(0.0, 1.0),
},
Vertex {
position: vec3(-0.5, -0.5, 0.5),
uv: vec2(0.0, 0.0),
},
Vertex {
position: vec3(-0.5, 0.5, 0.5),
uv: vec2(1.0, 0.0),
},
Vertex {
position: vec3(0.5, 0.5, 0.5),
uv: vec2(1.0, 0.0),
},
Vertex {
position: vec3(0.5, 0.5, -0.5),
uv: vec2(1.0, 1.0),
},
Vertex {
position: vec3(0.5, -0.5, -0.5),
uv: vec2(0.0, 1.0),
},
Vertex {
position: vec3(0.5, -0.5, -0.5),
uv: vec2(0.0, 1.0),
},
Vertex {
position: vec3(0.5, -0.5, 0.5),
uv: vec2(0.0, 0.0),
},
Vertex {
position: vec3(0.5, 0.5, 0.5),
uv: vec2(1.0, 0.0),
},
Vertex {
position: vec3(-0.5, -0.5, -0.5),
uv: vec2(0.0, 1.0),
},
Vertex {
position: vec3(0.5, -0.5, -0.5),
uv: vec2(1.0, 1.0),
},
Vertex {
position: vec3(0.5, -0.5, 0.5),
uv: vec2(1.0, 0.0),
},
Vertex {
position: vec3(0.5, -0.5, 0.5),
uv: vec2(1.0, 0.0),
},
Vertex {
position: vec3(-0.5, -0.5, 0.5),
uv: vec2(0.0, 0.0),
},
Vertex {
position: vec3(-0.5, -0.5, -0.5),
uv: vec2(0.0, 1.0),
},
Vertex {
position: vec3(-0.5, 0.5, -0.5),
uv: vec2(0.0, 1.0),
},
Vertex {
position: vec3(0.5, 0.5, -0.5),
uv: vec2(1.0, 1.0),
},
Vertex {
position: vec3(0.5, 0.5, 0.5),
uv: vec2(1.0, 0.0),
},
Vertex {
position: vec3(0.5, 0.5, 0.5),
uv: vec2(1.0, 0.0),
},
Vertex {
position: vec3(-0.5, 0.5, 0.5),
uv: vec2(0.0, 0.0),
},
Vertex {
position: vec3(-0.5, 0.5, -0.5),
uv: vec2(0.0, 1.0),
},
];
/*let data: &[f32] = &[
-0.5, -0.5, -0.5, 0.0, 0.0, 0.5, -0.5, -0.5, 1.0, 0.0, 0.5, 0.5, -0.5, 1.0, 1.0, 0.5, 0.5,
-0.5, 1.0, 1.0, -0.5, 0.5, -0.5, 0.0, 1.0, -0.5, -0.5, -0.5, 0.0, 0.0, -0.5, -0.5, 0.5,
0.0, 0.0, 0.5, -0.5, 0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 1.0, 0.5, 0.5, 0.5, 1.0, 1.0, -0.5,
0.5, 0.5, 0.0, 1.0, -0.5, -0.5, 0.5, 0.0, 0.0, -0.5, 0.5, 0.5, 1.0, 0.0, -0.5, 0.5, -0.5,
1.0, 1.0, -0.5, -0.5, -0.5, 0.0, 1.0, -0.5, -0.5, -0.5, 0.0, 1.0, -0.5, -0.5, 0.5, 0.0,
0.0, -0.5, 0.5, 0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 0.0, 0.5, 0.5, -0.5, 1.0, 1.0, 0.5,
-0.5, -0.5, 0.0, 1.0, 0.5, -0.5, -0.5, 0.0, 1.0, 0.5, -0.5, 0.5, 0.0, 0.0, 0.5, 0.5, 0.5,
1.0, 0.0, -0.5, -0.5, -0.5, 0.0, 1.0, 0.5, -0.5, -0.5, 1.0, 1.0, 0.5, -0.5, 0.5, 1.0, 0.0,
0.5, -0.5, 0.5, 1.0, 0.0, -0.5, -0.5, 0.5, 0.0, 0.0, -0.5, -0.5, -0.5, 0.0, 1.0, -0.5, 0.5,
-0.5, 0.0, 1.0, 0.5, 0.5, -0.5, 1.0, 1.0, 0.5, 0.5, 0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 0.0,
-0.5, 0.5, 0.5, 0.0, 0.0, -0.5, 0.5, -0.5, 0.0, 1.0,
];*/
let _indices: &[u32] = &[0, 1, 3, 1, 2, 3];
let object = context.create_static_buffer_non_indexed(vertices);
let bytes = Cursor::new(include_bytes!("../res/eater.png").to_vec());
shader_program.init(&mut context);
State {
shader_program,
context,
object,
texture: Image::load(bytes, ImageFormat::Png)
.expect("Failed to load image")
.into_texture(Default::default())
.expect("Failed to load as texture"),
size: window.get_size(),
}
}
fn render(state: &mut State, _glfw: &mut Glfw) {
let gl = &state.context;
let shader = &mut state.shader_program;
let texture = &state.texture;
gl.clear();
shader.enable();
texture.enable(TextureSlot::Slot0);
shader.our_texture = TextureSlot::Slot0;
let model = one::<Mat4>();
let _model = glm::rotate(&model, -55.0f32.to_radians(), &vec3(1.0f32, 0.0f32, 0.0f32));
let view = one::<Mat4>();
let view = glm::translate(&view, &vec3(0.0f32, 0.0f32, -3.0f32));
let projection: Mat4 = glm::perspective(45.0f32.to_radians(), 1.0, 0.1, 100.0);
/*let camera_pos: Vec3 = vec3(0.0, 0.0, 3.0);
let camera_target: Vec3 = vec3(0.0, 0.0, 0.0);
let camera_sub: Vec3 = camera_pos - camera_target;
let camera_direction: Vec3 = glm::normalize::<f32, U3>(&camera_sub);
let up = vec3(0.0, 1.0, 0.0);
let camera_right = glm::normalize(&glm::cross(&up, &camera_direction));
let camera_up = glm::cross(&camera_direction, &camera_right);
let view = glm::look_at(
&vec3(0.0, 0.0, 0.3),
&vec3(0.0, 0.0, 0.0),
&vec3(0.0, 0.1, 0.0),
);*/
// let trans = one::<Mat4>();
// let trans = glm::translate(&trans, &vec3(0.5, -0.5, 0.0f32));
unsafe {
gl::Enable(gl::MULTISAMPLE);
}
let translates = &[
glm::vec3(0.0, 0.0, 0.0),
glm::vec3(2.0, 5.0, -15.0),
glm::vec3(-1.5, -2.2, -2.5),
glm::vec3(-3.8, -2.0, -12.3),
glm::vec3(2.4, -0.4, -3.5),
glm::vec3(-1.7, 3.0, -7.5),
glm::vec3(1.3, -2.0, -2.5),
glm::vec3(1.5, 2.0, -2.5),
glm::vec3(1.5, 0.2, -1.5),
glm::vec3(-1.3, 1.0, -1.5),
];
shader.view = view;
shader.projection = projection;
let time = unsafe { glfwGetTime() } as f32;
let radius = 10.0;
let cam_x = time.sin() * radius;
let cam_z = time.cos() * radius;
shader.view = glm::look_at(
&vec3(cam_x, 0.0, cam_z),
&zero::<Vec3>(),
&vec3(0.0, 1.0, 0.0),
);
for i in 0..translates.len() {
let model = one::<Mat4>();
let model = glm::translate(&model, &translates[i]);
let angle = i as f32 * 20f32;
let model = glm::rotate(
&model,
unsafe { glfwGetTime() } as f32 * 50.0f32.to_radians(),
&vec3(0.5, 1.0, 0.0),
);
shader.model = glm::rotate(&model, angle, &vec3(1.0f32, 0.3f32, 0.5f32));
shader.apply(&gl);
state.object.draw();
}
}
fn main() {
let mut glfw = glfw::init::<()>(Some(Callback {
f: |err, err_str, _| {
println!("{:?}: {:?}", err, err_str);
},
data: (),
}))
.expect("Failed to init GLFW");
glfw.window_hint(WindowHint::ContextVersion(3, 3));
glfw.window_hint(WindowHint::OpenGlProfile(OpenGlProfileHint::Core));
glfw.window_hint(WindowHint::Samples(Some(4)));
let (mut window, events) = glfw
.create_window(500, 500, "T̶ R҉ I͜ A ͢N ͠G L̷ E̷", WindowMode::Windowed)
.expect("Failed to create window");
window.make_current();
window.set_key_polling(true);
glfw.set_swap_interval(SwapInterval::Adaptive);
let context = GlContext::new(|x| window.get_proc_address(x));
let mut state = init(context, &window);
unsafe {
gl::Viewport(0, 0, state.size.0, state.size.1);
gl::Enable(gl::DEPTH_TEST);
}
// let mut time = Instant::now();
// println!("0");
while !window.should_close() {
let (width, height) = window.get_size();
if state.size != (width, height) {
unsafe { gl::Viewport(0, 0, width, height) }
}
state.size = (width, height);
render(&mut state, &mut glfw);
window.swap_buffers();
glfw.poll_events();
for (_, event) in flush_messages(&events) {
if let WindowEvent::Key(key, _, Action::Release, _) = event {
if key == Key::Escape || key == Key::Q {
window.set_should_close(true);
}
}
}
//
// let new_time = Instant::now();
// println!(
// "\x1B[1A\x1B[Kfps: {}",
// (1.0 / (new_time - time).as_secs_f64()).floor()
// );
//
// time = new_time;
}
window.close();
}
Loading…
Cancel
Save