From b0854a665cdf29f27be0328e4717499d80ccaa98 Mon Sep 17 00:00:00 2001 From: Ricardo Alcantara Date: Tue, 21 Dec 2021 17:47:05 -0300 Subject: [PATCH] Update _2_text_rendering.rs --- Cargo.lock | 423 +++++++++++++----------- Cargo.toml | 2 + resources/fonts/Antonio-Bold.ttf | Bin 0 -> 37504 bytes src/_7_in_practice/_2_text_rendering.rs | 260 +++++++++++++++ src/_7_in_practice/mod.rs | 2 + src/_7_in_practice/shaders/text.fs | 12 + src/_7_in_practice/shaders/text.vs | 12 + src/main.rs | 1 + 8 files changed, 516 insertions(+), 196 deletions(-) create mode 100644 resources/fonts/Antonio-Bold.ttf create mode 100644 src/_7_in_practice/_2_text_rendering.rs create mode 100644 src/_7_in_practice/shaders/text.fs create mode 100644 src/_7_in_practice/shaders/text.vs diff --git a/Cargo.lock b/Cargo.lock index 31d991a..c3329f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,631 +1,662 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + [[package]] name = "adler32" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" [[package]] name = "approx" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08abcc3b4e9339e33a3d0a5ed15d84a687350c05689d825e0f6655eef9e76a94" [[package]] name = "arrayvec" version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" dependencies = [ - "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "nodrop", ] [[package]] name = "bitflags" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" [[package]] name = "byteorder" version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8389c509ec62b9fe8eca58c502a0acaf017737355615243496cde4994f8fa4f9" [[package]] name = "cc" -version = "1.0.18" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" [[package]] name = "cfg-if" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3" [[package]] name = "cgmath" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4b57c8f4e3a2e9ac07e0f6abc9c24b6fc9e1b54c3478cfb598f3d0023e51c" dependencies = [ - "approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "approx", + "num-traits 0.1.43", + "rand 0.4.3", ] [[package]] name = "cloudabi" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" dependencies = [ - "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", ] [[package]] name = "cmake" -version = "0.1.33" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7b858541263efe664aead4a5209a4ae5c5d2811167d4ed4ee0944503f8d2089" dependencies = [ - "cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", ] [[package]] name = "color_quant" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd" [[package]] name = "crossbeam-deque" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" dependencies = [ - "crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-epoch", + "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" dependencies = [ - "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec", + "cfg-if", + "crossbeam-utils", + "lazy_static", + "memoffset", + "nodrop", + "scopeguard", ] [[package]] name = "crossbeam-utils" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" dependencies = [ - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", ] [[package]] name = "deflate" version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32c8120d981901a9970a3a1c97cf8b630e0fa8c3ca31e75b6fd6fd5f9f427b31" dependencies = [ - "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "adler32", + "byteorder", ] [[package]] name = "either" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" [[package]] name = "enum_primitive" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180" +dependencies = [ + "num-traits 0.1.43", +] + +[[package]] +name = "freetype-rs" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73e26f5e4c01da8a78405a78078c1e6eba75ef7df900f5cf708583edd8f93f6c" +dependencies = [ + "bitflags", + "freetype-sys", + "libc", +] + +[[package]] +name = "freetype-sys" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac95ab6040ffce2a8e86c01e050bedf3d2763a17ae1719a5d4231da3078b1028" dependencies = [ - "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake", + "libc", + "pkg-config", ] [[package]] name = "fuchsia-zircon" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" dependencies = [ - "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "fuchsia-zircon-sys", ] [[package]] name = "fuchsia-zircon-sys" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" [[package]] name = "gif" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff3414b424657317e708489d2857d9575f4403698428b040b609b9d1c1a84a2c" dependencies = [ - "color_quant 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "color_quant", + "lzw", ] [[package]] name = "gl" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81457bb802910ad5b535eb48541c51830a761804aa5b7087adbc9d049aa57aca" dependencies = [ - "gl_generator 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gl_generator", ] [[package]] name = "gl_generator" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a795170cbd85b5a7baa58d6d7525cae6a03e486859860c220f7ebbbdd379d0a" dependencies = [ - "khronos_api 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "khronos_api", + "log", + "xml-rs", ] [[package]] name = "glfw" version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be0e1e2f834ed535c3e3d0e3f8b339187b1da7ff829ddf98757d0b2752a7b945" dependencies = [ - "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "glfw-sys 3.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "enum_primitive", + "glfw-sys", + "libc", + "log", + "num 0.1.42", + "semver", ] [[package]] name = "glfw-sys" version = "3.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f72bb86276679c5370276224546eef2dce99b23da2f364fd8b097c79db310b39" dependencies = [ - "cmake 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake", ] [[package]] name = "image" version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebdff791af04e30089bde8ad2a632b86af433b40c04db8d70ad4b21487db7a6a" dependencies = [ - "byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "gif 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jpeg-decoder 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-derive 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", - "num-rational 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "png 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder", + "gif", + "jpeg-decoder", + "lzw", + "num-derive", + "num-iter", + "num-rational 0.1.42", + "num-traits 0.2.5", + "png", + "scoped_threadpool", ] [[package]] name = "inflate" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f53b811ee8e2057ccf9643ca6b4277de90efaf5e61e55fd5254576926bb4245" dependencies = [ - "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "adler32", ] [[package]] name = "jpeg-decoder" version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8b7d43206b34b3f94ea9445174bda196e772049b9bddbc620c9d29b2d20110d" dependencies = [ - "byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder", + "rayon", ] [[package]] name = "khronos_api" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037ab472c33f67b5fbd3e9163a2645319e5356fcd355efa6d4eb7fff4bbcb554" [[package]] name = "lazy_static" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7" dependencies = [ - "version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check", ] [[package]] name = "learn-opengl-rs" version = "0.6.1" dependencies = [ - "cgmath 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", - "gl 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "glfw 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", - "image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tobj 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cgmath", + "freetype-rs", + "gl", + "glfw", + "image", + "num 0.2.0", + "rand 0.5.5", + "tobj", ] [[package]] name = "libc" version = "0.2.43" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" [[package]] name = "log" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cba860f648db8e6f269df990180c2217f333472b4a6e901e97446858487971e2" dependencies = [ - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", ] [[package]] name = "lzw" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084" [[package]] name = "memoffset" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" [[package]] name = "nodrop" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" [[package]] name = "nom" version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5b8c256fd9471521bcb84c3cdba98921497f1a331cbc15b8030fc63b82050ce" [[package]] name = "num" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" dependencies = [ - "num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", - "num-complex 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", - "num-rational 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.1.44", + "num-complex 0.1.43", + "num-integer", + "num-iter", + "num-rational 0.1.42", + "num-traits 0.2.5", ] [[package]] name = "num" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4825417e1e1406b3782a8ce92f4d53f26ec055e3622e1881ca8e9f5f9e08db" dependencies = [ - "num-bigint 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-complex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", - "num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.0", + "num-complex 0.2.0", + "num-integer", + "num-iter", + "num-rational 0.2.1", + "num-traits 0.2.5", ] [[package]] name = "num-bigint" version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e63899ad0da84ce718c14936262a41cee2c79c981fc0a0e7c7beb47d5a07e8c1" dependencies = [ - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer", + "num-traits 0.2.5", + "rand 0.4.3", + "rustc-serialize", ] [[package]] name = "num-bigint" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eceac7784c5dc97c2d6edf30259b4e153e6e2b42b3c85e9a6e9f45d06caef6e" dependencies = [ - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer", + "num-traits 0.2.5", ] [[package]] name = "num-complex" version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b288631d7878aaf59442cffd36910ea604ecd7745c36054328595114001c9656" dependencies = [ - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.5", + "rustc-serialize", ] [[package]] name = "num-complex" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68de83578789e0fbda3fa923035be83cf8bfd3b30ccfdecd5aa89bf8601f408e" dependencies = [ - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.5", ] [[package]] name = "num-derive" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d2c31b75c36a993d30c7a13d70513cb93f02acafdd5b7ba250f9b0e18615de7" dependencies = [ - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.14.8 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.5", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "num-integer" version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" dependencies = [ - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.5", ] [[package]] name = "num-iter" version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124" dependencies = [ - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer", + "num-traits 0.2.5", ] [[package]] name = "num-rational" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee314c74bd753fc86b4780aa9475da469155f3848473a261d2d18e35245a784e" dependencies = [ - "num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.1.44", + "num-integer", + "num-traits 0.2.5", + "rustc-serialize", ] [[package]] name = "num-rational" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e96f040177bb3da242b5b1ecf3f54b5d5af3efbbfb18608977a5d2767b22f10" dependencies = [ - "num-bigint 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.0", + "num-integer", + "num-traits 0.2.5", ] [[package]] name = "num-traits" version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" dependencies = [ - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.5", ] [[package]] name = "num-traits" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe" [[package]] name = "num_cpus" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] +[[package]] +name = "pkg-config" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" + [[package]] name = "png" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f54b9600d584d3b8a739e1662a595fab051329eff43f20e7d8cc22872962145b" dependencies = [ - "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "deflate 0.7.18 (registry+https://github.com/rust-lang/crates.io-index)", - "inflate 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "deflate", + "inflate", + "num-iter", ] [[package]] name = "proc-macro2" version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee5697238f0d893c7f0ecc59c0999f18d2af85e424de441178bcacc9f9e6cf67" dependencies = [ - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid", ] [[package]] name = "quote" version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed7d650913520df631972f21e104a4fa2f9c82a14afc65d17b388a2e29731e7c" dependencies = [ - "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", ] [[package]] name = "rand" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" dependencies = [ - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon", + "libc", + "winapi", ] [[package]] name = "rand" version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" dependencies = [ - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cloudabi", + "fuchsia-zircon", + "libc", + "rand_core", + "winapi", ] [[package]] name = "rand_core" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2" [[package]] name = "rayon" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df7a791f788cb4c516f0e091301a29c2b71ef680db5e644a7d68835c8ae6dbfa" dependencies = [ - "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque", + "either", + "rayon-core", ] [[package]] name = "rayon-core" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" dependencies = [ - "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque", + "lazy_static", + "libc", + "num_cpus", ] [[package]] name = "rustc-serialize" version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" [[package]] name = "scoped_threadpool" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" [[package]] name = "scopeguard" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" [[package]] name = "semver" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d5b7638a1f03815d94e88cb3b3c08e87f0db4d683ef499d1836aaf70a45623f" dependencies = [ - "nom 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "nom", ] [[package]] name = "syn" version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7bfcbb0c068d0f642a0ffbd5c604965a360a61f99e8add013cef23a838614f3" dependencies = [ - "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "unicode-xid", ] [[package]] name = "tobj" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5eb0cdeabef6fcefb92c6dcb8571ba1880d36eb608da4f9cf62673765eadc31" [[package]] name = "unicode-xid" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" [[package]] name = "version_check" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7716c242968ee87e5542f8021178248f267f295a5c4803beae8b8b7fd9bc6051" [[package]] name = "winapi" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd" dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "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.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2" dependencies = [ - "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[metadata] -"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" -"checksum approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08abcc3b4e9339e33a3d0a5ed15d84a687350c05689d825e0f6655eef9e76a94" -"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" -"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" -"checksum byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8389c509ec62b9fe8eca58c502a0acaf017737355615243496cde4994f8fa4f9" -"checksum cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "2119ea4867bd2b8ed3aecab467709720b2d55b1bcfe09f772fd68066eaf15275" -"checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3" -"checksum cgmath 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "64a4b57c8f4e3a2e9ac07e0f6abc9c24b6fc9e1b54c3478cfb598f3d0023e51c" -"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum cmake 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)" = "704fbf3bb5149daab0afb255dbea24a1f08d2f4099cedb9baab6d470d4c5eefb" -"checksum color_quant 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd" -"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" -"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" -"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" -"checksum deflate 0.7.18 (registry+https://github.com/rust-lang/crates.io-index)" = "32c8120d981901a9970a3a1c97cf8b630e0fa8c3ca31e75b6fd6fd5f9f427b31" -"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" -"checksum enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180" -"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum gif 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff3414b424657317e708489d2857d9575f4403698428b040b609b9d1c1a84a2c" -"checksum gl 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "81457bb802910ad5b535eb48541c51830a761804aa5b7087adbc9d049aa57aca" -"checksum gl_generator 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a795170cbd85b5a7baa58d6d7525cae6a03e486859860c220f7ebbbdd379d0a" -"checksum glfw 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "be0e1e2f834ed535c3e3d0e3f8b339187b1da7ff829ddf98757d0b2752a7b945" -"checksum glfw-sys 3.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f72bb86276679c5370276224546eef2dce99b23da2f364fd8b097c79db310b39" -"checksum image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebdff791af04e30089bde8ad2a632b86af433b40c04db8d70ad4b21487db7a6a" -"checksum inflate 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6f53b811ee8e2057ccf9643ca6b4277de90efaf5e61e55fd5254576926bb4245" -"checksum jpeg-decoder 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c8b7d43206b34b3f94ea9445174bda196e772049b9bddbc620c9d29b2d20110d" -"checksum khronos_api 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "037ab472c33f67b5fbd3e9163a2645319e5356fcd355efa6d4eb7fff4bbcb554" -"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7" -"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" -"checksum log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cba860f648db8e6f269df990180c2217f333472b4a6e901e97446858487971e2" -"checksum lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084" -"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" -"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" -"checksum nom 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b8c256fd9471521bcb84c3cdba98921497f1a331cbc15b8030fc63b82050ce" -"checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" -"checksum num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf4825417e1e1406b3782a8ce92f4d53f26ec055e3622e1881ca8e9f5f9e08db" -"checksum num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "e63899ad0da84ce718c14936262a41cee2c79c981fc0a0e7c7beb47d5a07e8c1" -"checksum num-bigint 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3eceac7784c5dc97c2d6edf30259b4e153e6e2b42b3c85e9a6e9f45d06caef6e" -"checksum num-complex 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "b288631d7878aaf59442cffd36910ea604ecd7745c36054328595114001c9656" -"checksum num-complex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "68de83578789e0fbda3fa923035be83cf8bfd3b30ccfdecd5aa89bf8601f408e" -"checksum num-derive 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d2c31b75c36a993d30c7a13d70513cb93f02acafdd5b7ba250f9b0e18615de7" -"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" -"checksum num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124" -"checksum num-rational 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "ee314c74bd753fc86b4780aa9475da469155f3848473a261d2d18e35245a784e" -"checksum num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4e96f040177bb3da242b5b1ecf3f54b5d5af3efbbfb18608977a5d2767b22f10" -"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" -"checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe" -"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" -"checksum png 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f54b9600d584d3b8a739e1662a595fab051329eff43f20e7d8cc22872962145b" -"checksum proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "ee5697238f0d893c7f0ecc59c0999f18d2af85e424de441178bcacc9f9e6cf67" -"checksum quote 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ed7d650913520df631972f21e104a4fa2f9c82a14afc65d17b388a2e29731e7c" -"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" -"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" -"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2" -"checksum rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "df7a791f788cb4c516f0e091301a29c2b71ef680db5e644a7d68835c8ae6dbfa" -"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" -"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" -"checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" -"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" -"checksum semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2d5b7638a1f03815d94e88cb3b3c08e87f0db4d683ef499d1836aaf70a45623f" -"checksum syn 0.14.8 (registry+https://github.com/rust-lang/crates.io-index)" = "b7bfcbb0c068d0f642a0ffbd5c604965a360a61f99e8add013cef23a838614f3" -"checksum tobj 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c5eb0cdeabef6fcefb92c6dcb8571ba1880d36eb608da4f9cf62673765eadc31" -"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" -"checksum version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7716c242968ee87e5542f8021178248f267f295a5c4803beae8b8b7fd9bc6051" -"checksum winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2" + "bitflags", +] diff --git a/Cargo.toml b/Cargo.toml index a7b1dd4..e8e7ff7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,8 @@ image = "0.19.0" tobj = "0.1.6" num = "0.2.0" rand = "0.5.5" +# only needed from chapter 7 text_rendering +freetype-rs = "0.29.0" [features] default = [ diff --git a/resources/fonts/Antonio-Bold.ttf b/resources/fonts/Antonio-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..6e78cd28971553405c51c9d31bf17472c1e2089d GIT binary patch literal 37504 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 literal 0 HcmV?d00001 diff --git a/src/_7_in_practice/_2_text_rendering.rs b/src/_7_in_practice/_2_text_rendering.rs new file mode 100644 index 0000000..34fe361 --- /dev/null +++ b/src/_7_in_practice/_2_text_rendering.rs @@ -0,0 +1,260 @@ +#![allow(non_upper_case_globals)] +extern crate glfw; +use self::glfw::{Action, Context, Key}; + +extern crate gl; +use self::gl::types::*; + +use std::collections::HashMap; +use std::ffi::CStr; +use std::mem; +use std::os::raw::c_void; +use std::path::Path; +use std::ptr; +use std::sync::mpsc::Receiver; + +use cgmath::{Matrix, Matrix4}; + +use shader::Shader; + +// settings +const SCR_WIDTH: u32 = 800; +const SCR_HEIGHT: u32 = 600; + +struct Character { + texture: u32, + size: cgmath::Vector2, + bearing: cgmath::Vector2, + advance: u32, +} + +#[allow(non_snake_case)] +pub fn main_7_2() { + // glfw: initialize and configure + // ------------------------------ + let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap(); + glfw.window_hint(glfw::WindowHint::ContextVersion(3, 3)); + glfw.window_hint(glfw::WindowHint::OpenGlProfile(glfw::OpenGlProfileHint::Core)); + #[cfg(target_os = "macos")] + glfw.window_hint(glfw::WindowHint::OpenGlForwardCompat(true)); + + // glfw window creation + // -------------------- + let (mut window, events) = glfw + .create_window(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", glfw::WindowMode::Windowed) + .expect("Failed to create GLFW window"); + + window.make_current(); + window.set_key_polling(true); + window.set_framebuffer_size_polling(true); + + // gl: load all OpenGL function pointers + // --------------------------------------- + gl::load_with(|symbol| window.get_proc_address(symbol) as *const _); + + let (shader, vao, vbo, characters) = unsafe { + // OpenGL state + // ------------ + gl::Enable(gl::CULL_FACE); + gl::Enable(gl::BLEND); + gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA); + + // compile and setup the shader + // ---------------------------- + let shader = Shader::new("src/_7_in_practice/shaders/text.vs", "src/_7_in_practice/shaders/text.fs"); + let projection: Matrix4 = cgmath::ortho(0.0, SCR_WIDTH as f32, 0.0, SCR_HEIGHT as f32, -1.0, 1.0); + shader.useProgram(); + let projection_loc = gl::GetUniformLocation(shader.ID, c_str!("projection").as_ptr()); + gl::UniformMatrix4fv(projection_loc, 1, gl::FALSE, projection.as_ptr()); + + // Init the library + let lib = freetype::Library::init().expect("ERROR::FREETYPE: Could not init FreeType Library"); + // find path to font + let font_name = Path::new("resources/fonts/Antonio-Bold.ttf"); + if !font_name.exists() { + print!("ERROR::FREETYPE: Failed to load font_name"); + return; + } + // Load a font face + let face = lib + .new_face(font_name, 0) + .expect("ERROR::FREETYPE: Failed to load font"); + + // set size to load glyphs as + face.set_pixel_sizes(0, 48).unwrap(); + + // disable byte-alignment restriction + gl::PixelStorei(gl::UNPACK_ALIGNMENT, 1); + + let mut characters: HashMap = HashMap::new(); + + // load first 128 characters of ASCII set + for c in 0..128 { + // Load character glyph + face.load_char(c, freetype::face::LoadFlag::RENDER) + .expect("ERROR::FREETYTPE: Failed to load Glyph"); + + let bitmap = face.glyph().bitmap(); + // generate texture + let mut texture = 0; + gl::GenTextures(1, &mut texture); + gl::BindTexture(gl::TEXTURE_2D, texture); + gl::TexImage2D( + gl::TEXTURE_2D, + 0, + gl::RED as i32, + bitmap.width(), + bitmap.rows() as i32, + 0, + gl::RED, + gl::UNSIGNED_BYTE, + bitmap.buffer().as_ptr() as *const c_void, + ); + // set texture options + gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as i32); + gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as i32); + gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR as i32); + gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as i32); + // now store character for later use + let character = Character { + texture, + size: cgmath::vec2(bitmap.width(), bitmap.rows()), + bearing: cgmath::vec2(face.glyph().bitmap_left(), face.glyph().bitmap_top()), + advance: face.glyph().advance().x as u32, + }; + + characters.insert(c as GLchar, character); + } + gl::BindTexture(gl::TEXTURE_2D, 0); + + // configure VAO/VBO for texture quads + // ----------------------------------- + let (mut VBO, mut VAO) = (0, 0); + gl::GenVertexArrays(1, &mut VAO); + gl::GenBuffers(1, &mut VBO); + gl::BindVertexArray(VAO); + gl::BindBuffer(gl::ARRAY_BUFFER, VBO); + gl::BufferData(gl::ARRAY_BUFFER, 6 * 4 * mem::size_of::() as GLsizeiptr, ptr::null(), gl::DYNAMIC_DRAW); + gl::EnableVertexAttribArray(0); + gl::VertexAttribPointer(0, 4, gl::FLOAT, gl::FALSE, 4 * mem::size_of::() as GLsizei, ptr::null()); + gl::BindBuffer(gl::ARRAY_BUFFER, 0); + gl::BindVertexArray(0); + + (shader, VAO, VBO, characters) + }; + + // render loop + // ----------- + while !window.should_close() { + // events + // ----- + + process_events(&mut window, &events); + unsafe { + gl::ClearColor(0.2, 0.3, 0.3, 1.0); + gl::Clear(gl::COLOR_BUFFER_BIT); + render_text( + &shader, + vao, + vbo, + &characters, + String::from("This is sample text"), + 25.0, + 25.0, + 1.0, + cgmath::vec3(0.5, 0.8, 0.2), + ); + render_text( + &shader, + vao, + vbo, + &characters, + String::from("(C) LearnOpenGL.com"), + 540.0, + 570.0, + 0.5, + cgmath::vec3(0.3, 0.7, 0.9), + ); + } + + // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.) + // ------------------------------------------------------------------------------- + window.swap_buffers(); + glfw.poll_events(); + } +} + +fn process_events(window: &mut glfw::Window, events: &Receiver<(f64, glfw::WindowEvent)>) { + for (_, event) in glfw::flush_messages(events) { + match event { + glfw::WindowEvent::FramebufferSize(width, height) => { + // make sure the viewport matches the new window dimensions; note that width and + // height will be significantly larger than specified on retina displays. + unsafe { gl::Viewport(0, 0, width, height) } + } + glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => window.set_should_close(true), + _ => {} + } + } +} + +// render line of text +// ------------------- +unsafe fn render_text( + shader: &Shader, + vao: u32, + vbo: u32, + characters: &HashMap, + text: String, + x: f32, + y: f32, + scale: f32, + color: cgmath::Vector3, +) { + // activate corresponding render state + shader.useProgram(); + let text_color_loc = gl::GetUniformLocation(shader.ID, c_str!("textColor").as_ptr()); + gl::Uniform3f(text_color_loc, color.x, color.y, color.z); + gl::ActiveTexture(gl::TEXTURE0); + gl::BindVertexArray(vao); + + let mut x_pos = x; + + // iterate through all characters + for c in text.chars() { + let key_c = c as GLchar; + let ch = &characters[&key_c]; + + let xpos = x_pos + ch.bearing.x as f32 * scale; + let ypos = y - (ch.size.y - ch.bearing.y) as f32 * scale; + + let w = ch.size.x as f32 * scale; + let h = ch.size.y as f32 * scale; + + #[rustfmt::skip] + let vertices: [[f32; 4]; 6] = [ + [ xpos, ypos + h, 0.0, 0.0 ], + [ xpos, ypos, 0.0, 1.0 ], + [ xpos + w, ypos, 1.0, 1.0 ], + + [ xpos, ypos + h, 0.0, 0.0 ], + [ xpos + w, ypos, 1.0, 1.0 ], + [ xpos + w, ypos + h, 1.0, 0.0 ], + ]; + + // render glyph texture over quad + gl::BindTexture(gl::TEXTURE_2D, ch.texture); + // update content of VBO memory + gl::BindBuffer(gl::ARRAY_BUFFER, vbo); + gl::BufferSubData(gl::ARRAY_BUFFER, 0, mem::size_of_val(&vertices) as GLsizeiptr, mem::transmute(&vertices[0])); // be sure to use gl::BufferSubData and not gl::BufferData + + gl::BindBuffer(gl::ARRAY_BUFFER, 0); + // render quad + gl::DrawArrays(gl::TRIANGLES, 0, 6); + // now advance cursors for next glyph (note that advance is number of 1/64 pixels) + x_pos += (ch.advance >> 6) as f32 * scale; // bitshift by 6 to get value in pixels (2^6 = 64 (divide amount of 1/64th pixels by 64 to get amount of pixels)) + } + + gl::BindVertexArray(0); + gl::BindTexture(gl::TEXTURE_2D, 0); +} diff --git a/src/_7_in_practice/mod.rs b/src/_7_in_practice/mod.rs index 43fc988..92d1419 100644 --- a/src/_7_in_practice/mod.rs +++ b/src/_7_in_practice/mod.rs @@ -1,2 +1,4 @@ mod _1_debugging; pub use self::_1_debugging::*; +mod _2_text_rendering; +pub use self::_2_text_rendering::*; diff --git a/src/_7_in_practice/shaders/text.fs b/src/_7_in_practice/shaders/text.fs new file mode 100644 index 0000000..bbd0c17 --- /dev/null +++ b/src/_7_in_practice/shaders/text.fs @@ -0,0 +1,12 @@ +#version 330 core +in vec2 TexCoords; +out vec4 color; + +uniform sampler2D text; +uniform vec3 textColor; + +void main() +{ + vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, TexCoords).r); + color = vec4(textColor, 1.0) * sampled; +} \ No newline at end of file diff --git a/src/_7_in_practice/shaders/text.vs b/src/_7_in_practice/shaders/text.vs new file mode 100644 index 0000000..bc275bd --- /dev/null +++ b/src/_7_in_practice/shaders/text.vs @@ -0,0 +1,12 @@ +#version 330 core +layout (location = 0) in vec4 vertex; // +out vec2 TexCoords; + +uniform mat4 projection; + +void main() +{ + gl_Position = projection * vec4(vertex.xy, 0.0, 1.0); + TexCoords = vertex.zw; +} + diff --git a/src/main.rs b/src/main.rs index 1d19d31..b711a40 100644 --- a/src/main.rs +++ b/src/main.rs @@ -118,6 +118,7 @@ fn main() { #[cfg(feature = "chapter-6")] "6_1_2" => main_6_1_2(), #[cfg(feature = "chapter-7")] "7_1" => main_7_1(), + #[cfg(feature = "chapter-7")] "7_2" => main_7_2(), _ => println!("Unknown tutorial id") }